Copybara import of the project: - 640766f44da30e659d473363fe3788f68210c91b Initial commit by Daniel Fisher <dfisher@gmail.com> - db8feea6954332f952028d55b1c6c1986bbe0e51 Add license, readme, and notice. by Daniel Fisher <dfisher@vt.edu> - 6b675dc0299d842316555b1323f5fe6b24527671 Add checkstyle config. by Daniel Fisher <dfisher@vt.edu> - 9fc1ff830ed4c545d1798c1236ae1d786e72dd76 Create multi module maven project. by Daniel Fisher <dfisher@vt.edu> - 1969f3f65e2705092d2b8e89277f01b58366c172 Add apache provider. by Daniel Fisher <dfisher@vt.edu> - 766cf9e83fc271c1ecbf1172e07d4b26f2e62d59 groupId not needed for child project. by Daniel Fisher <dfisher@vt.edu> - 7a6d432919a16e12fda2bec43a6caa10a0e6679c Add jldap provider. by Daniel Fisher <dfisher@vt.edu> - 096286255b376ccc40215ec8934c76c942a95165 Add opendj provider. by Daniel Fisher <dfisher@vt.edu> - 6c39c062ea7390aa758fb17e6cbd92389e878c65 Add unboundid provider. by Daniel Fisher <dfisher@vt.edu> - ded3084c975ad07fdf50b2f3ec356ee0f47489df Add description. by Daniel Fisher <dfisher@vt.edu> - 70cb87f6f5769af8fadd53fd528bfa51522839c2 Add beans library. by Daniel Fisher <dfisher@vt.edu> - b73703df6f3ee136c53d8740512c614928c91f88 Add json library. by Daniel Fisher <dfisher@vt.edu> - 6ac8b1c5bc5c1c82b907a6be91393b00299fc2fd Add templates library. by Daniel Fisher <dfisher@vt.edu> - ad3d02437290c323d7b7153bb38095a922951853 Add ldaptive webapp. by Daniel Fisher <dfisher@vt.edu> - 2984e9b7053c04fda1cdba3ab02d9f916ba3b156 Add module for creating distros. by Daniel Fisher <dfisher@vt.edu> - 834ff0422f4862425f74899787b2a19a7f0d50e9 Add integration test module. by Daniel Fisher <dfisher@vt.edu> - 2b86a211cadca4a495530fa4c1080382966a255a Add ldapi module. by Daniel Fisher <dfisher@vt.edu> - 9ea245c855aa726ef3ff2219f7e71d3d5c41f0c7 Update parent pom for child modules. by Daniel Fisher <dfisher@vt.edu> - 4f519586fb25ffcfa87bbeb0a03b03d5ea6e55fa Add ignore file. by Daniel Fisher <dfisher@vt.edu> - 744ee88f3928eecaf67922629c0c1506236efeae Add suppression annotation for unchecked varargs. by Daniel Fisher <dfisher@vt.edu> - 4377460cad4aa5bc2fcba407484905d6cddbd1a3 Update dependency versions. by Daniel Fisher <dfisher@vt.edu> - 7e745cd9646c167e41d7a0577cdd3cf0e0649389 Intellij cleanup. by Daniel Fisher <dfisher@vt.edu> - 995a46e2657b608b6ac9c5caf4f0d7197933ae5c Remove deprecated methods for version 1.1 by Daniel Fisher <dfisher@vt.edu> - d0a6ab61c933582827bcd65bcfff0ef9fec60017 Add scripts to make handling profiles easier. by Daniel Fisher <dfisher@vt.edu> - 608126a28a5382474d16a45475f50301f79ed5b5 Update source header. by Daniel Fisher <dfisher@vt.edu> - eee58c24b36c8a79f206253ff75bc80ced247525 Put original header back. by Daniel Fisher <dfisher@vt.edu> - 6fe5702d9cb918c240f68faded432874346ded9e Update for package script. by Daniel Fisher <dfisher@vt.edu> - e39c68bb7e8aac45278d687cdba7a5dd8f21ee53 Remove @version javadoc. by Daniel Fisher <dfisher@vt.edu> - 21a801df1b0a29b2c58218181eb59aa620cc0232 Remove javadoc version check. by Daniel Fisher <dfisher@vt.edu> - d3f396bd13d521e6d1efff1264436a22fbc8dfac Fix headers on generated source. by Daniel Fisher <dfisher@vt.edu> - 9cc3d821cd7a9ee2a05731bff4b560bb3023d436 Merge pull request #8 from vt-middleware/authz-id-entry-r... by Marvin S. Addison <marvin.addison@gmail.com> - 6798a5dd5b2e9e73859ce945e82b7faf7c1060ad Merge pull request #10 from vt-middleware/primary-group-id by Marvin S. Addison <marvin.addison@gmail.com> - c825492dad8df4750669e8c191a203f4f6234bf2 Add scheme support to the LdapURL class. by Daniel Fisher <dfisher@vt.edu> - e5c03beaaa3236d35a165a1e214f8f745f40aa7e Merge pull request #15 from vt-middleware/binary-attrs by David Hawes <dhawes@gmail.com> - b05ad6e49b746c9f7852cfd0abb107c4b06c4c9b Merge pull request #12 from vt-middleware/dns-srv by Daniel Fisher <dfisher@gmail.com> - bc78661049ffa60b73a0d10f1dadfa2d4e4211f0 Merge pull request #17 from vt-middleware/try-with-resour... by Marvin S. Addison <marvin.addison@gmail.com> - f149f9d95624778bf7c95faf4ce5ff1c5aa68541 Javadoc typo. by Daniel Fisher <dfisher@vt.edu> - a27497786ef91b22c72dce17e3d48dc3dd073073 Change version property names. by Daniel Fisher <dfisher@vt.edu> - f6aa34b97baf81380c778e07e4fb38f79fd6a5e6 Merge branch 'master' of github.com:vt-middleware/ldaptive by Daniel Fisher <dfisher@vt.edu> - dc3933e6a9f3df7104d35db7fbdfb8f47eab4f26 Update plugin and dependency versions. by Daniel Fisher <dfisher@vt.edu> - ebfdf55cab170eeec36fbb40a7eaa98b41d35739 Remove inheritDoc from @Override methods. by Daniel Fisher <dfisher@vt.edu> - 2f34256083eb00d2f2260429dea6c3913031756c Add object to the log statement. by Daniel Fisher <dfisher@vt.edu> - 85a65c9c9094a83aba8e7a80f295ae477000f0bc Fix checkstyle error. by Daniel Fisher <dfisher@vt.edu> - 158d48604345f3cdec5c37d059d5b57206cc90bf Add #renameAttribute method. by Daniel Fisher <dfisher@vt.edu> - aa19f789b091d93581a81572a682c03e450af89a Add unit test for LdapEntry#renameAttribute. by Daniel Fisher <dfisher@vt.edu> - cd99f5007cd847af35ac110499afa75518cb16e2 Fix mapping of byte[]. by Daniel Fisher <dfisher@vt.edu> - 1bb20f81a1b9bd02e77a03fe19f82f9ee5cd5e33 Fix issue #21. by Daniel Fisher <dfisher@vt.edu> - 297c6d1ebc8645ea75c6e22ec10e36c4f156da9c Fix checkstyle error. by Daniel Fisher <dfisher@gmail.com> - 4718a30383c59583c2016bf7ccf5bf8204c1faba Fixes issue #24. by Daniel Fisher <dfisher@gmail.com> - 034f731f439b9d08ab88058afeaa58dbb73ef366 Fixes #23. by Daniel Fisher <dfisher@gmail.com> - cd6fab4e553d5f6839373027aa59c2e6f601f32a Use a single type converter for all contexts. by Daniel Fisher <dfisher@vt.edu> - ffd00bcd8aca2214f9595a7db9c6854b166d5e0e Leverage jquery #text function to escape html. by Daniel Fisher <dfisher@vt.edu> - 860c2def6c672c436bb4600575cd81f21e586e31 Don't swallow exceptions on DN resolution. by Daniel Fisher <dfisher@vt.edu> - 65d1aed82caa3597c2acec4c1ebab378f1e23290 Bump copyright year. by Daniel Fisher <dfisher@vt.edu> - 8c2f9981df8b33673b61e35fce3db2868d21490d Merge pull request #26 from vt-middleware/referral-handler by Marvin S. Addison <marvin.addison@gmail.com> - 5a69a87a1003d9a8914fed7ee5ddfc111f89c14f Jalopy source code cleanup. by Daniel Fisher <dfisher@vt.edu> - eb6d7dd7bb3e0f8f327dfaed36084084481a310e Update dependencies. by Daniel Fisher <dfisher@vt.edu> - 0a31744188bb051e743cceffddf705e54d18bd6e Add null check to the search referral handler. by Daniel Fisher <dfisher@vt.edu> - 33b4be21e465f6f185b13751c9a79d204fc1b813 Merge pull request #30 from vt-middleware/auth-res-resolv... by Marvin S. Addison <marvin.addison@gmail.com> - d938e5de2671c0bb6bf6e5a09fbcae7664144dd8 Checkstyle cleanup. by Daniel Fisher <dfisher@vt.edu> - dd8631e4fa7bdfb4c38fdb583e95b85f51059103 Property renamed or no longer exists. by Daniel Fisher <dfisher@vt.edu> - 2c572f4ae5c1e5d4f5699e51fd51b27b6828c2d9 Update CredentialConfigFactory. by Daniel Fisher <dfisher@vt.edu> - 6035d8f7b04243ad55476ffd174a19bd1c837855 Update DTD versions. by Daniel Fisher <dfisher@vt.edu> - 91b6add2f475d271eac439dab34b23c5b4b6b741 Allow empty DESC. by Daniel Fisher <dfisher@vt.edu> - 425d031f48292da8d0a4edde66d10bfc8c27bbef Move to three digit version numbers. by Daniel Fisher <dfisher@vt.edu> - cbc1f1ca09876faeafacac92bbadeced3e1a1b98 Support OSGI manifest entries. by Daniel Fisher <dfisher@vt.edu> - 41706d42d8bbb4b625f52047662d5352de70760c Bug in #find implementation. by Daniel Fisher <dfisher@vt.edu> - 6a7c3a9e99fc1f2133f60cc5024be78654b16382 Add generics to ldap entry mappers. by Daniel Fisher <dfisher@vt.edu> - 442f5d9df070b4494539313f8c9a70df82f9f3d7 Remove attribute only if it was created. by Daniel Fisher <dfisher@vt.edu> - edbb670629e425a4c306641f05230368a84cf0c8 Merge pull request #38 from vt-middleware/dnparser-substr... by Marvin S. Addison <marvin.addison@gmail.com> - a7c01c7d06331582eeb9d583bd1a7f882a4a36eb Add support for no delimiter. by Daniel Fisher <dfisher@vt.edu> - c5c53b4fb721509909b2366bd0004e6d5bbb3e1c Use SearchResult#getNameInNamespace for search DNs. by Daniel Fisher <dfisher@vt.edu> - 7479aa3d78a64e5637e4bbd969aaf69137deaed6 Refactor #isInitialized to return a boolean. by Daniel Fisher <dfisher@vt.edu> - 23e782740c53c767aa67583b60e0113fb0bcd74d Unreachable block. by Daniel Fisher <dfisher@vt.edu> - 0f41735b6a86395020d1f35c85206a3f185cc318 Review test data with Java 7 & 8 in mind. by Daniel Fisher <dfisher@vt.edu> - 576d40c1dfa7e2e06d4923cb9fb851cd2dea37bd UnboundID can support cipher suites and protocols. by Daniel Fisher <dfisher@vt.edu> - 4e1ec7b058dd0bcb3cec3389b218d99a7a621cfa Add support Sorting and VLV controls for apache. by Daniel Fisher <dfisher@vt.edu> - 7f0b86e530a2ac3d25ff44fdbfccbaa23a49b76c Update plugin and dependency versions. by Daniel Fisher <dfisher@vt.edu> - c7c4f8e87e57dcbe9cc8be4e370b6c922ed79496 Prefer error over warning. by Daniel Fisher <dfisher@vt.edu> - 367e1f713b85db49d20a1ae765a9a6f60043caa6 pom.version is deprecated. by Daniel Fisher <dfisher@vt.edu> - eb0f8bc70fbefa223389068450b8ea24b9d6108b Checkstyle updates. by Daniel Fisher <dfisher@vt.edu> - fa98184e589733a7e7a2a39efba455b241f46fc6 Prefer edirectory error over warning. by Daniel Fisher <dfisher@vt.edu> - 953fc1ed4f09cf447713986f2848b4d6e09a19ba Don't throw unless no result code is found. by Daniel Fisher <dfisher@vt.edu> - 0476380f0af19e4fb7a94351fd0c5275a0421930 Enums reflection instantiation was incorrect. by Daniel Fisher <dfisher@vt.edu> - 2718807657fe48ba3de65cb9401fc5d03dbfd2ab Update plugin and dependency versions. by Daniel Fisher <dfisher@vt.edu> - 3109efc5b42b2d52c07c25863732d8901710373f Improve SSL related logging. by Daniel Fisher <dfisher@vt.edu> - 28c62d436b2af9647d9a0bcf8ec3b3eecf202eea Merge pull request #48 from mmoayyed/maven-badge by Daniel Fisher <dfisher@gmail.com> - 37847fb5afe2f7afe6c6e7738c3a12cb689aec17 Merge pull request #49 from vt-middleware/edir-auth-resp-... by Daniel Fisher <dfisher@gmail.com> - 2c0c7a9f4dd5441e86536eb4b1f03dce71de2d1b Update dependency versions. by Daniel Fisher <dfisher@vt.edu> - 447a04ac4512af17f23eb4ccaf1dcff54b69ee2f DigestMD5 works with the latest library. by Daniel Fisher <dfisher@vt.edu> - b1058a4f8bc7b8bf7622794a00699752112cdced DigestMD5 support by all providers now. by Daniel Fisher <dfisher@vt.edu> - a94eddd999c941f56234af75b152fa8d3867259a OpenDJ no longer hangs on this test. by Daniel Fisher <dfisher@vt.edu> - 3771a11beabba0f1dea5dc0ddee0dce60a32ffaa Fix checkstyle error. by Daniel Fisher <dfisher@vt.edu> - a21592e878dd07cbe4a0429eb00442e8529ad802 API change. by Daniel Fisher <dfisher@vt.edu> - f3d68334b9264ecc92cde4c314e8cf9ec1a9da70 Package should not be required for test execution. by Daniel Fisher <dfisher@vt.edu> - 747edbfbf9e46327fe27ac76c33562ebf52174c4 Include the exception message in the string format. by Daniel Fisher <dfisher@vt.edu> - c26c6513865a8ff0eb97db5576579695c786dffb Add support for specific attribute names. by Daniel Fisher <dfisher@vt.edu> - d969f540eac4b5326efa404672805d0e704ab0a2 Copy-paste wrong error message. by Daniel Fisher <dfisher@vt.edu> - 8be4c5be06dc457e8fcf99810fb882160277d8f3 Add SocketConfig to test. by Daniel Fisher <dfisher@vt.edu> - eff04371739890af84c9ea739e44acd9a4e171b5 Remove unused schema. by Daniel Fisher <dfisher@gmail.com> (And 166 more changes) GitOrigin-RevId: 434e20e7882bd0c36f40b36379e062b5b2fdfdc6 Change-Id: If2118daa0050ea0dc96ae56edf9083ae36f2947c
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6240411 --- /dev/null +++ b/.gitignore
@@ -0,0 +1,3 @@ +*.iml +.idea +target
diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..3afaca7 --- /dev/null +++ b/.travis.yml
@@ -0,0 +1,12 @@ +language: bash +sudo: required +services: + - docker +script: + - .travis/docker-run +branches: + only: + - master +env: + global: + secure: qfwhWA1zqbfrepSL+k1Aw82w98hqEtUEwog/90Bi04tfd8N9FIIi7/+qD0x1iDJZhfHJ5zHx4fRBncMHjiQjSxSMN3nUbBsQ47jtwlmZFybYuCNrFHDWThW4DglfLLzaoO2zGAWjMZeSRzr/ERNhOl2a1E/NKmpcorrLf/IWpXPdLi5VlXJ9hCbsBTIAYhXMjCWhRKzfMs9FqCkriS7OrfDqr6FahqUH9cxuGOGdl2Aad8nfaZu9yNKLcDbxQf2s6cwrFx9ewU/BgdaJBY4qBX3eEfykzoen1icdbuaI7bpCXMguEPDSiuwY/ezpPwsBmghyV7r4hjfx33cvQK/LLN3URkX4rfsNlKpRkthjxW5jpsVZ9OmEykaxKnws8W7wX8wkbVRhFB51j0uMusHsASwwGo+Whie1w9mAeB0/10vvSfQAMnQJu1/1a120lzxeMu31y1IdpnGI3Sqy7vwPOwmY0wZ81rTTOEj7niH3B6beG09fnB/srZ/6+FVeuim8i8HKLU32LDZk5T0PNjYo8J3ASiw6r8w9i5R/5ekHsKwVWbj0/dPNAgYrGjzd9TKLioMrhM1picGuOqYOeEwp2RvdvJsmwA8nnaLFuKbkOTb9pjJxebwgvQ6ZtC6XM4sItwaL+aclAeeQXRu7SCTMF+z22e6XltZJFXXkG7bg5yA=
diff --git a/.travis/deploy-snapshot b/.travis/deploy-snapshot new file mode 100755 index 0000000..6b5195b --- /dev/null +++ b/.travis/deploy-snapshot
@@ -0,0 +1,57 @@ +#!/bin/bash + +# Exit with nonzero exit code if anything fails +set -e + +# Do not run for pull requests +if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then + echo "Skipping snapshot deploy for PULL_REQUEST=${TRAVIS_PULL_REQUEST}." + exit 0 +fi + +# Do not run for tags +if [ ! -z "$TRAVIS_TAG" ]; then + echo "Skipping snapshot deploy for TAG=${TRAVIS_TAG}." + exit 0 +fi + +# Only run this script against master +if [ "$TRAVIS_BRANCH" != "master" ]; then + echo "Skipping snapshot deploy for BRANCH=${TRAVIS_BRANCH}." + exit 0 +fi + +# Only run this script for snapshots +VERSION=`cat core/target/maven-archiver/pom.properties |grep version` +if [[ "$VERSION" != *-SNAPSHOT ]]; then + echo "Skipping non-snapshot version for VERSION=${VERSION}." + exit 0 +fi + +SHA=`git rev-parse --verify HEAD` +echo "Publishing snapshot jar for revision ${SHA}" + +# Git configuration +git config --global user.name "Travis CI" +git config --global user.email "travis@travis-ci.org" +git config --global credential.helper "store --file=${PWD}/.git/credentials" +echo "https://${GH_TOKEN}:@github.com" >"${PWD}/.git/credentials" + +# Repo variables +REPO_NAME="maven-repo" +REPO_URL="https://github.com/vt-middleware/${REPO_NAME}.git" + +# Clone the maven repo +git clone $REPO_URL + +# Deploy the artifact to the maven repo +mvn -Papache,jldap,opendj,unboundid,ldapi deploy -DskipTests -DaltDeploymentRepository=snapshot::default::file://${REPO_NAME} + +# Push changes to the maven repo +cd $REPO_NAME +git add . +git commit -m "Deploy snapshot: ${SHA}" +git push origin master + +echo "Successfully deployed SNAPSHOT artifacts for job ${TRAVIS_JOB_NUMBER}" +
diff --git a/.travis/docker-cmds b/.travis/docker-cmds new file mode 100755 index 0000000..2467d0e --- /dev/null +++ b/.travis/docker-cmds
@@ -0,0 +1,19 @@ +#!/bin/bash + +# execute maven in docker +mvn install -Dmaven.javadoc.skip=true -B -V +ret_code=$? +if [ $ret_code != 0 ]; then + echo "Maven install failed with error code ${ret_code}" + exit $ret_code +fi + +# execute snapshot deploy in docker +.travis/deploy-snapshot +ret_code=$? +if [ $ret_code != 0 ]; then + echo "Deploy snapshot failed with error code ${ret_code}" + exit $ret_code +fi + +exit
diff --git a/.travis/docker-run b/.travis/docker-run new file mode 100755 index 0000000..d0bb100 --- /dev/null +++ b/.travis/docker-run
@@ -0,0 +1,19 @@ +#!/bin/bash + +# Exit with nonzero exit code if anything fails +set -e + +DOCKER_IMAGE="maven:3.5.0-jdk-8" +DOCKER_VOLUME="/apps/src" +DOCKER_ENV="$DOCKER_ENV -e TRAVIS_PULL_REQUEST" +DOCKER_ENV="$DOCKER_ENV -e TRAVIS_TAG" +DOCKER_ENV="$DOCKER_ENV -e TRAVIS_BRANCH" +DOCKER_ENV="$DOCKER_ENV -e TRAVIS_JOB_NUMBER" +DOCKER_ENV="$DOCKER_ENV -e GH_TOKEN" + +# run an interactive docker instance +docker run -it ${DOCKER_ENV} \ + -v $(pwd):${DOCKER_VOLUME} -w ${DOCKER_VOLUME} \ + ${DOCKER_IMAGE} .travis/docker-cmds + +exit
diff --git a/README.md b/README.md new file mode 100644 index 0000000..b2f447f --- /dev/null +++ b/README.md
@@ -0,0 +1,15 @@ +## Ldaptive [](https://maven-badges.herokuapp.com/maven-central/org.ldaptive/ldaptive) + +This project is dual licensed under both the LGPL and Apache 2. +If you have questions or comments about this library send e-mail to +ldaptive@googlegroups.com. + +### Building +```sh +git clone git@github.com:vt-middleware/ldaptive.git +cd ldaptive +./mvn_cmd package +``` + +### Documentation +See the website: http://www.ldaptive.org
diff --git a/apache-provider/pom.xml b/apache-provider/pom.xml new file mode 100644 index 0000000..3c94c8f --- /dev/null +++ b/apache-provider/pom.xml
@@ -0,0 +1,27 @@ +<?xml version='1.0' encoding='UTF-8'?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>ldaptive-apache</artifactId> + <packaging>jar</packaging> + <name>LDAPTIVE APACHE PROVIDER</name> + <description>Ldaptive apache provider</description> + <parent> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-parent</artifactId> + <version>1.2.3</version> + </parent> + + <dependencies> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive</artifactId> + </dependency> + <dependency> + <groupId>org.apache.directory.api</groupId> + <artifactId>api-all</artifactId> + </dependency> + </dependencies> + +</project>
diff --git a/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapConnection.java b/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapConnection.java new file mode 100644 index 0000000..313f8cd --- /dev/null +++ b/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapConnection.java
@@ -0,0 +1,1029 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.apache; + +import java.io.IOException; +import java.util.Map; +import org.apache.directory.api.ldap.codec.api.ExtendedResponseDecorator; +import org.apache.directory.api.ldap.model.cursor.CursorException; +import org.apache.directory.api.ldap.model.cursor.SearchCursor; +import org.apache.directory.api.ldap.model.entry.Entry; +import org.apache.directory.api.ldap.model.entry.Modification; +import org.apache.directory.api.ldap.model.exception.LdapOperationException; +import org.apache.directory.api.ldap.model.message.AbandonRequestImpl; +import org.apache.directory.api.ldap.model.message.AddRequestImpl; +import org.apache.directory.api.ldap.model.message.AddResponse; +import org.apache.directory.api.ldap.model.message.AliasDerefMode; +import org.apache.directory.api.ldap.model.message.BindRequestImpl; +import org.apache.directory.api.ldap.model.message.BindResponse; +import org.apache.directory.api.ldap.model.message.CompareRequestImpl; +import org.apache.directory.api.ldap.model.message.CompareResponse; +import org.apache.directory.api.ldap.model.message.Control; +import org.apache.directory.api.ldap.model.message.DeleteRequestImpl; +import org.apache.directory.api.ldap.model.message.DeleteResponse; +import org.apache.directory.api.ldap.model.message.ExtendedResponse; +import org.apache.directory.api.ldap.model.message.IntermediateResponse; +import org.apache.directory.api.ldap.model.message.LdapResult; +import org.apache.directory.api.ldap.model.message.Message; +import org.apache.directory.api.ldap.model.message.ModifyDnRequestImpl; +import org.apache.directory.api.ldap.model.message.ModifyDnResponse; +import org.apache.directory.api.ldap.model.message.ModifyRequestImpl; +import org.apache.directory.api.ldap.model.message.ModifyResponse; +import org.apache.directory.api.ldap.model.message.Referral; +import org.apache.directory.api.ldap.model.message.ResultResponse; +import org.apache.directory.api.ldap.model.message.SearchRequest; +import org.apache.directory.api.ldap.model.message.SearchRequestImpl; +import org.apache.directory.api.ldap.model.message.SearchResultDone; +import org.apache.directory.api.ldap.model.message.SearchResultEntry; +import org.apache.directory.api.ldap.model.message.SearchResultReference; +import org.apache.directory.api.ldap.model.message.SearchScope; +import org.apache.directory.api.ldap.model.name.Dn; +import org.apache.directory.ldap.client.api.LdapNetworkConnection; +import org.apache.directory.ldap.client.api.SaslCramMd5Request; +import org.apache.directory.ldap.client.api.SaslDigestMd5Request; +import org.apache.directory.ldap.client.api.SaslGssApiRequest; +import org.apache.directory.ldap.client.api.exception.InvalidConnectionException; +import org.ldaptive.AddRequest; +import org.ldaptive.BindRequest; +import org.ldaptive.CompareRequest; +import org.ldaptive.DeleteRequest; +import org.ldaptive.DerefAliases; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.ModifyDnRequest; +import org.ldaptive.ModifyRequest; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchReference; +import org.ldaptive.control.RequestControl; +import org.ldaptive.control.ResponseControl; +import org.ldaptive.extended.ExtendedRequest; +import org.ldaptive.extended.ExtendedResponseFactory; +import org.ldaptive.extended.UnsolicitedNotificationListener; +import org.ldaptive.intermediate.IntermediateResponseFactory; +import org.ldaptive.provider.ControlProcessor; +import org.ldaptive.provider.ProviderConnection; +import org.ldaptive.provider.ProviderUtils; +import org.ldaptive.provider.SearchItem; +import org.ldaptive.provider.SearchIterator; +import org.ldaptive.provider.SearchListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Apache LDAP provider implementation of ldap operations. + * + * @author Middleware Services + */ +public class ApacheLdapConnection implements ProviderConnection +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Ldap connection. */ + private LdapNetworkConnection connection; + + /** Provider configuration. */ + private final ApacheLdapProviderConfig config; + + + /** + * Creates a new apache ldap connection. + * + * @param lc ldap connection + * @param pc provider configuration + */ + public ApacheLdapConnection(final LdapNetworkConnection lc, final ApacheLdapProviderConfig pc) + { + connection = lc; + config = pc; + } + + + /** + * Returns the underlying ldap connection. + * + * @return ldap connection + */ + public LdapNetworkConnection getLdapConnection() + { + return connection; + } + + + @Override + public void close(final RequestControl[] controls) + throws LdapException + { + if (controls != null) { + throw new UnsupportedOperationException("Provider does not support unbind with controls"); + } + if (connection != null) { + try { + if (connection.isConnected()) { + connection.unBind(); + } + } catch (org.apache.directory.api.ldap.model.exception.LdapException e) { + logger.error("Error unbinding from LDAP", e); + } + try { + connection.close(); + } catch (IOException e) { + throw new LdapException(e); + } finally { + connection = null; + } + } + } + + + @Override + public Response<Void> bind(final BindRequest request) + throws LdapException + { + Response<Void> response; + if (request.getSaslConfig() != null) { + response = saslBind(request); + } else if (request.getDn() == null && request.getCredential() == null) { + response = anonymousBind(request); + } else { + response = simpleBind(request); + } + return response; + } + + + /** + * Performs an anonymous bind. + * + * @param request to bind with + * + * @return bind response + * + * @throws LdapException if an error occurs + */ + protected Response<Void> anonymousBind(final BindRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final BindRequestImpl bri = new BindRequestImpl(); + if (request.getControls() != null) { + bri.addAllControls(config.getControlProcessor().processRequestControls(request.getControls())); + } + + final BindResponse br = connection.bind(bri); + throwOperationException(request, br); + response = createResponse(request, null, br); + } catch (LdapOperationException e) { + processLdapOperationException(e); + } catch (org.apache.directory.api.ldap.model.exception.LdapException e) { + processLdapException(e); + } + return response; + } + + + /** + * Performs a simple bind. + * + * @param request to bind with + * + * @return bind response + * + * @throws LdapException if an error occurs + */ + protected Response<Void> simpleBind(final BindRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final BindRequestImpl bri = new BindRequestImpl(); + if (request.getControls() != null) { + bri.addAllControls(config.getControlProcessor().processRequestControls(request.getControls())); + } + bri.setVersion3(true); + bri.setSimple(true); + bri.setDn(new Dn(request.getDn())); + bri.setCredentials(request.getCredential().getBytes()); + + final BindResponse br = connection.bind(bri); + throwOperationException(request, br); + response = createResponse(request, null, br); + } catch (LdapOperationException e) { + processLdapOperationException(e); + } catch (org.apache.directory.api.ldap.model.exception.LdapException e) { + processLdapException(e); + } + return response; + } + + + /** + * Performs a sasl bind. + * + * @param request to bind with + * + * @return bind response + * + * @throws LdapException if an error occurs + */ + protected Response<Void> saslBind(final BindRequest request) + throws LdapException + { + Response<Void> response = null; + try { + BindResponse br; + switch (request.getSaslConfig().getMechanism()) { + + case EXTERNAL: + throw new UnsupportedOperationException("SASL External not supported"); + + case DIGEST_MD5: + + final SaslDigestMd5Request digestMd5Request = ApacheLdapSaslUtils.createDigestMd5Request( + request.getDn(), + request.getCredential(), + request.getSaslConfig()); + br = connection.bind(digestMd5Request); + break; + + case CRAM_MD5: + + final SaslCramMd5Request cramMd5Request = ApacheLdapSaslUtils.createCramMd5Request( + request.getDn(), + request.getCredential(), + request.getSaslConfig()); + br = connection.bind(cramMd5Request); + break; + + case GSSAPI: + + final SaslGssApiRequest gssApiRequest = ApacheLdapSaslUtils.createGssApiRequest( + request.getDn(), + request.getCredential(), + request.getSaslConfig()); + br = connection.bind(gssApiRequest); + break; + + default: + throw new IllegalArgumentException( + "Unknown SASL authentication mechanism: " + request.getSaslConfig().getMechanism()); + } + throwOperationException(request, br); + response = createResponse(request, null, br); + } catch (LdapOperationException e) { + processLdapOperationException(e); + } catch (org.apache.directory.api.ldap.model.exception.LdapException e) { + processLdapException(e); + } + return response; + } + + + @Override + public Response<Void> add(final AddRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final ApacheLdapUtils bu = new ApacheLdapUtils(); + final AddRequestImpl ari = new AddRequestImpl(); + if (request.getControls() != null) { + ari.addAllControls(config.getControlProcessor().processRequestControls(request.getControls())); + } + ari.setEntry(bu.fromLdapEntry(new LdapEntry(request.getDn(), request.getLdapAttributes()))); + + final AddResponse ar = connection.add(ari); + throwOperationException(request, ar); + response = createResponse(request, null, ar); + } catch (LdapOperationException e) { + processLdapOperationException(e); + } catch (org.apache.directory.api.ldap.model.exception.LdapException e) { + processLdapException(e); + } + return response; + } + + + @Override + public Response<Boolean> compare(final CompareRequest request) + throws LdapException + { + Response<Boolean> response = null; + try { + final CompareRequestImpl cri = new CompareRequestImpl(); + if (request.getControls() != null) { + cri.addAllControls(config.getControlProcessor().processRequestControls(request.getControls())); + } + cri.setName(new Dn(request.getDn())); + cri.setAttributeId(request.getAttribute().getName()); + if (request.getAttribute().isBinary()) { + cri.setAssertionValue(request.getAttribute().getBinaryValue()); + } else { + cri.setAssertionValue(request.getAttribute().getStringValue()); + } + + final CompareResponse cr = connection.compare(cri); + throwOperationException(request, cr); + response = createResponse(request, cr.isTrue(), cr); + } catch (LdapOperationException e) { + processLdapOperationException(e); + } catch (org.apache.directory.api.ldap.model.exception.LdapException e) { + processLdapException(e); + } + return response; + } + + + @Override + public Response<Void> delete(final DeleteRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final DeleteRequestImpl dri = new DeleteRequestImpl(); + if (request.getControls() != null) { + dri.addAllControls(config.getControlProcessor().processRequestControls(request.getControls())); + } + dri.setName(new Dn(request.getDn())); + + final DeleteResponse dr = connection.delete(dri); + throwOperationException(request, dr); + response = createResponse(request, null, dr); + } catch (LdapOperationException e) { + processLdapOperationException(e); + } catch (org.apache.directory.api.ldap.model.exception.LdapException e) { + processLdapException(e); + } + return response; + } + + + @Override + public Response<Void> modify(final ModifyRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final ApacheLdapUtils bu = new ApacheLdapUtils(); + final ModifyRequestImpl mri = new ModifyRequestImpl(); + if (request.getControls() != null) { + mri.addAllControls(config.getControlProcessor().processRequestControls(request.getControls())); + } + mri.setName(new Dn(request.getDn())); + for (Modification m : bu.fromAttributeModification(request.getAttributeModifications())) { + mri.addModification(m); + } + + final ModifyResponse mr = connection.modify(mri); + throwOperationException(request, mr); + response = createResponse(request, null, mr); + } catch (LdapOperationException e) { + processLdapOperationException(e); + } catch (org.apache.directory.api.ldap.model.exception.LdapException e) { + processLdapException(e); + } + return response; + } + + + @Override + public Response<Void> modifyDn(final ModifyDnRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final Dn dn = new Dn(request.getDn()); + final Dn newDn = new Dn(request.getNewDn()); + final ModifyDnRequestImpl mdri = new ModifyDnRequestImpl(); + if (request.getControls() != null) { + mdri.addAllControls(config.getControlProcessor().processRequestControls(request.getControls())); + } + mdri.setName(dn); + mdri.setNewRdn(newDn.getRdn()); + mdri.setNewSuperior(newDn.getParent()); + mdri.setDeleteOldRdn(request.getDeleteOldRDn()); + + final ModifyDnResponse mdr = connection.modifyDn(mdri); + throwOperationException(request, mdr); + response = createResponse(request, null, mdr); + } catch (LdapOperationException e) { + processLdapOperationException(e); + } catch (org.apache.directory.api.ldap.model.exception.LdapException e) { + processLdapException(e); + } + return response; + } + + + @Override + public SearchIterator search(final org.ldaptive.SearchRequest request) + throws LdapException + { + final ApacheLdapSearchIterator i = new ApacheLdapSearchIterator(request); + i.initialize(); + return i; + } + + + @Override + public void searchAsync(final org.ldaptive.SearchRequest request, final SearchListener listener) + throws LdapException + { + final ApacheLdapSearchListener l = new ApacheLdapSearchListener(request, listener); + l.initialize(); + } + + + @Override + public void abandon(final int messageId, final RequestControl[] controls) + throws LdapException + { + final AbandonRequestImpl ari = new AbandonRequestImpl(); + if (controls != null) { + ari.addAllControls(config.getControlProcessor().processRequestControls(controls)); + } + ari.setAbandoned(messageId); + connection.abandon(ari); + } + + + @Override + public Response<?> extendedOperation(final ExtendedRequest request) + throws LdapException + { + Response<?> response = null; + try { + final ExtendedResponse apacheExtRes = connection.extended(request.getOID(), request.encode()); + throwOperationException(request, apacheExtRes); + + byte[] responseValue = null; + if (apacheExtRes instanceof ExtendedResponseDecorator) { + responseValue = ((ExtendedResponseDecorator) apacheExtRes).getResponseValue(); + } + + final org.ldaptive.extended.ExtendedResponse<?> extRes = ExtendedResponseFactory.createExtendedResponse( + request.getOID(), + apacheExtRes.getResponseName(), + responseValue); + response = createResponse(request, extRes.getValue(), apacheExtRes); + } catch (LdapOperationException e) { + processLdapOperationException(e); + } catch (org.apache.directory.api.ldap.model.exception.LdapException e) { + processLdapException(e); + } + return response; + } + + + @Override + public void addUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + throw new UnsupportedOperationException("Unsolicited notifications not supported"); + } + + + @Override + public void removeUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + throw new UnsupportedOperationException("Unsolicited notifications not supported"); + } + + + /** + * Determines if the supplied response should result in an operation retry. + * + * @param request that produced the exception + * @param resultResponse provider response + * + * @throws LdapException wrapping the ldap exception + */ + protected void throwOperationException(final Request request, final ResultResponse resultResponse) + throws LdapException + { + final LdapResult ldapResult = resultResponse.getLdapResult(); + final Referral ref = ldapResult.getReferral(); + ProviderUtils.throwOperationException( + config.getOperationExceptionResultCodes(), + String.format("Ldap returned result code: %s", ldapResult.getResultCode()), + ldapResult.getResultCode().getResultCode(), + ldapResult.getMatchedDn() != null ? ldapResult.getMatchedDn().getName() : null, + processResponseControls(config.getControlProcessor(), request.getControls(), resultResponse), + ref != null ? ref.getLdapUrls().toArray(new String[ref.getReferralLength()]) : null, + false); + } + + + /** + * Creates an operation response with the supplied response data. + * + * @param <T> type of response + * @param request containing controls + * @param result of the operation + * @param resultResponse provider response + * + * @return operation response + */ + protected <T> Response<T> createResponse(final Request request, final T result, final ResultResponse resultResponse) + { + final LdapResult ldapResult = resultResponse.getLdapResult(); + final Referral ref = ldapResult.getReferral(); + return + new Response<>( + result, + ResultCode.valueOf(ldapResult.getResultCode().getValue()), + ldapResult.getDiagnosticMessage(), + ldapResult.getMatchedDn() != null ? ldapResult.getMatchedDn().getName() : null, + processResponseControls(config.getControlProcessor(), request.getControls(), resultResponse), + ref != null ? ref.getLdapUrls().toArray(new String[ref.getReferralLength()]) : null, + resultResponse.getMessageId()); + } + + + /** + * Determines if the supplied ldap exception should result in an operation exception. + * + * @param e that was produced + * + * @throws LdapException wrapping the ldap exception + */ + protected void processLdapOperationException(final LdapOperationException e) + throws LdapException + { + ProviderUtils.throwOperationException( + config.getOperationExceptionResultCodes(), + e, + e.getResultCode() != null ? e.getResultCode().getResultCode() : null, + e.getResolvedDn() != null ? e.getResolvedDn().getName() : null, + null, + null, + true); + } + + + /** + * Determines if the supplied ldap exception should result in an operation exception. + * + * @param e that was produced + * + * @throws LdapException wrapping the ldap exception + */ + protected void processLdapException(final org.apache.directory.api.ldap.model.exception.LdapException e) + throws LdapException + { + if (e instanceof InvalidConnectionException) { + // map InvalidConnectionException to error code SERVER_DOWN(81) + ProviderUtils.throwOperationException( + config.getOperationExceptionResultCodes(), + e, + ResultCode.SERVER_DOWN.value(), + null, + null, + null, + true); + } + throw new LdapException(e); + } + + + /** + * Retrieves the response controls from the supplied response and processes them with the supplied control processor. + * + * @param processor control processor + * @param requestControls that produced this response + * @param response to get controls from + * + * @return response controls + */ + public org.ldaptive.control.ResponseControl[] processResponseControls( + final ControlProcessor<Control> processor, + final RequestControl[] requestControls, + final Message response) + { + return processor.processResponseControls(getResponseControls(response)); + } + + + /** + * Retrieves the response controls from the supplied response. + * + * @param response to get controls from + * + * @return response controls + */ + public Control[] getResponseControls(final Message response) + { + Control[] ctls = null; + if (response != null) { + final Map<String, Control> respControls = response.getControls(); + ctls = respControls.values().toArray(new Control[respControls.size()]); + } + return ctls; + } + + + /** Search iterator for apache ldap search results. */ + protected class ApacheLdapSearchIterator extends AbstractApacheLdapSearch implements SearchIterator + { + + /** Response data. */ + private org.ldaptive.Response<Void> response; + + /** Ldap search cursor. */ + private SearchCursor cursor; + + + /** + * Creates a new apache ldap search iterator. + * + * @param sr search request + */ + public ApacheLdapSearchIterator(final org.ldaptive.SearchRequest sr) + { + super(sr); + } + + + /** + * Initializes this apache ldap search iterator. + * + * @throws org.ldaptive.LdapException if an error occurs + */ + public void initialize() + throws org.ldaptive.LdapException + { + boolean closeCursor = false; + try { + cursor = search(connection, request); + } catch (LdapOperationException e) { + closeCursor = true; + processLdapOperationException(e); + } catch (org.apache.directory.api.ldap.model.exception.LdapException e) { + closeCursor = true; + processLdapException(e); + } catch (RuntimeException e) { + closeCursor = true; + throw e; + } catch (Exception e) { + closeCursor = true; + throw new org.ldaptive.LdapException(e); + } finally { + if (closeCursor) { + try { + if (cursor != null) { + cursor.close(); + } + } catch (Exception e) { + logger.debug("Error closing search cursor", e); + } + } + } + } + + + @Override + public boolean hasNext() + throws org.ldaptive.LdapException + { + if (cursor == null || response != null) { + return false; + } + + boolean more = false; + try { + more = cursor.next(); + if (!more) { + final SearchResultDone done = cursor.getSearchResultDone(); + logger.trace("reading search result done: {}", done); + throwOperationException(request, done); + + final LdapResult ldapResult = done.getLdapResult(); + response = createResponse(request, null, done); + } + } catch (LdapOperationException e) { + processLdapOperationException(e); + } catch (org.apache.directory.api.ldap.model.exception.LdapException e) { + processLdapException(e); + } catch (LdapException | RuntimeException e) { + throw e; + } catch (Exception e) { + throw new org.ldaptive.LdapException(e); + } + return more; + } + + + @Override + public SearchItem next() + throws org.ldaptive.LdapException + { + SearchItem si = null; + try { + final org.apache.directory.api.ldap.model.message.Response curRes = cursor.get(); + if (curRes instanceof SearchResultEntry) { + si = processSearchResultEntry((SearchResultEntry) curRes); + } else if (curRes instanceof SearchResultReference) { + si = processSearchResultReference((SearchResultReference) curRes); + } else if (curRes instanceof IntermediateResponse) { + si = processIntermediateResponse((IntermediateResponse) curRes); + } + } catch (CursorException e) { + throw new org.ldaptive.LdapException(e); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new org.ldaptive.LdapException(e); + } + return si; + } + + + @Override + public org.ldaptive.Response<Void> getResponse() + { + return response; + } + + + @Override + public void close() + throws org.ldaptive.LdapException {} + } + + + /** Search listener for apache ldap search results. */ + protected class ApacheLdapSearchListener extends AbstractApacheLdapSearch + { + + /** Search result listener. */ + private final SearchListener listener; + + + /** + * Creates a new apache ldap search listener. + * + * @param sr search request + * @param sl search listener + */ + public ApacheLdapSearchListener(final org.ldaptive.SearchRequest sr, final SearchListener sl) + { + super(sr); + listener = sl; + } + + + /** + * Initializes this apache ldap search listener. + * + * @throws org.ldaptive.LdapException if an error occurs + */ + public void initialize() + throws org.ldaptive.LdapException + { + boolean closeCursor = false; + SearchCursor cursor = null; + try { + cursor = search(connection, request); + while (cursor.next()) { + final org.apache.directory.api.ldap.model.message.Response curRes = cursor.get(); + if (curRes instanceof SearchResultEntry) { + listener.searchItemReceived(processSearchResultEntry((SearchResultEntry) curRes)); + } else if (curRes instanceof SearchResultReference) { + listener.searchItemReceived(processSearchResultReference((SearchResultReference) curRes)); + } else if (curRes instanceof IntermediateResponse) { + listener.searchItemReceived(processIntermediateResponse((IntermediateResponse) curRes)); + } + } + + final SearchResultDone done = cursor.getSearchResultDone(); + final Response<Void> response = createResponse(request, null, done); + listener.responseReceived(response); + } catch (LdapOperationException e) { + closeCursor = true; + processLdapOperationException(e); + } catch (org.apache.directory.api.ldap.model.exception.LdapException e) { + closeCursor = true; + processLdapException(e); + } catch (RuntimeException e) { + closeCursor = true; + throw e; + } catch (Exception e) { + closeCursor = true; + throw new org.ldaptive.LdapException(e); + } finally { + if (closeCursor) { + try { + if (cursor != null) { + cursor.close(); + } + } catch (Exception e) { + logger.debug("Error closing search cursor", e); + } + } + } + } + } + + + /** Common search functionality for apache ldap iterators and listeners. */ + protected abstract class AbstractApacheLdapSearch + { + + /** Search request. */ + protected final org.ldaptive.SearchRequest request; + + /** Utility class. */ + protected final ApacheLdapUtils util; + + + /** + * Creates a new abstract apache ldap search. + * + * @param sr search request + */ + public AbstractApacheLdapSearch(final org.ldaptive.SearchRequest sr) + { + request = sr; + util = new ApacheLdapUtils(sr.getSortBehavior()); + util.setBinaryAttributes(sr.getBinaryAttributes()); + } + + + /** + * Executes an ldap search. + * + * @param conn to search with + * @param sr to read properties from + * + * @return ldap search results + * + * @throws org.apache.directory.api.ldap.model.exception.LdapException if an error occurs + */ + protected SearchCursor search(final LdapNetworkConnection conn, final org.ldaptive.SearchRequest sr) + throws org.apache.directory.api.ldap.model.exception.LdapException + { + final SearchRequest apacheSr = getSearchRequest(sr); + final Control[] c = config.getControlProcessor().processRequestControls(sr.getControls()); + if (c != null) { + apacheSr.addAllControls(c); + } + return conn.search(apacheSr); + } + + + /** + * Returns an apache ldap search request object configured with the supplied search request. + * + * @param sr search request containing configuration to create apache ldap search request + * + * @return search request + * + * @throws org.apache.directory.api.ldap.model.exception.LdapException if the search request cannot be initialized + */ + protected SearchRequest getSearchRequest(final org.ldaptive.SearchRequest sr) + throws org.apache.directory.api.ldap.model.exception.LdapException + { + final SearchRequest apacheSr = new SearchRequestImpl(); + if (sr.getReturnAttributes() != null) { + apacheSr.addAttributes(sr.getReturnAttributes()); + } + apacheSr.setBase(new Dn(sr.getBaseDn())); + + final AliasDerefMode deref = getAliasDerefMode(sr.getDerefAliases()); + // by default set dereferencing aliases to never, apache default is always + if (deref != null) { + apacheSr.setDerefAliases(deref); + } else { + apacheSr.setDerefAliases(AliasDerefMode.NEVER_DEREF_ALIASES); + } + if (sr.getSearchFilter() != null) { + apacheSr.setFilter(sr.getSearchFilter().format()); + } + + final SearchScope searchScope = getSearchScope(sr.getSearchScope()); + if (searchScope != null) { + apacheSr.setScope(searchScope); + } + apacheSr.setSizeLimit(sr.getSizeLimit()); + apacheSr.setTimeLimit((int) sr.getTimeLimit().getSeconds()); + apacheSr.setTypesOnly(sr.getTypesOnly()); + return apacheSr; + } + + + /** + * Returns the apache ldap search scope for the supplied search scope. + * + * @param ss search scope + * + * @return apache ldap search scope + */ + protected SearchScope getSearchScope(final org.ldaptive.SearchScope ss) + { + SearchScope scope = null; + if (ss == org.ldaptive.SearchScope.OBJECT) { + scope = SearchScope.OBJECT; + } else if (ss == org.ldaptive.SearchScope.ONELEVEL) { + scope = SearchScope.ONELEVEL; + } else if (ss == org.ldaptive.SearchScope.SUBTREE) { + scope = SearchScope.SUBTREE; + } + return scope; + } + + + /** + * Returns the apache ldap alias deref mode for the supplied deref aliases. + * + * @param deref deref aliases + * + * @return apache ldap alias deref mode + */ + protected AliasDerefMode getAliasDerefMode(final DerefAliases deref) + { + AliasDerefMode mode = null; + if (deref == DerefAliases.ALWAYS) { + mode = AliasDerefMode.DEREF_ALWAYS; + } else if (deref == DerefAliases.FINDING) { + mode = AliasDerefMode.DEREF_FINDING_BASE_OBJ; + } else if (deref == DerefAliases.NEVER) { + mode = AliasDerefMode.NEVER_DEREF_ALIASES; + } else if (deref == DerefAliases.SEARCHING) { + mode = AliasDerefMode.DEREF_IN_SEARCHING; + } + return mode; + } + + + /** + * Processes the response controls on the supplied entry and returns a corresponding search item. + * + * @param entry to process + * + * @return search item + */ + protected SearchItem processSearchResultEntry(final SearchResultEntry entry) + { + logger.trace("reading search entry: {}", entry); + + final Entry e = entry.getEntry(); + ResponseControl[] respControls = null; + if (entry.getControls() != null && entry.getControls().size() > 0) { + respControls = processResponseControls(config.getControlProcessor(), request.getControls(), entry); + } + + final SearchEntry se = util.toSearchEntry(e, respControls, entry.getMessageId()); + return new SearchItem(se); + } + + + /** + * Processes the response controls on the supplied reference and returns a corresponding search item. + * + * @param ref to process + * + * @return search item + */ + protected SearchItem processSearchResultReference(final SearchResultReference ref) + { + logger.trace("reading search reference: {}", ref); + + final Referral r = ref.getReferral(); + ResponseControl[] respControls = null; + if (ref.getControls() != null && ref.getControls().size() > 0) { + respControls = processResponseControls(config.getControlProcessor(), request.getControls(), ref); + } + + final SearchReference sr = new SearchReference(ref.getMessageId(), respControls, r.getLdapUrls()); + return new SearchItem(sr); + } + + + /** + * Processes the response controls on the supplied response and returns a corresponding search item. + * + * @param res to process + * + * @return search item + */ + protected SearchItem processIntermediateResponse(final IntermediateResponse res) + { + logger.trace("reading intermediate response: {}", res); + + ResponseControl[] respControls = null; + if (res.getControls() != null && res.getControls().size() > 0) { + respControls = processResponseControls(config.getControlProcessor(), request.getControls(), res); + } + + final org.ldaptive.intermediate.IntermediateResponse ir = IntermediateResponseFactory.createIntermediateResponse( + res.getResponseName(), + res.getResponseValue(), + respControls, + res.getMessageId()); + return new SearchItem(ir); + } + } +}
diff --git a/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapConnectionFactory.java b/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapConnectionFactory.java new file mode 100644 index 0000000..bf38225 --- /dev/null +++ b/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapConnectionFactory.java
@@ -0,0 +1,100 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.apache; + +import java.time.Duration; +import org.apache.directory.api.ldap.model.exception.LdapOperationException; +import org.apache.directory.ldap.client.api.LdapConnectionConfig; +import org.apache.directory.ldap.client.api.LdapNetworkConnection; +import org.ldaptive.ConnectionStrategy; +import org.ldaptive.LdapException; +import org.ldaptive.LdapURL; +import org.ldaptive.ResultCode; +import org.ldaptive.provider.AbstractProviderConnectionFactory; +import org.ldaptive.provider.ConnectionException; + +/** + * Creates ldap connections using the Apache LdapNetworkConnection class. + * + * @author Middleware Services + */ +public class ApacheLdapConnectionFactory extends AbstractProviderConnectionFactory<ApacheLdapProviderConfig> +{ + + /** Connection configuration. */ + private final LdapConnectionConfig ldapConnectionConfig; + + /** Whether to startTLS on connections. */ + private final boolean useStartTLS; + + /** Timeout for responses. */ + private final Duration responseTimeOut; + + + /** + * Creates a new Apache LDAP connection factory. + * + * @param url of the ldap to connect to + * @param strategy connection strategy + * @param config provider configuration + * @param lcc connection configuration + * @param tls whether to startTLS on connections + * @param timeOut timeout for responses + */ + public ApacheLdapConnectionFactory( + final String url, + final ConnectionStrategy strategy, + final ApacheLdapProviderConfig config, + final LdapConnectionConfig lcc, + final boolean tls, + final Duration timeOut) + { + super(url, strategy, config); + ldapConnectionConfig = lcc; + useStartTLS = tls; + responseTimeOut = timeOut; + } + + + @Override + protected ApacheLdapConnection createInternal(final String url) + throws LdapException + { + final LdapURL ldapUrl = new LdapURL(url); + ldapConnectionConfig.setLdapHost(ldapUrl.getLastEntry().getHostname()); + ldapConnectionConfig.setLdapPort(ldapUrl.getLastEntry().getPort()); + + ApacheLdapConnection conn = null; + boolean closeConn = false; + try { + final LdapNetworkConnection lc = new LdapNetworkConnection(ldapConnectionConfig); + conn = new ApacheLdapConnection(lc, getProviderConfig()); + lc.connect(); + if (useStartTLS) { + lc.startTls(); + } + if (responseTimeOut != null) { + lc.setTimeOut(responseTimeOut.toMillis()); + } + } catch (LdapOperationException e) { + closeConn = true; + throw new ConnectionException(e, ResultCode.valueOf(e.getResultCode().getValue())); + } catch (org.apache.directory.api.ldap.model.exception.LdapException e) { + closeConn = true; + throw new ConnectionException(e); + } catch (RuntimeException e) { + closeConn = true; + throw e; + } finally { + if (closeConn) { + try { + if (conn != null) { + conn.close(null); + } + } catch (LdapException e) { + logger.debug("Problem tearing down connection", e); + } + } + } + return conn; + } +}
diff --git a/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapControlHandler.java b/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapControlHandler.java new file mode 100644 index 0000000..1706afb --- /dev/null +++ b/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapControlHandler.java
@@ -0,0 +1,192 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.apache; + +import java.nio.ByteBuffer; +import org.apache.directory.api.ldap.extras.controls.SynchronizationModeEnum; +import org.apache.directory.api.ldap.extras.controls.ad.AdDirSync; +import org.apache.directory.api.ldap.extras.controls.ad.AdDirSyncFlag; +import org.apache.directory.api.ldap.extras.controls.ad.AdDirSyncImpl; +import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicy; +import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyErrorEnum; +import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyImpl; +import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyResponse; +import org.apache.directory.api.ldap.extras.controls.syncrepl.syncDone.SyncDoneValue; +import org.apache.directory.api.ldap.extras.controls.syncrepl.syncInfoValue.SyncRequestValueImpl; +import org.apache.directory.api.ldap.extras.controls.syncrepl.syncState.SyncStateValue; +import org.apache.directory.api.ldap.extras.controls.vlv.VirtualListViewRequestImpl; +import org.apache.directory.api.ldap.extras.controls.vlv.VirtualListViewResponse; +import org.apache.directory.api.ldap.model.message.Control; +import org.apache.directory.api.ldap.model.message.controls.ChangeType; +import org.apache.directory.api.ldap.model.message.controls.EntryChange; +import org.apache.directory.api.ldap.model.message.controls.ManageDsaITImpl; +import org.apache.directory.api.ldap.model.message.controls.PagedResults; +import org.apache.directory.api.ldap.model.message.controls.PagedResultsImpl; +import org.apache.directory.api.ldap.model.message.controls.PersistentSearchImpl; +import org.apache.directory.api.ldap.model.message.controls.SortKey; +import org.apache.directory.api.ldap.model.message.controls.SortRequestControlImpl; +import org.apache.directory.api.ldap.model.message.controls.SortResponse; +import org.ldaptive.LdapUtils; +import org.ldaptive.ResultCode; +import org.ldaptive.ad.control.DirSyncControl; +import org.ldaptive.asn1.UuidType; +import org.ldaptive.control.EntryChangeNotificationControl; +import org.ldaptive.control.ManageDsaITControl; +import org.ldaptive.control.PagedResultsControl; +import org.ldaptive.control.PasswordPolicyControl; +import org.ldaptive.control.PersistentSearchChangeType; +import org.ldaptive.control.PersistentSearchRequestControl; +import org.ldaptive.control.SortRequestControl; +import org.ldaptive.control.SortResponseControl; +import org.ldaptive.control.SyncDoneControl; +import org.ldaptive.control.SyncRequestControl; +import org.ldaptive.control.SyncStateControl; +import org.ldaptive.control.VirtualListViewRequestControl; +import org.ldaptive.control.VirtualListViewResponseControl; +import org.ldaptive.provider.ControlHandler; + +/** + * Apache Ldap control handler. + * + * @author Middleware Services + */ +public class ApacheLdapControlHandler implements ControlHandler<Control> +{ + + + @Override + public Class<Control> getControlType() + { + return Control.class; + } + + + @Override + public String getOID(final Control control) + { + return control.getOid(); + } + + + @Override + public Control handleRequest(final org.ldaptive.control.RequestControl requestControl) + { + Control ctl = null; + if (ManageDsaITControl.OID.equals(requestControl.getOID())) { + ctl = new ManageDsaITImpl(requestControl.getCriticality()); + } else if (SortRequestControl.OID.equals(requestControl.getOID())) { + final SortRequestControl c = (SortRequestControl) requestControl; + ctl = new SortRequestControlImpl(); + for (org.ldaptive.control.SortKey k : c.getSortKeys()) { + ((SortRequestControlImpl) ctl).addSortKey( + new SortKey(k.getAttributeDescription(), k.getMatchingRuleId(), k.getReverseOrder())); + } + ctl.setCritical(c.getCriticality()); + } else if (PagedResultsControl.OID.equals(requestControl.getOID())) { + final PagedResultsControl c = (PagedResultsControl) requestControl; + ctl = new PagedResultsImpl(); + ((PagedResultsImpl) ctl).setSize(c.getSize()); + ((PagedResultsImpl) ctl).setCookie(c.getCookie()); + ctl.setCritical(c.getCriticality()); + } else if (PasswordPolicyControl.OID.equals(requestControl.getOID())) { + final PasswordPolicyControl c = (PasswordPolicyControl) requestControl; + ctl = new PasswordPolicyImpl(); + ctl.setCritical(c.getCriticality()); + } else if (SyncRequestControl.OID.equals(requestControl.getOID())) { + final SyncRequestControl c = (SyncRequestControl) requestControl; + ctl = new SyncRequestValueImpl(); + ((SyncRequestValueImpl) ctl).setCookie(c.getCookie()); + ((SyncRequestValueImpl) ctl).setReloadHint(c.getReloadHint()); + ((SyncRequestValueImpl) ctl).setMode(SynchronizationModeEnum.getSyncMode(c.getRequestMode().value())); + ctl.setCritical(c.getCriticality()); + } else if (PersistentSearchRequestControl.OID.equals(requestControl.getOID())) { + final PersistentSearchRequestControl c = (PersistentSearchRequestControl) requestControl; + ctl = new PersistentSearchImpl(); + for (PersistentSearchChangeType type : c.getChangeTypes()) { + ((PersistentSearchImpl) ctl).enableNotification(ChangeType.getChangeType(type.value())); + } + ((PersistentSearchImpl) ctl).setChangesOnly(c.getChangesOnly()); + ((PersistentSearchImpl) ctl).setReturnECs(c.getReturnEcs()); + ctl.setCritical(c.getCriticality()); + } else if (DirSyncControl.OID.equals(requestControl.getOID())) { + final DirSyncControl c = (DirSyncControl) requestControl; + ctl = new AdDirSyncImpl(); + ((AdDirSyncImpl) ctl).setCookie(c.getCookie()); + ((AdDirSyncImpl) ctl).setFlags(AdDirSyncFlag.getFlags((int) c.getFlags())); + ((AdDirSyncImpl) ctl).setMaxReturnLength(c.getMaxAttributeCount()); + ctl.setCritical(c.getCriticality()); + } else if (VirtualListViewRequestControl.OID.equals(requestControl.getOID())) { + final VirtualListViewRequestControl c = (VirtualListViewRequestControl) requestControl; + ctl = new VirtualListViewRequestImpl(); + ((VirtualListViewRequestImpl) ctl).setBeforeCount(c.getBeforeCount()); + ((VirtualListViewRequestImpl) ctl).setAfterCount(c.getAfterCount()); + ((VirtualListViewRequestImpl) ctl).setContentCount(c.getContentCount()); + ((VirtualListViewRequestImpl) ctl).setOffset(c.getTargetOffset()); + ((VirtualListViewRequestImpl) ctl).setContextId(c.getContextID()); + ((VirtualListViewRequestImpl) ctl).setAssertionValue(LdapUtils.utf8Encode(c.getAssertionValue())); + ctl.setCritical(c.getCriticality()); + } + return ctl; + } + + + @Override + public org.ldaptive.control.ResponseControl handleResponse(final Control responseControl) + { + org.ldaptive.control.ResponseControl ctl = null; + if (SortResponseControl.OID.equals(responseControl.getOid())) { + final SortResponse c = (SortResponse) responseControl; + ctl = new SortResponseControl( + ResultCode.valueOf(c.getSortResult().getVal()), c.getAttributeName(), c.isCritical()); + } else if (PagedResultsControl.OID.equals(responseControl.getOid())) { + final PagedResults c = (PagedResults) responseControl; + ctl = new PagedResultsControl(c.getSize(), c.getCookie(), c.isCritical()); + } else if (PasswordPolicyControl.OID.equals(responseControl.getOid())) { + final PasswordPolicy c = (PasswordPolicy) responseControl; + if (c.hasResponse()) { + ctl = new PasswordPolicyControl(c.isCritical()); + + final PasswordPolicyResponse ppr = c.getResponse(); + ((PasswordPolicyControl) ctl).setTimeBeforeExpiration(ppr.getTimeBeforeExpiration()); + ((PasswordPolicyControl) ctl).setGraceAuthNsRemaining(ppr.getGraceAuthNRemaining()); + + final PasswordPolicyErrorEnum error = ppr.getPasswordPolicyError(); + if (error != null) { + ((PasswordPolicyControl) ctl).setError(PasswordPolicyControl.Error.valueOf(error.getValue())); + } + } + } else if (SyncStateControl.OID.equals(responseControl.getOid())) { + final SyncStateValue c = (SyncStateValue) responseControl; + ctl = new SyncStateControl( + SyncStateControl.State.valueOf(c.getSyncStateType().getValue()), + UuidType.decode(ByteBuffer.wrap(c.getEntryUUID())), + c.getCookie(), + c.isCritical()); + } else if (SyncDoneControl.OID.equals(responseControl.getOid())) { + final SyncDoneValue c = (SyncDoneValue) responseControl; + ctl = new SyncDoneControl(c.getCookie(), c.isRefreshDeletes(), c.isCritical()); + } else if (EntryChangeNotificationControl.OID.equals(responseControl.getOid())) { + final EntryChange c = (EntryChange) responseControl; + ctl = new EntryChangeNotificationControl( + PersistentSearchChangeType.valueOf(c.getChangeType().getValue()), + c.getPreviousDn().toString(), + c.getChangeNumber(), + c.isCritical()); + } else if (DirSyncControl.OID.equals(responseControl.getOid())) { + final AdDirSync c = (AdDirSync) responseControl; + ctl = new DirSyncControl( + new DirSyncControl.Flag[] {DirSyncControl.Flag.valueOf(AdDirSyncFlag.getBitmask(c.getFlags())), }, + c.getCookie(), + c.getMaxReturnLength(), + c.isCritical()); + } else if (VirtualListViewResponseControl.OID.equals(responseControl.getOid())) { + final VirtualListViewResponse c = (VirtualListViewResponse) responseControl; + ctl = new VirtualListViewResponseControl( + c.getTargetPosition(), + c.getContentCount(), + ResultCode.valueOf(c.getVirtualListViewResult().getValue()), + c.getContextId(), + c.isCritical()); + } + return ctl; + } +}
diff --git a/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapProvider.java b/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapProvider.java new file mode 100644 index 0000000..947f797 --- /dev/null +++ b/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapProvider.java
@@ -0,0 +1,152 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.apache; + +import java.security.GeneralSecurityException; +import javax.net.ssl.KeyManager; +import javax.net.ssl.TrustManager; +import org.apache.directory.ldap.client.api.LdapConnectionConfig; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.LdapURL; +import org.ldaptive.provider.Provider; +import org.ldaptive.provider.ProviderConnectionFactory; +import org.ldaptive.ssl.CertificateHostnameVerifier; +import org.ldaptive.ssl.CredentialConfig; +import org.ldaptive.ssl.DefaultHostnameVerifier; +import org.ldaptive.ssl.DefaultSSLContextInitializer; +import org.ldaptive.ssl.HostnameVerifierConfig; +import org.ldaptive.ssl.HostnameVerifyingTrustManager; +import org.ldaptive.ssl.SSLContextInitializer; + +/** + * Exposes a connection factory for creating ldap connections with Apache LDAP. + * + * @author Middleware Services + */ +public class ApacheLdapProvider implements Provider<ApacheLdapProviderConfig> +{ + + + /** Provider configuration. */ + private ApacheLdapProviderConfig config = new ApacheLdapProviderConfig(); + + + @Override + public ProviderConnectionFactory<ApacheLdapProviderConfig> getConnectionFactory(final ConnectionConfig cc) + { + LdapConnectionConfig lcc = config.getLdapConnectionConfig(); + if (lcc == null) { + lcc = getDefaultLdapConnectionConfig(cc); + } + return new ApacheLdapConnectionFactory( + cc.getLdapUrl(), + cc.getConnectionStrategy(), + config, + lcc, + cc.getUseStartTLS(), + cc.getResponseTimeout()); + } + + + /** + * Returns an SSLContextInitializer configured with a hostname verifier. Uses a {@link DefaultHostnameVerifier} if no + * SSL config has been configured. + * + * @param cc connection configuration + * + * @return SSL Context Initializer + */ + protected SSLContextInitializer getHostnameVerifierSSLContextInitializer(final ConnectionConfig cc) + { + final LdapURL ldapUrl = new LdapURL(cc.getLdapUrl()); + SSLContextInitializer contextInit; + if (cc.getSslConfig() != null && !cc.getSslConfig().isEmpty()) { + final CredentialConfig credConfig = cc.getSslConfig().getCredentialConfig(); + final TrustManager[] managers = cc.getSslConfig().getTrustManagers(); + final CertificateHostnameVerifier verifier = cc.getSslConfig().getHostnameVerifier(); + if (credConfig != null) { + try { + contextInit = credConfig.createSSLContextInitializer(); + } catch (GeneralSecurityException e) { + throw new IllegalArgumentException(e); + } + } else { + if (managers != null) { + contextInit = new DefaultSSLContextInitializer(false); + } else { + contextInit = new DefaultSSLContextInitializer(true); + } + } + + if (managers != null) { + contextInit.setTrustManagers(managers); + } + if (verifier != null) { + contextInit.setHostnameVerifierConfig(new HostnameVerifierConfig(verifier, ldapUrl.getHostnames())); + } else { + contextInit.setHostnameVerifierConfig( + new HostnameVerifierConfig(new DefaultHostnameVerifier(), ldapUrl.getHostnames())); + } + } else { + contextInit = new DefaultSSLContextInitializer(true); + contextInit.setTrustManagers( + new HostnameVerifyingTrustManager(new DefaultHostnameVerifier(), ldapUrl.getHostnames())); + } + return contextInit; + } + + + /** + * Returns the default connection configuration for this provider. + * + * @param cc to configure with + * + * @return ldap connection configuration + */ + protected LdapConnectionConfig getDefaultLdapConnectionConfig(final ConnectionConfig cc) + { + final LdapConnectionConfig lcc = new LdapConnectionConfig(); + if (cc.getUseStartTLS() || cc.getUseSSL() || cc.getLdapUrl().toLowerCase().contains("ldaps://")) { + final SSLContextInitializer contextInit = getHostnameVerifierSSLContextInitializer(cc); + TrustManager[] trustManagers; + KeyManager[] keyManagers; + try { + trustManagers = contextInit.getTrustManagers(); + keyManagers = contextInit.getKeyManagers(); + } catch (GeneralSecurityException e) { + throw new IllegalArgumentException(e); + } + + lcc.setUseSsl(cc.getUseSSL() || cc.getLdapUrl().toLowerCase().contains("ldaps://")); + lcc.setTrustManagers(trustManagers); + lcc.setKeyManagers(keyManagers); + if (cc.getSslConfig() != null && cc.getSslConfig().getEnabledCipherSuites() != null) { + lcc.setEnabledCipherSuites(cc.getSslConfig().getEnabledCipherSuites()); + } + if (cc.getSslConfig() != null && cc.getSslConfig().getEnabledProtocols() != null) { + lcc.setSslProtocol(cc.getSslConfig().getEnabledProtocols()[0]); + } + } + return lcc; + } + + + @Override + public ApacheLdapProviderConfig getProviderConfig() + { + return config; + } + + + @Override + public void setProviderConfig(final ApacheLdapProviderConfig pc) + { + config = pc; + } + + + @Override + public ApacheLdapProvider newInstance() + { + return new ApacheLdapProvider(); + } +}
diff --git a/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapProviderConfig.java b/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapProviderConfig.java new file mode 100644 index 0000000..41e3cd4 --- /dev/null +++ b/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapProviderConfig.java
@@ -0,0 +1,68 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.apache; + +import java.util.Arrays; +import org.apache.directory.api.ldap.model.message.Control; +import org.apache.directory.ldap.client.api.LdapConnectionConfig; +import org.ldaptive.ResultCode; +import org.ldaptive.provider.ControlProcessor; +import org.ldaptive.provider.ProviderConfig; + +/** + * Contains configuration data for the Apache Ldap provider. + * + * @author Middleware Services + */ +public class ApacheLdapProviderConfig extends ProviderConfig<Control> +{ + + /** Connection configuration. */ + private LdapConnectionConfig connectionConfig; + + + /** Default constructor. */ + public ApacheLdapProviderConfig() + { + setOperationExceptionResultCodes(ResultCode.SERVER_DOWN); + setControlProcessor(new ControlProcessor<>(new ApacheLdapControlHandler())); + } + + + /** + * Returns the connection configuration. + * + * @return connection configuration + */ + public LdapConnectionConfig getLdapConnectionConfig() + { + return connectionConfig; + } + + + /** + * Sets the connection configuration. + * + * @param config connection configuration + */ + public void setLdapConnectionConfig(final LdapConnectionConfig config) + { + checkImmutable(); + logger.trace("setting ldapConnectionConfig: {}", config); + connectionConfig = config; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::operationExceptionResultCodes=%s, properties=%s, controlProcessor=%s, ldapConnectionConfig=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(getOperationExceptionResultCodes()), + getProperties(), + getControlProcessor(), + connectionConfig); + } +}
diff --git a/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapSaslUtils.java b/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapSaslUtils.java new file mode 100644 index 0000000..8e45a8e --- /dev/null +++ b/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapSaslUtils.java
@@ -0,0 +1,229 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.apache; + +import javax.security.auth.login.Configuration; +import org.apache.directory.api.ldap.model.constants.SaslQoP; +import org.apache.directory.api.ldap.model.constants.SaslSecurityStrength; +import org.apache.directory.ldap.client.api.SaslCramMd5Request; +import org.apache.directory.ldap.client.api.SaslDigestMd5Request; +import org.apache.directory.ldap.client.api.SaslGssApiRequest; +import org.ldaptive.Credential; +import org.ldaptive.sasl.DigestMd5Config; +import org.ldaptive.sasl.GssApiConfig; +import org.ldaptive.sasl.QualityOfProtection; +import org.ldaptive.sasl.SaslConfig; +import org.ldaptive.sasl.SecurityStrength; + +/** + * Support for SASL authentication. + * + * @author Middleware Services + */ +public final class ApacheLdapSaslUtils +{ + + + /** Default constructor. */ + private ApacheLdapSaslUtils() {} + + + /** + * Creates a new digest md5 request. + * + * @param username to bind as + * @param credential to bind with + * @param config to set sasl parameters + * + * @return digest md5 request + */ + protected static SaslDigestMd5Request createDigestMd5Request( + final String username, + final Credential credential, + final SaslConfig config) + { + final SaslDigestMd5Request request = new SaslDigestMd5Request(); + if (username != null) { + request.setUsername(username); + } + if (credential != null) { + request.setCredentials(credential.getBytes()); + } + if (config.getAuthorizationId() != null && !"".equals(config.getAuthorizationId())) { + request.setAuthorizationId(config.getAuthorizationId()); + } + if (config.getMutualAuthentication() != null) { + request.setMutualAuthentication(config.getMutualAuthentication()); + } + if (config.getQualityOfProtection() != null) { + request.setQualityOfProtection(getQualityOfProtection(config.getQualityOfProtection())); + } + if (config.getSecurityStrength() != null) { + request.setSecurityStrength(getSecurityStrength(config.getSecurityStrength())); + } + if (config instanceof DigestMd5Config) { + final DigestMd5Config c = (DigestMd5Config) config; + if (c.getRealm() != null) { + request.setRealmName(c.getRealm()); + } + } + return request; + } + + + /** + * Creates a new cram md5 request. + * + * @param username to bind as + * @param credential to bind with + * @param config to set sasl parameters + * + * @return cram md5 request + */ + protected static SaslCramMd5Request createCramMd5Request( + final String username, + final Credential credential, + final SaslConfig config) + { + final SaslCramMd5Request request = new SaslCramMd5Request(); + if (username != null) { + request.setUsername(username); + } + if (credential != null) { + request.setCredentials(credential.getBytes()); + } + if (config.getAuthorizationId() != null && !"".equals(config.getAuthorizationId())) { + request.setAuthorizationId(config.getAuthorizationId()); + } + if (config.getMutualAuthentication() != null) { + request.setMutualAuthentication(config.getMutualAuthentication()); + } + if (config.getQualityOfProtection() != null) { + request.setQualityOfProtection(getQualityOfProtection(config.getQualityOfProtection())); + } + if (config.getSecurityStrength() != null) { + request.setSecurityStrength(getSecurityStrength(config.getSecurityStrength())); + } + return request; + } + + + /** + * Creates a new gssapi request. + * + * @param username to bind as + * @param credential to bind with + * @param config to set sasl parameters + * + * @return gssapi request + */ + protected static SaslGssApiRequest createGssApiRequest( + final String username, + final Credential credential, + final SaslConfig config) + { + final SaslGssApiRequest request = new SaslGssApiRequest(); + if (username != null) { + request.setUsername(username); + } + if (credential != null) { + request.setCredentials(credential.getBytes()); + } + if (config.getAuthorizationId() != null) { + request.setAuthorizationId(config.getAuthorizationId()); + } + if (config.getMutualAuthentication() != null) { + request.setMutualAuthentication(config.getMutualAuthentication()); + } + if (config.getQualityOfProtection() != null) { + request.setQualityOfProtection(getQualityOfProtection(config.getQualityOfProtection())); + } + if (config.getSecurityStrength() != null) { + request.setSecurityStrength(getSecurityStrength(config.getSecurityStrength())); + } + if (config instanceof GssApiConfig) { + final GssApiConfig c = (GssApiConfig) config; + if (c.getRealm() != null) { + request.setRealmName(c.getRealm()); + } + } + + final String realm = System.getProperty("java.security.krb5.realm"); + if (realm != null) { + request.setRealmName(realm); + } + + final String kdcHost = System.getProperty("java.security.krb5.kdc"); + if (kdcHost != null) { + request.setKdcHost(kdcHost); + } + + final String loginConfig = System.getProperty("java.security.auth.login.config"); + if (loginConfig != null) { + request.setLoginModuleConfiguration(Configuration.getConfiguration()); + } + request.setLoginContextName("com.sun.security.jgss.initiate"); + return request; + } + + + /** + * Returns the SASL quality of protection string for the supplied enum. + * + * @param qop quality of protection enum + * + * @return SASL quality of protection + */ + protected static SaslQoP getQualityOfProtection(final QualityOfProtection qop) + { + SaslQoP e; + switch (qop) { + + case AUTH: + e = SaslQoP.AUTH; + break; + + case AUTH_INT: + e = SaslQoP.AUTH_INT; + break; + + case AUTH_CONF: + e = SaslQoP.AUTH_CONF; + break; + + default: + throw new IllegalArgumentException("Unknown SASL quality of protection: " + qop); + } + return e; + } + + + /** + * Returns the SASL security strength string for the supplied enum. + * + * @param ss security strength enum + * + * @return SASL security strength + */ + protected static SaslSecurityStrength getSecurityStrength(final SecurityStrength ss) + { + SaslSecurityStrength e; + switch (ss) { + + case HIGH: + e = SaslSecurityStrength.HIGH; + break; + + case MEDIUM: + e = SaslSecurityStrength.MEDIUM; + break; + + case LOW: + e = SaslSecurityStrength.LOW; + break; + + default: + throw new IllegalArgumentException("Unknown SASL security strength: " + ss); + } + return e; + } +}
diff --git a/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapUtils.java b/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapUtils.java new file mode 100644 index 0000000..1098190 --- /dev/null +++ b/apache-provider/src/main/java/org/ldaptive/provider/apache/ApacheLdapUtils.java
@@ -0,0 +1,243 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.apache; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import org.apache.directory.api.ldap.model.entry.Attribute; +import org.apache.directory.api.ldap.model.entry.BinaryValue; +import org.apache.directory.api.ldap.model.entry.DefaultAttribute; +import org.apache.directory.api.ldap.model.entry.DefaultEntry; +import org.apache.directory.api.ldap.model.entry.DefaultModification; +import org.apache.directory.api.ldap.model.entry.Entry; +import org.apache.directory.api.ldap.model.entry.Modification; +import org.apache.directory.api.ldap.model.entry.ModificationOperation; +import org.apache.directory.api.ldap.model.entry.StringValue; +import org.apache.directory.api.ldap.model.entry.Value; +import org.apache.directory.api.ldap.model.exception.LdapException; +import org.ldaptive.AttributeModification; +import org.ldaptive.AttributeModificationType; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.SearchEntry; +import org.ldaptive.SortBehavior; +import org.ldaptive.control.ResponseControl; + +/** + * Provides methods for converting between Apache Ldap specific objects and ldaptive specific objects. + * + * @author Middleware Services + */ +public class ApacheLdapUtils +{ + + /** Ldap result sort behavior. */ + private final SortBehavior sortBehavior; + + /** Attributes that should be treated as binary. */ + private List<String> binaryAttrs; + + + /** Default constructor. */ + public ApacheLdapUtils() + { + sortBehavior = SortBehavior.getDefaultSortBehavior(); + } + + + /** + * Creates a new apache ldap util. + * + * @param sb sort behavior + */ + public ApacheLdapUtils(final SortBehavior sb) + { + sortBehavior = sb; + } + + + /** + * Returns the list of binary attributes. + * + * @return list of binary attributes + */ + public List<String> getBinaryAttributes() + { + return binaryAttrs; + } + + + /** + * Sets the list of binary attributes. + * + * @param s binary attributes + */ + public void setBinaryAttributes(final String[] s) + { + if (s != null) { + binaryAttrs = Arrays.asList(s); + } + } + + + /** + * Returns an apache ldap value for the supplied object. + * + * @param o object value + * + * @return apache ldap value + */ + public static Value<?> createValue(final Object o) + { + if (o instanceof String) { + return new StringValue((String) o); + } else if (o instanceof byte[]) { + return new BinaryValue((byte[]) o); + } else { + throw new IllegalArgumentException("Unsupported attribute value type " + o.getClass()); + } + } + + + /** + * Returns an apache ldap attribute that represents the values in the supplied ldap attribute. + * + * @param la ldap attribute + * + * @return apache ldap attribute + */ + public Attribute fromLdapAttribute(final LdapAttribute la) + { + final DefaultAttribute attribute = new DefaultAttribute(la.getName()); + if (la.isBinary()) { + for (byte[] value : la.getBinaryValues()) { + attribute.add(createValue(value)); + } + } else { + for (String value : la.getStringValues()) { + attribute.add(createValue(value)); + } + } + return attribute; + } + + + /** + * Returns an ldap attribute using the supplied apache ldap attribute. + * + * @param a apache ldap attribute + * + * @return ldap attribute + */ + public LdapAttribute toLdapAttribute(final Attribute a) + { + boolean isBinary = false; + if (a.getId().contains(";binary")) { + isBinary = true; + } else if (binaryAttrs != null && binaryAttrs.contains(a.getUpId())) { + isBinary = true; + } + + final LdapAttribute la = new LdapAttribute(sortBehavior, isBinary); + la.setName(a.getUpId()); + for (Value<?> v : a) { + if (isBinary) { + la.addBinaryValue(v.getBytes()); + } else { + la.addStringValue(v.getString()); + } + } + return la; + } + + + /** + * Returns a list of apache ldap attribute that represents the values in the supplied ldap attributes. + * + * @param c ldap attributes + * + * @return apache ldap attributes + */ + public Attribute[] fromLdapAttributes(final Collection<LdapAttribute> c) + { + return c.stream().map(this::fromLdapAttribute).toArray(Attribute[]::new); + } + + + /** + * Returns an apache ldap entry that represents the supplied ldap entry. + * + * @param le ldap entry + * + * @return apache ldap entry + * + * @throws LdapException if the apache object cannot be created + */ + public Entry fromLdapEntry(final LdapEntry le) + throws LdapException + { + final DefaultEntry entry = new DefaultEntry(le.getDn()); + entry.add(fromLdapAttributes(le.getAttributes())); + return entry; + } + + + /** + * Returns a search entry using the supplied apache ldap entry. + * + * @param e apache ldap entry + * @param c response controls + * @param id message id + * + * @return search entry + */ + public SearchEntry toSearchEntry(final Entry e, final ResponseControl[] c, final int id) + { + final SearchEntry se = new SearchEntry(id, c, sortBehavior); + se.setDn(e.getDn().getName()); + for (Attribute a : e) { + se.addAttribute(toLdapAttribute(a)); + } + return se; + } + + + /** + * Returns apache ldap modifications using the supplied attribute modifications. + * + * @param am attribute modifications + * + * @return apache ldap modifications + */ + public Modification[] fromAttributeModification(final AttributeModification[] am) + { + final Modification[] mods = new Modification[am.length]; + for (int i = 0; i < am.length; i++) { + mods[i] = new DefaultModification( + getAttributeModification(am[i].getAttributeModificationType()), + fromLdapAttribute(am[i].getAttribute())); + } + return mods; + } + + + /** + * Returns the apache ldap modification operation for the supplied attribute modification type. + * + * @param am attribute modification type + * + * @return modification operation + */ + protected static ModificationOperation getAttributeModification(final AttributeModificationType am) + { + ModificationOperation op = null; + if (am == AttributeModificationType.ADD) { + op = ModificationOperation.ADD_ATTRIBUTE; + } else if (am == AttributeModificationType.REMOVE) { + op = ModificationOperation.REMOVE_ATTRIBUTE; + } else if (am == AttributeModificationType.REPLACE) { + op = ModificationOperation.REPLACE_ATTRIBUTE; + } + return op; + } +}
diff --git a/beans/pom.xml b/beans/pom.xml new file mode 100644 index 0000000..084b90c --- /dev/null +++ b/beans/pom.xml
@@ -0,0 +1,42 @@ +<?xml version='1.0' encoding='UTF-8'?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>ldaptive-beans</artifactId> + <packaging>jar</packaging> + <name>LDAPTIVE BEANS</name> + <description>Mapping, persistence, and code generation API for reading and writing POJOs to an LDAP directory</description> + <parent> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-parent</artifactId> + <version>1.2.3</version> + </parent> + + <dependencies> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-beans</artifactId> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-expression</artifactId> + <optional>true</optional> + </dependency> + <dependency> + <groupId>com.sun.codemodel</groupId> + <artifactId>codemodel</artifactId> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + </dependency> + </dependencies> + +</project>
diff --git a/beans/src/main/java/org/ldaptive/beans/AbstractClassDescriptor.java b/beans/src/main/java/org/ldaptive/beans/AbstractClassDescriptor.java new file mode 100644 index 0000000..57046dd --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/AbstractClassDescriptor.java
@@ -0,0 +1,219 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapUtils; +import org.ldaptive.SortBehavior; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base implementation of a class descriptor. Stores a map of {@link AttributeValueMutator} and a {@link + * DnValueMutator}. + * + * @author Middleware Services + */ +public abstract class AbstractClassDescriptor implements ClassDescriptor +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Attribute value mutators for this class. */ + private final Map<String, AttributeValueMutator> attributeMutators = new HashMap<>(); + + /** Dn value mutator for this class. */ + private DnValueMutator dnMutator; + + + /** + * Sets the dn value mutator. + * + * @param mutator to set + */ + protected void setDnValueMutator(final DnValueMutator mutator) + { + if (dnMutator != null) { + throw new IllegalStateException("Found duplicate dn"); + } + dnMutator = mutator; + } + + + /** + * Adds an attribute value mutator to this class descriptor. + * + * @param mutator to add + */ + protected void addAttributeValueMutator(final AttributeValueMutator mutator) + { + if (attributeMutators.containsKey(mutator.getName())) { + throw new IllegalStateException("Found duplicate attribute name '" + mutator.getName() + "'"); + } + attributeMutators.put(mutator.getName(), mutator); + } + + + /** + * Adds attribute value mutators to this class descriptor. + * + * @param mutators to add + */ + protected void addAttributeValueMutator(final Collection<AttributeValueMutator> mutators) + { + mutators.forEach(this::addAttributeValueMutator); + } + + + @Override + public DnValueMutator getDnValueMutator() + { + return dnMutator; + } + + + @Override + public Collection<AttributeValueMutator> getAttributeValueMutators() + { + return attributeMutators.values(); + } + + + @Override + public AttributeValueMutator getAttributeValueMutator(final String name) + { + return attributeMutators.get(name); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::dnMutator=%s, attributeMutators=%s]", + getClass().getName(), + hashCode(), + dnMutator, + attributeMutators); + } + + + /** Stores the DN value from a {@link Entry} configuration. Setter method is a no-op. */ + protected class SimpleDnValueMutator implements DnValueMutator + { + + /** DN value to store. */ + private final String dn; + + + /** + * Creates a new simple dn value mutator. + * + * @param value that is the DN + */ + public SimpleDnValueMutator(final String value) + { + dn = value; + } + + + @Override + public String getValue(final Object object) + { + return dn; + } + + + @Override + public void setValue(final Object object, final String value) {} + } + + + /** Stores an {@link Attribute} configuration in an {@link LdapAttribute} object. Setter methods are no-ops. */ + protected class SimpleAttributeValueMutator implements AttributeValueMutator + { + + /** Ldap attribute to operate on. */ + private final LdapAttribute la; + + + /** + * Creates a new simple attribute value mutator. + * + * @param name of the attribute + * @param values of the attribute + * @param binary whether values contains base64 encoded data + * @param behavior sort behavior of the attribute + */ + public SimpleAttributeValueMutator( + final String name, + final String[] values, + final boolean binary, + final SortBehavior behavior) + { + la = new LdapAttribute(behavior, binary); + la.setName(name); + if (binary) { + for (String value : values) { + la.addBinaryValue(LdapUtils.base64Decode(value)); + } + } else { + la.addStringValue(values); + } + } + + + @Override + public String getName() + { + return la.getName(); + } + + + @Override + public boolean isBinary() + { + return la.isBinary(); + } + + + @Override + public SortBehavior getSortBehavior() + { + return la.getSortBehavior(); + } + + + @Override + public Collection<String> getStringValues(final Object object) + { + return la.getStringValues(); + } + + + @Override + public Collection<byte[]> getBinaryValues(final Object object) + { + return la.getBinaryValues(); + } + + + @Override + public void setStringValues(final Object object, final Collection<String> values) {} + + + @Override + public void setBinaryValues(final Object object, final Collection<byte[]> values) {} + + + @Override + public String toString() + { + return String.format("[%s@%d::ldapAttribute=%s]", getClass().getName(), hashCode(), la); + } + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/AbstractLdapEntryMapper.java b/beans/src/main/java/org/ldaptive/beans/AbstractLdapEntryMapper.java new file mode 100644 index 0000000..2eceb4f --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/AbstractLdapEntryMapper.java
@@ -0,0 +1,114 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans; + +import java.util.Collection; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base implementation of an ldap entry mapper. Uses a {@link ClassDescriptor} for decoding and encoding of objects. + * + * @param <T> type of object to map + * + * @author Middleware Services + */ +public abstract class AbstractLdapEntryMapper<T> implements LdapEntryMapper<T> +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + + /** + * Returns the class descriptor. + * + * @param object to return the class descriptor for + * + * @return class descriptor + */ + protected abstract ClassDescriptor getClassDescriptor(final T object); + + + @Override + public String mapDn(final T object) + { + final ClassDescriptor descriptor = getClassDescriptor(object); + final DnValueMutator dnMutator = descriptor.getDnValueMutator(); + return dnMutator.getValue(object); + } + + + /** + * Injects data from the supplied source object into a new instance of ldap entry. + * + * @param source to read from + * + * @return ldap entry + */ + public LdapEntry map(final T source) + { + final LdapEntry dest = new LdapEntry(); + map(source, dest); + return dest; + } + + + @Override + public void map(final T source, final LdapEntry dest) + { + logger.debug("map {} to {}", source, dest); + + final ClassDescriptor descriptor = getClassDescriptor(source); + final DnValueMutator dnMutator = descriptor.getDnValueMutator(); + if (dnMutator != null) { + dest.setDn(dnMutator.getValue(source)); + } + for (AttributeValueMutator mutator : descriptor.getAttributeValueMutators()) { + logger.debug("using mutator {}", mutator); + if (mutator != null) { + final LdapAttribute attr = new LdapAttribute(mutator.getSortBehavior(), mutator.isBinary()); + attr.setName(mutator.getName()); + if (attr.isBinary()) { + final Collection<byte[]> c = mutator.getBinaryValues(source); + if (c != null) { + attr.addBinaryValues(c); + } + } else { + final Collection<String> c = mutator.getStringValues(source); + if (c != null) { + attr.addStringValues(c); + } + } + if (attr.size() > 0) { + dest.addAttribute(attr); + } + } + } + } + + + @Override + public void map(final LdapEntry source, final T dest) + { + logger.debug("map {} to {}", source, dest); + + final ClassDescriptor descriptor = getClassDescriptor(dest); + final DnValueMutator dnMutator = descriptor.getDnValueMutator(); + if (dnMutator != null) { + dnMutator.setValue(dest, source.getDn()); + } + source.getAttributes().stream().filter(attr -> attr.size() > 0).forEach(attr -> { + final AttributeValueMutator mutator = descriptor.getAttributeValueMutator(attr.getName()); + logger.debug("using mutator {} for attribute {}", mutator, attr); + if (mutator != null) { + if (attr.isBinary()) { + mutator.setBinaryValues(dest, attr.getBinaryValues()); + } else { + mutator.setStringValues(dest, attr.getStringValues()); + } + } + }); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/Attribute.java b/beans/src/main/java/org/ldaptive/beans/Attribute.java new file mode 100644 index 0000000..1532591 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/Attribute.java
@@ -0,0 +1,61 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.ldaptive.SortBehavior; + +/** + * Annotation to describe LDAP attribute data on a bean. + * + * @author Middleware Services + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.ANNOTATION_TYPE) +public @interface Attribute +{ + + /** + * Attribute name. + * + * @return name of this attribute + */ + String name() default ""; + + /** + * Attribute values. Mutually exclusive with {@link #property()}. + * + * @return concrete values for this attribute + */ + String[] values() default {}; + + /** + * Name of the method or field that maps to this attribute. Mutually exclusive with {@link #values()}. + * + * @return property that contains attribute values + */ + String property() default ""; + + /** + * Whether this attribute is binary. + * + * @return whether this attribute is binary + */ + boolean binary() default false; + + /** + * Sort behavior for this attribute. + * + * @return sort behavior + */ + SortBehavior sortBehavior() default SortBehavior.UNORDERED; + + /** + * Transcoder for this attribute. + * + * @return transcoder class name + */ + String transcoder() default ""; +}
diff --git a/beans/src/main/java/org/ldaptive/beans/AttributeValueMutator.java b/beans/src/main/java/org/ldaptive/beans/AttributeValueMutator.java new file mode 100644 index 0000000..efb3163 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/AttributeValueMutator.java
@@ -0,0 +1,76 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans; + +import java.util.Collection; +import org.ldaptive.SortBehavior; + +/** + * Interface for mutating an attribute value on an arbitrary object. + * + * @author Middleware Services + */ +public interface AttributeValueMutator +{ + + + /** + * Returns the name of the attribute. + * + * @return attribute name + */ + String getName(); + + + /** + * Returns whether the attribute is binary. + * + * @return whether the attribute is binary + */ + boolean isBinary(); + + + /** + * Returns the sort behavior of the attribute. + * + * @return sort behavior of the attribute + */ + SortBehavior getSortBehavior(); + + + /** + * Returns the string values of the attribute. + * + * @param object containing attribute values + * + * @return attribute values + */ + Collection<String> getStringValues(Object object); + + + /** + * Returns the binary values of the attribute. + * + * @param object containing attribute values + * + * @return attribute values + */ + Collection<byte[]> getBinaryValues(Object object); + + + /** + * Sets the string values of the attribute. + * + * @param object to set values on + * @param values to set + */ + void setStringValues(Object object, Collection<String> values); + + + /** + * Sets the binary values of the attribute. + * + * @param object to set values on + * @param values to set + */ + void setBinaryValues(Object object, Collection<byte[]> values); +}
diff --git a/beans/src/main/java/org/ldaptive/beans/ClassDescriptor.java b/beans/src/main/java/org/ldaptive/beans/ClassDescriptor.java new file mode 100644 index 0000000..cb7f6ab --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/ClassDescriptor.java
@@ -0,0 +1,47 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans; + +import java.util.Collection; + +/** + * Describes the attribute value mutators and DN value mutators for a specific type. + * + * @author Middleware Services + */ +public interface ClassDescriptor +{ + + + /** + * Prepare this class descriptor for use. + * + * @param type of object to describe + */ + void initialize(Class<?> type); + + + /** + * Returns the DN value mutator for this type. + * + * @return dn value mutator + */ + DnValueMutator getDnValueMutator(); + + + /** + * Returns the attribute value mutators for this type. + * + * @return value mutators + */ + Collection<AttributeValueMutator> getAttributeValueMutators(); + + + /** + * Returns the attribute value mutator for the attribute with the supplied name. + * + * @param name of the attribute + * + * @return value mutator + */ + AttributeValueMutator getAttributeValueMutator(String name); +}
diff --git a/beans/src/main/java/org/ldaptive/beans/DnValueMutator.java b/beans/src/main/java/org/ldaptive/beans/DnValueMutator.java new file mode 100644 index 0000000..dd14d04 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/DnValueMutator.java
@@ -0,0 +1,29 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans; + +/** + * Interface for mutating the DN value on an arbitrary object. + * + * @author Middleware Services + */ +public interface DnValueMutator +{ + + /** + * Returns the DN value for the supplied object. + * + * @param object to return the DN of + * + * @return DN value + */ + String getValue(final Object object); + + + /** + * Set the DN value for the supplied object. + * + * @param object to set the DN on + * @param value of the DN + */ + void setValue(final Object object, final String value); +}
diff --git a/beans/src/main/java/org/ldaptive/beans/Entry.java b/beans/src/main/java/org/ldaptive/beans/Entry.java new file mode 100644 index 0000000..6994a0b --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/Entry.java
@@ -0,0 +1,32 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation to describe an LDAP entry on a bean. + * + * @author Middleware Services + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface Entry +{ + + /** + * Entry DN. + * + * @return dn of this entry + */ + String dn(); + + /** + * Entry attributes. + * + * @return attributes + */ + Attribute[] attributes() default {}; +}
diff --git a/beans/src/main/java/org/ldaptive/beans/LdapEntryMapper.java b/beans/src/main/java/org/ldaptive/beans/LdapEntryMapper.java new file mode 100644 index 0000000..c29ac5c --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/LdapEntryMapper.java
@@ -0,0 +1,43 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans; + +import org.ldaptive.LdapEntry; + +/** + * Interface for ldap entry mappers. + * + * @param <T> type of object to map + * + * @author Middleware Services + */ +public interface LdapEntryMapper<T> +{ + + + /** + * Returns the LDAP DN for the supplied object. + * + * @param object to retrieve the DN from + * + * @return LDAP DN + */ + String mapDn(T object); + + + /** + * Injects data from the supplied source object into the supplied ldap entry. + * + * @param source to read from + * @param dest to write to + */ + void map(T source, LdapEntry dest); + + + /** + * Injects data from the supplied ldap entry into the supplied destination object. + * + * @param source to read from + * @param dest to write to + */ + void map(LdapEntry source, T dest); +}
diff --git a/beans/src/main/java/org/ldaptive/beans/generate/BeanGenerator.java b/beans/src/main/java/org/ldaptive/beans/generate/BeanGenerator.java new file mode 100644 index 0000000..f7422cb --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/generate/BeanGenerator.java
@@ -0,0 +1,740 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.generate; + +import java.io.File; +import java.io.IOException; +import java.security.cert.Certificate; +import java.time.ZonedDateTime; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.UUID; +import java.util.stream.Collectors; +import com.sun.codemodel.JAnnotationArrayMember; +import com.sun.codemodel.JAnnotationUse; +import com.sun.codemodel.JClass; +import com.sun.codemodel.JClassAlreadyExistsException; +import com.sun.codemodel.JCodeModel; +import com.sun.codemodel.JConditional; +import com.sun.codemodel.JDefinedClass; +import com.sun.codemodel.JDocComment; +import com.sun.codemodel.JExpr; +import com.sun.codemodel.JExpression; +import com.sun.codemodel.JFieldVar; +import com.sun.codemodel.JInvocation; +import com.sun.codemodel.JMethod; +import com.sun.codemodel.JMod; +import com.sun.codemodel.JVar; +import org.ldaptive.beans.generate.props.BeanGeneratorPropertySource; +import org.ldaptive.schema.AttributeType; +import org.ldaptive.schema.AttributeUsage; +import org.ldaptive.schema.ObjectClass; +import org.ldaptive.schema.Schema; +import org.ldaptive.schema.Syntax; + +/** + * Utility class for creating Java POJOs from an LDAP schema. Sample usage: + * + * <pre> + Schema schema = new Schema(new DefaultConnectionFactory( + "ldap://directory.ldaptive.org")); + BeanGenerator generator = new BeanGenerator( + schema, + "com.my.package", + new String[] {"inetOrgPerson"}); + generator.generate(); + generator.write(); + * </pre> + * + * @author Middleware Services + */ +public class BeanGenerator +{ + + /** Code model for java class creation. */ + private final JCodeModel codeModel = new JCodeModel(); + + /** Schema to generate beans from. */ + private Schema schema; + + /** Package to create beans in. */ + private String packageName; + + /** Object classes to build beans for. */ + private String[] objectClasses; + + /** Whether to include optional attributes. */ + private boolean useOptionalAttributes = true; + + /** Whether to include operational attributes. */ + private boolean useOperationalAttributes; + + /** Whether to include superior classes for each object class. */ + private boolean includeSuperiorClasses; + + /** Mapping to determine attribute value type. */ + private Map<String, Class<?>> typeMappings = getDefaultTypeMappings(); + + /** Name mappings. */ + private Map<String, String> nameMappings = new HashMap<>(); + + /** Excluded names. */ + private String[] excludedNames = new String[0]; + + + /** Default constructor. */ + public BeanGenerator() {} + + + /** + * Creates a new bean generator. A bean will be generated for each supplied object class. + * + * @param s schema containing directory data for generation + * @param name package name to place the generated classes in + * @param oc object classes to generate beans for + */ + public BeanGenerator(final Schema s, final String name, final String[] oc) + { + schema = s; + packageName = name; + objectClasses = oc; + } + + + /** + * Returns the schema. + * + * @return schema + */ + public Schema getSchema() + { + return schema; + } + + + /** + * Sets the schema. + * + * @param s schema + */ + public void setSchema(final Schema s) + { + schema = s; + } + + + /** + * Returns the package name where beans will be generated. + * + * @return package name + */ + public String getPackageName() + { + return packageName; + } + + + /** + * Sets the package name where beans will be generated. + * + * @param name package name + */ + public void setPackageName(final String name) + { + packageName = name; + } + + + /** + * Returns the object classes. A class is generated for each object class. + * + * @return object classes + */ + public String[] getObjectClasses() + { + return objectClasses; + } + + + /** + * Sets the object classes. A class is generated for each object class. + * + * @param oc object classes + */ + public void setObjectClasses(final String... oc) + { + objectClasses = oc; + } + + + /** + * Returns whether to include optional attributes in bean generation. + * + * @return whether to include optional attributes + */ + public boolean isUseOptionalAttributes() + { + return useOptionalAttributes; + } + + + /** + * Sets whether to include optional attributes in bean generation. + * + * @param b whether to include optional attributes + */ + public void setUseOptionalAttributes(final boolean b) + { + useOptionalAttributes = b; + } + + + /** + * Returns whether to include operational attributes in bean generation. + * + * @return whether to include operational attributes + */ + public boolean isUseOperationalAttributes() + { + return useOperationalAttributes; + } + + + /** + * Sets whether to include operational attributes in bean generation. + * + * @param b whether to include operational attributes + */ + public void setUseOperationalAttributes(final boolean b) + { + useOperationalAttributes = b; + } + + + /** + * Returns whether to include superior classes in bean generation. + * + * @return whether to include superior classes attributes + */ + public boolean isIncludeSuperiorClasses() + { + return includeSuperiorClasses; + } + + + /** + * Sets whether to include superior classes in bean generation. + * + * @param b whether to include superior classes + */ + public void setIncludeSuperiorClasses(final boolean b) + { + includeSuperiorClasses = b; + } + + + /** + * Returns the type mappings. Type mappings is syntax OID to class type and is used to determine field type in the + * generated POJOs. + * + * @return type mappings + */ + public Map<String, Class<?>> getTypeMappings() + { + return typeMappings; + } + + + /** + * Sets the type mappings. Type mappings is syntax OID to class type and is used to determine field type in the + * generated POJOs. + * + * @param m type mappings + */ + public void setTypeMappings(final Map<String, Class<?>> m) + { + typeMappings = m; + } + + + /** + * Returns the mapping of directory attribute name to bean property. This property is used to override the default + * schema name. For instance, you may prefer using 'countryName' to 'c', which would be set as 'c'=>'countryName'. + * + * @return attribute name to bean property mapping + */ + public Map<String, String> getNameMappings() + { + return nameMappings; + } + + + /** + * Sets the mapping of directory attribute name to bean property. + * + * @param m name mappings + * + * @throws NullPointerException if m is null + */ + public void setNameMappings(final Map<String, String> m) + { + if (m == null) { + throw new NullPointerException("Name mappings cannot be null"); + } + nameMappings = m; + } + + + /** + * Returns the attribute names to exclude from bean generation. Excludes an attribute from the generated POJO. For + * instance, you may not want 'userPassword' included in your bean. + * + * @return attribute names to exclude + */ + public String[] getExcludedNames() + { + return excludedNames; + } + + + /** + * Sets the attribute names to exclude from bean generation. + * + * @param names to exclude + * + * @throws NullPointerException if names is null + */ + public void setExcludedNames(final String... names) + { + if (names == null) { + throw new NullPointerException("Excluded names cannot be null"); + } + excludedNames = names; + } + + + /** + * Returns the default syntax types used to determine attribute property type. + * + * @return map of syntax OID to class type + */ + protected static Map<String, Class<?>> getDefaultTypeMappings() + { + final Map<String, Class<?>> m = new HashMap<>(); + m.put("1.3.6.1.4.1.1466.115.121.1.7", Boolean.class); + m.put("1.3.6.1.4.1.1466.115.121.1.5", byte[].class); + m.put("1.3.6.1.4.1.1466.115.121.1.8", Certificate.class); + m.put("1.3.6.1.4.1.1466.115.121.1.24", ZonedDateTime.class); + m.put("1.3.6.1.4.1.1466.115.121.1.36", Integer.class); + m.put("1.3.6.1.1.16.1", UUID.class); + return m; + } + + + /** + * Returns the class for the supplied attribute type and syntax. If the attribute type syntax OID is found in the + * default type mapping it is used. Otherwise if the syntax is "X-NOT-HUMAN-READABLE", a byte array is used. + * + * @param type attribute type + * @param syntax associated with the attribute type + * + * @return syntax type + */ + protected Class<?> getSyntaxType(final AttributeType type, final Syntax syntax) + { + Class<?> t = null; + for (Map.Entry<String, Class<?>> entry : typeMappings.entrySet()) { + if (entry.getKey().equals(type.getSyntaxOID(false))) { + t = entry.getValue(); + } + } + if (t == null) { + if (Syntax.containsBooleanExtension(syntax, "X-NOT-HUMAN-READABLE")) { + t = byte[].class; + } else { + t = String.class; + } + } + return t; + } + + + /** + * Generates a class for each configured object class. See {@link #objectClasses}. {@link #write(String)} must be + * invoked to write the classes to disk. + */ + public void generate() + { + for (String objectClass : objectClasses) { + final JDefinedClass definedClass = createClass(packageName, objectClass); + final JDocComment jDocComment = definedClass.javadoc(); + jDocComment.add(String.format("Ldaptive generated bean for objectClass '%s'", objectClass)); + + final ObjectClass oc = schema.getObjectClass(objectClass); + final Set<String> attributeNames = getAttributeNames(oc); + if (useOperationalAttributes) { + attributeNames.addAll( + schema.getAttributeTypes().stream().filter( + type -> AttributeUsage.DIRECTORY_OPERATION.equals(type.getUsage())).map( + AttributeType::getName).collect(Collectors.toList())); + } + + final Map<String, AttributeType> mutators = new TreeMap<>(); + for (String name : attributeNames) { + final AttributeType type = schema.getAttributeType(name); + if (!isNameExcluded(type)) { + if (nameMappings.containsKey(type.getName())) { + mutators.put(nameMappings.get(type.getName()), type); + } else { + mutators.put(formatAttributeName(type.getName()), type); + } + } + } + + // add entry annotation + final JAnnotationUse entryAnnotation = definedClass.annotate(codeModel.ref(org.ldaptive.beans.Entry.class)); + entryAnnotation.param("dn", "dn"); + + final JAnnotationArrayMember attrArray = entryAnnotation.paramArray("attributes"); + + // add mutator for the DN + createMutators(definedClass, "dn", String.class, false); + + // add mutators for each attribute + for (Map.Entry<String, AttributeType> mutator : mutators.entrySet()) { + final Class<?> syntaxType = getSyntaxType( + mutator.getValue(), + schema.getSyntax(mutator.getValue().getSyntaxOID(false))); + if (mutator.getValue().isSingleValued()) { + createMutators(definedClass, mutator.getKey(), syntaxType, false); + } else { + createMutators(definedClass, mutator.getKey(), syntaxType, true); + } + + // add attribute annotation + final JAnnotationUse attrAnnotation = attrArray.annotate(org.ldaptive.beans.Attribute.class); + attrAnnotation.param("name", mutator.getValue().getName()); + if (!mutator.getKey().equals(mutator.getValue().getName())) { + attrAnnotation.param("property", mutator.getKey()); + } + if (byte[].class.equals(syntaxType)) { + attrAnnotation.param("binary", true); + } + } + + // create additional methods + createHashCode(definedClass); + createEquals(definedClass); + createToString(definedClass); + } + } + + + /** + * Returns the attribute names to use for the supplied object class. See {@link #getAttributeNames(ObjectClass, Set)}. + * + * @param objectClass to retrieve names from + * + * @return set of all attribute names used for bean generation + */ + private Set<String> getAttributeNames(final ObjectClass objectClass) + { + return getAttributeNames(objectClass, new HashSet<>()); + } + + + /** + * Returns the attribute names to use for the supplied object class. This method is invoked recursively if superior + * classes are included. + * + * @param objectClass to retrieve names from + * @param processed object classes that have already been processed + * + * @return set of all attribute names used for bean generation + */ + private Set<String> getAttributeNames(final ObjectClass objectClass, final Set<ObjectClass> processed) + { + final Set<String> attributeNames = new HashSet<>(); + if (objectClass != null) { + if (objectClass.getRequiredAttributes() != null) { + attributeNames.addAll(Arrays.asList(objectClass.getRequiredAttributes())); + } + if (useOptionalAttributes && objectClass.getOptionalAttributes() != null) { + attributeNames.addAll(Arrays.asList(objectClass.getOptionalAttributes())); + } + processed.add(objectClass); + if (includeSuperiorClasses && objectClass.getSuperiorClasses() != null) { + for (String oc : objectClass.getSuperiorClasses()) { + final ObjectClass superiorOc = schema.getObjectClass(oc); + if (!processed.contains(superiorOc)) { + attributeNames.addAll(getAttributeNames(superiorOc, processed)); + } + } + } + } + return attributeNames; + } + + + /** + * Formats the supplied name for use as a Java property. + * + * @param name to format + * + * @return formatted name + */ + private String formatAttributeName(final String name) + { + String formatted; + if (name.contains("-")) { + formatted = name.replace("-", ""); + } else { + formatted = name; + } + return formatted; + } + + + /** + * Returns whether the supplied attribute type has a matching OID or name in the excluded names list. + * + * @param type to compare + * + * @return whether attribute type should be excluded from bean generation + */ + private boolean isNameExcluded(final AttributeType type) + { + if (excludedNames != null && excludedNames.length > 0) { + for (String excluded : excludedNames) { + if (type.getOID().equals(excluded) || type.hasName(excluded)) { + return true; + } + } + } + return false; + } + + + /** + * Creates a class in the supplied package. + * + * @param classPackage to place the class in + * @param className to create + * + * @return class + * + * @throws IllegalArgumentException if the class already exists + */ + protected JDefinedClass createClass(final String classPackage, final String className) + { + String fqClassName; + if (!Character.isUpperCase(className.charAt(0))) { + fqClassName = String.format( + "%s.%s", + classPackage, + className.substring(0, 1).toUpperCase() + className.substring(1, className.length())); + } else { + fqClassName = String.format("%s.%s", classPackage, className); + } + + try { + return codeModel._class(fqClassName); + } catch (JClassAlreadyExistsException e) { + throw new IllegalArgumentException("Class already exists: " + fqClassName, e); + } + } + + + /** + * Creates the getter and setter methods on the supplied class for the supplied name. + * + * @param clazz to put getter and setter methods on + * @param name of the property + * @param syntaxType of the property + * @param multivalue whether this property is a collection + */ + protected void createMutators( + final JDefinedClass clazz, + final String name, + final Class<?> syntaxType, + final boolean multivalue) + { + final String upperName = name.substring(0, 1).toUpperCase() + name.substring(1, name.length()); + if (multivalue) { + final JClass detailClass = codeModel.ref(syntaxType); + final JClass collectionClass = codeModel.ref(Collection.class); + final JClass genericClass = collectionClass.narrow(detailClass); + final JFieldVar field = clazz.field(JMod.PRIVATE, genericClass, name); + final JMethod getterMethod = clazz.method(JMod.PUBLIC, genericClass, "get" + upperName); + getterMethod.body()._return(field); + + final JMethod setterMethod = clazz.method(JMod.PUBLIC, Void.TYPE, "set" + upperName); + setterMethod.param(genericClass, "c"); + setterMethod.body().assign(JExpr._this().ref(name), JExpr.ref("c")); + + } else { + final JFieldVar field = clazz.field(JMod.PRIVATE, syntaxType, name); + final JMethod getterMethod = clazz.method(JMod.PUBLIC, syntaxType, "get" + upperName); + getterMethod.body()._return(field); + + final JMethod setterMethod = clazz.method(JMod.PUBLIC, Void.TYPE, "set" + upperName); + setterMethod.param(syntaxType, "s"); + setterMethod.body().assign(JExpr._this().ref(name), JExpr.ref("s")); + } + } + + + /** + * Creates the hashCode method on the supplied class. Leverages {@link org.ldaptive.LdapUtils#computeHashCode(int, + * Object...)}. + * + * @param clazz to put hashCode method on + */ + private void createHashCode(final JDefinedClass clazz) + { + final JClass ldapUtilsClass = codeModel.ref(org.ldaptive.LdapUtils.class); + final JInvocation computeHashCode = ldapUtilsClass.staticInvoke("computeHashCode"); + final JMethod hashCode = clazz.method(JMod.PUBLIC, int.class, "hashCode"); + hashCode.annotate(java.lang.Override.class); + // CheckStyle:MagicNumber OFF + computeHashCode.arg(JExpr.lit(7919)); + // CheckStyle:MagicNumber ON + for (Map.Entry<String, JFieldVar> entry : clazz.fields().entrySet()) { + computeHashCode.arg(JExpr._this().ref(entry.getValue())); + } + hashCode.body()._return(computeHashCode); + } + + + /** + * Creates the equals method on the supplied class. Leverages {@link org.ldaptive.LdapUtils#areEqual(Object, Object)}. + * + * @param clazz to put equals method on + */ + private void createEquals(final JDefinedClass clazz) + { + final JMethod equals = clazz.method(JMod.PUBLIC, boolean.class, "equals"); + equals.annotate(java.lang.Override.class); + final JVar o = equals.param(Object.class, "o"); + + final JConditional ifSame = equals.body()._if(o.eq(JExpr._this())); + ifSame._then()._return(JExpr.TRUE); + + final JConditional ifInstance = equals.body()._if(o._instanceof(clazz)); + final JVar v = ifInstance._then().decl(clazz, "v", JExpr.cast(clazz, o)); + JExpression propertyComparison = null; + for (Map.Entry<String, JFieldVar> entry : clazz.fields().entrySet()) { + final JClass ldapUtilsClass = codeModel.ref(org.ldaptive.LdapUtils.class); + final JInvocation areEqual = ldapUtilsClass.staticInvoke("areEqual"); + areEqual.arg(entry.getValue()); + areEqual.arg(v.ref(entry.getValue())); + if (propertyComparison == null) { + propertyComparison = areEqual; + } else { + propertyComparison = propertyComparison.cand(areEqual); + } + } + ifInstance._then()._return(propertyComparison); + + equals.body()._return(JExpr.FALSE); + } + + + /** + * Creates the toString method on the supplied class. Creates a string that contains every property on the generated + * bean. + * + * @param clazz to put toString method on + */ + private void createToString(final JDefinedClass clazz) + { + final JClass stringClass = codeModel.ref(java.lang.String.class); + final JInvocation format = stringClass.staticInvoke("format"); + final JMethod toString = clazz.method(JMod.PUBLIC, String.class, "toString"); + toString.annotate(java.lang.Override.class); + + final StringBuilder sb = new StringBuilder("[%s@%d::"); + for (Map.Entry<String, JFieldVar> entry : clazz.fields().entrySet()) { + sb.append(entry.getKey()).append("=%s, "); + } + sb.setLength(sb.length() - 2); + sb.append("]"); + format.arg(sb.toString()); + format.arg(JExpr._this().invoke("getClass").invoke("getName")); + format.arg(JExpr._this().invoke("hashCode")); + for (Map.Entry<String, JFieldVar> entry : clazz.fields().entrySet()) { + format.arg(JExpr._this().ref(entry.getValue())); + } + toString.body()._return(format); + } + + + /** + * Writes the generated classes to disk. Invokes {@link #write(String)} with ".". + * + * @throws IOException if the write fails + */ + public void write() + throws IOException + { + write("."); + } + + + /** + * Writes the generated classes to disk at the supplied path. + * + * @param path to write the classes to + * + * @throws IOException if the write fails + */ + public void write(final String path) + throws IOException + { + final File f = new File(path); + if (!f.exists()) { + f.mkdirs(); + } + codeModel.build(f); + } + + + /** + * Provides command line access to a {@link BeanGenerator}. Expects two arguments: + * + * <ol> + * <li>path to a configuration property file</li> + * <li>target directory to write files to</li> + * </ol> + * + * <p>A sample configuration property file looks like:</p> + * + * <pre> + org.ldaptive.packageName=my.package.ldap.beans + org.ldaptive.objectClasses=eduPerson + org.ldaptive.nameMappings=c=countryName,l=localityName + org.ldaptive.excludedNames=userPassword + org.ldaptive.ldapUrl=ldap://directory.ldaptive.org + * </pre> + * + * @param args command line arguments + * + * @throws Exception if any error occurs + */ + public static void main(final String[] args) + throws Exception + { + final String propsPath = args[0]; + final String targetPath = args[1]; + + final BeanGenerator generator = new BeanGenerator(); + final BeanGeneratorPropertySource source = new BeanGeneratorPropertySource(generator, propsPath); + source.initialize(); + generator.generate(); + generator.write(targetPath); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/generate/props/BeanGeneratorPropertyInvoker.java b/beans/src/main/java/org/ldaptive/beans/generate/props/BeanGeneratorPropertyInvoker.java new file mode 100644 index 0000000..6f85a21 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/generate/props/BeanGeneratorPropertyInvoker.java
@@ -0,0 +1,56 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.generate.props; + +import java.util.HashMap; +import java.util.Map; +import org.ldaptive.props.AbstractPropertyInvoker; + +/** + * Handles properties for {@link org.ldaptive.beans.generate.BeanGenerator}. + * + * @author Middleware Services + */ +public class BeanGeneratorPropertyInvoker extends AbstractPropertyInvoker +{ + + + /** + * Creates a new bean generator property invoker for the supplied class. + * + * @param c class that has setter methods + */ + public BeanGeneratorPropertyInvoker(final Class<?> c) + { + initialize(c); + } + + + @Override + @SuppressWarnings("unchecked") + protected Object convertValue(final Class<?> type, final String value) + { + Object newValue = value; + if (type != String.class) { + if (Map.class.isAssignableFrom(type)) { + newValue = new HashMap<String, Object>(); + + final String[] keyValues = value.split(","); + for (String keyValue : keyValues) { + final String[] s = keyValue.split("="); + if (s[1].endsWith(".class")) { + ((Map) newValue).put( + s[0], + createTypeFromPropertyValue(Class.class, s[1].substring(0, s[1].indexOf(".class")))); + } else if (s[1].startsWith("[")) { + ((Map) newValue).put(s[0], createTypeFromPropertyValue(Class.class, s[1])); + } else { + ((Map) newValue).put(s[0], s[1]); + } + } + } else { + newValue = convertSimpleType(type, value); + } + } + return newValue; + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/generate/props/BeanGeneratorPropertySource.java b/beans/src/main/java/org/ldaptive/beans/generate/props/BeanGeneratorPropertySource.java new file mode 100644 index 0000000..01d55c2 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/generate/props/BeanGeneratorPropertySource.java
@@ -0,0 +1,119 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.generate.props; + +import java.io.Reader; +import java.util.Properties; +import java.util.Set; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.LdapException; +import org.ldaptive.beans.generate.BeanGenerator; +import org.ldaptive.props.AbstractPropertySource; +import org.ldaptive.props.DefaultConnectionFactoryPropertySource; +import org.ldaptive.schema.Schema; +import org.ldaptive.schema.SchemaFactory; + +/** + * Reads properties specific to {@link BeanGenerator} and returns an initialized object of that type. + * + * @author Middleware Services + */ +public final class BeanGeneratorPropertySource extends AbstractPropertySource<BeanGenerator> +{ + + /** Invoker for bean generator. */ + private static final BeanGeneratorPropertyInvoker INVOKER = new BeanGeneratorPropertyInvoker(BeanGenerator.class); + + + /** + * Creates a new bean generator property source using the default properties file. + * + * @param bg bean generator to invoke properties on + */ + public BeanGeneratorPropertySource(final BeanGenerator bg) + { + this(bg, PROPERTIES_FILE); + } + + + /** + * Creates a new bean generator property source. + * + * @param pc bean generator to invoke properties on + * @param paths to read properties from + */ + public BeanGeneratorPropertySource(final BeanGenerator pc, final String... paths) + { + this(pc, loadProperties(paths)); + } + + + /** + * Creates a new bean generator property source. + * + * @param pc bean generator to invoke properties on + * @param readers to read properties from + */ + public BeanGeneratorPropertySource(final BeanGenerator pc, final Reader... readers) + { + this(pc, loadProperties(readers)); + } + + + /** + * Creates a new bean generator property source. + * + * @param pc bean generator to invoke properties on + * @param props to read properties from + */ + public BeanGeneratorPropertySource(final BeanGenerator pc, final Properties props) + { + this(pc, PropertyDomain.LDAP, props); + } + + + /** + * Creates a new bean generator property source. + * + * @param pc bean generator to invoke properties on + * @param domain that properties are in + * @param props to read properties from + */ + public BeanGeneratorPropertySource(final BeanGenerator pc, final PropertyDomain domain, final Properties props) + { + super(pc, domain, props); + } + + + @Override + public void initialize() + { + initializeObject(INVOKER); + + Schema schema = object.getSchema(); + if (schema == null) { + final DefaultConnectionFactory cf = new DefaultConnectionFactory(); + final DefaultConnectionFactoryPropertySource cfPropSource = new DefaultConnectionFactoryPropertySource( + cf, + propertiesDomain, + properties); + cfPropSource.initialize(); + try { + schema = SchemaFactory.createSchema(cf); + } catch (LdapException e) { + throw new IllegalArgumentException("Error reading schema from LDAP", e); + } + object.setSchema(schema); + } + } + + + /** + * Returns the property names for this property source. + * + * @return all property names + */ + public static Set<String> getProperties() + { + return INVOKER.getProperties(); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/persistence/DefaultLdapEntryManager.java b/beans/src/main/java/org/ldaptive/beans/persistence/DefaultLdapEntryManager.java new file mode 100644 index 0000000..326fab7 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/persistence/DefaultLdapEntryManager.java
@@ -0,0 +1,187 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.persistence; + +import org.ldaptive.AddOperation; +import org.ldaptive.AddRequest; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.DeleteOperation; +import org.ldaptive.DeleteRequest; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.LdapUtils; +import org.ldaptive.Response; +import org.ldaptive.ReturnAttributes; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.beans.LdapEntryMapper; +import org.ldaptive.ext.MergeOperation; +import org.ldaptive.ext.MergeRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Default implementation of an ldap entry manager. Uses an {@link LdapEntryMapper} to convert objects to entries, then + * invokes LDAP operations with those objects. By default all attributes are requested using both the '*' and '+' + * syntaxes. For attributes that must be requested by name, use {@link #DefaultLdapEntryManager(LdapEntryMapper, + * ConnectionFactory, String[])}. + * + * @param <T> type of object to manage + * + * @author Middleware Services + */ +public class DefaultLdapEntryManager<T> implements LdapEntryManager<T> +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Mapper for converting ldap entry to object type. */ + private final LdapEntryMapper<T> ldapEntryMapper; + + /** Connection factory for LDAP communication. */ + private final ConnectionFactory connectionFactory; + + /** Additional attributes to include in searches. */ + private final String[] returnAttributes; + + + /** + * Creates a new default ldap entry manager. + * + * @param mapper for object conversion + * @param factory for LDAP communication + */ + public DefaultLdapEntryManager(final LdapEntryMapper<T> mapper, final ConnectionFactory factory) + { + this(mapper, factory, null); + } + + + /** + * Creates a new default ldap entry manager. Use of attrs is for cases where a directory does not support either the + * '*' or '+' syntaxes for returning all attributes of a given type. + * + * @param mapper for object conversion + * @param factory for LDAP communication + * @param attrs additional return attributes + */ + public DefaultLdapEntryManager(final LdapEntryMapper<T> mapper, final ConnectionFactory factory, final String[] attrs) + { + ldapEntryMapper = mapper; + connectionFactory = factory; + returnAttributes = attrs; + } + + + /** + * Returns the ldap entry mapper. + * + * @return ldap entry mapper + */ + public LdapEntryMapper<T> getLdapEntryMapper() + { + return ldapEntryMapper; + } + + + /** + * Returns the connection factory. + * + * @return connection factory + */ + public ConnectionFactory getConnectionFactory() + { + return connectionFactory; + } + + + /** + * Returns the return attributes. + * + * @return additional attributes to include in searches. + */ + public String[] getReturnAttributes() + { + return returnAttributes; + } + + + @Override + public T find(final T object) + throws LdapException + { + final String dn = getLdapEntryMapper().mapDn(object); + String[] attrs = ReturnAttributes.ALL.value(); + if (returnAttributes != null) { + attrs = LdapUtils.concatArrays(attrs, returnAttributes); + } + final SearchRequest request = SearchRequest.newObjectScopeSearchRequest(dn, attrs); + try (Connection conn = getConnectionFactory().getConnection()) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final Response<SearchResult> response = search.execute(request); + if (response.getResult().size() == 0) { + throw new IllegalArgumentException( + String.format("Unable to find ldap entry %s, no entries returned: %s", dn, response)); + } + if (response.getResult().size() > 1) { + throw new IllegalArgumentException( + String.format("Unable to find ldap entry %s, multiple entries returned: %s", dn, response)); + } + getLdapEntryMapper().map(response.getResult().getEntry(), object); + } + return object; + } + + + @Override + public Response<Void> add(final T object) + throws LdapException + { + final LdapEntry entry = new LdapEntry(); + getLdapEntryMapper().map(object, entry); + + final AddRequest request = new AddRequest(entry.getDn(), entry.getAttributes()); + try (Connection conn = getConnectionFactory().getConnection()) { + conn.open(); + + final AddOperation add = new AddOperation(conn); + return add.execute(request); + } + } + + + @Override + public Response<Void> merge(final T object) + throws LdapException + { + final LdapEntry entry = new LdapEntry(); + getLdapEntryMapper().map(object, entry); + + final MergeRequest request = new MergeRequest(entry); + try (Connection conn = getConnectionFactory().getConnection()) { + conn.open(); + + final MergeOperation merge = new MergeOperation(conn); + return merge.execute(request); + } + } + + + @Override + public Response<Void> delete(final T object) + throws LdapException + { + final String dn = getLdapEntryMapper().mapDn(object); + final DeleteRequest request = new DeleteRequest(dn); + try (Connection conn = getConnectionFactory().getConnection()) { + conn.open(); + + final DeleteOperation delete = new DeleteOperation(conn); + return delete.execute(request); + } + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/persistence/LdapEntryManager.java b/beans/src/main/java/org/ldaptive/beans/persistence/LdapEntryManager.java new file mode 100644 index 0000000..1c01c01 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/persistence/LdapEntryManager.java
@@ -0,0 +1,69 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.persistence; + +import org.ldaptive.LdapException; +import org.ldaptive.Response; + +/** + * Interface to manage objects that have been annotated to contain LDAP data. + * + * @param <T> type of object to manage + * + * @author Middleware Services + */ +public interface LdapEntryManager<T> +{ + + + /** + * Searches for the supplied annotated object in an LDAP and returns the object mapped with it's ldap attribute + * properties set. + * + * @param object to find + * + * @return mapped object + * + * @throws LdapException if the object cannot be found + */ + T find(T object) + throws LdapException; + + + /** + * Adds the supplied annotated object to an LDAP. + * + * @param object to add + * + * @return LDAP response from the add operation + * + * @throws LdapException if the add fails + */ + Response<Void> add(T object) + throws LdapException; + + + /** + * Merges the supplied annotated object in an LDAP. See {@link org.ldaptive.ext.MergeOperation}. + * + * @param object to merge + * + * @return LDAP response from the merge operation + * + * @throws LdapException if the merge fails + */ + Response<Void> merge(T object) + throws LdapException; + + + /** + * Deletes the supplied annotated object from an LDAP. + * + * @param object to delete + * + * @return LDAP response from the delete operation + * + * @throws LdapException if the delete fails + */ + Response<Void> delete(T object) + throws LdapException; +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/AbstractAttributeValueMutator.java b/beans/src/main/java/org/ldaptive/beans/reflect/AbstractAttributeValueMutator.java new file mode 100644 index 0000000..80cf635 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/AbstractAttributeValueMutator.java
@@ -0,0 +1,84 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import org.ldaptive.SortBehavior; +import org.ldaptive.beans.AttributeValueMutator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base implementation of a {@link AttributeValueMutator}. Uses a {@link ReflectionTranscoder} for mutating values. + * + * @author Middleware Services + */ +public abstract class AbstractAttributeValueMutator implements AttributeValueMutator +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Name of the attribute. */ + private final String attributeName; + + /** Whether this attribute is binary. */ + private final boolean attributeBinary; + + /** Sort behavior of this attribute. */ + private final SortBehavior attributeSortBehavior; + + /** Transcoder for modifying this attribute. */ + private final ReflectionTranscoder valueTranscoder; + + + /** + * Creates a new abstract attribute value mutator. + * + * @param name of the attribute + * @param binary whether this attribute is binary + * @param sortBehavior how to sort this attribute + * @param transcoder for mutating the attribute + */ + public AbstractAttributeValueMutator( + final String name, + final boolean binary, + final SortBehavior sortBehavior, + final ReflectionTranscoder transcoder) + { + attributeName = name; + attributeBinary = binary; + attributeSortBehavior = sortBehavior; + valueTranscoder = transcoder; + } + + + @Override + public String getName() + { + return attributeName; + } + + + @Override + public boolean isBinary() + { + return attributeBinary; + } + + + @Override + public SortBehavior getSortBehavior() + { + return attributeSortBehavior; + } + + + /** + * Returns the reflection transcoder. + * + * @return reflection transcoder + */ + protected ReflectionTranscoder getReflectionTranscoder() + { + return valueTranscoder; + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/AbstractCollectionReflectionTranscoder.java b/beans/src/main/java/org/ldaptive/beans/reflect/AbstractCollectionReflectionTranscoder.java new file mode 100644 index 0000000..b24ae70 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/AbstractCollectionReflectionTranscoder.java
@@ -0,0 +1,159 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Reflection transcoder for an object that implements a {@link Collection}. + * + * @author Middleware Services + */ +public abstract class AbstractCollectionReflectionTranscoder implements ReflectionTranscoder +{ + + /** Type that is a collection. */ + private final Class<?> type; + + /** Used for collections that do not contain arrays. */ + private final SingleValueReflectionTranscoder<?> singleValueTranscoder; + + /** Used for collections that contain arrays. */ + private final ArrayReflectionTranscoder arrayTranscoder; + + + /** + * Creates a new abstract collection reflection transcoder. + * + * @param c class that is a collection + * @param transcoder to operate on elements of the collection + */ + public AbstractCollectionReflectionTranscoder(final Class<?> c, final SingleValueReflectionTranscoder<?> transcoder) + { + type = c; + singleValueTranscoder = transcoder; + arrayTranscoder = null; + } + + + /** + * Creates a new abstract collection reflection transcoder. + * + * @param c class that is a collection + * @param transcoder to operate on elements of the collection + */ + public AbstractCollectionReflectionTranscoder(final Class<?> c, final ArrayReflectionTranscoder transcoder) + { + type = c; + singleValueTranscoder = null; + arrayTranscoder = transcoder; + } + + + @Override + public Object decodeStringValues(final Collection<String> values) + { + final Collection<Object> decoded = createCollection(Object.class); + if (arrayTranscoder != null) { + decoded.add(arrayTranscoder.decodeStringValues(values)); + } else { + for (String value : values) { + final List<String> l = new ArrayList<>(1); + l.add(value); + decoded.add(singleValueTranscoder.decodeStringValues(l)); + } + } + return decoded; + } + + + @Override + public Object decodeBinaryValues(final Collection<byte[]> values) + { + final Collection<Object> decoded = createCollection(Object.class); + if (arrayTranscoder != null) { + decoded.add(arrayTranscoder.decodeBinaryValues(values)); + } else { + for (byte[] value : values) { + final List<byte[]> l = new ArrayList<>(1); + l.add(value); + decoded.add(singleValueTranscoder.decodeBinaryValues(l)); + } + } + return decoded; + } + + + @Override + public Collection<String> encodeStringValues(final Object values) + { + final Collection<String> encoded = createCollection(String.class); + if (values != null) { + for (Object o : (Collection<?>) values) { + if (arrayTranscoder != null) { + encoded.addAll(arrayTranscoder.encodeStringValues(o)); + } else { + encoded.addAll(singleValueTranscoder.encodeStringValues(o)); + } + } + } + return encoded; + } + + + @Override + public Collection<byte[]> encodeBinaryValues(final Object values) + { + final Collection<byte[]> encoded = createCollection(byte[].class); + if (values != null) { + for (Object o : (Collection<?>) values) { + if (arrayTranscoder != null) { + encoded.addAll(arrayTranscoder.encodeBinaryValues(o)); + } else { + encoded.addAll(singleValueTranscoder.encodeBinaryValues(o)); + } + } + } + return encoded; + } + + + /** + * Returns a collection implementation of the correct type for this transcoder. + * + * @param <T> type of collection + * @param clazz type of collection + * + * @return collection implementation + */ + protected abstract <T> Collection<T> createCollection(Class<T> clazz); + + + @Override + public Class<?> getType() + { + return type; + } + + + @Override + public boolean supports(final Class<?> t) + { + return getType().isAssignableFrom(t); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::type=%s, singleValueTranscoder=%s, arrayTranscoder=%s]", + getClass().getName(), + hashCode(), + type, + singleValueTranscoder, + arrayTranscoder); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/ArrayReflectionTranscoder.java b/beans/src/main/java/org/ldaptive/beans/reflect/ArrayReflectionTranscoder.java new file mode 100644 index 0000000..087fa9e --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/ArrayReflectionTranscoder.java
@@ -0,0 +1,166 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * Reflection transcoder which expects to operate on collections containing an array of values. + * + * @author Middleware Services + */ +public class ArrayReflectionTranscoder implements ReflectionTranscoder +{ + + /** Underlying value transcoder. */ + private final SingleValueReflectionTranscoder<?> valueTranscoder; + + /** Type of array element for this transcoder. */ + private final Class<?> type; + + + /** + * Creates a new array reflection transcoder. + * + * @param transcoder to operate on individual array elements + */ + public ArrayReflectionTranscoder(final SingleValueReflectionTranscoder<?> transcoder) + { + valueTranscoder = transcoder; + type = Array.newInstance(valueTranscoder.getType(), 0).getClass(); + } + + + @Override + public Object decodeStringValues(final Collection<String> values) + { + final Object decoded = Array.newInstance(valueTranscoder.getType(), values.size()); + final Iterator<String> iter = values.iterator(); + for (int i = 0; i < values.size(); i++) { + final List<String> l = new ArrayList<>(1); + l.add(iter.next()); + Array.set(decoded, i, valueTranscoder.decodeStringValues(l)); + } + return decoded; + } + + + @Override + public Object decodeBinaryValues(final Collection<byte[]> values) + { + final Object decoded = Array.newInstance(valueTranscoder.getType(), values.size()); + final Iterator<byte[]> iter = values.iterator(); + for (int i = 0; i < values.size(); i++) { + final List<byte[]> l = new ArrayList<>(1); + l.add(iter.next()); + Array.set(decoded, i, valueTranscoder.decodeBinaryValues(l)); + } + return decoded; + } + + + @Override + public Collection<String> encodeStringValues(final Object values) + { + final List<String> encoded = new ArrayList<>(); + if (values instanceof Object[]) { + for (Object o : (Object[]) values) { + encoded.addAll(valueTranscoder.encodeStringValues(o)); + } + } else { + if (values instanceof boolean[]) { + for (boolean o : (boolean[]) values) { + encoded.addAll(valueTranscoder.encodeStringValues(o)); + } + } else if (values instanceof double[]) { + for (double o : (double[]) values) { + encoded.addAll(valueTranscoder.encodeStringValues(o)); + } + } else if (values instanceof float[]) { + for (float o : (float[]) values) { + encoded.addAll(valueTranscoder.encodeStringValues(o)); + } + } else if (values instanceof int[]) { + for (int o : (int[]) values) { + encoded.addAll(valueTranscoder.encodeStringValues(o)); + } + } else if (values instanceof long[]) { + for (long o : (long[]) values) { + encoded.addAll(valueTranscoder.encodeStringValues(o)); + } + } else if (values instanceof short[]) { + for (short o : (short[]) values) { + encoded.addAll(valueTranscoder.encodeStringValues(o)); + } + } else { + throw new IllegalArgumentException("Unsupported array type: " + values); + } + } + return encoded; + } + + + @Override + public Collection<byte[]> encodeBinaryValues(final Object values) + { + final List<byte[]> encoded = new ArrayList<>(); + if (values instanceof Object[]) { + for (Object o : (Object[]) values) { + encoded.addAll(valueTranscoder.encodeBinaryValues(o)); + } + } else { + if (values instanceof boolean[]) { + for (boolean o : (boolean[]) values) { + encoded.addAll(valueTranscoder.encodeBinaryValues(o)); + } + } else if (values instanceof double[]) { + for (double o : (double[]) values) { + encoded.addAll(valueTranscoder.encodeBinaryValues(o)); + } + } else if (values instanceof float[]) { + for (float o : (float[]) values) { + encoded.addAll(valueTranscoder.encodeBinaryValues(o)); + } + } else if (values instanceof int[]) { + for (int o : (int[]) values) { + encoded.addAll(valueTranscoder.encodeBinaryValues(o)); + } + } else if (values instanceof long[]) { + for (long o : (long[]) values) { + encoded.addAll(valueTranscoder.encodeBinaryValues(o)); + } + } else if (values instanceof short[]) { + for (short o : (short[]) values) { + encoded.addAll(valueTranscoder.encodeBinaryValues(o)); + } + } else { + throw new IllegalArgumentException("Unsupported array type: " + values); + } + } + return encoded; + } + + + @Override + public Class<?> getType() + { + return type; + } + + + @Override + public boolean supports(final Class<?> t) + { + return getType().equals(t); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::valueTranscoder=%s]", getClass().getName(), hashCode(), valueTranscoder); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/DefaultClassDescriptor.java b/beans/src/main/java/org/ldaptive/beans/reflect/DefaultClassDescriptor.java new file mode 100644 index 0000000..eb0af23 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/DefaultClassDescriptor.java
@@ -0,0 +1,56 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import org.ldaptive.beans.AbstractClassDescriptor; +import org.ldaptive.beans.Attribute; +import org.ldaptive.beans.Entry; + +/** + * Default implementation of a class descriptor. Reads the {@link Entry} annotation and sets the appropriate DN and + * attribute value mutators. + * + * @author Middleware Services + */ +public class DefaultClassDescriptor extends AbstractClassDescriptor +{ + + + @Override + public void initialize(final Class<?> type) + { + // check for entry annotation + final Entry entryAnnotation = type.getAnnotation(Entry.class); + if (entryAnnotation != null) { + + // add any method descriptors that match attributes + final MethodClassDescriptor methodDescriptor = new MethodClassDescriptor(); + methodDescriptor.initialize(type); + if (methodDescriptor.getDnValueMutator() != null) { + setDnValueMutator(methodDescriptor.getDnValueMutator()); + } + addAttributeValueMutator(methodDescriptor.getAttributeValueMutators()); + + // add any field descriptors that aren't available as method mutators + final FieldClassDescriptor fieldDescriptor = new FieldClassDescriptor(); + fieldDescriptor.initialize(type); + if (getDnValueMutator() == null && fieldDescriptor.getDnValueMutator() != null) { + setDnValueMutator(fieldDescriptor.getDnValueMutator()); + } + fieldDescriptor.getAttributeValueMutators().stream().filter( + mutator -> getAttributeValueMutator(mutator.getName()) == null).forEach(this::addAttributeValueMutator); + + // add any hard coded attributes that have a values declaration + for (final Attribute attr : entryAnnotation.attributes()) { + if ("".equals(attr.property()) && attr.values().length > 0) { + addAttributeValueMutator( + new SimpleAttributeValueMutator(attr.name(), attr.values(), attr.binary(), attr.sortBehavior())); + } + } + + // if no DN mutator has been set, use the value in the annotation + if (getDnValueMutator() == null) { + setDnValueMutator(new SimpleDnValueMutator(entryAnnotation.dn())); + } + } + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/DefaultDnValueMutator.java b/beans/src/main/java/org/ldaptive/beans/reflect/DefaultDnValueMutator.java new file mode 100644 index 0000000..52f5851 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/DefaultDnValueMutator.java
@@ -0,0 +1,60 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.util.Collection; +import java.util.Collections; +import org.ldaptive.beans.AttributeValueMutator; +import org.ldaptive.beans.DnValueMutator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Uses a {@link AttributeValueMutator} to mutate the configured DN of an object. + * + * @author Middleware Services + */ +public class DefaultDnValueMutator implements DnValueMutator +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Mutator for the DN. */ + private final AttributeValueMutator dnMutator; + + + /** + * Creates a new default dn value mutator. + * + * @param mutator for the DN + */ + public DefaultDnValueMutator(final AttributeValueMutator mutator) + { + dnMutator = mutator; + } + + + @Override + public String getValue(final Object object) + { + final Collection<String> c = dnMutator.getStringValues(object); + if (c != null && !c.isEmpty()) { + return c.iterator().next(); + } + return null; + } + + + @Override + public void setValue(final Object object, final String value) + { + dnMutator.setStringValues(object, Collections.singletonList(value)); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::dnMutator=%s]", getClass().getName(), hashCode(), dnMutator); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/DefaultLdapEntryMapper.java b/beans/src/main/java/org/ldaptive/beans/reflect/DefaultLdapEntryMapper.java new file mode 100644 index 0000000..b4dbf06 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/DefaultLdapEntryMapper.java
@@ -0,0 +1,53 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.util.HashMap; +import java.util.Map; +import org.ldaptive.beans.AbstractLdapEntryMapper; +import org.ldaptive.beans.ClassDescriptor; + +/** + * Stores the class descriptors for a specific object in a static map. + * + * @param <T> type of object to map + * + * @author Middleware Services + */ +public class DefaultLdapEntryMapper<T> extends AbstractLdapEntryMapper<T> +{ + + /** Class descriptors for mapping objects. */ + private static final Map<Class<?>, ClassDescriptor> CLASS_DESCRIPTORS = new HashMap<>(); + + + @Override + protected ClassDescriptor getClassDescriptor(final Object object) + { + ClassDescriptor descriptor; + final Class<?> type = object.getClass(); + synchronized (CLASS_DESCRIPTORS) { + if (!CLASS_DESCRIPTORS.containsKey(type)) { + descriptor = createClassDescriptor(type); + CLASS_DESCRIPTORS.put(type, descriptor); + } else { + descriptor = CLASS_DESCRIPTORS.get(type); + } + } + return descriptor; + } + + + /** + * Creates a class descriptor for the supplied type. + * + * @param type to create class descriptor for + * + * @return class descriptor + */ + protected ClassDescriptor createClassDescriptor(final Class<?> type) + { + final DefaultClassDescriptor descriptor = new DefaultClassDescriptor(); + descriptor.initialize(type); + return descriptor; + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/DefaultReflectionTranscoder.java b/beans/src/main/java/org/ldaptive/beans/reflect/DefaultReflectionTranscoder.java new file mode 100644 index 0000000..15c7bcf --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/DefaultReflectionTranscoder.java
@@ -0,0 +1,277 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.ldaptive.io.BooleanValueTranscoder; +import org.ldaptive.io.ByteArrayValueTranscoder; +import org.ldaptive.io.CertificateValueTranscoder; +import org.ldaptive.io.CharArrayValueTranscoder; +import org.ldaptive.io.DoubleValueTranscoder; +import org.ldaptive.io.FloatValueTranscoder; +import org.ldaptive.io.GeneralizedTimeValueTranscoder; +import org.ldaptive.io.IntegerValueTranscoder; +import org.ldaptive.io.LongValueTranscoder; +import org.ldaptive.io.ObjectValueTranscoder; +import org.ldaptive.io.ShortValueTranscoder; +import org.ldaptive.io.StringValueTranscoder; +import org.ldaptive.io.UUIDValueTranscoder; +import org.ldaptive.io.ValueTranscoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Default implementation of a reflection transcoder. Determines the correct underlying reflection transcoder by + * inspecting the class type characteristics. + * + * @author Middleware Services + */ +public class DefaultReflectionTranscoder implements ReflectionTranscoder +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Custom transcoder to override the default transcoder. */ + private final SingleValueReflectionTranscoder<?> customTranscoder; + + /** Transcoder for this type. */ + private final ReflectionTranscoder valueTranscoder; + + /** Set of transcoders support single values. */ + private final Set<SingleValueReflectionTranscoder<?>> singleValueTranscoders; + + + /** + * Creates a new default reflection transcoder. + * + * @param type of object to transcode + */ + public DefaultReflectionTranscoder(final Type type) + { + this(type, null); + } + + + /** + * Creates a new default reflection transcoder. + * + * @param type of object to transcode + * @param transcoder custom transcoder for this type + */ + public DefaultReflectionTranscoder(final Type type, final ValueTranscoder<?> transcoder) + { + if (transcoder != null) { + customTranscoder = SingleValueReflectionTranscoder.newInstance(transcoder); + } else { + customTranscoder = null; + } + singleValueTranscoders = getDefaultSingleValueTranscoders(); + if (type instanceof Class) { + final Class<?> c = (Class<?>) type; + if (c.isArray()) { + if (byte[].class == c || char[].class == c) { + valueTranscoder = getSingleValueReflectionTranscoder(c); + } else { + valueTranscoder = new ArrayReflectionTranscoder(getSingleValueReflectionTranscoder(c.getComponentType())); + } + } else if (Collection.class.isAssignableFrom(c)) { + valueTranscoder = getCollectionEncoder(c, Object.class); + } else { + valueTranscoder = getSingleValueReflectionTranscoder(c); + } + } else if (type instanceof ParameterizedType) { + final ParameterizedType pt = (ParameterizedType) type; + final Type rawType = pt.getRawType(); + final Type[] typeArgs = pt.getActualTypeArguments(); + if (typeArgs.length != 1) { + throw new IllegalArgumentException("Unsupported type arguments: " + Arrays.toString(typeArgs)); + } + + final Class<?> rawClass = ReflectionUtils.classFromType(rawType); + if (typeArgs[0] instanceof GenericArrayType) { + final GenericArrayType gat = (GenericArrayType) typeArgs[0]; + if (Collection.class.isAssignableFrom(rawClass)) { + valueTranscoder = getCollectionEncoder(rawClass, gat); + } else { + throw new IllegalArgumentException("Unsupported type: " + rawClass); + } + } else if (typeArgs[0] instanceof Class) { + if (Collection.class.isAssignableFrom(rawClass)) { + valueTranscoder = getCollectionEncoder(rawClass, typeArgs[0]); + } else { + throw new IllegalArgumentException("Unsupported type: " + rawClass); + } + } else { + throw new IllegalArgumentException("Unsupported type: " + rawClass); + } + } else { + throw new IllegalArgumentException("Unsupported type: " + type); + } + } + + + /** + * Initializes the set of default single value transcoders. + * + * @return single value transcoders + */ + protected Set<SingleValueReflectionTranscoder<?>> getDefaultSingleValueTranscoders() + { + final Set<SingleValueReflectionTranscoder<?>> transcoders = new HashSet<>(); + transcoders.add(new SingleValueReflectionTranscoder<>(new ObjectValueTranscoder())); + transcoders.add(new SingleValueReflectionTranscoder<>(new BooleanValueTranscoder())); + transcoders.add(new SingleValueReflectionTranscoder<>(new BooleanValueTranscoder(true))); + transcoders.add(new SingleValueReflectionTranscoder<>(new DoubleValueTranscoder())); + transcoders.add(new SingleValueReflectionTranscoder<>(new DoubleValueTranscoder(true))); + transcoders.add(new SingleValueReflectionTranscoder<>(new FloatValueTranscoder())); + transcoders.add(new SingleValueReflectionTranscoder<>(new FloatValueTranscoder(true))); + transcoders.add(new SingleValueReflectionTranscoder<>(new IntegerValueTranscoder())); + transcoders.add(new SingleValueReflectionTranscoder<>(new IntegerValueTranscoder(true))); + transcoders.add(new SingleValueReflectionTranscoder<>(new LongValueTranscoder())); + transcoders.add(new SingleValueReflectionTranscoder<>(new LongValueTranscoder(true))); + transcoders.add(new SingleValueReflectionTranscoder<>(new ShortValueTranscoder())); + transcoders.add(new SingleValueReflectionTranscoder<>(new ShortValueTranscoder(true))); + transcoders.add(new SingleValueReflectionTranscoder<>(new StringValueTranscoder())); + transcoders.add(new SingleValueReflectionTranscoder<>(new ByteArrayValueTranscoder())); + transcoders.add(new SingleValueReflectionTranscoder<>(new CharArrayValueTranscoder())); + transcoders.add(new SingleValueReflectionTranscoder<>(new CertificateValueTranscoder())); + transcoders.add(new SingleValueReflectionTranscoder<>(new GeneralizedTimeValueTranscoder())); + transcoders.add(new SingleValueReflectionTranscoder<>(new UUIDValueTranscoder())); + return transcoders; + } + + + /** + * Returns the appropriate single value encoder for the supplied type. + * + * @param type to provide a single value encoder for + * + * @return single value reflection transcoder + */ + protected SingleValueReflectionTranscoder getSingleValueReflectionTranscoder(final Class<?> type) + { + if (customTranscoder != null) { + return customTranscoder; + } + for (SingleValueReflectionTranscoder transcoder : singleValueTranscoders) { + @SuppressWarnings("unchecked") + final boolean supports = transcoder.supports(type); + if (supports) { + return transcoder; + } + } + throw new IllegalArgumentException("Unsupported type: " + type); + } + + + /** + * Returns the appropriate collection encoder for the supplied type. + * + * @param type to provide a collection encoder for + * @param genericType of the collection + * + * @return reflection transcoder for a collection + */ + protected ReflectionTranscoder getCollectionEncoder(final Class<?> type, final Type genericType) + { + Class<?> genericClass; + boolean isGenericArray = false; + if (genericType instanceof GenericArrayType) { + final Class<?> c = ReflectionUtils.classFromType(((GenericArrayType) genericType).getGenericComponentType()); + if (Byte.TYPE == c) { + genericClass = byte[].class; + } else if (Character.TYPE == c) { + genericClass = char[].class; + } else { + genericClass = c; + isGenericArray = true; + } + } else { + genericClass = ReflectionUtils.classFromType(genericType); + } + + ReflectionTranscoder encoder; + if (type == Collection.class || List.class.isAssignableFrom(type)) { + if (isGenericArray) { + encoder = new ListReflectionTranscoder( + type, + new ArrayReflectionTranscoder(getSingleValueReflectionTranscoder(genericClass))); + } else { + encoder = new ListReflectionTranscoder(type, getSingleValueReflectionTranscoder(genericClass)); + } + } else if (Set.class.isAssignableFrom(type)) { + if (isGenericArray) { + encoder = new SetReflectionTranscoder( + type, + new ArrayReflectionTranscoder(getSingleValueReflectionTranscoder(genericClass))); + } else { + encoder = new SetReflectionTranscoder(type, getSingleValueReflectionTranscoder(genericClass)); + } + } else { + throw new IllegalArgumentException("Unsupported type: " + type + " with generic type: " + genericType); + } + return encoder; + } + + + @Override + public Object decodeStringValues(final Collection<String> values) + { + return valueTranscoder.decodeStringValues(values); + } + + + @Override + public Object decodeBinaryValues(final Collection<byte[]> values) + { + return valueTranscoder.decodeBinaryValues(values); + } + + + @Override + public Collection<String> encodeStringValues(final Object values) + { + return valueTranscoder.encodeStringValues(values); + } + + + @Override + public Collection<byte[]> encodeBinaryValues(final Object values) + { + return valueTranscoder.encodeBinaryValues(values); + } + + + @Override + public Class<?> getType() + { + return valueTranscoder.getType(); + } + + + @Override + public boolean supports(final Class<?> type) + { + return valueTranscoder.supports(type); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::customTranscoder=%s, valueTranscoder=%s]", + getClass().getName(), + hashCode(), + customTranscoder, + valueTranscoder); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/FieldAttributeValueMutator.java b/beans/src/main/java/org/ldaptive/beans/reflect/FieldAttributeValueMutator.java new file mode 100644 index 0000000..bb1e2d6 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/FieldAttributeValueMutator.java
@@ -0,0 +1,109 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Collection; +import org.ldaptive.SortBehavior; + +/** + * Attribute mutator associated with the {@link Field} of an object. + * + * @author Middleware Services + */ +public class FieldAttributeValueMutator extends AbstractAttributeValueMutator +{ + + /** Field to operate on. */ + private final Field f; + + /** Whether the field has a final modifier. */ + private final boolean isFinal; + + + /** + * Creates a new field attribute value mutator. + * + * @param transcoder for mutating the field + * @param field to mutate + */ + public FieldAttributeValueMutator(final ReflectionTranscoder transcoder, final Field field) + { + super(null, false, null, transcoder); + f = field; + f.setAccessible(true); + isFinal = Modifier.isFinal(f.getModifiers()); + } + + + /** + * Creates a new field attribute value mutator. + * + * @param name of the attribute + * @param binary whether the attribute is binary + * @param sortBehavior sort behavior of the attribute + * @param transcoder to mutate the field + * @param field to mutate + */ + public FieldAttributeValueMutator( + final String name, + final boolean binary, + final SortBehavior sortBehavior, + final ReflectionTranscoder transcoder, + final Field field) + { + super(name, binary, sortBehavior, transcoder); + f = field; + f.setAccessible(true); + isFinal = Modifier.isFinal(f.getModifiers()); + } + + + @Override + public Collection<String> getStringValues(final Object object) + { + return getReflectionTranscoder().encodeStringValues(ReflectionUtils.getField(f, object)); + } + + + @Override + public Collection<byte[]> getBinaryValues(final Object object) + { + return getReflectionTranscoder().encodeBinaryValues(ReflectionUtils.getField(f, object)); + } + + + @Override + public void setStringValues(final Object object, final Collection<String> values) + { + if (!isFinal) { + ReflectionUtils.setField(f, object, getReflectionTranscoder().decodeStringValues(values)); + } + } + + + @Override + public void setBinaryValues(final Object object, final Collection<byte[]> values) + { + if (!isFinal) { + ReflectionUtils.setField(f, object, getReflectionTranscoder().decodeBinaryValues(values)); + } + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::name=%s, binary=%s, sortBehavior=%s, " + + "reflectionTranscoder=%s, field=%s]", + getClass().getName(), + hashCode(), + getName(), + isBinary(), + getSortBehavior(), + getReflectionTranscoder(), + f); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/FieldClassDescriptor.java b/beans/src/main/java/org/ldaptive/beans/reflect/FieldClassDescriptor.java new file mode 100644 index 0000000..1b09697 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/FieldClassDescriptor.java
@@ -0,0 +1,100 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; +import org.ldaptive.beans.AbstractClassDescriptor; +import org.ldaptive.beans.Attribute; +import org.ldaptive.beans.AttributeValueMutator; +import org.ldaptive.beans.DnValueMutator; +import org.ldaptive.beans.Entry; +import org.ldaptive.io.ValueTranscoder; + +/** + * Creates DN and attribute mutators for the {@link Field}s on a type. + * + * @author Middleware Services + */ +public class FieldClassDescriptor extends AbstractClassDescriptor +{ + + + @Override + public void initialize(final Class<?> type) + { + final Map<String, Field> fields = getDeclaredFields(type); + final Entry entryAnnotation = type.getAnnotation(Entry.class); + if (fields.containsKey(entryAnnotation.dn())) { + setDnValueMutator(createDnValueMutator(fields.get(entryAnnotation.dn()))); + } + for (Attribute attr : entryAnnotation.attributes()) { + if (attr.values().length == 0) { + final String property = attr.property().length() > 0 ? attr.property() : attr.name(); + if (fields.containsKey(property)) { + addAttributeValueMutator(createAttributeValueMutator(fields.get(property), attr)); + } + } + } + } + + + /** + * Returns a map of all the field names to the field. + * + * @param type to read declared fields from + * + * @return map of field names to field + */ + protected Map<String, Field> getDeclaredFields(final Class<?> type) + { + final Map<String, Field> fields = new HashMap<>(); + Class<?> c = type; + while (c != null) { + for (Field field : c.getDeclaredFields()) { + if (!fields.containsKey(field.getName())) { + fields.put(field.getName(), field); + } + } + c = c.getSuperclass(); + } + return fields; + } + + + /** + * Returns a dn value mutator for the supplied field. + * + * @param field to create dn value mutator for + * + * @return dn value mutator + */ + protected DnValueMutator createDnValueMutator(final Field field) + { + return + new DefaultDnValueMutator( + new FieldAttributeValueMutator(new DefaultReflectionTranscoder(field.getGenericType()), field)); + } + + + /** + * Returns an attribute value mutator for the supplied field. + * + * @param field to create attribute value mutator for + * @param attribute attribute containing metadata + * + * @return attribute value mutator + */ + protected AttributeValueMutator createAttributeValueMutator(final Field field, final Attribute attribute) + { + final String name = "".equals(attribute.name()) ? field.getName() : attribute.name(); + final ValueTranscoder<?> transcoder = TranscoderFactory.getInstance(attribute.transcoder()); + return + new FieldAttributeValueMutator( + name, + attribute.binary(), + attribute.sortBehavior(), + new DefaultReflectionTranscoder(field.getGenericType(), transcoder), + field); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/ListReflectionTranscoder.java b/beans/src/main/java/org/ldaptive/beans/reflect/ListReflectionTranscoder.java new file mode 100644 index 0000000..f823ee6 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/ListReflectionTranscoder.java
@@ -0,0 +1,54 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +/** + * Reflection transcoder for an object that implements {@link List}. + * + * @author Middleware Services + */ +public class ListReflectionTranscoder extends AbstractCollectionReflectionTranscoder +{ + + + /** + * Creates a new list reflection transcoder. + * + * @param c class that is a list + * @param transcoder to operate on elements of the list + */ + public ListReflectionTranscoder(final Class<?> c, final SingleValueReflectionTranscoder<?> transcoder) + { + super(c, transcoder); + } + + + /** + * Creates a new list reflection transcoder. + * + * @param c class that is a list + * @param transcoder to operate on elements of the list + */ + public ListReflectionTranscoder(final Class<?> c, final ArrayReflectionTranscoder transcoder) + { + super(c, transcoder); + } + + + @Override + protected <T> Collection<T> createCollection(final Class<T> clazz) + { + final Class<?> type = getType(); + List<T> l; + if (LinkedList.class.isAssignableFrom(type)) { + l = new LinkedList<>(); + } else { + l = new ArrayList<>(); + } + return l; + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/MethodAttributeValueMutator.java b/beans/src/main/java/org/ldaptive/beans/reflect/MethodAttributeValueMutator.java new file mode 100644 index 0000000..19d40fc --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/MethodAttributeValueMutator.java
@@ -0,0 +1,128 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.lang.reflect.Method; +import java.util.Collection; +import org.ldaptive.SortBehavior; + +/** + * Attribute mutator associated with the {@link Method} of an object. + * + * @author Middleware Services + */ +public class MethodAttributeValueMutator extends AbstractAttributeValueMutator +{ + + /** Method to get data from. */ + private final Method getterMethod; + + /** Method to set data on. */ + private final Method setterMethod; + + + /** + * Creates a new method attribute value mutator. + * + * @param transcoder for mutating the methods + * @param getter method to read data + * @param setter method to write data + */ + public MethodAttributeValueMutator(final ReflectionTranscoder transcoder, final Method getter, final Method setter) + { + super(null, false, null, transcoder); + getterMethod = getter; + if (getterMethod != null) { + getterMethod.setAccessible(true); + } + setterMethod = setter; + if (setterMethod != null) { + setterMethod.setAccessible(true); + } + } + + + /** + * Creates a new method attribute value mutator. + * + * @param name of the attribute + * @param binary whether the attribute is binary + * @param sortBehavior sort behavior of the attribute + * @param transcoder to mutate the methods + * @param getter method to read data + * @param setter method to write data + */ + public MethodAttributeValueMutator( + final String name, + final boolean binary, + final SortBehavior sortBehavior, + final ReflectionTranscoder transcoder, + final Method getter, + final Method setter) + { + super(name, binary, sortBehavior, transcoder); + getterMethod = getter; + if (getterMethod != null) { + getterMethod.setAccessible(true); + } + setterMethod = setter; + if (setterMethod != null) { + setterMethod.setAccessible(true); + } + } + + + @Override + public Collection<String> getStringValues(final Object object) + { + if (getterMethod == null) { + return null; + } + return getReflectionTranscoder().encodeStringValues(ReflectionUtils.invokeGetterMethod(getterMethod, object)); + } + + + @Override + public Collection<byte[]> getBinaryValues(final Object object) + { + if (getterMethod == null) { + return null; + } + return getReflectionTranscoder().encodeBinaryValues(ReflectionUtils.invokeGetterMethod(getterMethod, object)); + } + + + @Override + public void setStringValues(final Object object, final Collection<String> values) + { + if (setterMethod != null) { + ReflectionUtils.invokeSetterMethod(setterMethod, object, getReflectionTranscoder().decodeStringValues(values)); + } + } + + + @Override + public void setBinaryValues(final Object object, final Collection<byte[]> values) + { + if (setterMethod != null) { + ReflectionUtils.invokeSetterMethod(setterMethod, object, getReflectionTranscoder().decodeBinaryValues(values)); + } + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::name=%s, binary=%s, sortBehavior=%s, " + + "reflectionTranscoder=%s, getterMethod=%s, setterMethod=%s]", + getClass().getName(), + hashCode(), + getName(), + isBinary(), + getSortBehavior(), + getReflectionTranscoder(), + getterMethod, + setterMethod); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/MethodClassDescriptor.java b/beans/src/main/java/org/ldaptive/beans/reflect/MethodClassDescriptor.java new file mode 100644 index 0000000..2163817 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/MethodClassDescriptor.java
@@ -0,0 +1,112 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.util.HashMap; +import java.util.Map; +import org.ldaptive.beans.AbstractClassDescriptor; +import org.ldaptive.beans.Attribute; +import org.ldaptive.beans.AttributeValueMutator; +import org.ldaptive.beans.DnValueMutator; +import org.ldaptive.beans.Entry; +import org.ldaptive.io.ValueTranscoder; + +/** + * Creates DN and attribute mutators for the {@link java.lang.reflect.Method}s on a type. Leverages the {@link + * Introspector} class for reading descriptors. + * + * @author Middleware Services + */ +public class MethodClassDescriptor extends AbstractClassDescriptor +{ + + + @Override + public void initialize(final Class<?> type) + { + final Map<String, PropertyDescriptor> descriptors = getPropertyDescriptors(type); + final Entry entryAnnotation = type.getAnnotation(Entry.class); + if (descriptors.containsKey(entryAnnotation.dn())) { + setDnValueMutator(createDnValueMutator(descriptors.get(entryAnnotation.dn()))); + } + for (Attribute attr : entryAnnotation.attributes()) { + if (attr.values().length == 0) { + final String property = attr.property().length() > 0 ? attr.property() : attr.name(); + if (descriptors.containsKey(property)) { + addAttributeValueMutator(createAttributeValueMutator(descriptors.get(property), attr)); + } + } + } + } + + + /** + * Returns a map of property descriptor names to property descriptor. + * + * @param type of class to inspect + * + * @return map of name to property descriptor + */ + protected Map<String, PropertyDescriptor> getPropertyDescriptors(final Class<?> type) + { + final Map<String, PropertyDescriptor> descriptors = new HashMap<>(); + try { + final BeanInfo info = Introspector.getBeanInfo(type); + if (info != null) { + final PropertyDescriptor[] desc = info.getPropertyDescriptors(); + if (desc != null) { + for (PropertyDescriptor pd : desc) { + descriptors.put(pd.getName(), pd); + } + } + } + } catch (IntrospectionException e) { + throw new IllegalArgumentException(e); + } + return descriptors; + } + + + /** + * Returns a dn value mutator for the supplied property descriptor. + * + * @param desc to create dn value mutator for + * + * @return dn value mutator + */ + protected DnValueMutator createDnValueMutator(final PropertyDescriptor desc) + { + return + new DefaultDnValueMutator( + new MethodAttributeValueMutator( + new DefaultReflectionTranscoder(desc.getReadMethod().getGenericReturnType()), + desc.getReadMethod(), + desc.getWriteMethod())); + } + + + /** + * Returns an attribute value mutator for the supplied property descriptor. + * + * @param desc to create attribute value mutator for + * @param attribute attribute containing metadata + * + * @return attribute value mutator + */ + protected AttributeValueMutator createAttributeValueMutator(final PropertyDescriptor desc, final Attribute attribute) + { + final String name = "".equals(attribute.name()) ? desc.getName() : attribute.name(); + final ValueTranscoder<?> transcoder = TranscoderFactory.getInstance(attribute.transcoder()); + return + new MethodAttributeValueMutator( + name, + attribute.binary(), + attribute.sortBehavior(), + new DefaultReflectionTranscoder(desc.getReadMethod().getGenericReturnType(), transcoder), + desc.getReadMethod(), + desc.getWriteMethod()); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/ReflectionTranscoder.java b/beans/src/main/java/org/ldaptive/beans/reflect/ReflectionTranscoder.java new file mode 100644 index 0000000..690f31b --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/ReflectionTranscoder.java
@@ -0,0 +1,71 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.util.Collection; + +/** + * Interface for reflection based transcoders. + * + * @author Middleware Services + */ +public interface ReflectionTranscoder +{ + + + /** + * Decodes the supplied values into an object. + * + * @param values to decode + * + * @return object initialized with the values + */ + Object decodeStringValues(Collection<String> values); + + + /** + * Decodes the supplied values into an object. + * + * @param values to decode + * + * @return object initialized with the values + */ + Object decodeBinaryValues(Collection<byte[]> values); + + + /** + * Encodes the supplied value into one or more strings for use in an attribute. + * + * @param value containing data to encode as strings + * + * @return string attribute values + */ + Collection<String> encodeStringValues(Object value); + + + /** + * Encodes the supplied value into one or more byte arrays for use in an attribute. + * + * @param value containing data to encode as byte arrays + * + * @return binary attribute values + */ + Collection<byte[]> encodeBinaryValues(Object value); + + + /** + * Returns the type produced by this transcoder. + * + * @return type produced by this transcoder + */ + Class<?> getType(); + + + /** + * Returns whether this transcoder can convert object of the supplied type. + * + * @param type of object + * + * @return whether the supplied type can be converted + */ + boolean supports(Class<?> type); +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/ReflectionUtils.java b/beans/src/main/java/org/ldaptive/beans/reflect/ReflectionUtils.java new file mode 100644 index 0000000..4babbbf --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/ReflectionUtils.java
@@ -0,0 +1,116 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Type; + +/** + * Provides utility methods for common reflection operations. + * + * @author Middleware Services + */ +public final class ReflectionUtils +{ + + + /** Default constructor. */ + private ReflectionUtils() {} + + + /** + * Casts the supplied type to a class. + * + * @param t to cast + * + * @return class cast from t + * + * @throws IllegalArgumentException if t is not an instance of Class + */ + public static Class<?> classFromType(final Type t) + { + if (!(t instanceof Class)) { + throw new IllegalArgumentException("Unsupported type: " + t); + } + return (Class<?>) t; + } + + + /** + * Returns the value of the supplied field on the supplied object. + * + * @param field containing the value to return + * @param object that has the field + * + * @return value of the field on the object + * + * @throws IllegalArgumentException if the field cannot be retrieved + */ + public static Object getField(final Field field, final Object object) + { + try { + return field.get(object); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } + } + + + /** + * Sets the supplied value of the supplied field on the supplied object. + * + * @param field of the object to set + * @param object that has the field + * @param value to set + * + * @throws IllegalArgumentException if the field cannot be set + */ + public static void setField(final Field field, final Object object, final Object value) + { + try { + field.set(object, value); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } + } + + + /** + * Invokes the supplied method on the supplied object. + * + * @param method to invoke + * @param object that has the method + * + * @return value of the invoked method + * + * @throws IllegalArgumentException if the method cannot be invoked + */ + public static Object invokeGetterMethod(final Method method, final Object object) + { + try { + return method.invoke(object); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new IllegalArgumentException(e); + } + } + + + /** + * Invokes the supplied method on the supplied object with the supplied value as a parameter. + * + * @param method to invoke + * @param object that has the method + * @param value to set + * + * @throws IllegalArgumentException if the method cannot be invoked + */ + public static void invokeSetterMethod(final Method method, final Object object, final Object value) + { + try { + method.invoke(object, value); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new IllegalArgumentException(e); + } + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/SetReflectionTranscoder.java b/beans/src/main/java/org/ldaptive/beans/reflect/SetReflectionTranscoder.java new file mode 100644 index 0000000..e7449ef --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/SetReflectionTranscoder.java
@@ -0,0 +1,57 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.TreeSet; + +/** + * Reflection transcoder for an object that implements {@link Set}. + * + * @author Middleware Services + */ +public class SetReflectionTranscoder extends AbstractCollectionReflectionTranscoder +{ + + + /** + * Creates a new set reflection transcoder. + * + * @param c class that is a set + * @param transcoder to operate on elements of the set + */ + public SetReflectionTranscoder(final Class<?> c, final SingleValueReflectionTranscoder<?> transcoder) + { + super(c, transcoder); + } + + + /** + * Creates a new set reflection transcoder. + * + * @param c class that is a set + * @param transcoder to operate on elements of the set + */ + public SetReflectionTranscoder(final Class<?> c, final ArrayReflectionTranscoder transcoder) + { + super(c, transcoder); + } + + + @Override + protected <T> Collection<T> createCollection(final Class<T> clazz) + { + final Class<?> type = getType(); + Set<T> s; + if (LinkedHashSet.class.isAssignableFrom(type)) { + s = new LinkedHashSet<>(); + } else if (TreeSet.class.isAssignableFrom(type)) { + s = new TreeSet<>(); + } else { + s = new HashSet<>(); + } + return s; + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/SingleValueReflectionTranscoder.java b/beans/src/main/java/org/ldaptive/beans/reflect/SingleValueReflectionTranscoder.java new file mode 100644 index 0000000..e8eb972 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/SingleValueReflectionTranscoder.java
@@ -0,0 +1,123 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import org.ldaptive.io.ValueTranscoder; + +/** + * Reflection transcoder which expects to operate on collections containing a single value. + * + * @param <T> type of object to transcode + * + * @author Middleware Services + */ +public class SingleValueReflectionTranscoder<T> implements ReflectionTranscoder +{ + + /** Underlying value transcoder. */ + private final ValueTranscoder<T> valueTranscoder; + + + /** + * Creates a new single value reflection transcoder. + * + * @param transcoder for a single value + */ + public SingleValueReflectionTranscoder(final ValueTranscoder<T> transcoder) + { + valueTranscoder = transcoder; + } + + + /** + * Creates a new single value reflection transcoder. Useful when the type of the value transcoder is unknown. + * + * @param <T> type to transcode + * @param transcoder for a single value + * + * @return single value reflection transcoder + */ + public static <T> SingleValueReflectionTranscoder<T> newInstance(final ValueTranscoder<T> transcoder) + { + return new SingleValueReflectionTranscoder<>(transcoder); + } + + + @Override + public Object decodeStringValues(final Collection<String> values) + { + if (values != null && values.size() > 1) { + throw new IllegalArgumentException("Multiple values not supported"); + } + if (values != null && !values.isEmpty()) { + return valueTranscoder.decodeStringValue(values.iterator().next()); + } + return null; + } + + + @Override + public Object decodeBinaryValues(final Collection<byte[]> values) + { + if (values != null && values.size() > 1) { + throw new IllegalArgumentException("Multiple values not supported"); + } + if (values != null && !values.isEmpty()) { + return valueTranscoder.decodeBinaryValue(values.iterator().next()); + } + return null; + } + + + @Override + public Collection<String> encodeStringValues(final Object value) + { + final List<String> l = new ArrayList<>(1); + if (value != null) { + @SuppressWarnings("unchecked") + final String s = valueTranscoder.encodeStringValue((T) value); + if (s != null) { + l.add(s); + } + } + return l; + } + + + @Override + public Collection<byte[]> encodeBinaryValues(final Object value) + { + final List<byte[]> l = new ArrayList<>(1); + if (value != null) { + @SuppressWarnings("unchecked") + final byte[] b = valueTranscoder.encodeBinaryValue((T) value); + if (b != null) { + l.add(b); + } + } + return l; + } + + + @Override + public Class<?> getType() + { + return valueTranscoder.getType(); + } + + + @Override + public boolean supports(final Class<?> type) + { + return getType().equals(type); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::valueTranscoder=%s]", getClass().getName(), hashCode(), valueTranscoder); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/reflect/TranscoderFactory.java b/beans/src/main/java/org/ldaptive/beans/reflect/TranscoderFactory.java new file mode 100644 index 0000000..df1f5c2 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/reflect/TranscoderFactory.java
@@ -0,0 +1,68 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.util.HashMap; +import java.util.Map; +import org.ldaptive.io.ValueTranscoder; + +/** + * Creates value transcoders and stores them in a static map. + * + * @author Middleware Services + */ +public final class TranscoderFactory +{ + + /** Value transcoders. */ + private static final Map<String, ValueTranscoder<?>> TRANSCODERS = new HashMap<>(); + + + /** Default constructor. */ + private TranscoderFactory() {} + + + /** + * Returns a value transcoder for the supplied type. If the type cannot be found it is instantiated and cached for + * future use. + * + * @param type of value transcoder + * + * @return value transcoder + */ + public static ValueTranscoder<?> getInstance(final String type) + { + if (type == null || "".equals(type)) { + return null; + } + + ValueTranscoder<?> transcoder; + synchronized (TRANSCODERS) { + if (!TRANSCODERS.containsKey(type)) { + transcoder = createValueTranscoder(type); + TRANSCODERS.put(type, transcoder); + } else { + transcoder = TRANSCODERS.get(type); + } + } + return transcoder; + } + + + /** + * Creates a value transcoder for the supplied type. + * + * @param type to create value transcoder for + * + * @return value transcoder + * + * @throws IllegalArgumentException if the supplied type cannot be instantiated + */ + protected static ValueTranscoder<?> createValueTranscoder(final String type) + { + try { + return (ValueTranscoder<?>) Class.forName(type).newInstance(); + } catch (Exception e) { + throw new IllegalArgumentException("Could not instantiate transcoder", e); + } + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/NamespaceHandler.java b/beans/src/main/java/org/ldaptive/beans/spring/NamespaceHandler.java new file mode 100644 index 0000000..0717415 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/NamespaceHandler.java
@@ -0,0 +1,55 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring; + +import org.ldaptive.beans.spring.parser.ADAuthenticatorBeanDefinitionParser; +import org.ldaptive.beans.spring.parser.AggregateAuthenticatorBeanDefinitionParser; +import org.ldaptive.beans.spring.parser.AggregatePooledSearchExecutorBeanDefinitionParser; +import org.ldaptive.beans.spring.parser.AggregateSearchExecutorBeanDefinitionParser; +import org.ldaptive.beans.spring.parser.AnonSearchAuthenticatorBeanDefinitionParser; +import org.ldaptive.beans.spring.parser.BindSearchAuthenticatorBeanDefinitionParser; +import org.ldaptive.beans.spring.parser.ConnectionConfigBeanDefinitionParser; +import org.ldaptive.beans.spring.parser.ConnectionFactoryBeanDefinitionParser; +import org.ldaptive.beans.spring.parser.ConnectionPoolBeanDefinitionParser; +import org.ldaptive.beans.spring.parser.DirectAuthenticatorBeanDefinitionParser; +import org.ldaptive.beans.spring.parser.ParallelPooledSearchExecutorBeanDefinitionParser; +import org.ldaptive.beans.spring.parser.ParallelSearchExecutorBeanDefinitionParser; +import org.ldaptive.beans.spring.parser.PooledConnectionFactoryBeanDefinitionParser; +import org.ldaptive.beans.spring.parser.SaslBindSearchAuthenticatorBeanDefinitionParser; +import org.ldaptive.beans.spring.parser.SearchExecutorBeanDefinitionParser; +import org.springframework.beans.factory.xml.NamespaceHandlerSupport; + +/** + * Spring namespace handler for ldaptive. + * + * @author Middleware Services + */ +public class NamespaceHandler extends NamespaceHandlerSupport +{ + + + @Override + public void init() + { + registerBeanDefinitionParser("anonymous-search-authenticator", new AnonSearchAuthenticatorBeanDefinitionParser()); + registerBeanDefinitionParser("bind-search-authenticator", new BindSearchAuthenticatorBeanDefinitionParser()); + registerBeanDefinitionParser( + "sasl-bind-search-authenticator", + new SaslBindSearchAuthenticatorBeanDefinitionParser()); + registerBeanDefinitionParser("direct-authenticator", new DirectAuthenticatorBeanDefinitionParser()); + registerBeanDefinitionParser("ad-authenticator", new ADAuthenticatorBeanDefinitionParser()); + registerBeanDefinitionParser("aggregate-authenticator", new AggregateAuthenticatorBeanDefinitionParser()); + registerBeanDefinitionParser("pooled-connection-factory", new PooledConnectionFactoryBeanDefinitionParser()); + registerBeanDefinitionParser("connection-factory", new ConnectionFactoryBeanDefinitionParser()); + registerBeanDefinitionParser("connection-pool", new ConnectionPoolBeanDefinitionParser()); + registerBeanDefinitionParser("connection-config", new ConnectionConfigBeanDefinitionParser()); + registerBeanDefinitionParser("search-executor", new SearchExecutorBeanDefinitionParser()); + registerBeanDefinitionParser("parallel-search-executor", new ParallelSearchExecutorBeanDefinitionParser()); + registerBeanDefinitionParser( + "parallel-pooled-search-executor", + new ParallelPooledSearchExecutorBeanDefinitionParser()); + registerBeanDefinitionParser("aggregate-search-executor", new AggregateSearchExecutorBeanDefinitionParser()); + registerBeanDefinitionParser( + "aggregate-pooled-search-executor", + new AggregatePooledSearchExecutorBeanDefinitionParser()); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/SpelAttributeValueMutator.java b/beans/src/main/java/org/ldaptive/beans/spring/SpelAttributeValueMutator.java new file mode 100644 index 0000000..770564b --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/SpelAttributeValueMutator.java
@@ -0,0 +1,290 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; +import org.ldaptive.SortBehavior; +import org.ldaptive.beans.Attribute; +import org.ldaptive.beans.AttributeValueMutator; +import org.ldaptive.io.ValueTranscoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.Expression; +import org.springframework.expression.ExpressionParser; +import org.springframework.expression.spel.standard.SpelExpressionParser; + +/** + * Attribute mutator that uses a SPEL expression and evaluation context. + * + * @author Middleware Services + */ +public class SpelAttributeValueMutator implements AttributeValueMutator +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Attribute containing the SPEL expression. */ + private final Attribute attribute; + + /** SPEL expression to access values. */ + private final Expression expression; + + /** Evaluation context. */ + private final EvaluationContext evaluationContext; + + /** Custom transcoder for this attribute. */ + private final ValueTranscoder transcoder; + + + /** + * Creates a new spel attribute value mutator. + * + * @param attr containing the SPEL configuration + * @param context containing the values + */ + public SpelAttributeValueMutator(final Attribute attr, final EvaluationContext context) + { + attribute = attr; + + final ExpressionParser parser = new SpelExpressionParser(); + expression = parser.parseExpression(attribute.property().length() > 0 ? attribute.property() : attribute.name()); + evaluationContext = context; + if ("".equals(attribute.transcoder())) { + transcoder = null; + } else { + transcoder = parser.parseExpression(attribute.transcoder()).getValue(ValueTranscoder.class); + } + } + + + @Override + public String getName() + { + return attribute.name(); + } + + + @Override + public boolean isBinary() + { + return attribute.binary(); + } + + + @Override + public SortBehavior getSortBehavior() + { + return attribute.sortBehavior(); + } + + + @Override + public Collection<String> getStringValues(final Object object) + { + return getValues(object, String.class); + } + + + @Override + public Collection<byte[]> getBinaryValues(final Object object) + { + return getValues(object, byte[].class); + } + + + /** + * Uses the configured expression and evaluation context to retrieve values from the supplied object. Values are the + * placed in a collection and returned. + * + * @param <T> either String or byte[] + * @param object to get values from + * @param type of objects to place in the collection + * + * @return values in the supplied object + */ + protected <T> Collection<T> getValues(final Object object, final Class<T> type) + { + Collection<T> values = null; + final Object converted = expression.getValue(evaluationContext, object); + if (converted != null) { + if (converted instanceof byte[] || converted instanceof char[]) { + values = createCollection(List.class, 1); + + final T value = convertValue(converted, converted.getClass(), type); + if (value != null) { + values.add(value); + } + } else if (converted.getClass().isArray()) { + final int length = Array.getLength(converted); + values = createCollection(List.class, length); + for (int i = 0; i < length; i++) { + final Object o = Array.get(converted, i); + if (o != null) { + final T value = convertValue(o, o.getClass(), type); + if (value != null) { + values.add(value); + } + } + } + } else if (Collection.class.isAssignableFrom(converted.getClass())) { + final Collection<?> col = (Collection<?>) converted; + values = createCollection(converted.getClass(), col.size()); + for (Object o : col) { + if (o != null) { + final T value = convertValue(o, o.getClass(), type); + if (value != null) { + values.add(value); + } + } + } + } else { + values = createCollection(List.class, 1); + + final T value = convertValue(converted, converted.getClass(), type); + if (value != null) { + values.add(value); + } + } + } + return values; + } + + + /** + * Converts the supplied value to the target type. If a custom transcoder has been configured it is used. Otherwise + * the type converter from the evaluation context is used. + * + * @param <T> either String or byte[] + * @param value to convert + * @param sourceType to convert from + * @param targetType to convert to + * + * @return converted value + */ + @SuppressWarnings("unchecked") + protected <T> T convertValue(final Object value, final Class<?> sourceType, final Class<T> targetType) + { + T converted; + if (transcoder != null) { + if (byte[].class == targetType) { + converted = (T) transcoder.encodeBinaryValue(value); + } else if (String.class == targetType) { + converted = (T) transcoder.encodeStringValue(value); + } else { + throw new IllegalArgumentException("targetType must be either String.class or byte[].class"); + } + } else { + converted = (T) evaluationContext.getTypeConverter().convertValue( + value, + TypeDescriptor.valueOf(sourceType), + TypeDescriptor.valueOf(targetType)); + } + return converted; + } + + + @Override + public void setStringValues(final Object object, final Collection<String> values) + { + setValues(object, values, String.class); + } + + + @Override + public void setBinaryValues(final Object object, final Collection<byte[]> values) + { + setValues(object, values, byte[].class); + } + + + /** + * Uses the configured expression and evaluation context to set values on the supplied object. If a custom transcoder + * has been configured it is executed on the values before they are passed to the expression. + * + * @param <T> either String or byte[] + * @param object to set values on + * @param values to set + * @param type of objects in the collection + */ + protected <T> void setValues(final Object object, final Collection<T> values, final Class<T> type) + { + if (transcoder != null) { + final Collection<Object> newValues = createCollection(values.getClass(), values.size()); + for (T t : values) { + if (byte[].class == type) { + newValues.add(transcoder.decodeBinaryValue((byte[]) t)); + } else if (String.class == type) { + newValues.add(transcoder.decodeStringValue((String) t)); + } else { + throw new IllegalArgumentException("type must be either String.class or byte[].class"); + } + } + expression.setValue(evaluationContext, object, newValues); + } else { + if (values != null && values.size() == 1) { + expression.setValue(evaluationContext, object, values.iterator().next()); + } else { + expression.setValue(evaluationContext, object, values); + } + } + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::attribute=%s, expression=%s, evaluationContext=%s, " + + "transcoder=%s]", + getClass().getName(), + hashCode(), + attribute, + expression, + evaluationContext, + transcoder); + } + + + /** + * Creates a best fit collection for the supplied type. + * + * @param <T> collection type + * @param type of collection to create + * @param size of the collection + * + * @return collection + */ + protected static <T> Collection<T> createCollection(final Class<?> type, final int size) + { + Collection<T> c; + if (List.class.isAssignableFrom(type)) { + if (LinkedList.class.isAssignableFrom(type)) { + c = new LinkedList<>(); + } else { + c = new ArrayList<>(size); + } + } else if (Set.class.isAssignableFrom(type)) { + if (LinkedHashSet.class.isAssignableFrom(type)) { + c = new LinkedHashSet<>(size); + } else if (TreeSet.class.isAssignableFrom(type)) { + c = new TreeSet<>(); + } else { + c = new HashSet<>(size); + } + } else { + c = new ArrayList<>(size); + } + return c; + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/SpelDnValueMutator.java b/beans/src/main/java/org/ldaptive/beans/spring/SpelDnValueMutator.java new file mode 100644 index 0000000..1655472 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/SpelDnValueMutator.java
@@ -0,0 +1,66 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring; + +import org.ldaptive.beans.DnValueMutator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.Expression; + +/** + * Uses a SPEL expression and evaluation context to mutate the configured DN of an object. + * + * @author Middleware Services + */ +public class SpelDnValueMutator implements DnValueMutator +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** SPEL expression to access the DN. */ + private final Expression expression; + + /** Evaluation context. */ + private final EvaluationContext evaluationContext; + + + /** + * Creates a new spel dn value mutator. + * + * @param exp to access the DN + * @param context containing the DN + */ + public SpelDnValueMutator(final Expression exp, final EvaluationContext context) + { + expression = exp; + evaluationContext = context; + } + + + @Override + public String getValue(final Object object) + { + return expression.getValue(evaluationContext, object, String.class); + } + + + @Override + public void setValue(final Object object, final String value) + { + expression.setValue(evaluationContext, object, value); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::expression=%s, evaluationContext=%s]", + getClass().getName(), + hashCode(), + expression, + evaluationContext); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/SpringClassDescriptor.java b/beans/src/main/java/org/ldaptive/beans/spring/SpringClassDescriptor.java new file mode 100644 index 0000000..54e6b5f --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/SpringClassDescriptor.java
@@ -0,0 +1,75 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring; + +import org.ldaptive.beans.AbstractClassDescriptor; +import org.ldaptive.beans.Attribute; +import org.ldaptive.beans.DnValueMutator; +import org.ldaptive.beans.Entry; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.spel.SpelParseException; +import org.springframework.expression.spel.standard.SpelExpressionParser; + +/** + * Spring implementation of a class descriptor. Uses an {@link EvaluationContext} with SPEL expressions to find property + * values. + * + * @author Middleware Services + */ +public class SpringClassDescriptor extends AbstractClassDescriptor +{ + + /** Context for evaluating spring expressions. */ + private final EvaluationContext evaluationContext; + + + /** + * Creates a new spring class descriptor. + * + * @param context to use for SPEL evaluation + */ + public SpringClassDescriptor(final EvaluationContext context) + { + evaluationContext = context; + } + + + @Override + public void initialize(final Class<?> type) + { + // check for entry annotation + final Entry entryAnnotation = AnnotationUtils.findAnnotation(type, Entry.class); + if (entryAnnotation != null) { + if (!"".equals(entryAnnotation.dn())) { + setDnValueMutator(createDnValueMutator(entryAnnotation.dn())); + } + for (final Attribute attr : entryAnnotation.attributes()) { + if ("".equals(attr.property()) && attr.values().length > 0) { + addAttributeValueMutator( + new SimpleAttributeValueMutator(attr.name(), attr.values(), attr.binary(), attr.sortBehavior())); + } else { + addAttributeValueMutator(new SpelAttributeValueMutator(attr, evaluationContext)); + } + } + } + } + + + /** + * Creates a dn value mutator for the supplied SPEL dn property expression. If an expression cannot be created, a + * simple dn value mutator is returned. + * + * @param dnProperty SPEL expression + * + * @return {@link SpelDnValueMutator} if dnProperty can be parsed. Otherwise returns simple dn value mutator + */ + protected DnValueMutator createDnValueMutator(final String dnProperty) + { + try { + return new SpelDnValueMutator(new SpelExpressionParser().parseExpression(dnProperty), evaluationContext); + } catch (SpelParseException e) { + logger.debug("Could not parse dn expression, using SimpleDnValueMutator", e); + return new SimpleDnValueMutator(dnProperty); + } + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/SpringLdapEntryMapper.java b/beans/src/main/java/org/ldaptive/beans/spring/SpringLdapEntryMapper.java new file mode 100644 index 0000000..d54c80b --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/SpringLdapEntryMapper.java
@@ -0,0 +1,112 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring; + +import java.time.ZonedDateTime; +import org.ldaptive.beans.AbstractLdapEntryMapper; +import org.ldaptive.beans.ClassDescriptor; +import org.ldaptive.beans.spring.convert.StringToZonedDateTimeConverter; +import org.ldaptive.beans.spring.convert.ZonedDateTimeToStringConverter; +import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.support.DefaultConversionService; +import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.TypeConverter; +import org.springframework.expression.spel.support.StandardEvaluationContext; +import org.springframework.expression.spel.support.StandardTypeConverter; + +/** + * Uses a {@link SpringClassDescriptor} for ldap entry mapping. + * + * @param <T> type of object to map + * + * @author Middleware Services + */ +public class SpringLdapEntryMapper<T> extends AbstractLdapEntryMapper<T> +{ + + /** Type converter used by all contexts. */ + private final TypeConverter typeConverter; + + + /** Default constructor. */ + public SpringLdapEntryMapper() + { + this((Converter<?, ?>) null); + } + + + /** + * Creates a new spring ldap entry mapper. + * + * @param c additional converters to add to the spring conversion service. + */ + public SpringLdapEntryMapper(final Converter<?, ?>... c) + { + typeConverter = createTypeConverter(c); + } + + + @Override + protected ClassDescriptor getClassDescriptor(final Object object) + { + final SpringClassDescriptor descriptor = new SpringClassDescriptor(createEvaluationContext(object)); + descriptor.initialize(object.getClass()); + return descriptor; + } + + + /** + * Creates an evaluation context to use in the spring class descriptor. Adds the default converters from the default + * conversion service. + * + * @param object to supply to the evaluation context + * + * @return evalutation context + */ + protected EvaluationContext createEvaluationContext(final Object object) + { + final StandardEvaluationContext context = new StandardEvaluationContext(object); + context.setTypeConverter(typeConverter); + return context; + } + + + /** + * Returns a type converter that is initialized with the supplied converters and any converters supplied by {@link + * #addDefaultConverters(GenericConversionService)}. + * + * @param converters to add to the conversion service + * + * @return type converter + */ + protected TypeConverter createTypeConverter(final Converter<?, ?>... converters) + { + final GenericConversionService conversionService = new GenericConversionService(); + DefaultConversionService.addDefaultConverters(conversionService); + if (converters != null) { + for (Converter<?, ?> converter : converters) { + if (converter != null) { + conversionService.addConverter(converter); + } + } + } + addDefaultConverters(conversionService); + return new StandardTypeConverter(conversionService); + } + + + /** + * Adds default converters to the supplied conversion service. + * + * @param service to add default converters to + */ + protected void addDefaultConverters(final GenericConversionService service) + { + if (!service.canConvert(String.class, ZonedDateTime.class)) { + service.addConverter(new StringToZonedDateTimeConverter()); + } + if (!service.canConvert(ZonedDateTime.class, String.class)) { + service.addConverter(new ZonedDateTimeToStringConverter()); + } + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/convert/DurationToStringConverter.java b/beans/src/main/java/org/ldaptive/beans/spring/convert/DurationToStringConverter.java new file mode 100644 index 0000000..e56dc2f --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/convert/DurationToStringConverter.java
@@ -0,0 +1,21 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.convert; + +import java.time.Duration; +import org.springframework.core.convert.converter.Converter; + +/** + * Convert a {@link Duration} to a String. + * + * @author Middleware Services + */ +public class DurationToStringConverter implements Converter<Duration, String> +{ + + + @Override + public String convert(final Duration d) + { + return d.toString(); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/convert/StringToDurationConverter.java b/beans/src/main/java/org/ldaptive/beans/spring/convert/StringToDurationConverter.java new file mode 100644 index 0000000..ecf8357 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/convert/StringToDurationConverter.java
@@ -0,0 +1,21 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.convert; + +import java.time.Duration; +import org.springframework.core.convert.converter.Converter; + +/** + * Convert a String to a {@link Duration}. + * + * @author Middleware Services + */ +public class StringToDurationConverter implements Converter<String, Duration> +{ + + + @Override + public Duration convert(final String s) + { + return Duration.parse(s); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/convert/StringToZonedDateTimeConverter.java b/beans/src/main/java/org/ldaptive/beans/spring/convert/StringToZonedDateTimeConverter.java new file mode 100644 index 0000000..b30e457 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/convert/StringToZonedDateTimeConverter.java
@@ -0,0 +1,23 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.convert; + +import java.time.ZonedDateTime; +import org.ldaptive.io.GeneralizedTimeValueTranscoder; +import org.springframework.core.convert.converter.Converter; + +/** + * Convert a String to a {@link ZonedDateTime}. + * + * @author Middleware Services + */ +public class StringToZonedDateTimeConverter implements Converter<String, ZonedDateTime> +{ + + + @Override + public ZonedDateTime convert(final String s) + { + final GeneralizedTimeValueTranscoder transcoder = new GeneralizedTimeValueTranscoder(); + return transcoder.decodeStringValue(s); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/convert/ZonedDateTimeToStringConverter.java b/beans/src/main/java/org/ldaptive/beans/spring/convert/ZonedDateTimeToStringConverter.java new file mode 100644 index 0000000..9e30bcb --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/convert/ZonedDateTimeToStringConverter.java
@@ -0,0 +1,23 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.convert; + +import java.time.ZonedDateTime; +import org.ldaptive.io.GeneralizedTimeValueTranscoder; +import org.springframework.core.convert.converter.Converter; + +/** + * Convert a {@link ZonedDateTime} to a String. + * + * @author Middleware Services + */ +public class ZonedDateTimeToStringConverter implements Converter<ZonedDateTime, String> +{ + + + @Override + public String convert(final ZonedDateTime t) + { + final GeneralizedTimeValueTranscoder transcoder = new GeneralizedTimeValueTranscoder(); + return transcoder.encodeStringValue(t); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/ADAuthenticatorBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/ADAuthenticatorBeanDefinitionParser.java new file mode 100644 index 0000000..672b2dd --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/ADAuthenticatorBeanDefinitionParser.java
@@ -0,0 +1,61 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.ad.handler.ObjectGuidHandler; +import org.ldaptive.ad.handler.ObjectSidHandler; +import org.ldaptive.auth.PooledSearchEntryResolver; +import org.ldaptive.auth.SearchEntryResolver; +import org.ldaptive.handler.SearchEntryHandler; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <pre>ad-authenticator</pre> elements. + * + * @author Middleware Services + */ +public class ADAuthenticatorBeanDefinitionParser extends AbstractSearchAuthenticatorBeanDefinitionParser +{ + + + @Override + protected String resolveId( + final Element element, + // CheckStyle:IllegalTypeCheck OFF + final AbstractBeanDefinition definition, + // CheckStyle:IllegalTypeCheck ON + final ParserContext parserContext) + throws BeanDefinitionStoreException + { + final String idAttrValue = element.getAttribute("id"); + return StringUtils.hasText(idAttrValue) ? idAttrValue : "ad-authenticator"; + } + + + @Override + protected BeanDefinitionBuilder parseEntryResolver( + final Element element, + final BeanDefinitionBuilder connectionFactory) + { + BeanDefinitionBuilder entryResolver; + if (element.hasAttribute("resolveEntryWithBindCredentials") && + Boolean.valueOf(element.getAttribute("resolveEntryWithBindCredentials"))) { + if (element.getAttribute("disablePooling") != null && Boolean.valueOf(element.getAttribute("disablePooling"))) { + entryResolver = BeanDefinitionBuilder.genericBeanDefinition(SearchEntryResolver.class); + } else { + entryResolver = BeanDefinitionBuilder.genericBeanDefinition(PooledSearchEntryResolver.class); + } + entryResolver.addPropertyValue("connectionFactory", connectionFactory.getBeanDefinition()); + } else { + entryResolver = super.parseEntryResolver(element, connectionFactory); + } + entryResolver.addPropertyValue( + "searchEntryHandlers", + new SearchEntryHandler[]{new ObjectGuidHandler(), new ObjectSidHandler()}); + return entryResolver; + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractAuthenticatorBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractAuthenticatorBeanDefinitionParser.java new file mode 100644 index 0000000..b3b7095 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractAuthenticatorBeanDefinitionParser.java
@@ -0,0 +1,169 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.auth.Authenticator; +import org.ldaptive.auth.BindAuthenticationHandler; +import org.ldaptive.auth.PooledBindAuthenticationHandler; +import org.ldaptive.auth.ext.ActiveDirectoryAuthenticationResponseHandler; +import org.ldaptive.auth.ext.EDirectoryAuthenticationResponseHandler; +import org.ldaptive.auth.ext.FreeIPAAuthenticationResponseHandler; +import org.ldaptive.auth.ext.PasswordExpirationAuthenticationResponseHandler; +import org.ldaptive.auth.ext.PasswordPolicyAuthenticationResponseHandler; +import org.ldaptive.control.PasswordPolicyControl; +import org.ldaptive.pool.PooledConnectionFactory; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.w3c.dom.Element; + +/** + * Common implementation for all authenticators. + * + * @author Middleware Services + */ +public abstract class AbstractAuthenticatorBeanDefinitionParser extends AbstractConnectionPoolBeanDefinitionParser +{ + + + @Override + protected Class<?> getBeanClass(final Element element) + { + return Authenticator.class; + } + + + /** + * Creates a pooled authentication handler for performing binds. + * + * @param element containing configuration + * + * @return pooled bind authentication handler bean definition builder + */ + protected BeanDefinitionBuilder parseAuthHandler(final Element element) + { + BeanDefinitionBuilder authHandler; + if (element.getAttribute("disablePooling") != null && Boolean.valueOf(element.getAttribute("disablePooling"))) { + authHandler = BeanDefinitionBuilder.genericBeanDefinition(BindAuthenticationHandler.class); + authHandler.addPropertyValue( + "connectionFactory", + parseDefaultConnectionFactory(null, element, false).getBeanDefinition()); + } else { + String name = "bind-pool"; + if (element.hasAttribute("id")) { + name = element.getAttribute("id") + "-bind-pool"; + } + authHandler = BeanDefinitionBuilder.genericBeanDefinition(PooledBindAuthenticationHandler.class); + final BeanDefinitionBuilder connectionFactory = BeanDefinitionBuilder.genericBeanDefinition( + PooledConnectionFactory.class); + connectionFactory.addPropertyValue( + "connectionPool", + parseConnectionPool(null, name, element, false).getBeanDefinition()); + authHandler.addPropertyValue("connectionFactory", connectionFactory.getBeanDefinition()); + } + return authHandler; + } + + + /** + * Creates an authentication response handler bean definition builder. The supplied authentication handler will be + * updated with any necessary request controls that the response handler may require. + * + * @param authenticator bean definition builder for the authenticator + * @param authHandler bean definition builder for the authentication handler + * @param element containing authentication response handler + * + * @return authentication response handler bean definition builder + */ + protected BeanDefinitionBuilder parseAuthResponseHandler( + final BeanDefinitionBuilder authenticator, + final BeanDefinitionBuilder authHandler, + final Element element) + { + BeanDefinitionBuilder responseHandler = null; + BeanDefinitionBuilder requestControls = null; + + final Element handlerElement = getDirectChild( + getDirectChild(element, "authentication-response-handler"), + "password-policy-handler", + "password-expiration-handler", + "e-directory-handler", + "free-ipa-handler", + "active-directory-handler"); + if (handlerElement != null) { + switch (handlerElement.getLocalName()) { + + case "password-policy-handler": + responseHandler = BeanDefinitionBuilder.genericBeanDefinition( + PasswordPolicyAuthenticationResponseHandler.class); + requestControls = BeanDefinitionBuilder.genericBeanDefinition(PasswordPolicyControl.class); + break; + + case "password-expiration-handler": + responseHandler = BeanDefinitionBuilder.genericBeanDefinition( + PasswordExpirationAuthenticationResponseHandler.class); + break; + + case "e-directory-handler": + responseHandler = BeanDefinitionBuilder.genericBeanDefinition( + EDirectoryAuthenticationResponseHandler.class); + if (handlerElement.hasAttribute("warningPeriod")) { + final BeanDefinitionBuilder period = BeanDefinitionBuilder.rootBeanDefinition( + AbstractAuthenticatorBeanDefinitionParser.class, + "parsePeriod"); + period.addConstructorArgValue(handlerElement.getAttribute("warningPeriod")); + responseHandler.addPropertyValue("warningPeriod", period.getBeanDefinition()); + } + authenticator.addPropertyValue("returnAttributes", EDirectoryAuthenticationResponseHandler.ATTRIBUTES); + break; + + case "free-ipa-handler": + responseHandler = BeanDefinitionBuilder.genericBeanDefinition(FreeIPAAuthenticationResponseHandler.class); + if (handlerElement.hasAttribute("expirationPeriod")) { + final BeanDefinitionBuilder period = BeanDefinitionBuilder.rootBeanDefinition( + AbstractAuthenticatorBeanDefinitionParser.class, + "parsePeriod"); + period.addConstructorArgValue(handlerElement.getAttribute("expirationPeriod")); + responseHandler.addPropertyValue("expirationPeriod", period.getBeanDefinition()); + } + if (handlerElement.hasAttribute("warningPeriod")) { + final BeanDefinitionBuilder period = BeanDefinitionBuilder.rootBeanDefinition( + AbstractAuthenticatorBeanDefinitionParser.class, + "parsePeriod"); + period.addConstructorArgValue(handlerElement.getAttribute("warningPeriod")); + responseHandler.addPropertyValue("warningPeriod", period.getBeanDefinition()); + } + if (handlerElement.hasAttribute("maxLoginFailures")) { + responseHandler.addPropertyValue("maxLoginFailures", handlerElement.getAttribute("maxLoginFailures")); + } + authenticator.addPropertyValue("returnAttributes", FreeIPAAuthenticationResponseHandler.ATTRIBUTES); + break; + + case "active-directory-handler": + responseHandler = BeanDefinitionBuilder.genericBeanDefinition( + ActiveDirectoryAuthenticationResponseHandler.class); + if (handlerElement.hasAttribute("expirationPeriod")) { + final BeanDefinitionBuilder period = BeanDefinitionBuilder.rootBeanDefinition( + AbstractAuthenticatorBeanDefinitionParser.class, + "parsePeriod"); + period.addConstructorArgValue(handlerElement.getAttribute("expirationPeriod")); + responseHandler.addPropertyValue("expirationPeriod", period.getBeanDefinition()); + } + if (handlerElement.hasAttribute("warningPeriod")) { + final BeanDefinitionBuilder period = BeanDefinitionBuilder.rootBeanDefinition( + AbstractAuthenticatorBeanDefinitionParser.class, + "parsePeriod"); + period.addConstructorArgValue(handlerElement.getAttribute("warningPeriod")); + responseHandler.addPropertyValue("warningPeriod", period.getBeanDefinition()); + } + authenticator.addPropertyValue("returnAttributes", ActiveDirectoryAuthenticationResponseHandler.ATTRIBUTES); + break; + + default: + throw new IllegalArgumentException("Unknown authentication response handler: " + handlerElement.getLocalName()); + } + } + + if (requestControls != null) { + authHandler.addPropertyValue("authenticationControls", requestControls.getBeanDefinition()); + } + return responseHandler; + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractBeanDefinitionParser.java new file mode 100644 index 0000000..5d8a872 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractBeanDefinitionParser.java
@@ -0,0 +1,109 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import java.time.Duration; +import java.time.Period; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Common implementation for all bean definition parsers + * + * @author Middleware Services + */ +public abstract class AbstractBeanDefinitionParser extends AbstractSingleBeanDefinitionParser +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + + /** + * Returns a {@link Period} for the supplied value. + * + * @param value to parse + * + * @return period + */ + protected static Period parsePeriod(final String value) + { + return Period.parse(value); + } + + + /** + * Returns a {@link Duration} for the supplied value. + * + * @param value to parse + * + * @return duration + */ + protected static Duration parseDuration(final String value) + { + return Duration.parse(value); + } + + + /** + * Returns the first direct child element of the parent element with a name that matches any of the supplied names. + * + * @param parent element to inspect + * @param names local names of the element to return + * + * @return child element or null + */ + protected static Element getDirectChild(final Element parent, final String... names) + { + if (parent != null) { + for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) { + for (String name : names) { + if (child instanceof Element && name.equals(child.getLocalName())) { + return (Element) child; + } + } + } + } + return null; + } + + + /** + * Sets a property if the given attribute exists on the element. The property name used is the same as the attribute + * name. + * + * @param element from which to obtain property + * @param attribute value for obtaining property + * @param builder to receive property + */ + protected void setIfPresent( + final Element element, + final String attribute, + final BeanDefinitionBuilder builder) + { + setIfPresent(element, attribute, attribute, builder); + } + + + /** + * Sets a property if the given attribute exists on the element. + * + * @param element from which to obtain property + * @param property to set + * @param attribute value for obtaining property + * @param builder to receive property + */ + protected void setIfPresent( + final Element element, + final String attribute, + final String property, + final BeanDefinitionBuilder builder) + { + if (element.hasAttribute(attribute)) { + builder.addPropertyValue(property, element.getAttribute(attribute)); + } + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractConnectionConfigBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractConnectionConfigBeanDefinitionParser.java new file mode 100644 index 0000000..2125e0e --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractConnectionConfigBeanDefinitionParser.java
@@ -0,0 +1,135 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.BindConnectionInitializer; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.ssl.KeyStoreCredentialConfig; +import org.ldaptive.ssl.SslConfig; +import org.ldaptive.ssl.X509CredentialConfig; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.w3c.dom.Element; + +/** + * Common implementation for parsers that extend connection-config. + * + * @author Middleware Services + */ +public abstract class AbstractConnectionConfigBeanDefinitionParser extends AbstractBeanDefinitionParser +{ + + + /** + * Creates a connection config. If a bindDn and bindCredential are present, a {@link BindConnectionInitializer} is + * inserted into the connection config. + * + * @param builder bean definition builder to set properties on, may be null + * @param element containing configuration + * @param includeConnectionInitializer whether to include a connection initializer + * + * @return connection config bean definition builder + */ + protected BeanDefinitionBuilder parseConnectionConfig( + final BeanDefinitionBuilder builder, + final Element element, + final boolean includeConnectionInitializer) + { + BeanDefinitionBuilder connectionConfig = builder; + if (connectionConfig == null) { + connectionConfig = BeanDefinitionBuilder.genericBeanDefinition(ConnectionConfig.class); + } + setIfPresent(element, "ldapUrl", connectionConfig); + connectionConfig.addPropertyValue("useStartTLS", element.getAttribute("useStartTLS")); + connectionConfig.addPropertyValue("useSSL", element.getAttribute("useSSL")); + final BeanDefinitionBuilder connectTimeout = BeanDefinitionBuilder.rootBeanDefinition( + AbstractAuthenticatorBeanDefinitionParser.class, + "parseDuration"); + connectTimeout.addConstructorArgValue(element.getAttribute("connectTimeout")); + connectionConfig.addPropertyValue("connectTimeout", connectTimeout.getBeanDefinition()); + + if (element.hasAttribute("trustCertificates") || element.hasAttribute("authenticationCertificate")) { + final BeanDefinitionBuilder sslConfig = BeanDefinitionBuilder.genericBeanDefinition(SslConfig.class); + sslConfig.addPropertyValue("credentialConfig", parseX509CredentialConfig(null, element).getBeanDefinition()); + connectionConfig.addPropertyValue("sslConfig", sslConfig.getBeanDefinition()); + } else if (element.hasAttribute("trustStore") || element.hasAttribute("keyStore")) { + final BeanDefinitionBuilder sslConfig = BeanDefinitionBuilder.genericBeanDefinition(SslConfig.class); + sslConfig.addPropertyValue("credentialConfig", parseKeyStoreCredentialConfig(null, element).getBeanDefinition()); + connectionConfig.addPropertyValue("sslConfig", sslConfig.getBeanDefinition()); + } + + if (includeConnectionInitializer && element.hasAttribute("bindDn")) { + connectionConfig.addPropertyValue( + "connectionInitializer", + parseConnectionInitializer(null, element).getBeanDefinition()); + } + return connectionConfig; + } + + + /** + * Creates a bind connection initializer. + * + * @param builder bean definition builder to set properties on, may be null + * @param element containing configuration + * + * @return bind connection initializer bean definition builder + */ + protected BeanDefinitionBuilder parseConnectionInitializer(final BeanDefinitionBuilder builder, final Element element) + { + BeanDefinitionBuilder initializer = builder; + if (initializer == null) { + initializer = BeanDefinitionBuilder.genericBeanDefinition(BindConnectionInitializer.class); + } + initializer.addPropertyValue("bindDn", element.getAttribute("bindDn")); + setIfPresent(element, "bindCredential", initializer); + return initializer; + } + + + /** + * Creates a X509 credential config. + * + * @param builder bean definition builder to set properties on, may be null + * @param element containing configuration + * + * @return x509 credential config bean definition builder + */ + protected BeanDefinitionBuilder parseX509CredentialConfig(final BeanDefinitionBuilder builder, final Element element) + { + BeanDefinitionBuilder credentialConfig = builder; + if (credentialConfig == null) { + credentialConfig = BeanDefinitionBuilder.genericBeanDefinition(X509CredentialConfig.class); + } + setIfPresent(element, "trustCertificates", credentialConfig); + setIfPresent(element, "authenticationCertificate", credentialConfig); + setIfPresent(element, "authenticationKey", credentialConfig); + return credentialConfig; + } + + + /** + * Creates a keystore credential config. + * + * @param builder bean definition builder to set properties on, may be null + * @param element containing configuration + * + * @return keystore credential config bean definition builder + */ + protected BeanDefinitionBuilder parseKeyStoreCredentialConfig( + final BeanDefinitionBuilder builder, + final Element element) + { + BeanDefinitionBuilder credentialConfig = builder; + if (credentialConfig == null) { + credentialConfig = BeanDefinitionBuilder.genericBeanDefinition(KeyStoreCredentialConfig.class); + } + setIfPresent(element, "trustStore", credentialConfig); + setIfPresent(element, "trustStorePassword", credentialConfig); + setIfPresent(element, "trustStoreType", credentialConfig); + setIfPresent(element, "trustStoreAliases", credentialConfig); + setIfPresent(element, "keyStore", credentialConfig); + setIfPresent(element, "keyStorePassword", credentialConfig); + setIfPresent(element, "keyStoreType", credentialConfig); + setIfPresent(element, "keyStoreAliases", credentialConfig); + return credentialConfig; + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractConnectionFactoryBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractConnectionFactoryBeanDefinitionParser.java new file mode 100644 index 0000000..1870f71 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractConnectionFactoryBeanDefinitionParser.java
@@ -0,0 +1,56 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.DefaultConnectionFactory; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.w3c.dom.Element; + +/** + * Common implementation for all connection factories. + * + * @author Middleware Services + */ +public abstract class AbstractConnectionFactoryBeanDefinitionParser extends AbstractConnectionConfigBeanDefinitionParser +{ + + + /** + * Creates a default connection factory. + * + * @param builder bean definition builder to set properties on, may be null + * @param element containing configuration + * @param includeConnectionInitializer whether to include a connection initializer + * + * @return default connection factory bean definition builder + */ + protected BeanDefinitionBuilder parseDefaultConnectionFactory( + final BeanDefinitionBuilder builder, + final Element element, + final boolean includeConnectionInitializer) + { + BeanDefinitionBuilder factory = builder; + if (factory == null) { + factory = BeanDefinitionBuilder.genericBeanDefinition(DefaultConnectionFactory.class); + } + factory.addPropertyValue( + "connectionConfig", + parseConnectionConfig(null, element, includeConnectionInitializer).getBeanDefinition()); + if (element.hasAttribute("provider")) { + factory.addPropertyValue("provider", parseProvider(element).getBeanDefinition()); + } + return factory; + } + + + /** + * Creates a provider. + * + * @param element containing configuration + * + * @return provider bean definition builder + */ + protected BeanDefinitionBuilder parseProvider(final Element element) + { + return BeanDefinitionBuilder.genericBeanDefinition(element.getAttribute("provider")); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractConnectionPoolBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractConnectionPoolBeanDefinitionParser.java new file mode 100644 index 0000000..c133214 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractConnectionPoolBeanDefinitionParser.java
@@ -0,0 +1,101 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.pool.BlockingConnectionPool; +import org.ldaptive.pool.IdlePruneStrategy; +import org.ldaptive.pool.PoolConfig; +import org.ldaptive.pool.SearchValidator; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.w3c.dom.Element; + +/** + * Common implementation for all pooled connection factories. + * + * @author Middleware Services + */ +public abstract class AbstractConnectionPoolBeanDefinitionParser extends AbstractConnectionFactoryBeanDefinitionParser +{ + + + /** + * Creates a blocking connection pool. + * + * @param builder bean definition builder to set properties on, may be null + * @param name of the connection pool + * @param element containing configuration + * @param includeConnectionInitializer whether to include a connection initializer + * + * @return blocking connection pool bean definition builder + */ + protected BeanDefinitionBuilder parseConnectionPool( + final BeanDefinitionBuilder builder, + final String name, + final Element element, + final boolean includeConnectionInitializer) + { + BeanDefinitionBuilder pool = builder; + if (pool == null) { + pool = BeanDefinitionBuilder.genericBeanDefinition(BlockingConnectionPool.class); + } + pool.addPropertyValue("name", name); + pool.addPropertyValue( + "connectionFactory", + parseDefaultConnectionFactory(null, element, includeConnectionInitializer).getBeanDefinition()); + pool.addPropertyValue("poolConfig", parsePoolConfig(null, element).getBeanDefinition()); + + final BeanDefinitionBuilder blockWaitTime = BeanDefinitionBuilder.rootBeanDefinition( + AbstractAuthenticatorBeanDefinitionParser.class, + "parseDuration"); + blockWaitTime.addConstructorArgValue(element.getAttribute("blockWaitTime")); + pool.addPropertyValue("blockWaitTime", blockWaitTime.getBeanDefinition()); + + + pool.addPropertyValue("failFastInitialize", element.getAttribute("failFastInitialize")); + final BeanDefinitionBuilder pruneStrategy = BeanDefinitionBuilder.genericBeanDefinition(IdlePruneStrategy.class); + final BeanDefinitionBuilder prunePeriod = BeanDefinitionBuilder.rootBeanDefinition( + AbstractAuthenticatorBeanDefinitionParser.class, + "parseDuration"); + prunePeriod.addConstructorArgValue(element.getAttribute("prunePeriod")); + final BeanDefinitionBuilder idleTime = BeanDefinitionBuilder.rootBeanDefinition( + AbstractAuthenticatorBeanDefinitionParser.class, + "parseDuration"); + idleTime.addConstructorArgValue(element.getAttribute("idleTime")); + pruneStrategy.addPropertyValue("prunePeriod", prunePeriod.getBeanDefinition()); + pruneStrategy.addPropertyValue("idleTime", idleTime.getBeanDefinition()); + pool.addPropertyValue("pruneStrategy", pruneStrategy.getBeanDefinition()); + pool.addPropertyValue("validator", new SearchValidator()); + if (element.hasAttribute("ldapUrl")) { + pool.setInitMethodName("initialize"); + } else { + logger.info("No ldapUrl attribute found for element {}, pool not initialized.", name); + } + return pool; + } + + + /** + * Creates a pool config. + * + * @param builder bean definition builder to set properties on, may be null + * @param element containing configuration + * + * @return pool config bean definition builder + */ + protected BeanDefinitionBuilder parsePoolConfig(final BeanDefinitionBuilder builder, final Element element) + { + BeanDefinitionBuilder poolConfig = builder; + if (poolConfig == null) { + poolConfig = BeanDefinitionBuilder.genericBeanDefinition(PoolConfig.class); + } + poolConfig.addPropertyValue("minPoolSize", element.getAttribute("minPoolSize")); + poolConfig.addPropertyValue("maxPoolSize", element.getAttribute("maxPoolSize")); + poolConfig.addPropertyValue("validateOnCheckOut", element.getAttribute("validateOnCheckOut")); + poolConfig.addPropertyValue("validatePeriodically", element.getAttribute("validatePeriodically")); + final BeanDefinitionBuilder validatePeriod = BeanDefinitionBuilder.rootBeanDefinition( + AbstractAuthenticatorBeanDefinitionParser.class, + "parseDuration"); + validatePeriod.addConstructorArgValue(element.getAttribute("validatePeriod")); + poolConfig.addPropertyValue("validatePeriod", validatePeriod.getBeanDefinition()); + return poolConfig; + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractSearchAuthenticatorBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractSearchAuthenticatorBeanDefinitionParser.java new file mode 100644 index 0000000..d8ac534 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/AbstractSearchAuthenticatorBeanDefinitionParser.java
@@ -0,0 +1,127 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.auth.PooledSearchDnResolver; +import org.ldaptive.auth.SearchDnResolver; +import org.ldaptive.auth.SearchEntryResolver; +import org.ldaptive.pool.PooledConnectionFactory; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.w3c.dom.Element; + +/** + * Common implementation for search based authenticators. + * + * @author Middleware Services + */ +public abstract class AbstractSearchAuthenticatorBeanDefinitionParser extends AbstractAuthenticatorBeanDefinitionParser +{ + + + @Override + protected void doParse(final Element element, final ParserContext context, final BeanDefinitionBuilder builder) + { + String name = "search-pool"; + if (element.hasAttribute("id")) { + name = element.getAttribute("id") + "-search-pool"; + } + + BeanDefinitionBuilder connectionFactory; + BeanDefinitionBuilder dnResolver; + if (element.getAttribute("disablePooling") != null && Boolean.valueOf(element.getAttribute("disablePooling"))) { + connectionFactory = parseDefaultConnectionFactory(null, element, true); + dnResolver = parseDnResolver( + BeanDefinitionBuilder.genericBeanDefinition(SearchDnResolver.class), + element, + connectionFactory); + } else { + connectionFactory = parsePooledConnectionFactory(null, name, element, true); + dnResolver = parseDnResolver(null, element, connectionFactory); + } + + final BeanDefinitionBuilder authHandler = parseAuthHandler(element); + final BeanDefinitionBuilder authResponseHandler = parseAuthResponseHandler(builder, authHandler, element); + if (authResponseHandler != null) { + builder.addPropertyValue("authenticationResponseHandlers", authResponseHandler.getBeanDefinition()); + } + + builder.addConstructorArgValue(dnResolver.getBeanDefinition()); + builder.addConstructorArgValue(authHandler.getBeanDefinition()); + + final BeanDefinitionBuilder entryResolver = parseEntryResolver(element, connectionFactory); + builder.addPropertyValue("entryResolver", entryResolver.getBeanDefinition()); + + setIfPresent(element, "returnAttributes", builder); + builder.addPropertyValue("resolveEntryOnFailure", element.getAttribute("resolveEntryOnFailure")); + } + + + /** + * Creates a DN resolver. + * + * @param builder bean definition builder to set properties on, may be null + * @param element containing configuration + * @param connectionFactory to use for DN resolution + * + * @return pooled search dn resolver bean definition builder + */ + protected BeanDefinitionBuilder parseDnResolver( + final BeanDefinitionBuilder builder, + final Element element, + final BeanDefinitionBuilder connectionFactory) + { + BeanDefinitionBuilder dnResolver = builder; + if (dnResolver == null) { + dnResolver = BeanDefinitionBuilder.genericBeanDefinition(PooledSearchDnResolver.class); + } + dnResolver.addPropertyValue("baseDn", element.getAttribute("baseDn")); + dnResolver.addPropertyValue("subtreeSearch", element.getAttribute("subtreeSearch")); + dnResolver.addPropertyValue("userFilter", element.getAttribute("userFilter")); + dnResolver.addPropertyValue("allowMultipleDns", element.getAttribute("allowMultipleDns")); + dnResolver.addPropertyValue("connectionFactory", connectionFactory.getBeanDefinition()); + return dnResolver; + } + + + /** + * Creates an entry resolver. + * + * @param element containing configuration + * @param connectionFactory that was used for DN resolution + * + * @return search entry resolver bean definition builder + */ + protected BeanDefinitionBuilder parseEntryResolver( + final Element element, + final BeanDefinitionBuilder connectionFactory) + { + return BeanDefinitionBuilder.genericBeanDefinition(SearchEntryResolver.class); + } + + + /** + * Creates a pooled connection factory. + * + * @param builder bean definition builder to set properties on, may be null + * @param name of the connection pool + * @param element containing configuration + * @param includeConnectionInitializer whether to include a connection initializer + * + * @return pooled connection factory bean definition builder + */ + protected BeanDefinitionBuilder parsePooledConnectionFactory( + final BeanDefinitionBuilder builder, + final String name, + final Element element, + final boolean includeConnectionInitializer) + { + BeanDefinitionBuilder connectionFactory = builder; + if (connectionFactory == null) { + connectionFactory = BeanDefinitionBuilder.genericBeanDefinition(PooledConnectionFactory.class); + } + connectionFactory.addPropertyValue( + "connectionPool", + parseConnectionPool(null, name, element, includeConnectionInitializer).getBeanDefinition()); + return connectionFactory; + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/AggregateAuthenticatorBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/AggregateAuthenticatorBeanDefinitionParser.java new file mode 100644 index 0000000..2eed510 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/AggregateAuthenticatorBeanDefinitionParser.java
@@ -0,0 +1,225 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.ldaptive.auth.AggregateDnResolver; +import org.ldaptive.auth.AuthenticationHandler; +import org.ldaptive.auth.AuthenticationResponseHandler; +import org.ldaptive.auth.Authenticator; +import org.ldaptive.auth.DnResolver; +import org.ldaptive.auth.EntryResolver; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.ManagedList; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Parser for <pre>aggregate-authenticator</pre> elements. + * + * @author Middleware Services + */ +public class AggregateAuthenticatorBeanDefinitionParser + extends org.springframework.beans.factory.xml.AbstractBeanDefinitionParser +{ + + + @Override + protected String resolveId( + final Element element, + // CheckStyle:IllegalTypeCheck OFF + final AbstractBeanDefinition definition, + // CheckStyle:IllegalTypeCheck ON + final ParserContext parserContext) + throws BeanDefinitionStoreException + { + final String idAttrValue = element.getAttribute("id"); + return StringUtils.hasText(idAttrValue) ? idAttrValue : "aggregate-authenticator"; + } + + + @Override + protected AbstractBeanDefinition parseInternal(final Element element, final ParserContext context) + { + final BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition( + AggregateAuthenticatorFactoryBean.class); + final ManagedList<BeanDefinition> authenticators = new ManagedList<>(); + for (Node child = element.getFirstChild(); child != null; child = child.getNextSibling()) { + BeanDefinitionParser parser = null; + if (child instanceof Element) { + switch (child.getLocalName()) { + + case "anonymous-search-authenticator": + parser = new AnonSearchAuthenticatorBeanDefinitionParser(); + break; + + case "bind-search-authenticator": + parser = new BindSearchAuthenticatorBeanDefinitionParser(); + break; + + case "sasl-bind-search-authenticator": + parser = new SaslBindSearchAuthenticatorBeanDefinitionParser(); + break; + + case "direct-authenticator": + parser = new DirectAuthenticatorBeanDefinitionParser(); + break; + + case "ad-authenticator": + parser = new ADAuthenticatorBeanDefinitionParser(); + break; + + default: + throw new IllegalArgumentException("Unknown authenticator type: " + child.getLocalName()); + } + } + if (parser != null) { + authenticators.add(parser.parse((Element) child, context)); + } + } + + factory.addPropertyValue("authenticators", authenticators); + factory.addPropertyValue("allowMultipleDns", element.getAttribute("allowMultipleDns")); + if (element.hasAttribute("returnAttributes")) { + factory.addPropertyValue("returnAttributes", element.getAttribute("returnAttributes")); + } + factory.addPropertyValue("resolveEntryOnFailure", element.getAttribute("resolveEntryOnFailure")); + return factory.getBeanDefinition(); + } + + + /** + * Factory bean that creates an authenticator with an {@link AggregateDnResolver}. + */ + protected static class AggregateAuthenticatorFactoryBean implements FactoryBean<Authenticator> + { + + /** Authenticators to aggregate. */ + private List<Authenticator> authenticators; + + /** Value for {@link AggregateDnResolver#allowMultipleDns}. */ + private boolean allowMultipleDns; + + /** Value for {@link Authenticator#returnAttributes}. */ + private String[] returnAttributes; + + /** Value of {@link Authenticator#resolveEntryOnFailure}. */ + private boolean resolveEntryOnFailure; + + + /** + * Sets the authenticators to aggregate. + * + * @param auths authenticators to aggregate + */ + public void setAuthenticators(final List<Authenticator> auths) + { + authenticators = auths; + } + + + /** + * Sets whether the aggrgate authenticator will allow multiple DNs. + * + * @param b whether multiple DNs are allowed + */ + public void setAllowMultipleDns(final boolean b) + { + allowMultipleDns = b; + } + + + /** + * Sets the return attributes. + * + * @param attrs return attributes + */ + public void setReturnAttributes(final String... attrs) + { + returnAttributes = attrs; + } + + + /** + * Sets whether to execute the entry resolver on authentication failure. + * + * @param b whether to execute the entry resolver + */ + public void setResolveEntryOnFailure(final boolean b) + { + resolveEntryOnFailure = b; + } + + + @Override + public Authenticator getObject() throws Exception + { + final Authenticator aggregateAuth = new Authenticator(); + final Map<String, DnResolver> dnResolvers = new HashMap<>(); + final Map<String, AuthenticationHandler> authHandlers = new HashMap<>(); + final Map<String, EntryResolver> entryResolvers = new HashMap<>(); + final Map<String, AuthenticationResponseHandler[]> responseHandlers = new HashMap<>(); + + int count = 0; + for (Authenticator auth : authenticators) { + final String id = String.format("%s-%s", auth.hashCode(), String.valueOf(count++)); + dnResolvers.put(id, auth.getDnResolver()); + authHandlers.put(id, auth.getAuthenticationHandler()); + if (auth.getEntryResolver() != null) { + entryResolvers.put(id, auth.getEntryResolver()); + } + if (auth.getAuthenticationResponseHandlers() != null) { + responseHandlers.put(id, auth.getAuthenticationResponseHandlers()); + } + } + + final AggregateDnResolver dnResolver = new AggregateDnResolver(); + dnResolver.setAllowMultipleDns(allowMultipleDns); + dnResolver.setDnResolvers(dnResolvers); + aggregateAuth.setDnResolver(dnResolver); + + final AggregateDnResolver.AuthenticationHandler authHandler = new AggregateDnResolver.AuthenticationHandler(); + authHandler.setAuthenticationHandlers(authHandlers); + aggregateAuth.setAuthenticationHandler(authHandler); + + if (!entryResolvers.isEmpty()) { + final AggregateDnResolver.EntryResolver entryResolver = new AggregateDnResolver.EntryResolver(); + entryResolver.setEntryResolvers(entryResolvers); + aggregateAuth.setEntryResolver(entryResolver); + } + + if (!responseHandlers.isEmpty()) { + final AggregateDnResolver.AuthenticationResponseHandler responseHandler = + new AggregateDnResolver.AuthenticationResponseHandler(); + responseHandler.setAuthenticationResponseHandlers(responseHandlers); + aggregateAuth.setAuthenticationResponseHandlers(responseHandler); + } + + aggregateAuth.setReturnAttributes(returnAttributes); + aggregateAuth.setResolveEntryOnFailure(resolveEntryOnFailure); + return aggregateAuth; + } + + + @Override + public Class<Authenticator> getObjectType() + { + return Authenticator.class; + } + + + @Override + public boolean isSingleton() + { + return true; + } + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/AggregatePooledSearchExecutorBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/AggregatePooledSearchExecutorBeanDefinitionParser.java new file mode 100644 index 0000000..5c8f983 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/AggregatePooledSearchExecutorBeanDefinitionParser.java
@@ -0,0 +1,50 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.concurrent.AggregatePooledSearchExecutor; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <pre>aggregate-pooled-search-executor</pre> elements. + * + * @author Middleware Services + */ +public class AggregatePooledSearchExecutorBeanDefinitionParser extends SearchExecutorBeanDefinitionParser +{ + + + @Override + protected String resolveId( + final Element element, + // CheckStyle:IllegalTypeCheck OFF + final AbstractBeanDefinition definition, + // CheckStyle:IllegalTypeCheck ON + final ParserContext parserContext) + throws BeanDefinitionStoreException + { + final String idAttrValue = element.getAttribute("id"); + return StringUtils.hasText(idAttrValue) ? idAttrValue : "aggregate-pooled-search-executor"; + } + + + @Override + protected Class<?> getBeanClass(final Element element) + { + return AggregatePooledSearchExecutor.class; + } + + + @Override + protected void doParse( + final Element element, + final ParserContext context, + final BeanDefinitionBuilder builder) + { + super.doParse(element, context, builder); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/AggregateSearchExecutorBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/AggregateSearchExecutorBeanDefinitionParser.java new file mode 100644 index 0000000..bbfaa26 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/AggregateSearchExecutorBeanDefinitionParser.java
@@ -0,0 +1,50 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.concurrent.AggregateSearchExecutor; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <pre>aggregate-search-executor</pre> elements. + * + * @author Middleware Services + */ +public class AggregateSearchExecutorBeanDefinitionParser extends SearchExecutorBeanDefinitionParser +{ + + + @Override + protected String resolveId( + final Element element, + // CheckStyle:IllegalTypeCheck OFF + final AbstractBeanDefinition definition, + // CheckStyle:IllegalTypeCheck ON + final ParserContext parserContext) + throws BeanDefinitionStoreException + { + final String idAttrValue = element.getAttribute("id"); + return StringUtils.hasText(idAttrValue) ? idAttrValue : "aggregate-search-executor"; + } + + + @Override + protected Class<?> getBeanClass(final Element element) + { + return AggregateSearchExecutor.class; + } + + + @Override + protected void doParse( + final Element element, + final ParserContext context, + final BeanDefinitionBuilder builder) + { + super.doParse(element, context, builder); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/AnonSearchAuthenticatorBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/AnonSearchAuthenticatorBeanDefinitionParser.java new file mode 100644 index 0000000..4a9b439 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/AnonSearchAuthenticatorBeanDefinitionParser.java
@@ -0,0 +1,31 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <pre>anonymous-search-authenticator</pre> elements. + * + * @author Middleware Services + */ +public class AnonSearchAuthenticatorBeanDefinitionParser extends AbstractSearchAuthenticatorBeanDefinitionParser +{ + + + @Override + protected String resolveId( + final Element element, + // CheckStyle:IllegalTypeCheck OFF + final AbstractBeanDefinition definition, + // CheckStyle:IllegalTypeCheck ON + final ParserContext parserContext) + throws BeanDefinitionStoreException + { + final String idAttrValue = element.getAttribute("id"); + return StringUtils.hasText(idAttrValue) ? idAttrValue : "anonymous-search-authenticator"; + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/BindSearchAuthenticatorBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/BindSearchAuthenticatorBeanDefinitionParser.java new file mode 100644 index 0000000..754a754 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/BindSearchAuthenticatorBeanDefinitionParser.java
@@ -0,0 +1,55 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.auth.PooledSearchEntryResolver; +import org.ldaptive.auth.SearchEntryResolver; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <pre>bind-search-authenticator</pre> elements. + * + * @author Middleware Services + */ +public class BindSearchAuthenticatorBeanDefinitionParser extends AbstractSearchAuthenticatorBeanDefinitionParser +{ + + + @Override + protected String resolveId( + final Element element, + // CheckStyle:IllegalTypeCheck OFF + final AbstractBeanDefinition definition, + // CheckStyle:IllegalTypeCheck ON + final ParserContext parserContext) + throws BeanDefinitionStoreException + { + final String idAttrValue = element.getAttribute("id"); + return StringUtils.hasText(idAttrValue) ? idAttrValue : "bind-search-authenticator"; + } + + + @Override + protected BeanDefinitionBuilder parseEntryResolver( + final Element element, + final BeanDefinitionBuilder connectionFactory) + { + BeanDefinitionBuilder entryResolver; + if (element.hasAttribute("resolveEntryWithBindCredentials") && + Boolean.valueOf(element.getAttribute("resolveEntryWithBindCredentials"))) { + if (element.getAttribute("disablePooling") != null && Boolean.valueOf(element.getAttribute("disablePooling"))) { + entryResolver = BeanDefinitionBuilder.genericBeanDefinition(SearchEntryResolver.class); + } else { + entryResolver = BeanDefinitionBuilder.genericBeanDefinition(PooledSearchEntryResolver.class); + } + entryResolver.addPropertyValue("connectionFactory", connectionFactory.getBeanDefinition()); + } else { + entryResolver = super.parseEntryResolver(element, connectionFactory); + } + return entryResolver; + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/ConnectionConfigBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/ConnectionConfigBeanDefinitionParser.java new file mode 100644 index 0000000..0513d2b --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/ConnectionConfigBeanDefinitionParser.java
@@ -0,0 +1,50 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.ConnectionConfig; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <pre>connection-config</pre> elements. + * + * @author Middleware Services + */ +public class ConnectionConfigBeanDefinitionParser extends AbstractConnectionConfigBeanDefinitionParser +{ + + + @Override + protected String resolveId( + final Element element, + // CheckStyle:IllegalTypeCheck OFF + final AbstractBeanDefinition definition, + // CheckStyle:IllegalTypeCheck ON + final ParserContext parserContext) + throws BeanDefinitionStoreException + { + final String idAttrValue = element.getAttribute("id"); + return StringUtils.hasText(idAttrValue) ? idAttrValue : "connection-config"; + } + + + @Override + protected Class<?> getBeanClass(final Element element) + { + return ConnectionConfig.class; + } + + + @Override + protected void doParse( + final Element element, + final ParserContext context, + final BeanDefinitionBuilder builder) + { + parseConnectionConfig(builder, element, true); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/ConnectionFactoryBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/ConnectionFactoryBeanDefinitionParser.java new file mode 100644 index 0000000..93943bb --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/ConnectionFactoryBeanDefinitionParser.java
@@ -0,0 +1,47 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.DefaultConnectionFactory; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <pre>connection-factory</pre> elements. + * + * @author Middleware Services + */ +public class ConnectionFactoryBeanDefinitionParser extends AbstractConnectionFactoryBeanDefinitionParser +{ + + + @Override + protected String resolveId( + final Element element, + // CheckStyle:IllegalTypeCheck OFF + final AbstractBeanDefinition definition, + // CheckStyle:IllegalTypeCheck ON + final ParserContext parserContext) + throws BeanDefinitionStoreException + { + final String idAttrValue = element.getAttribute("id"); + return StringUtils.hasText(idAttrValue) ? idAttrValue : "connection-factory"; + } + + + @Override + protected Class<?> getBeanClass(final Element element) + { + return DefaultConnectionFactory.class; + } + + + @Override + protected void doParse(final Element element, final ParserContext context, final BeanDefinitionBuilder builder) + { + parseDefaultConnectionFactory(builder, element, true); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/ConnectionPoolBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/ConnectionPoolBeanDefinitionParser.java new file mode 100644 index 0000000..4cbc163 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/ConnectionPoolBeanDefinitionParser.java
@@ -0,0 +1,52 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.pool.BlockingConnectionPool; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <pre>connection-pool</pre> elements. + * + * @author Middleware Services + */ +public class ConnectionPoolBeanDefinitionParser extends AbstractConnectionPoolBeanDefinitionParser +{ + + + @Override + protected String resolveId( + final Element element, + // CheckStyle:IllegalTypeCheck OFF + final AbstractBeanDefinition definition, + // CheckStyle:IllegalTypeCheck ON + final ParserContext parserContext) + throws BeanDefinitionStoreException + { + final String idAttrValue = element.getAttribute("id"); + return StringUtils.hasText(idAttrValue) ? idAttrValue : "connection-pool"; + } + + + @Override + protected Class<?> getBeanClass(final Element element) + { + return BlockingConnectionPool.class; + } + + + @Override + protected void doParse( + final Element element, final ParserContext context, final BeanDefinitionBuilder builder) + { + String name = "connection-pool"; + if (element.hasAttribute("id")) { + name = element.getAttribute("id") + "-connection-pool"; + } + parseConnectionPool(builder, name, element, true).getBeanDefinition(); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/DirectAuthenticatorBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/DirectAuthenticatorBeanDefinitionParser.java new file mode 100644 index 0000000..6978a0d --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/DirectAuthenticatorBeanDefinitionParser.java
@@ -0,0 +1,49 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.auth.FormatDnResolver; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <pre>direct-authenticator</pre> elements. + * + * @author Middleware Services + */ +public class DirectAuthenticatorBeanDefinitionParser extends AbstractAuthenticatorBeanDefinitionParser +{ + + + @Override + protected String resolveId( + final Element element, + // CheckStyle:IllegalTypeCheck OFF + final AbstractBeanDefinition definition, + // CheckStyle:IllegalTypeCheck ON + final ParserContext parserContext) + throws BeanDefinitionStoreException + { + final String idAttrValue = element.getAttribute("id"); + return StringUtils.hasText(idAttrValue) ? idAttrValue : "direct-authenticator"; + } + + + @Override + protected void doParse( + final Element element, final ParserContext context, final BeanDefinitionBuilder builder) + { + final BeanDefinitionBuilder authHandler = parseAuthHandler(element); + final BeanDefinitionBuilder authResponseHandler = parseAuthResponseHandler(builder, authHandler, element); + if (authResponseHandler != null) { + builder.addPropertyValue("authenticationResponseHandlers", authResponseHandler.getBeanDefinition()); + } + final BeanDefinitionBuilder dnResolver = BeanDefinitionBuilder.genericBeanDefinition(FormatDnResolver.class); + dnResolver.addConstructorArgValue(element.getAttribute("format")); + builder.addConstructorArgValue(dnResolver.getBeanDefinition()); + builder.addConstructorArgValue(authHandler.getBeanDefinition()); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/ParallelPooledSearchExecutorBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/ParallelPooledSearchExecutorBeanDefinitionParser.java new file mode 100644 index 0000000..9a50b1d --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/ParallelPooledSearchExecutorBeanDefinitionParser.java
@@ -0,0 +1,50 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.concurrent.ParallelPooledSearchExecutor; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <pre>parallel-pooled-search-executor</pre> elements. + * + * @author Middleware Services + */ +public class ParallelPooledSearchExecutorBeanDefinitionParser extends SearchExecutorBeanDefinitionParser +{ + + + @Override + protected String resolveId( + final Element element, + // CheckStyle:IllegalTypeCheck OFF + final AbstractBeanDefinition definition, + // CheckStyle:IllegalTypeCheck ON + final ParserContext parserContext) + throws BeanDefinitionStoreException + { + final String idAttrValue = element.getAttribute("id"); + return StringUtils.hasText(idAttrValue) ? idAttrValue : "parallel-pooled-search-executor"; + } + + + @Override + protected Class<?> getBeanClass(final Element element) + { + return ParallelPooledSearchExecutor.class; + } + + + @Override + protected void doParse( + final Element element, + final ParserContext context, + final BeanDefinitionBuilder builder) + { + super.doParse(element, context, builder); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/ParallelSearchExecutorBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/ParallelSearchExecutorBeanDefinitionParser.java new file mode 100644 index 0000000..0a61d03 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/ParallelSearchExecutorBeanDefinitionParser.java
@@ -0,0 +1,50 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.concurrent.ParallelSearchExecutor; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <pre>parallel-search-executor</pre> elements. + * + * @author Middleware Services + */ +public class ParallelSearchExecutorBeanDefinitionParser extends SearchExecutorBeanDefinitionParser +{ + + + @Override + protected String resolveId( + final Element element, + // CheckStyle:IllegalTypeCheck OFF + final AbstractBeanDefinition definition, + // CheckStyle:IllegalTypeCheck ON + final ParserContext parserContext) + throws BeanDefinitionStoreException + { + final String idAttrValue = element.getAttribute("id"); + return StringUtils.hasText(idAttrValue) ? idAttrValue : "parallel-search-executor"; + } + + + @Override + protected Class<?> getBeanClass(final Element element) + { + return ParallelSearchExecutor.class; + } + + + @Override + protected void doParse( + final Element element, + final ParserContext context, + final BeanDefinitionBuilder builder) + { + super.doParse(element, context, builder); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/PooledConnectionFactoryBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/PooledConnectionFactoryBeanDefinitionParser.java new file mode 100644 index 0000000..af6c79c --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/PooledConnectionFactoryBeanDefinitionParser.java
@@ -0,0 +1,54 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.pool.PooledConnectionFactory; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <pre>pooled-connection-factory</pre> elements. + * + * @author Middleware Services + */ +public class PooledConnectionFactoryBeanDefinitionParser extends AbstractConnectionPoolBeanDefinitionParser +{ + + + @Override + protected String resolveId( + final Element element, + // CheckStyle:IllegalTypeCheck OFF + final AbstractBeanDefinition definition, + // CheckStyle:IllegalTypeCheck ON + final ParserContext parserContext) + throws BeanDefinitionStoreException + { + final String idAttrValue = element.getAttribute("id"); + return StringUtils.hasText(idAttrValue) ? idAttrValue : "pooled-connection-factory"; + } + + + @Override + protected Class<?> getBeanClass(final Element element) + { + return PooledConnectionFactory.class; + } + + + @Override + protected void doParse( + final Element element, + final ParserContext context, + final BeanDefinitionBuilder builder) + { + String name = "connection-pool"; + if (element.hasAttribute("id")) { + name = element.getAttribute("id") + "-connection-pool"; + } + builder.addPropertyValue("connectionPool", parseConnectionPool(null, name, element, true).getBeanDefinition()); + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/SaslBindSearchAuthenticatorBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/SaslBindSearchAuthenticatorBeanDefinitionParser.java new file mode 100644 index 0000000..d78ff0e --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/SaslBindSearchAuthenticatorBeanDefinitionParser.java
@@ -0,0 +1,110 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.sasl.CramMd5Config; +import org.ldaptive.sasl.DigestMd5Config; +import org.ldaptive.sasl.ExternalConfig; +import org.ldaptive.sasl.GssApiConfig; +import org.ldaptive.sasl.SaslConfig; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <pre>sasl-bind-search-authenticator</pre> elements. + * + * @author Middleware Services + */ +public class SaslBindSearchAuthenticatorBeanDefinitionParser extends AbstractSearchAuthenticatorBeanDefinitionParser +{ + + + @Override + protected String resolveId( + final Element element, + // CheckStyle:IllegalTypeCheck OFF + final AbstractBeanDefinition definition, + // CheckStyle:IllegalTypeCheck ON + final ParserContext parserContext) throws BeanDefinitionStoreException + { + final String idAttrValue = element.getAttribute("id"); + return StringUtils.hasText(idAttrValue) ? idAttrValue : "sasl-bind-search-authenticator"; + } + + + /** + * Creates a bind connection initializer. + * + * @param builder bean definition builder to set properties on, may be null + * @param element containing configuration + * + * @return bind connection initializer bean definition + */ + @Override + protected BeanDefinitionBuilder parseConnectionInitializer(final BeanDefinitionBuilder builder, final Element element) + { + final BeanDefinitionBuilder initializer = super.parseConnectionInitializer(builder, element); + initializer.addPropertyValue("bindSaslConfig", parseSaslConfig(element).getBeanDefinition()); + return initializer; + } + + + /** + * Creates a sasl config. + * + * @param element containing configuration + * + * @return sasl config bean definition builder + */ + protected BeanDefinitionBuilder parseSaslConfig(final Element element) + { + final BeanDefinitionBuilder saslConfig = BeanDefinitionBuilder.rootBeanDefinition( + SaslBindSearchAuthenticatorBeanDefinitionParser.class, + "parseSaslConfig"); + saslConfig.addConstructorArgValue(element.getAttribute("mechanism")); + setIfPresent(element, "realm", saslConfig); + setIfPresent(element, "authorizationId", saslConfig); + setIfPresent(element, "mutualAuthentication", saslConfig); + setIfPresent(element, "qualityOfProtection", saslConfig); + setIfPresent(element, "securityStrength", saslConfig); + return saslConfig; + } + + + /** + * Returns a {@link SaslConfig} for the supplied value. + * + * @param value to parse + * + * @return mechanism + */ + protected static SaslConfig parseSaslConfig(final String value) + { + SaslConfig saslConfig; + switch (value) { + + case "DIGEST_MD5": + saslConfig = new DigestMd5Config(); + break; + + case "CRAM_MD5": + saslConfig = new CramMd5Config(); + break; + + case "EXTERNAL": + saslConfig = new ExternalConfig(); + break; + + case "GSSAPI": + saslConfig = new GssApiConfig(); + break; + + default: + throw new IllegalArgumentException("Unknown SASL mechanism " + value); + } + return saslConfig; + } +}
diff --git a/beans/src/main/java/org/ldaptive/beans/spring/parser/SearchExecutorBeanDefinitionParser.java b/beans/src/main/java/org/ldaptive/beans/spring/parser/SearchExecutorBeanDefinitionParser.java new file mode 100644 index 0000000..e03a882 --- /dev/null +++ b/beans/src/main/java/org/ldaptive/beans/spring/parser/SearchExecutorBeanDefinitionParser.java
@@ -0,0 +1,68 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring.parser; + +import org.ldaptive.SearchExecutor; +import org.ldaptive.SearchFilter; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <pre>search-executor</pre> elements. + * + * @author Middleware Services + */ +public class SearchExecutorBeanDefinitionParser extends AbstractBeanDefinitionParser +{ + + + @Override + protected String resolveId( + final Element element, + // CheckStyle:IllegalTypeCheck OFF + final AbstractBeanDefinition definition, + // CheckStyle:IllegalTypeCheck ON + final ParserContext parserContext) + throws BeanDefinitionStoreException + { + final String idAttrValue = element.getAttribute("id"); + return StringUtils.hasText(idAttrValue) ? idAttrValue : "search-executor"; + } + + + @Override + protected Class<?> getBeanClass(final Element element) + { + return SearchExecutor.class; + } + + + @Override + protected void doParse( + final Element element, + final ParserContext context, + final BeanDefinitionBuilder builder) + { + builder.addPropertyValue("baseDn", element.getAttribute("baseDn")); + if (element.hasAttribute("searchFilter")) { + final BeanDefinitionBuilder filter = BeanDefinitionBuilder.genericBeanDefinition(SearchFilter.class); + filter.addPropertyValue("filter", element.getAttribute("searchFilter")); + builder.addPropertyValue("searchFilter", filter.getBeanDefinition()); + } + setIfPresent(element, "returnAttributes", builder); + builder.addPropertyValue("searchScope", element.getAttribute("searchScope")); + if (element.hasAttribute("timeLimit")) { + final BeanDefinitionBuilder timeLimit = BeanDefinitionBuilder.rootBeanDefinition( + AbstractAuthenticatorBeanDefinitionParser.class, + "parseDuration"); + timeLimit.addConstructorArgValue(element.getAttribute("timeLimit")); + builder.addPropertyValue("timeLimit", timeLimit.getBeanDefinition()); + } + setIfPresent(element, "sizeLimit", builder); + setIfPresent(element, "binaryAttributes", builder); + builder.addPropertyValue("sortBehavior", element.getAttribute("sortBehavior")); + } +}
diff --git a/beans/src/main/resources/META-INF/spring.handlers b/beans/src/main/resources/META-INF/spring.handlers new file mode 100644 index 0000000..d3a0e1f --- /dev/null +++ b/beans/src/main/resources/META-INF/spring.handlers
@@ -0,0 +1 @@ +http\://www.ldaptive.org/schema/spring-ext=org.ldaptive.beans.spring.NamespaceHandler \ No newline at end of file
diff --git a/beans/src/main/resources/META-INF/spring.schemas b/beans/src/main/resources/META-INF/spring.schemas new file mode 100644 index 0000000..f650209 --- /dev/null +++ b/beans/src/main/resources/META-INF/spring.schemas
@@ -0,0 +1 @@ +http\://www.ldaptive.org/schema/spring-ext.xsd=org/ldaptive/beans/spring/spring-ext.xsd \ No newline at end of file
diff --git a/beans/src/main/resources/org/ldaptive/beans/spring/spring-ext.xsd b/beans/src/main/resources/org/ldaptive/beans/spring/spring-ext.xsd new file mode 100644 index 0000000..5bf887e --- /dev/null +++ b/beans/src/main/resources/org/ldaptive/beans/spring/spring-ext.xsd
@@ -0,0 +1,260 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xsd:schema xmlns="http://www.ldaptive.org/schema/spring-ext" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + targetNamespace="http://www.ldaptive.org/schema/spring-ext" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + + <xsd:import namespace="http://www.springframework.org/schema/beans"/> + + <xsd:element name="anonymous-search-authenticator" type="anonymousSearchAuthenticatorType"/> + <xsd:element name="bind-search-authenticator" type="bindSearchAuthenticatorType"/> + <xsd:element name="sasl-bind-search-authenticator" type="saslBindSearchAuthenticatorType"/> + <xsd:element name="direct-authenticator" type="directAuthenticatorType"/> + <xsd:element name="ad-authenticator" type="adAuthenticatorType"/> + <xsd:element name="aggregate-authenticator" type="aggregateAuthenticatorType"/> + <xsd:element name="pooled-connection-factory" type="pooledConnectionFactoryType"/> + <xsd:element name="connection-factory" type="connectionFactoryType"/> + <xsd:element name="connection-pool" type="connectionPoolType"/> + <xsd:element name="connection-config" type="connectionConfigType"/> + <xsd:element name="search-executor" type="searchExecutorType"/> + <xsd:element name="parallel-search-executor" type="searchExecutorType"/> + <xsd:element name="parallel-pooled-search-executor" type="searchExecutorType"/> + <xsd:element name="aggregate-search-executor" type="searchExecutorType"/> + <xsd:element name="aggregate-pooled-search-executor" type="searchExecutorType"/> + + <!-- Authenticator configuration --> + <xsd:complexType name="anonymousSearchAuthenticatorType"> + <xsd:complexContent> + <xsd:extension base="baseSearchAuthenticatorType"> + <xsd:sequence> + <xsd:element name="authentication-response-handler" type="authenticationResponseHandlerType" minOccurs="0" maxOccurs="1"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="bindSearchAuthenticatorType"> + <xsd:complexContent> + <xsd:extension base="baseBindSearchAuthenticatorType"> + <xsd:sequence> + <xsd:element name="authentication-response-handler" type="authenticationResponseHandlerType" minOccurs="0" maxOccurs="1"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="saslBindSearchAuthenticatorType"> + <xsd:complexContent> + <xsd:extension base="baseBindSearchAuthenticatorType"> + <xsd:sequence> + <xsd:element name="authentication-response-handler" type="authenticationResponseHandlerType" minOccurs="0" maxOccurs="1"/> + </xsd:sequence> + <xsd:attribute name="mechanism" type="xsd:string" use="required"/> + <xsd:attribute name="authorizationId" type="xsd:string" use="optional"/> + <xsd:attribute name="mutualAuthentication" type="xsd:string" use="optional"/> + <xsd:attribute name="qualityOfProtection" type="xsd:string" use="optional"/> + <xsd:attribute name="securityStrength" type="xsd:string" use="optional"/> + <xsd:attribute name="realm" type="xsd:string" use="optional"/> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="directAuthenticatorType"> + <xsd:complexContent> + <xsd:extension base="baseAuthenticatorType"> + <xsd:sequence> + <xsd:element name="authentication-response-handler" type="authenticationResponseHandlerType" minOccurs="0" maxOccurs="1"/> + </xsd:sequence> + <xsd:attribute name="format" type="xsd:string" use="required"/> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="adAuthenticatorType"> + <xsd:complexContent> + <xsd:extension base="baseBindSearchAuthenticatorType"> + <xsd:sequence> + <xsd:element name="authentication-response-handler" type="adAuthenticationResponseHandlerType" minOccurs="0" maxOccurs="1"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="aggregateAuthenticatorType"> + <xsd:choice minOccurs="0" maxOccurs="unbounded"> + <xsd:element name="anonymous-search-authenticator" type="anonymousSearchAuthenticatorType"/> + <xsd:element name="bind-search-authenticator" type="bindSearchAuthenticatorType"/> + <xsd:element name="sasl-bind-search-authenticator" type="saslBindSearchAuthenticatorType"/> + <xsd:element name="direct-authenticator" type="directAuthenticatorType"/> + <xsd:element name="ad-authenticator" type="adAuthenticatorType"/> + </xsd:choice> + <xsd:attribute name="returnAttributes" type="xsd:string" use="optional"/> + <xsd:attribute name="allowMultipleDns" type="xsd:string" use="optional" default="false"/> + <xsd:attribute name="resolveEntryOnFailure" type="xsd:string" use="optional" default="false"/> + </xsd:complexType> + + <xsd:complexType name="baseBindSearchAuthenticatorType"> + <xsd:complexContent> + <xsd:extension base="baseSearchAuthenticatorType"> + <xsd:attribute name="bindDn" type="xsd:string" use="required"/> + <xsd:attribute name="bindCredential" type="xsd:string" use="optional"/> + <xsd:attribute name="resolveEntryWithBindCredentials" type="xsd:string" use="optional" default="false"/> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="baseSearchAuthenticatorType"> + <xsd:complexContent> + <xsd:extension base="baseAuthenticatorType"> + <xsd:attribute name="baseDn" type="xsd:string" use="required"/> + <xsd:attribute name="userFilter" type="xsd:string" use="required"/> + <xsd:attribute name="subtreeSearch" type="xsd:string" use="optional" default="false"/> + <xsd:attribute name="returnAttributes" type="xsd:string" use="optional"/> + <xsd:attribute name="allowMultipleDns" type="xsd:string" use="optional" default="false"/> + <xsd:attribute name="resolveEntryOnFailure" type="xsd:string" use="optional" default="false"/> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="baseAuthenticatorType"> + <xsd:attribute name="provider" type="xsd:string" use="optional"/> + <xsd:attribute name="ldapUrl" type="xsd:string" use="required"/> + <xsd:attributeGroup ref="connectionPoolGroup"/> + <xsd:attributeGroup ref="connectionConfigGroup"/> + </xsd:complexType> + + <xsd:complexType name="authenticationResponseHandlerType"> + <xsd:choice> + <xsd:element name="password-policy-handler" type="passwordPolicyAuthenticationResponseHandlerType"/> + <xsd:element name="password-expiration-handler" type="passwordExpirationAuthenticationResponseHandlerType"/> + <xsd:element name="e-directory-handler" type="eDirectoryAuthenticationResponseHandlerType"/> + <xsd:element name="free-ipa-handler" type="freeIPAAuthenticationResponseHandlerType"/> + </xsd:choice> + </xsd:complexType> + + <xsd:complexType name="adAuthenticationResponseHandlerType"> + <xsd:sequence> + <xsd:element name="active-directory-handler" type="activeDirectoryAuthenticationResponseHandlerType"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="eDirectoryAuthenticationResponseHandlerType"> + <xsd:complexContent> + <xsd:extension base="baseAuthenticationResponseHandlerType"> + <xsd:attribute name="warningPeriod" type="xsd:string" use="optional"/> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="freeIPAAuthenticationResponseHandlerType"> + <xsd:complexContent> + <xsd:extension base="baseAuthenticationResponseHandlerType"> + <xsd:attribute name="expirationPeriod" type="xsd:string" use="optional"/> + <xsd:attribute name="warningPeriod" type="xsd:string" use="optional"/> + <xsd:attribute name="maxLoginFailures" type="xsd:string" use="optional"/> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="passwordPolicyAuthenticationResponseHandlerType"> + <xsd:complexContent> + <xsd:extension base="baseAuthenticationResponseHandlerType"> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="passwordExpirationAuthenticationResponseHandlerType"> + <xsd:complexContent> + <xsd:extension base="baseAuthenticationResponseHandlerType"> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="activeDirectoryAuthenticationResponseHandlerType"> + <xsd:complexContent> + <xsd:extension base="baseAuthenticationResponseHandlerType"> + <xsd:attribute name="expirationPeriod" type="xsd:string" use="optional"/> + <xsd:attribute name="warningPeriod" type="xsd:string" use="optional"/> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="baseAuthenticationResponseHandlerType"> + <xsd:attribute name="id" type="xsd:ID" use="optional"/> + </xsd:complexType> + + <!-- Standard ldaptive bean configuration for connection factories, pools, config, search executors --> + <xsd:complexType name="pooledConnectionFactoryType"> + <xsd:complexContent> + <xsd:extension base="connectionPoolType"/> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="connectionPoolType"> + <xsd:complexContent> + <xsd:extension base="connectionFactoryType"> + <xsd:attributeGroup ref="connectionPoolGroup"/> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="connectionFactoryType"> + <xsd:complexContent> + <xsd:extension base="connectionConfigType"> + <xsd:attribute name="provider" type="xsd:string" use="optional"/> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="connectionConfigType"> + <xsd:attribute name="ldapUrl" type="xsd:string" use="optional"/> + <xsd:attribute name="bindDn" type="xsd:string" use="optional"/> + <xsd:attribute name="bindCredential" type="xsd:string" use="optional"/> + <xsd:attributeGroup ref="connectionConfigGroup"/> + </xsd:complexType> + + <xsd:complexType name="searchExecutorType"> + <xsd:attribute name="id" type="xsd:ID" use="optional"/> + <xsd:attribute name="baseDn" type="xsd:string" use="optional" default=""/> + <xsd:attribute name="searchFilter" type="xsd:string" use="optional"/> + <xsd:attribute name="returnAttributes" type="xsd:string" use="optional"/> + <xsd:attribute name="searchScope" type="xsd:string" use="optional" default="SUBTREE"/> + <xsd:attribute name="timeLimit" type="xsd:string" use="optional"/> + <xsd:attribute name="sizeLimit" type="xsd:string" use="optional"/> + <xsd:attribute name="binaryAttributes" type="xsd:string" use="optional"/> + <xsd:attribute name="sortBehavior" type="xsd:string" use="optional" default="UNORDERED"/> + </xsd:complexType> + + <xsd:attributeGroup name="connectionPoolGroup"> + <xsd:attribute name="blockWaitTime" type="xsd:string" use="optional" default="PT3S"/> + <xsd:attribute name="failFastInitialize" type="xsd:string" use="optional" default="false"/> + <xsd:attribute name="minPoolSize" type="xsd:string" use="optional" default="3"/> + <xsd:attribute name="maxPoolSize" type="xsd:string" use="optional" default="10"/> + <xsd:attribute name="validateOnCheckOut" type="xsd:string" use="optional" default="false"/> + <xsd:attribute name="validatePeriodically" type="xsd:string" use="optional" default="true"/> + <xsd:attribute name="validatePeriod" type="xsd:string" use="optional" default="PT5M"/> + <xsd:attribute name="prunePeriod" type="xsd:string" use="optional" default="PT5M"/> + <xsd:attribute name="idleTime" type="xsd:string" use="optional" default="PT10M"/> + <xsd:attribute name="disablePooling" type="xsd:string" use="optional" default="false"/> + </xsd:attributeGroup> + + <!-- Since ldapUrl is optional in some circumstances, it must be specified in the parent type --> + <xsd:attributeGroup name="connectionConfigGroup"> + <xsd:attribute name="id" type="xsd:ID" use="optional"/> + <xsd:attribute name="connectTimeout" type="xsd:string" use="optional" default="PT3S"/> + <xsd:attribute name="useSSL" type="xsd:string" use="optional" default="false"/> + <xsd:attribute name="useStartTLS" type="xsd:string" use="optional" default="true"/> + <xsd:attribute name="trustCertificates" type="xsd:string" use="optional"/> + <xsd:attribute name="authenticationCertificate" type="xsd:string" use="optional"/> + <xsd:attribute name="authenticationKey" type="xsd:string" use="optional"/> + <xsd:attribute name="trustStore" type="xsd:string" use="optional"/> + <xsd:attribute name="trustStorePassword" type="xsd:string" use="optional" default="changeit"/> + <xsd:attribute name="trustStoreType" type="xsd:string" use="optional" default="JKS"/> + <xsd:attribute name="trustStoreAliases" type="xsd:string" use="optional"/> + <xsd:attribute name="keyStore" type="xsd:string" use="optional"/> + <xsd:attribute name="keyStorePassword" type="xsd:string" use="optional" default="changeit"/> + <xsd:attribute name="keyStoreType" type="xsd:string" use="optional" default="JKS"/> + <xsd:attribute name="keyStoreAliases" type="xsd:string" use="optional"/> + </xsd:attributeGroup> +</xsd:schema> \ No newline at end of file
diff --git a/beans/src/test/java/org/ldaptive/beans/generate/BeanGeneratorTest.java b/beans/src/test/java/org/ldaptive/beans/generate/BeanGeneratorTest.java new file mode 100644 index 0000000..5538abe --- /dev/null +++ b/beans/src/test/java/org/ldaptive/beans/generate/BeanGeneratorTest.java
@@ -0,0 +1,66 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.generate; + +import org.ldaptive.schema.Schema; +import org.ldaptive.schema.SchemaFactory; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit tests for {@link BeanGenerator}. + * + * @author Middleware Services + */ +public class BeanGeneratorTest +{ + + + /** + * Test data for bean generator. + * + * @return custom objects + * + * @throws Exception if a schema cannot be read + */ + @DataProvider(name = "schemas") + public Object[][] createSchemas() + throws Exception + { + return + new Object[][] { + new Object[] { + SchemaFactory.createSchema(BeanGeneratorTest.class.getResourceAsStream("/subschema.ldif")), + "org.ldaptive.beans.schema.subschema", + new String[] {"inetOrgPerson"}, + }, + new Object[] { + SchemaFactory.createSchema(BeanGeneratorTest.class.getResourceAsStream("/allschema.ldif")), + "org.ldaptive.beans.schema.allschema", + new String[] {"inetOrgPerson"}, + }, + }; + } + + + /** + * @param schema to generate beans from + * @param packageName to generate beans in + * @param objectClasses to generate beans for + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans"}, dataProvider = "schemas") + public void generate(final Schema schema, final String packageName, final String[] objectClasses) + throws Exception + { + final BeanGenerator generator = new BeanGenerator(); + generator.setSchema(schema); + generator.setObjectClasses(objectClasses); + generator.setPackageName(packageName); + generator.setUseOperationalAttributes(true); + generator.setUseOptionalAttributes(true); + generator.setIncludeSuperiorClasses(true); + generator.generate(); + generator.write("target/generated-test-sources/ldaptive"); + } +}
diff --git a/beans/src/test/java/org/ldaptive/beans/reflect/BinaryCustomObject.java b/beans/src/test/java/org/ldaptive/beans/reflect/BinaryCustomObject.java new file mode 100644 index 0000000..18c3414 --- /dev/null +++ b/beans/src/test/java/org/ldaptive/beans/reflect/BinaryCustomObject.java
@@ -0,0 +1,273 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapUtils; +import org.ldaptive.SortBehavior; +import org.ldaptive.beans.Attribute; +import org.ldaptive.beans.Entry; + +/** + * Class for testing bean annotations. + * + * @author Middleware Services + */ +public class BinaryCustomObject implements CustomObject +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 21; + + // CheckStyle:JavadocVariable OFF + // CheckStyle:DeclarationOrder OFF + private byte[] type1; + protected byte[] type2; + private byte[] type3; + private Collection<byte[]> typeCol1; + protected Collection<byte[]> typeCol2; + private Set<byte[]> typeSet1; + protected Set<byte[]> typeSet2; + private List<byte[]> typeList1; + protected List<byte[]> typeList2; + // CheckStyle:DeclarationOrder ON + // CheckStyle:JavadocVariable ON + + + // CheckStyle:JavadocMethod OFF + // CheckStyle:LeftCurly OFF + public byte[] getType1() { return type1; } + public void setType1(final byte[] t) { type1 = t; } + public void writeType2(final byte[] t) { type2 = t; } + public byte[] getType3() { return type3; } + public void setType3(final byte[] t) { type3 = t; } + public Collection<byte[]> getTypeCol1() { return typeCol1; } + public void setTypeCol1(final Collection<byte[]> c) { typeCol1 = c; } + public void writeTypeCol2(final Collection<byte[]> c) { typeCol2 = c; } + public Set<byte[]> getTypeSet1() { return typeSet1; } + public void setTypeSet1(final Set<byte[]> s) { typeSet1 = s; } + public void writeTypeSet2(final Set<byte[]> s) { typeSet2 = s; } + public List<byte[]> getTypeList1() { return typeList1; } + public void setTypeList1(final List<byte[]> l) { typeList1 = l; } + public void writeTypeList2(final List<byte[]> l) { typeList2 = l; } + // CheckStyle:LeftCurly ON + // CheckStyle:JavadocMethod ON + + + @Override + public void initialize() {} + + + @Override + public boolean equals(final Object o) + { + return o != null && hashCode() == o.hashCode(); + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + type1, + type2, + type3, + typeCol1 != null ? Collections.unmodifiableCollection(typeCol1) : null, + typeCol2 != null ? Collections.unmodifiableCollection(typeCol2) : null, + typeSet1, + typeSet2, + typeList1, + typeList2); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::" + + "type1=%s, type2=%s, type3=%s, " + + "typeCol1=%s, typeCol2=%s, " + + "typeSet1=%s, typeSet2=%s, " + + "typeList1=%s, typeList2=%s]", + getClass().getSimpleName(), + hashCode(), + Arrays.toString(type1), + Arrays.toString(type2), + Arrays.toString(type3), + toString(typeCol1), + toString(typeCol2), + toString(typeSet1), + toString(typeSet2), + toString(typeList1), + toString(typeList2)); + } + + + /** + * Returns a string representation of the supplied collection. + * + * @param c collection to represent as a string + * + * @return collection as a string + */ + private String toString(final Collection<byte[]> c) + { + String s = null; + if (c != null) { + s = ""; + for (byte[] t : c) { + s += Arrays.toString(t); + } + } + return s; + } + + + /** + * Creates a binary custom object for testing. + * + * @param <T> type of binary custom object + * @param type of binary custom object + * + * @return instance of binary custom object + */ + public static <T extends BinaryCustomObject> T createCustomObject(final Class<T> type) + { + // CheckStyle:MagicNumber OFF + final Set<byte[]> s1 = new LinkedHashSet<>(); + s1.add(new byte[] {0x22, 0x0F, 0x1F}); + s1.add(new byte[] {0x23}); + + final T o1; + try { + o1 = type.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new IllegalStateException(e); + } + o1.setType1(new byte[] {0x01}); + o1.writeType2(new byte[] {0x02, 0x0F}); + o1.setType3(new byte[] {0x03, 0x0F, 0x1F}); + o1.setTypeCol1(Arrays.asList(new byte[] {0x20, 0x0F, 0x1F}, new byte[] {0x21})); + o1.writeTypeCol2(Arrays.asList(new byte[] {0x20, 0x0F, 0x1F}, new byte[] {0x21})); + o1.setTypeSet1(s1); + o1.writeTypeSet2(s1); + o1.setTypeList1(Arrays.asList(new byte[] {0x24, 0x0F, 0x1F}, new byte[] {0x25})); + o1.writeTypeList2(Arrays.asList(new byte[] {0x24, 0x0F, 0x1F}, new byte[] {0x25})); + + return o1; + // CheckStyle:MagicNumber ON + } + + + /** + * Creates an ldap entry containing binary data. + * + * @return ldap entry + */ + public static LdapEntry createLdapEntry() + { + // CheckStyle:MagicNumber OFF + final LdapAttribute typeCol1 = new LdapAttribute(SortBehavior.ORDERED, true); + typeCol1.setName("typeCol1"); + typeCol1.addBinaryValue(new byte[] {0x20, 0x0F, 0x1F}, new byte[] {0x21}); + + final LdapAttribute typeCol2 = new LdapAttribute(SortBehavior.ORDERED, true); + typeCol2.setName("typeCol2"); + typeCol2.addBinaryValue(new byte[] {0x20, 0x0F, 0x1F}, new byte[] {0x21}); + + final LdapAttribute typeSet1 = new LdapAttribute(SortBehavior.ORDERED, true); + typeSet1.setName("typeSet1"); + typeSet1.addBinaryValue(new byte[] {0x22, 0x0F, 0x1F}, new byte[] {0x23}); + + final LdapAttribute typeSet2 = new LdapAttribute(SortBehavior.ORDERED, true); + typeSet2.setName("typeSet2"); + typeSet2.addBinaryValue(new byte[] {0x22, 0x0F, 0x1F}, new byte[] {0x23}); + + final LdapAttribute typeList1 = new LdapAttribute(SortBehavior.ORDERED, true); + typeList1.setName("typeList1"); + typeList1.addBinaryValue(new byte[] {0x24, 0x0F, 0x1F}, new byte[] {0x25}); + + final LdapAttribute typeList2 = new LdapAttribute(SortBehavior.ORDERED, true); + typeList2.setName("typeList2"); + typeList2.addBinaryValue(new byte[] {0x24, 0x0F, 0x1F}, new byte[] {0x25}); + + final LdapEntry entry = new LdapEntry(); + entry.setDn("cn=Binary Entry,ou=people,dc=ldaptive,dc=org"); + entry.addAttribute( + new LdapAttribute("customname1", new byte[] {0x40, 0x41, 0x42, 0x43}), + new LdapAttribute("customname2", new byte[] {0x44, 0x45, 0x46, 0x47}, new byte[] {0x48, 0x49, 0x50, 0x51}), + new LdapAttribute("type1", new byte[] {0x01}), + new LdapAttribute("type2", new byte[] {0x02, 0x0F}), + new LdapAttribute("binarythree", new byte[] {0x03, 0x0F, 0x1F}), + typeCol1, + typeCol2, + typeSet1, + typeSet2, + typeList1, + typeList2); + return entry; + // CheckStyle:MagicNumber ON + } + + + /** Test class for the default ldap entry mapper. */ + @Entry( + dn = "cn=Binary Entry,ou=people,dc=ldaptive,dc=org", attributes = { + @Attribute(name = "customname1", values = "QEFCQw==", binary = true), + @Attribute( + name = "customname2", values = {"REVGRw==", "SElQUQ=="}, binary = true, sortBehavior = SortBehavior.ORDERED + ), + @Attribute(name = "type1", property = "type1", binary = true), + @Attribute(name = "type2", property = "type2", binary = true), + @Attribute(name = "binarythree", property = "type3", binary = true), + @Attribute(name = "typeCol1", property = "typeCol1", binary = true, sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeCol2", property = "typeCol2", binary = true, sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeSet1", property = "typeSet1", binary = true), + @Attribute(name = "typeSet2", property = "typeSet2", binary = true), + @Attribute(name = "typeList1", property = "typeList1", binary = true, sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeList2", property = "typeList2", binary = true, sortBehavior = SortBehavior.ORDERED)}) + public static class Default extends BinaryCustomObject {} + + + /** Test class for the spring ldap entry mapper. */ + @Entry( + dn = "cn=Binary Entry,ou=people,dc=ldaptive,dc=org", attributes = { + @Attribute(name = "customname1", values = "QEFCQw==", binary = true), + @Attribute( + name = "customname2", values = {"REVGRw==", "SElQUQ=="}, binary = true, sortBehavior = SortBehavior.ORDERED + ), + @Attribute(name = "type1", property = "type1", binary = true), + @Attribute(name = "type2", property = "type2", binary = true), + @Attribute(name = "binarythree", property = "type3", binary = true), + @Attribute(name = "typeCol1", property = "typeCol1", binary = true, sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeCol2", property = "typeCol2", binary = true, sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeSet1", property = "typeSet1", binary = true), + @Attribute(name = "typeSet2", property = "typeSet2", binary = true), + @Attribute(name = "typeList1", property = "typeList1", binary = true, sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeList2", property = "typeList2", binary = true, sortBehavior = SortBehavior.ORDERED)}) + public static class Spring extends BinaryCustomObject + { + // CheckStyle:JavadocMethod OFF + // CheckStyle:LeftCurly OFF + public byte[] getType2() { return type2; } + public void setType2(final byte[] t) { type2 = t; } + public Collection<byte[]> getTypeCol2() { return typeCol2; } + public void setTypeCol2(final Collection<byte[]> c) { typeCol2 = c; } + public Set<byte[]> getTypeSet2() { return typeSet2; } + public void setTypeSet2(final Set<byte[]> s) { typeSet2 = s; } + public List<byte[]> getTypeList2() { return typeList2; } + public void setTypeList2(final List<byte[]> l) { typeList2 = l; } + // CheckStyle:LeftCurly ON + // CheckStyle:JavadocMethod ON + } +}
diff --git a/beans/src/test/java/org/ldaptive/beans/reflect/BooleanCustomObject.java b/beans/src/test/java/org/ldaptive/beans/reflect/BooleanCustomObject.java new file mode 100644 index 0000000..5dec5bb --- /dev/null +++ b/beans/src/test/java/org/ldaptive/beans/reflect/BooleanCustomObject.java
@@ -0,0 +1,267 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapUtils; +import org.ldaptive.SortBehavior; +import org.ldaptive.beans.Attribute; +import org.ldaptive.beans.Entry; + +/** + * Class for testing bean annotations. + * + * @author Middleware Services + */ +public class BooleanCustomObject implements CustomObject +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 51; + + // CheckStyle:JavadocVariable OFF + // CheckStyle:DeclarationOrder OFF + private boolean type1; + protected boolean type2; + private boolean type3; + private boolean[] typeArray1; + protected boolean[] typeArray2; + private Collection<Boolean> typeCol1; + protected Collection<Boolean> typeCol2; + private Set<Boolean> typeSet1; + protected Set<Boolean> typeSet2; + private List<Boolean> typeList1; + protected List<Boolean> typeList2; + // CheckStyle:DeclarationOrder ON + // CheckStyle:JavadocVariable ON + + + // CheckStyle:JavadocMethod OFF + // CheckStyle:LeftCurly OFF + public boolean getType1() { return type1; } + public void setType1(final boolean t) { type1 = t; } + public void writeType2(final boolean t) { type2 = t; } + public boolean getType3() { return type3; } + public void setType3(final boolean t) { type3 = t; } + public boolean[] getTypeArray1() { return typeArray1; } + public void setTypeArray1(final boolean[] t) { typeArray1 = t; } + public void writeTypeArray2(final boolean[] t) { typeArray2 = t; } + public Collection<Boolean> getTypeCol1() { return typeCol1; } + public void setTypeCol1(final Collection<Boolean> c) { typeCol1 = c; } + public void writeTypeCol2(final Collection<Boolean> c) { typeCol2 = c; } + public Set<Boolean> getTypeSet1() { return typeSet1; } + public void setTypeSet1(final Set<Boolean> s) { typeSet1 = s; } + public void writeTypeSet2(final Set<Boolean> s) { typeSet2 = s; } + public List<Boolean> getTypeList1() { return typeList1; } + public void setTypeList1(final List<Boolean> l) { typeList1 = l; } + public void writeTypeList2(final List<Boolean> l) { typeList2 = l; } + // CheckStyle:LeftCurly ON + // CheckStyle:JavadocMethod ON + + + @Override + public void initialize() {} + + + @Override + public boolean equals(final Object o) + { + return o != null && hashCode() == o.hashCode(); + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + type1, + type2, + type3, + typeArray1, + typeArray2, + typeCol1 != null ? Collections.unmodifiableCollection(typeCol1) : null, + typeCol2 != null ? Collections.unmodifiableCollection(typeCol2) : null, + typeSet1, + typeSet2, + typeList1, + typeList2); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::" + + "type1=%s, type2=%s, type3=%s, " + + "typeArray1=%s, typeArray2=%s, " + + "typeCol1=%s, typeCol2=%s, " + + "typeSet1=%s, typeSet2=%s, " + + "typeList1=%s, typeList2=%s]", + getClass().getSimpleName(), + hashCode(), + type1, + type2, + type3, + Arrays.toString(typeArray1), + Arrays.toString(typeArray2), + typeCol1, + typeCol2, + typeSet1, + typeSet2, + typeList1, + typeList2); + } + + + /** + * Creates a boolean custom object for testing. + * + * @param <T> type of boolean custom object + * @param type of boolean custom object + * + * @return instance of boolean custom object + */ + public static <T extends BooleanCustomObject> T createCustomObject(final Class<T> type) + { + final Set<Boolean> s1 = new HashSet<>(); + s1.add(true); + s1.add(false); + + final T o1; + try { + o1 = type.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new IllegalStateException(e); + } + o1.setType1(true); + o1.writeType2(false); + o1.setType3(true); + o1.setTypeArray1(new boolean[] {false, true}); + o1.writeTypeArray2(new boolean[] {false, true}); + o1.setTypeCol1(Arrays.asList(true, false)); + o1.writeTypeCol2(Arrays.asList(false, true)); + o1.setTypeSet1(s1); + o1.writeTypeSet2(s1); + o1.setTypeList1(Arrays.asList(false, true)); + o1.writeTypeList2(Arrays.asList(true, false)); + + return o1; + } + + + /** + * Creates an ldap entry containing boolean based string values. + * + * @return ldap entry + */ + public static LdapEntry createLdapEntry() + { + final LdapAttribute typeArray1 = new LdapAttribute(SortBehavior.ORDERED); + typeArray1.setName("typeArray1"); + typeArray1.addStringValue("false", "true"); + + final LdapAttribute typeArray2 = new LdapAttribute(SortBehavior.ORDERED); + typeArray2.setName("typeArray2"); + typeArray2.addStringValue("false", "true"); + + final LdapAttribute typeCol1 = new LdapAttribute(SortBehavior.ORDERED); + typeCol1.setName("typeCol1"); + typeCol1.addStringValue("true", "false"); + + final LdapAttribute typeCol2 = new LdapAttribute(SortBehavior.ORDERED); + typeCol2.setName("typeCol2"); + typeCol2.addStringValue("false", "true"); + + final LdapAttribute typeSet1 = new LdapAttribute(SortBehavior.ORDERED); + typeSet1.setName("typeSet1"); + typeSet1.addStringValue("true", "false"); + + final LdapAttribute typeSet2 = new LdapAttribute(SortBehavior.ORDERED); + typeSet2.setName("typeSet2"); + typeSet2.addStringValue("true", "false"); + + final LdapAttribute typeList1 = new LdapAttribute(SortBehavior.ORDERED); + typeList1.setName("typeList1"); + typeList1.addStringValue("false", "true"); + + final LdapAttribute typeList2 = new LdapAttribute(SortBehavior.ORDERED); + typeList2.setName("typeList2"); + typeList2.addStringValue("true", "false"); + + final LdapEntry entry = new LdapEntry(); + entry.setDn("cn=Boolean Entry,ou=people,dc=ldaptive,dc=org"); + entry.addAttribute( + new LdapAttribute("type1", "true"), + new LdapAttribute("type2", "false"), + new LdapAttribute("booleanthree", "true"), + typeArray1, + typeArray2, + typeCol1, + typeCol2, + typeSet1, + typeSet2, + typeList1, + typeList2); + return entry; + } + + + /** Test class for the default ldap entry mapper. */ + @Entry( + dn = "cn=Boolean Entry,ou=people,dc=ldaptive,dc=org", attributes = { + @Attribute(name = "type1", property = "type1"), + @Attribute(name = "type2", property = "type2"), + @Attribute(name = "booleanthree", property = "type3"), + @Attribute(name = "typeArray1", property = "typeArray1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeArray2", property = "typeArray2", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeCol1", property = "typeCol1"), + @Attribute(name = "typeCol2", property = "typeCol2"), + @Attribute(name = "typeSet1", property = "typeSet1"), + @Attribute(name = "typeSet2", property = "typeSet2"), + @Attribute(name = "typeList1", property = "typeList1"), + @Attribute(name = "typeList2", property = "typeList2")}) + public static class Default extends BooleanCustomObject {} + + + /** Test class for the spring ldap entry mapper. */ + @Entry( + dn = "cn=Boolean Entry,ou=people,dc=ldaptive,dc=org", attributes = { + @Attribute(name = "type1", property = "type1"), + @Attribute(name = "type2", property = "type2"), + @Attribute(name = "booleanthree", property = "type3"), + @Attribute(name = "typeArray1", property = "typeArray1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeArray2", property = "typeArray2", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeCol1", property = "typeCol1"), + @Attribute(name = "typeCol2", property = "typeCol2"), + @Attribute(name = "typeSet1", property = "typeSet1"), + @Attribute(name = "typeSet2", property = "typeSet2"), + @Attribute(name = "typeList1", property = "typeList1"), + @Attribute(name = "typeList2", property = "typeList2")}) + public static class Spring extends BooleanCustomObject + { + // CheckStyle:JavadocMethod OFF + // CheckStyle:LeftCurly OFF + public boolean getType2() { return type2; } + public void setType2(final boolean t) { type2 = t; } + public boolean[] getTypeArray2() { return typeArray2; } + public void setTypeArray2(final boolean[] t) { typeArray2 = t; } + public Collection<Boolean> getTypeCol2() { return typeCol2; } + public void setTypeCol2(final Collection<Boolean> c) { typeCol2 = c; } + public Set<Boolean> getTypeSet2() { return typeSet2; } + public void setTypeSet2(final Set<Boolean> s) { typeSet2 = s; } + public List<Boolean> getTypeList2() { return typeList2; } + public void setTypeList2(final List<Boolean> l) { typeList2 = l; } + // CheckStyle:LeftCurly ON + // CheckStyle:JavadocMethod ON + } +}
diff --git a/beans/src/test/java/org/ldaptive/beans/reflect/CharCustomObject.java b/beans/src/test/java/org/ldaptive/beans/reflect/CharCustomObject.java new file mode 100644 index 0000000..89a2382 --- /dev/null +++ b/beans/src/test/java/org/ldaptive/beans/reflect/CharCustomObject.java
@@ -0,0 +1,224 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.ldaptive.LdapUtils; +import org.ldaptive.SortBehavior; +import org.ldaptive.beans.Attribute; +import org.ldaptive.beans.Entry; + +/** + * Class for testing bean annotations. + * + * @author Middleware Services + */ +public class CharCustomObject implements CustomObject +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 31; + + // CheckStyle:JavadocVariable OFF + // CheckStyle:DeclarationOrder OFF + private String customDn; + private char[] type1; + protected char[] type2; + private char[] type3; + private Collection<char[]> typeCol1; + protected Collection<char[]> typeCol2; + private Set<char[]> typeSet1; + protected Set<char[]> typeSet2; + private List<char[]> typeList1; + protected List<char[]> typeList2; + // CheckStyle:DeclarationOrder ON + // CheckStyle:JavadocVariable ON + + + // CheckStyle:JavadocMethod OFF + // CheckStyle:LeftCurly OFF + public CharCustomObject() {} + public CharCustomObject(final String s) { setCustomDn(s); } + + + public String getCustomDn() { return customDn; } + public void setCustomDn(final String s) { customDn = s; } + public char[] getType1() { return type1; } + public void setType1(final char[] t) { type1 = t; } + public void writeType2(final char[] t) { type2 = t; } + public char[] getType3() { return type3; } + public void setType3(final char[] t) { type3 = t; } + public Collection<char[]> getTypeCol1() { return typeCol1; } + public void setTypeCol1(final Collection<char[]> c) { typeCol1 = c; } + public void writeTypeCol2(final Collection<char[]> c) { typeCol2 = c; } + public Set<char[]> getTypeSet1() { return typeSet1; } + public void setTypeSet1(final Set<char[]> s) { typeSet1 = s; } + public void writeTypeSet2(final Set<char[]> s) { typeSet2 = s; } + public List<char[]> getTypeList1() { return typeList1; } + public void setTypeList1(final List<char[]> l) { typeList1 = l; } + public void writeTypeList2(final List<char[]> l) { typeList2 = l; } + // CheckStyle:LeftCurly ON + // CheckStyle:JavadocMethod ON + + + @Override + public void initialize() {} + + + @Override + public boolean equals(final Object o) + { + return o != null && hashCode() == o.hashCode(); + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + getCustomDn(), + type1, + type2, + type3, + typeCol1, + typeCol2, + typeSet1, + typeSet2, + typeList1, + typeList2); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::" + + "customDn=%s, " + + "type1=%s, type2=%s, type3=%s, " + + "typeCol1=%s, typeCol2=%s, " + + "typeSet1=%s, typeSet2=%s, " + + "typeList1=%s, typeList2=%s]", + getClass().getSimpleName(), + hashCode(), + getCustomDn(), + Arrays.toString(type1), + Arrays.toString(type2), + Arrays.toString(type3), + toString(typeCol1), + toString(typeCol2), + toString(typeSet1), + toString(typeSet2), + toString(typeList1), + toString(typeList2)); + } + + + /** + * Returns a string representation of the supplied collection. + * + * @param c collection to represent as a string + * + * @return collection as a string + */ + private String toString(final Collection<char[]> c) + { + String s = null; + if (c != null) { + s = ""; + for (char[] t : c) { + s += Arrays.toString(t); + } + } + return s; + } + + + /** + * Creates a char custom object for testing. + * + * @param <T> type of char custom object + * @param type of char custom object + * + * @return instance of char custom object + */ + public static <T extends CharCustomObject> T createCustomObject(final Class<T> type) + { + final Set<char[]> s1 = new HashSet<>(); + s1.add(new char[] {'t', 's', 'v', '1'}); + s1.add(new char[] {'t', 's', 'v', '2'}); + + final T o1; + try { + o1 = type.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new IllegalStateException(e); + } + o1.setCustomDn("cn=String Entry,ou=people,dc=ldaptive,dc=org"); + o1.setType1(new char[] {'t', 'v', '1'}); + o1.writeType2(new char[] {'t', 'v', '2'}); + o1.setType3(new char[] {'t', 'v', '3'}); + o1.setTypeCol1(Arrays.asList(new char[] {'t', 'c', 'v', '1'}, new char[] {'t', 'c', 'v', '2'})); + o1.writeTypeCol2(Arrays.asList(new char[] {'t', 'c', 'v', '1'}, new char[] {'t', 'c', 'v', '2'})); + o1.setTypeSet1(s1); + o1.writeTypeSet2(s1); + o1.setTypeList1(Arrays.asList(new char[] {'t', 'l', 'v', '1'}, new char[] {'t', 'l', 'v', '2'})); + o1.writeTypeList2(Arrays.asList(new char[] {'t', 'l', 'v', '1'}, new char[] {'t', 'l', 'v', '2'})); + + return o1; + } + + + /** Test class for the default ldap entry mapper. */ + @Entry( + dn = "customDn", attributes = { + @Attribute(name = "customname1", values = "customvalue1"), + @Attribute(name = "customname2", values = {"customvalue1", "customvalue2"}), + @Attribute(name = "type1", property = "type1"), + @Attribute(name = "type2", property = "type2"), + @Attribute(name = "stringthree", property = "type3"), + @Attribute(name = "typeCol1", property = "typeCol1"), + @Attribute(name = "typeCol2", property = "typeCol2"), + @Attribute(name = "typeSet1", property = "typeSet1"), + @Attribute(name = "typeSet2", property = "typeSet2"), + @Attribute(name = "typeList1", property = "typeList1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeList2", property = "typeList2", sortBehavior = SortBehavior.ORDERED)}) + public static class Default extends CharCustomObject {} + + + /** Test class for the spring ldap entry mapper. */ + @Entry( + dn = "customDn", attributes = { + @Attribute(name = "customname1", values = "customvalue1"), + @Attribute(name = "customname2", values = {"customvalue1", "customvalue2"}), + @Attribute(name = "type1", property = "type1"), + @Attribute(name = "type2", property = "type2"), + @Attribute(name = "stringthree", property = "type3"), + @Attribute(name = "typeCol1", property = "typeCol1"), + @Attribute(name = "typeCol2", property = "typeCol2"), + @Attribute(name = "typeSet1", property = "typeSet1"), + @Attribute(name = "typeSet2", property = "typeSet2"), + @Attribute(name = "typeList1", property = "typeList1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeList2", property = "typeList2", sortBehavior = SortBehavior.ORDERED)}) + public static class Spring extends CharCustomObject + { + // CheckStyle:JavadocMethod OFF + // CheckStyle:LeftCurly OFF + public char[] getType2() { return type2; } + public void setType2(final char[] t) { type2 = t; } + public Collection<char[]> getTypeCol2() { return typeCol2; } + public void setTypeCol2(final Collection<char[]> c) { typeCol2 = c; } + public Set<char[]> getTypeSet2() { return typeSet2; } + public void setTypeSet2(final Set<char[]> s) { typeSet2 = s; } + public List<char[]> getTypeList2() { return typeList2; } + public void setTypeList2(final List<char[]> l) { typeList2 = l; } + // CheckStyle:LeftCurly ON + // CheckStyle:JavadocMethod ON + } +}
diff --git a/beans/src/test/java/org/ldaptive/beans/reflect/CustomObject.java b/beans/src/test/java/org/ldaptive/beans/reflect/CustomObject.java new file mode 100644 index 0000000..3e16e64 --- /dev/null +++ b/beans/src/test/java/org/ldaptive/beans/reflect/CustomObject.java
@@ -0,0 +1,65 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import org.ldaptive.io.ValueTranscoder; + +/** + * Interface for testing bean annotations. + * + * @author Middleware Services + */ +public interface CustomObject +{ + + + /** Prepare this object for use. */ + void initialize(); + + + /** Transcoder that adds 'prefix-' to string values. */ + class PrefixStringValueTranscoder implements ValueTranscoder<String> + { + + /** Default constructor. */ + public PrefixStringValueTranscoder() {} + + + /** + * Constructor with a non string param. + * + * @param i ignored argument + */ + public PrefixStringValueTranscoder(final int i) {} + + + @Override + public String decodeStringValue(final String value) + { + return value.replaceFirst("prefix-", ""); + } + + @Override + public String decodeBinaryValue(final byte[] value) + { + throw new UnsupportedOperationException(); + } + + @Override + public String encodeStringValue(final String value) + { + return String.format("prefix-%s", value); + } + + @Override + public byte[] encodeBinaryValue(final String value) + { + throw new UnsupportedOperationException(); + } + + @Override + public Class<String> getType() + { + return String.class; + } + } +}
diff --git a/beans/src/test/java/org/ldaptive/beans/reflect/FloatCustomObject.java b/beans/src/test/java/org/ldaptive/beans/reflect/FloatCustomObject.java new file mode 100644 index 0000000..67f1628 --- /dev/null +++ b/beans/src/test/java/org/ldaptive/beans/reflect/FloatCustomObject.java
@@ -0,0 +1,280 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapUtils; +import org.ldaptive.SortBehavior; +import org.ldaptive.beans.Attribute; +import org.ldaptive.beans.Entry; + +/** + * Class for testing bean annotations. + * + * @author Middleware Services + */ +public class FloatCustomObject implements CustomObject +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 41; + + // CheckStyle:JavadocVariable OFF + // CheckStyle:DeclarationOrder OFF + private String floatDn; + private Float type1; + protected Float type2; + private Float type3; + private Float[] typeArray1; + protected Float[] typeArray2; + private Collection<Float> typeCol1; + protected Collection<Float> typeCol2; + private Set<Float> typeSet1; + protected Set<Float> typeSet2; + private List<Float> typeList1; + protected List<Float> typeList2; + // CheckStyle:DeclarationOrder ON + // CheckStyle:JavadocVariable ON + + + // CheckStyle:JavadocMethod OFF + // CheckStyle:LeftCurly OFF + public FloatCustomObject() {} + public FloatCustomObject(final String s) { setFloatDn(s); } + + + public String getFloatDn() { return floatDn; } + public void setFloatDn(final String s) { floatDn = s; } + public Float getType1() { return type1; } + public void setType1(final Float t) { type1 = t; } + public void writeType2(final Float t) { type2 = t; } + public Float getType3() { return type3; } + public void setType3(final Float t) { type3 = t; } + public Float[] getTypeArray1() { return typeArray1; } + public void setTypeArray1(final Float[] t) { typeArray1 = t; } + public void writeTypeArray2(final Float[] t) { typeArray2 = t; } + public Collection<Float> getTypeCol1() { return typeCol1; } + public void setTypeCol1(final Collection<Float> c) { typeCol1 = c; } + public void writeTypeCol2(final Collection<Float> c) { typeCol2 = c; } + public Set<Float> getTypeSet1() { return typeSet1; } + public void setTypeSet1(final Set<Float> s) { typeSet1 = s; } + public void writeTypeSet2(final Set<Float> s) { typeSet2 = s; } + public List<Float> getTypeList1() { return typeList1; } + public void setTypeList1(final List<Float> l) { typeList1 = l; } + public void writeTypeList2(final List<Float> l) { typeList2 = l; } + // CheckStyle:LeftCurly ON + // CheckStyle:JavadocMethod ON + + + @Override + public void initialize() {} + + + @Override + public boolean equals(final Object o) + { + return o != null && hashCode() == o.hashCode(); + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + floatDn, + type1, + type2, + type3, + typeArray1, + typeArray2, + typeCol1 != null ? Collections.unmodifiableCollection(typeCol1) : null, + typeCol2 != null ? Collections.unmodifiableCollection(typeCol2) : null, + typeSet1, + typeSet2, + typeList1, + typeList2); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::" + + "integerDn=%s, " + + "type1=%s, type2=%s, type3=%s, " + + "typeArray1=%s, typeArray2=%s, " + + "typeCol1=%s, typeCol2=%s, " + + "typeSet1=%s, typeSet2=%s, " + + "typeList1=%s, typeList2=%s]", + getClass().getSimpleName(), + hashCode(), + floatDn, + type1, + type2, + type3, + Arrays.toString(typeArray1), + Arrays.toString(typeArray2), + typeCol1, + typeCol2, + typeSet1, + typeSet2, + typeList1, + typeList2); + } + + + /** + * Creates a float custom object for testing. + * + * @param <T> type of float custom object + * @param type of float custom object + * + * @return instance of float custom object + */ + public static <T extends FloatCustomObject> T createCustomObject(final Class<T> type) + { + // CheckStyle:MagicNumber OFF + final Set<Float> s1 = new HashSet<>(); + s1.add(601.6f); + s1.add(602.6f); + + final T o1; + try { + o1 = type.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new IllegalStateException(e); + } + o1.setFloatDn("cn=Float Entry,ou=people,dc=ldaptive,dc=org"); + o1.setType1(100.1f); + o1.writeType2(200.2f); + o1.setType3(300.3f); + o1.setTypeArray1(new Float[] {301.1f, 302.2f}); + o1.writeTypeArray2(new Float[] {301.1f, 302.2f}); + o1.setTypeCol1(Arrays.asList(501.5f, 502.5f)); + o1.writeTypeCol2(Arrays.asList(501.5f, 502.5f)); + o1.setTypeSet1(s1); + o1.writeTypeSet2(s1); + o1.setTypeList1(Arrays.asList(701.7f, 702.7f)); + o1.writeTypeList2(Arrays.asList(701.7f, 702.7f)); + + return o1; + // CheckStyle:MagicNumber ON + } + + + /** + * Creates an ldap entry containing float based string values. + * + * @return ldap entry + */ + public static LdapEntry createLdapEntry() + { + final LdapAttribute typeArray1 = new LdapAttribute(SortBehavior.ORDERED); + typeArray1.setName("typeArray1"); + typeArray1.addStringValue("301.1", "302.2"); + + final LdapAttribute typeArray2 = new LdapAttribute(SortBehavior.ORDERED); + typeArray2.setName("typeArray2"); + typeArray2.addStringValue("301.1", "302.2"); + + final LdapAttribute typeCol1 = new LdapAttribute(SortBehavior.ORDERED); + typeCol1.setName("typeCol1"); + typeCol1.addStringValue("501.5", "502.5"); + + final LdapAttribute typeCol2 = new LdapAttribute(SortBehavior.ORDERED); + typeCol2.setName("typeCol2"); + typeCol2.addStringValue("501.5", "502.5"); + + final LdapAttribute typeSet1 = new LdapAttribute(SortBehavior.ORDERED); + typeSet1.setName("typeSet1"); + typeSet1.addStringValue("601.6", "602.6"); + + final LdapAttribute typeSet2 = new LdapAttribute(SortBehavior.ORDERED); + typeSet2.setName("typeSet2"); + typeSet2.addStringValue("601.6", "602.6"); + + final LdapAttribute typeList1 = new LdapAttribute(SortBehavior.ORDERED); + typeList1.setName("typeList1"); + typeList1.addStringValue("701.7", "702.7"); + + final LdapAttribute typeList2 = new LdapAttribute(SortBehavior.ORDERED); + typeList2.setName("typeList2"); + typeList2.addStringValue("701.7", "702.7"); + + final LdapEntry entry = new LdapEntry(); + entry.setDn("cn=Float Entry,ou=people,dc=ldaptive,dc=org"); + entry.addAttribute( + new LdapAttribute("type1", "100.1"), + new LdapAttribute("type2", "200.2"), + new LdapAttribute("numberthree", "300.3"), + typeArray1, + typeArray2, + typeCol1, + typeCol2, + typeSet1, + typeSet2, + typeList1, + typeList2); + return entry; + } + + + /** Test class for the default ldap entry mapper. */ + @Entry( + dn = "floatDn", attributes = { + @Attribute(name = "type1", property = "type1"), + @Attribute(name = "type2", property = "type2"), + @Attribute(name = "numberthree", property = "type3"), + @Attribute(name = "typeArray1", property = "typeArray1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeArray2", property = "typeArray2", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeCol1", property = "typeCol1"), + @Attribute(name = "typeCol2", property = "typeCol2"), + @Attribute(name = "typeSet1", property = "typeSet1"), + @Attribute(name = "typeSet2", property = "typeSet2"), + @Attribute(name = "typeList1", property = "typeList1"), + @Attribute(name = "typeList2", property = "typeList2")}) + public static class Default extends FloatCustomObject {} + + + /** Test class for the spring ldap entry mapper. */ + @Entry( + dn = "floatDn", attributes = { + @Attribute(name = "type1", property = "type1"), + @Attribute(name = "type2", property = "type2"), + @Attribute(name = "numberthree", property = "type3"), + @Attribute(name = "typeArray1", property = "typeArray1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeArray2", property = "typeArray2", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeCol1", property = "typeCol1"), + @Attribute(name = "typeCol2", property = "typeCol2"), + @Attribute(name = "typeSet1", property = "typeSet1"), + @Attribute(name = "typeSet2", property = "typeSet2"), + @Attribute(name = "typeList1", property = "typeList1"), + @Attribute(name = "typeList2", property = "typeList2")}) + public static class Spring extends FloatCustomObject + { + // CheckStyle:JavadocMethod OFF + // CheckStyle:LeftCurly OFF + public Float getType2() { return type2; } + public void setType2(final Float t) { type2 = t; } + public Float[] getTypeArray2() { return typeArray2; } + public void setTypeArray2(final Float[] t) { typeArray2 = t; } + public Collection<Float> getTypeCol2() { return typeCol2; } + public void setTypeCol2(final Collection<Float> c) { typeCol2 = c; } + public Set<Float> getTypeSet2() { return typeSet2; } + public void setTypeSet2(final Set<Float> s) { typeSet2 = s; } + public List<Float> getTypeList2() { return typeList2; } + public void setTypeList2(final List<Float> l) { typeList2 = l; } + // CheckStyle:LeftCurly ON + // CheckStyle:JavadocMethod ON + } +}
diff --git a/beans/src/test/java/org/ldaptive/beans/reflect/IntCustomObject.java b/beans/src/test/java/org/ldaptive/beans/reflect/IntCustomObject.java new file mode 100644 index 0000000..ce9ed51 --- /dev/null +++ b/beans/src/test/java/org/ldaptive/beans/reflect/IntCustomObject.java
@@ -0,0 +1,210 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.ldaptive.LdapUtils; +import org.ldaptive.SortBehavior; +import org.ldaptive.beans.Attribute; +import org.ldaptive.beans.Entry; + +/** + * Class for testing bean annotations. + * + * @author Middleware Services + */ +public class IntCustomObject implements CustomObject +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 51; + + // CheckStyle:JavadocVariable OFF + // CheckStyle:DeclarationOrder OFF + private int type1; + protected int type2; + private int type3; + private int[] typeArray1; + protected int[] typeArray2; + private Collection<Integer> typeCol1; + protected Collection<Integer> typeCol2; + private Set<Integer> typeSet1; + protected Set<Integer> typeSet2; + private List<Integer> typeList1; + protected List<Integer> typeList2; + // CheckStyle:DeclarationOrder ON + // CheckStyle:JavadocVariable ON + + + // CheckStyle:JavadocMethod OFF + // CheckStyle:LeftCurly OFF + public int getType1() { return type1; } + public void setType1(final int t) { type1 = t; } + public void writeType2(final int t) { type2 = t; } + public int getType3() { return type3; } + public void setType3(final int t) { type3 = t; } + public int[] getTypeArray1() { return typeArray1; } + public void setTypeArray1(final int[] t) { typeArray1 = t; } + public void writeTypeArray2(final int[] t) { typeArray2 = t; } + public Collection<Integer> getTypeCol1() { return typeCol1; } + public void setTypeCol1(final Collection<Integer> c) { typeCol1 = c; } + public void writeTypeCol2(final Collection<Integer> c) { typeCol2 = c; } + public Set<Integer> getTypeSet1() { return typeSet1; } + public void setTypeSet1(final Set<Integer> s) { typeSet1 = s; } + public void writeTypeSet2(final Set<Integer> s) { typeSet2 = s; } + public List<Integer> getTypeList1() { return typeList1; } + public void setTypeList1(final List<Integer> l) { typeList1 = l; } + public void writeTypeList2(final List<Integer> l) { typeList2 = l; } + // CheckStyle:LeftCurly ON + // CheckStyle:JavadocMethod ON + + + @Override + public void initialize() {} + + + @Override + public boolean equals(final Object o) + { + return o != null && hashCode() == o.hashCode(); + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + type1, + type2, + type3, + typeArray1, + typeArray2, + typeCol1 != null ? Collections.unmodifiableCollection(typeCol1) : null, + typeCol2 != null ? Collections.unmodifiableCollection(typeCol2) : null, + typeSet1, + typeSet2, + typeList1, + typeList2); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::" + + "type1=%s, type2=%s, type3=%s, " + + "typeArray1=%s, typeArray2=%s, " + + "typeCol1=%s, typeCol2=%s, " + + "typeSet1=%s, typeSet2=%s, " + + "typeList1=%s, typeList2=%s]", + getClass().getSimpleName(), + hashCode(), + type1, + type2, + type3, + Arrays.toString(typeArray1), + Arrays.toString(typeArray2), + typeCol1, + typeCol2, + typeSet1, + typeSet2, + typeList1, + typeList2); + } + + + /** + * Creates an int custom object for testing. + * + * @param <T> type of int custom object + * @param type of int custom object + * + * @return instance of int custom object + */ + public static <T extends IntCustomObject> T createCustomObject(final Class<T> type) + { + // CheckStyle:MagicNumber OFF + final Set<Integer> s1 = new HashSet<>(); + s1.add(601); + s1.add(602); + + final T o1; + try { + o1 = type.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new IllegalStateException(e); + } + o1.setType1(100); + o1.writeType2(200); + o1.setType3(300); + o1.setTypeArray1(new int[] {301, 302}); + o1.writeTypeArray2(new int[] {301, 302}); + o1.setTypeCol1(Arrays.asList(501, 502)); + o1.writeTypeCol2(Arrays.asList(501, 502)); + o1.setTypeSet1(s1); + o1.writeTypeSet2(s1); + o1.setTypeList1(Arrays.asList(701, 702)); + o1.writeTypeList2(Arrays.asList(701, 702)); + + return o1; + // CheckStyle:MagicNumber ON + } + + + /** Test class for the default ldap entry mapper. */ + @Entry( + dn = "cn=Integer Entry,ou=people,dc=ldaptive,dc=org", attributes = { + @Attribute(name = "type1", property = "type1"), + @Attribute(name = "type2", property = "type2"), + @Attribute(name = "numberthree", property = "type3"), + @Attribute(name = "typeArray1", property = "typeArray1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeArray2", property = "typeArray2", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeCol1", property = "typeCol1"), + @Attribute(name = "typeCol2", property = "typeCol2"), + @Attribute(name = "typeSet1", property = "typeSet1"), + @Attribute(name = "typeSet2", property = "typeSet2"), + @Attribute(name = "typeList1", property = "typeList1"), + @Attribute(name = "typeList2", property = "typeList2")}) + public static class Default extends IntCustomObject {} + + + /** Test class for the spring ldap entry mapper. */ + @Entry( + dn = "cn=Integer Entry,ou=people,dc=ldaptive,dc=org", attributes = { + @Attribute(name = "type1", property = "type1"), + @Attribute(name = "type2", property = "type2"), + @Attribute(name = "numberthree", property = "type3"), + @Attribute(name = "typeArray1", property = "typeArray1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeArray2", property = "typeArray2", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeCol1", property = "typeCol1"), + @Attribute(name = "typeCol2", property = "typeCol2"), + @Attribute(name = "typeSet1", property = "typeSet1"), + @Attribute(name = "typeSet2", property = "typeSet2"), + @Attribute(name = "typeList1", property = "typeList1"), + @Attribute(name = "typeList2", property = "typeList2")}) + public static class Spring extends IntCustomObject + { + // CheckStyle:JavadocMethod OFF + // CheckStyle:LeftCurly OFF + public int getType2() { return type2; } + public void setType2(final int t) { type2 = t; } + public int[] getTypeArray2() { return typeArray2; } + public void setTypeArray2(final int[] t) { typeArray2 = t; } + public Collection<Integer> getTypeCol2() { return typeCol2; } + public void setTypeCol2(final Collection<Integer> c) { typeCol2 = c; } + public Set<Integer> getTypeSet2() { return typeSet2; } + public void setTypeSet2(final Set<Integer> s) { typeSet2 = s; } + public List<Integer> getTypeList2() { return typeList2; } + public void setTypeList2(final List<Integer> l) { typeList2 = l; } + // CheckStyle:LeftCurly ON + // CheckStyle:JavadocMethod ON + } +}
diff --git a/beans/src/test/java/org/ldaptive/beans/reflect/IntegerCustomObject.java b/beans/src/test/java/org/ldaptive/beans/reflect/IntegerCustomObject.java new file mode 100644 index 0000000..43c51ac --- /dev/null +++ b/beans/src/test/java/org/ldaptive/beans/reflect/IntegerCustomObject.java
@@ -0,0 +1,280 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapUtils; +import org.ldaptive.SortBehavior; +import org.ldaptive.beans.Attribute; +import org.ldaptive.beans.Entry; + +/** + * Class for testing bean annotations. + * + * @author Middleware Services + */ +public class IntegerCustomObject implements CustomObject +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 41; + + // CheckStyle:JavadocVariable OFF + // CheckStyle:DeclarationOrder OFF + private String integerDn; + private Integer type1; + protected Integer type2; + private Integer type3; + private Integer[] typeArray1; + protected Integer[] typeArray2; + private Collection<Integer> typeCol1; + protected Collection<Integer> typeCol2; + private Set<Integer> typeSet1; + protected Set<Integer> typeSet2; + private List<Integer> typeList1; + protected List<Integer> typeList2; + // CheckStyle:DeclarationOrder ON + // CheckStyle:JavadocVariable ON + + + // CheckStyle:JavadocMethod OFF + // CheckStyle:LeftCurly OFF + public IntegerCustomObject() {} + public IntegerCustomObject(final String s) { setIntegerDn(s); } + + + public String getIntegerDn() { return integerDn; } + public void setIntegerDn(final String s) { integerDn = s; } + public Integer getType1() { return type1; } + public void setType1(final Integer t) { type1 = t; } + public void writeType2(final Integer t) { type2 = t; } + public Integer getType3() { return type3; } + public void setType3(final Integer t) { type3 = t; } + public Integer[] getTypeArray1() { return typeArray1; } + public void setTypeArray1(final Integer[] t) { typeArray1 = t; } + public void writeTypeArray2(final Integer[] t) { typeArray2 = t; } + public Collection<Integer> getTypeCol1() { return typeCol1; } + public void setTypeCol1(final Collection<Integer> c) { typeCol1 = c; } + public void writeTypeCol2(final Collection<Integer> c) { typeCol2 = c; } + public Set<Integer> getTypeSet1() { return typeSet1; } + public void setTypeSet1(final Set<Integer> s) { typeSet1 = s; } + public void writeTypeSet2(final Set<Integer> s) { typeSet2 = s; } + public List<Integer> getTypeList1() { return typeList1; } + public void setTypeList1(final List<Integer> l) { typeList1 = l; } + public void writeTypeList2(final List<Integer> l) { typeList2 = l; } + // CheckStyle:LeftCurly ON + // CheckStyle:JavadocMethod ON + + + @Override + public void initialize() {} + + + @Override + public boolean equals(final Object o) + { + return o != null && hashCode() == o.hashCode(); + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + integerDn, + type1, + type2, + type3, + typeArray1, + typeArray2, + typeCol1 != null ? Collections.unmodifiableCollection(typeCol1) : null, + typeCol2 != null ? Collections.unmodifiableCollection(typeCol2) : null, + typeSet1, + typeSet2, + typeList1, + typeList2); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::" + + "integerDn=%s, " + + "type1=%s, type2=%s, type3=%s, " + + "typeArray1=%s, typeArray2=%s, " + + "typeCol1=%s, typeCol2=%s, " + + "typeSet1=%s, typeSet2=%s, " + + "typeList1=%s, typeList2=%s]", + getClass().getSimpleName(), + hashCode(), + integerDn, + type1, + type2, + type3, + Arrays.toString(typeArray1), + Arrays.toString(typeArray2), + typeCol1, + typeCol2, + typeSet1, + typeSet2, + typeList1, + typeList2); + } + + + /** + * Creates an integer custom object for testing. + * + * @param <T> type of integer custom object + * @param type of integer custom object + * + * @return instance of integer custom object + */ + public static <T extends IntegerCustomObject> T createCustomObject(final Class<T> type) + { + // CheckStyle:MagicNumber OFF + final Set<Integer> s1 = new HashSet<>(); + s1.add(601); + s1.add(602); + + final T o1; + try { + o1 = type.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new IllegalStateException(e); + } + o1.setIntegerDn("cn=Integer Entry,ou=people,dc=ldaptive,dc=org"); + o1.setType1(100); + o1.writeType2(200); + o1.setType3(300); + o1.setTypeArray1(new Integer[] {301, 302}); + o1.writeTypeArray2(new Integer[] {301, 302}); + o1.setTypeCol1(Arrays.asList(501, 502)); + o1.writeTypeCol2(Arrays.asList(501, 502)); + o1.setTypeSet1(s1); + o1.writeTypeSet2(s1); + o1.setTypeList1(Arrays.asList(701, 702)); + o1.writeTypeList2(Arrays.asList(701, 702)); + + return o1; + // CheckStyle:MagicNumber ON + } + + + /** + * Creates an ldap entry containing integer based string values. + * + * @return ldap entry + */ + public static LdapEntry createLdapEntry() + { + final LdapAttribute typeArray1 = new LdapAttribute(SortBehavior.ORDERED); + typeArray1.setName("typeArray1"); + typeArray1.addStringValue("301", "302"); + + final LdapAttribute typeArray2 = new LdapAttribute(SortBehavior.ORDERED); + typeArray2.setName("typeArray2"); + typeArray2.addStringValue("301", "302"); + + final LdapAttribute typeCol1 = new LdapAttribute(SortBehavior.ORDERED); + typeCol1.setName("typeCol1"); + typeCol1.addStringValue("501", "502"); + + final LdapAttribute typeCol2 = new LdapAttribute(SortBehavior.ORDERED); + typeCol2.setName("typeCol2"); + typeCol2.addStringValue("501", "502"); + + final LdapAttribute typeSet1 = new LdapAttribute(SortBehavior.ORDERED); + typeSet1.setName("typeSet1"); + typeSet1.addStringValue("601", "602"); + + final LdapAttribute typeSet2 = new LdapAttribute(SortBehavior.ORDERED); + typeSet2.setName("typeSet2"); + typeSet2.addStringValue("601", "602"); + + final LdapAttribute typeList1 = new LdapAttribute(SortBehavior.ORDERED); + typeList1.setName("typeList1"); + typeList1.addStringValue("701", "702"); + + final LdapAttribute typeList2 = new LdapAttribute(SortBehavior.ORDERED); + typeList2.setName("typeList2"); + typeList2.addStringValue("701", "702"); + + final LdapEntry entry = new LdapEntry(); + entry.setDn("cn=Integer Entry,ou=people,dc=ldaptive,dc=org"); + entry.addAttribute( + new LdapAttribute("type1", "100"), + new LdapAttribute("type2", "200"), + new LdapAttribute("numberthree", "300"), + typeArray1, + typeArray2, + typeCol1, + typeCol2, + typeSet1, + typeSet2, + typeList1, + typeList2); + return entry; + } + + + /** Test class for the default ldap entry mapper. */ + @Entry( + dn = "integerDn", attributes = { + @Attribute(name = "type1", property = "type1"), + @Attribute(name = "type2", property = "type2"), + @Attribute(name = "numberthree", property = "type3"), + @Attribute(name = "typeArray1", property = "typeArray1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeArray2", property = "typeArray2", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeCol1", property = "typeCol1"), + @Attribute(name = "typeCol2", property = "typeCol2"), + @Attribute(name = "typeSet1", property = "typeSet1"), + @Attribute(name = "typeSet2", property = "typeSet2"), + @Attribute(name = "typeList1", property = "typeList1"), + @Attribute(name = "typeList2", property = "typeList2")}) + public static class Default extends IntegerCustomObject {} + + + /** Test class for the spring ldap entry mapper. */ + @Entry( + dn = "integerDn", attributes = { + @Attribute(name = "type1", property = "type1"), + @Attribute(name = "type2", property = "type2"), + @Attribute(name = "numberthree", property = "type3"), + @Attribute(name = "typeArray1", property = "typeArray1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeArray2", property = "typeArray2", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeCol1", property = "typeCol1"), + @Attribute(name = "typeCol2", property = "typeCol2"), + @Attribute(name = "typeSet1", property = "typeSet1"), + @Attribute(name = "typeSet2", property = "typeSet2"), + @Attribute(name = "typeList1", property = "typeList1"), + @Attribute(name = "typeList2", property = "typeList2")}) + public static class Spring extends IntegerCustomObject + { + // CheckStyle:JavadocMethod OFF + // CheckStyle:LeftCurly OFF + public Integer getType2() { return type2; } + public void setType2(final Integer t) { type2 = t; } + public Integer[] getTypeArray2() { return typeArray2; } + public void setTypeArray2(final Integer[] t) { typeArray2 = t; } + public Collection<Integer> getTypeCol2() { return typeCol2; } + public void setTypeCol2(final Collection<Integer> c) { typeCol2 = c; } + public Set<Integer> getTypeSet2() { return typeSet2; } + public void setTypeSet2(final Set<Integer> s) { typeSet2 = s; } + public List<Integer> getTypeList2() { return typeList2; } + public void setTypeList2(final List<Integer> l) { typeList2 = l; } + // CheckStyle:LeftCurly ON + // CheckStyle:JavadocMethod ON + } +}
diff --git a/beans/src/test/java/org/ldaptive/beans/reflect/LdapEntryMapperTest.java b/beans/src/test/java/org/ldaptive/beans/reflect/LdapEntryMapperTest.java new file mode 100644 index 0000000..c08fa0d --- /dev/null +++ b/beans/src/test/java/org/ldaptive/beans/reflect/LdapEntryMapperTest.java
@@ -0,0 +1,152 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import org.ldaptive.LdapEntry; +import org.ldaptive.beans.LdapEntryMapper; +import org.ldaptive.beans.spring.SpringLdapEntryMapper; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit tests for {@link LdapEntryMapper} implementations. + * + * @author Middleware Services + */ +public class LdapEntryMapperTest +{ + + + /** + * Test data for string based object. + * + * @return custom objects + */ + @DataProvider(name = "objects") + public Object[][] createCustomObjects() + { + final DefaultLdapEntryMapper defaultMapper = new DefaultLdapEntryMapper(); + final SpringLdapEntryMapper springMapper = new SpringLdapEntryMapper(); + + final LdapEntry stringEntry = StringCustomObject.createLdapEntry(); + final LdapEntry charEntry = StringCustomObject.createLdapEntry(); + charEntry.removeAttribute("col1"); + charEntry.removeAttribute("col2"); + charEntry.removeAttribute("typeArray1"); + charEntry.removeAttribute("typeArray2"); + charEntry.removeAttribute("transcoded"); + + final LdapEntry integerEntry = IntegerCustomObject.createLdapEntry(); + final LdapEntry floatEntry = FloatCustomObject.createLdapEntry(); + final LdapEntry booleanEntry = BooleanCustomObject.createLdapEntry(); + final LdapEntry binaryEntry = BinaryCustomObject.createLdapEntry(); + + return + new Object[][] { + new Object[] { + StringCustomObject.createCustomObject(StringCustomObject.Default.class), + stringEntry, + defaultMapper, + }, + new Object[] { + StringCustomObject.createCustomObject(StringCustomObject.Spring.class), + stringEntry, + springMapper, + }, + new Object[] { + CharCustomObject.createCustomObject(CharCustomObject.Default.class), + charEntry, + defaultMapper, + }, + new Object[] { + IntegerCustomObject.createCustomObject(IntegerCustomObject.Default.class), + integerEntry, + defaultMapper, + }, + new Object[] { + IntegerCustomObject.createCustomObject(IntegerCustomObject.Spring.class), + integerEntry, + springMapper, + }, + new Object[] { + IntCustomObject.createCustomObject(IntCustomObject.Default.class), + integerEntry, + defaultMapper, + }, + new Object[] { + IntCustomObject.createCustomObject(IntCustomObject.Spring.class), + integerEntry, + springMapper, + }, + new Object[] { + FloatCustomObject.createCustomObject(FloatCustomObject.Default.class), + floatEntry, + defaultMapper, + }, + new Object[] { + FloatCustomObject.createCustomObject(FloatCustomObject.Spring.class), + floatEntry, + springMapper, + }, + new Object[] { + BooleanCustomObject.createCustomObject(BooleanCustomObject.Default.class), + booleanEntry, + defaultMapper, + }, + new Object[] { + BooleanCustomObject.createCustomObject(BooleanCustomObject.Spring.class), + booleanEntry, + springMapper, + }, + new Object[] { + BinaryCustomObject.createCustomObject(BinaryCustomObject.Default.class), + binaryEntry, + defaultMapper, + }, + new Object[] { + BinaryCustomObject.createCustomObject(BinaryCustomObject.Spring.class), + binaryEntry, + springMapper, + }, + }; + } + + + /** + * @param object initialized with data + * @param entry to compare with mapped entry + * @param mapper to invoke + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans"}, dataProvider = "objects") + public void mapToLdapEntry( + final CustomObject object, + final LdapEntry entry, + final LdapEntryMapper<CustomObject> mapper) + throws Exception + { + final LdapEntry mapped = new LdapEntry(); + object.initialize(); + mapper.map(object, mapped); + Assert.assertEquals(entry, mapped); + } + + + /** + * @param object to compare with mapped object + * @param entry initialized with data + * @param mapper to invoke + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans"}, dataProvider = "objects") + public void mapToObject(final CustomObject object, final LdapEntry entry, final LdapEntryMapper<CustomObject> mapper) + throws Exception + { + final CustomObject mapped = object.getClass().newInstance(); + mapper.map(entry, mapped); + mapped.initialize(); + Assert.assertEquals(object, mapped); + } +}
diff --git a/beans/src/test/java/org/ldaptive/beans/reflect/StringCustomObject.java b/beans/src/test/java/org/ldaptive/beans/reflect/StringCustomObject.java new file mode 100644 index 0000000..98aeba1 --- /dev/null +++ b/beans/src/test/java/org/ldaptive/beans/reflect/StringCustomObject.java
@@ -0,0 +1,327 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.reflect; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapUtils; +import org.ldaptive.SortBehavior; +import org.ldaptive.beans.Attribute; +import org.ldaptive.beans.Entry; + +/** + * Class for testing beans annotations. + * + * @author Middleware Services + */ +public class StringCustomObject implements CustomObject +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 11; + + // CheckStyle:JavadocVariable OFF + // CheckStyle:DeclarationOrder OFF + private String type1; + protected String type2; + private String type3; + private String[] typeArray1; + protected String[] typeArray2; + private Collection col1; + protected Collection col2; + private Collection<String> typeCol1; + protected Collection<String> typeCol2; + private Set<String> typeSet1; + protected Set<String> typeSet2; + private List<String> typeList1; + protected List<String> typeList2; + private String transcoded; + private final String[] nullArray1 = new String[] {null}; + private List<String> nullList1; + // CheckStyle:DeclarationOrder ON + // CheckStyle:JavadocVariable ON + + + // CheckStyle:JavadocMethod OFF + // CheckStyle:LeftCurly OFF + public String getType1() { return type1; } + public void setType1(final String t) { type1 = t; } + public void writeType2(final String t) { type2 = t; } + public String getType3() { return type3; } + public void setType3(final String t) { type3 = t; } + public String[] getTypeArray1() { return typeArray1; } + public void setTypeArray1(final String[] t) { typeArray1 = t; } + public void writeTypeArray2(final String[] t) { typeArray2 = t; } + public Collection getCol1() { return col1; } + public void setCol1(final Collection c) { col1 = c; } + public void writeCol2(final Collection c) { col2 = c; } + public Collection<String> getTypeCol1() { return typeCol1; } + public void setTypeCol1(final Collection<String> c) { typeCol1 = c; } + public void writeTypeCol2(final Collection<String> c) { typeCol2 = c; } + public Set<String> getTypeSet1() { return typeSet1; } + public void setTypeSet1(final Set<String> s) { typeSet1 = s; } + public void writeTypeSet2(final Set<String> s) { typeSet2 = s; } + public List<String> getTypeList1() { return typeList1; } + public void setTypeList1(final List<String> l) { typeList1 = l; } + public void writeTypeList2(final List<String> l) { typeList2 = l; } + public String getTranscoded() { return transcoded; } + public void setTranscoded(final String t) { transcoded = t; } + public String[] getNullArray1() { return nullArray1; } + public List<String> getNullList1() { return nullList1; } + // CheckStyle:LeftCurly ON + // CheckStyle:JavadocMethod ON + + + @Override + public void initialize() + { + nullList1 = new ArrayList<>(1); + nullList1.add(null); + } + + + @Override + public boolean equals(final Object o) + { + return o != null && hashCode() == o.hashCode(); + } + + + @Override + @SuppressWarnings("unchecked") + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + type1, + type2, + type3, + typeArray1, + typeArray2, + col1 != null ? Collections.unmodifiableCollection(col1) : null, + col2 != null ? Collections.unmodifiableCollection(col2) : null, + typeCol1 != null ? Collections.unmodifiableCollection(typeCol1) : null, + typeCol2 != null ? Collections.unmodifiableCollection(typeCol2) : null, + typeSet1, + typeSet2, + typeList1, + typeList2, + transcoded); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::type1=%s, type2=%s, type3=%s, typeArray1=%s, typeArray2=%s, " + + "col1=%s, col2=%s, typeCol1=%s, typeCol2=%s, " + + "typeSet1=%s, typeSet2=%s, typeList1=%s, typeList2=%s, transcoded=%s]", + getClass().getSimpleName(), + hashCode(), + type1, + type2, + type3, + Arrays.toString(typeArray1), + Arrays.toString(typeArray2), + col1, + col2, + typeCol1, + typeCol2, + typeSet1, + typeSet2, + typeList1, + typeList2, + transcoded); + } + + + /** + * Creates a string custom object for testing. + * + * @param <T> type of string custom object + * @param type of string custom object + * + * @return instance of string custom object + */ + public static <T extends StringCustomObject> T createCustomObject(final Class<T> type) + { + final Set<String> s1 = new HashSet<>(); + s1.add("tsv1"); + s1.add("tsv2"); + + final T o1; + try { + o1 = type.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new IllegalStateException(e); + } + o1.setType1("tv1"); + o1.writeType2("tv2"); + o1.setType3("tv3"); + o1.setTypeArray1(new String[] {"tav1", "tav2"}); + o1.writeTypeArray2(new String[] {"tav1", "tav2"}); + o1.setCol1(Arrays.asList("cv1", "cv2")); + o1.writeCol2(Arrays.asList("cv1", "cv2")); + o1.setTypeCol1(Arrays.asList("tcv1", "tcv2")); + o1.writeTypeCol2(Arrays.asList("tcv1", "tcv2")); + o1.setTypeSet1(s1); + o1.writeTypeSet2(s1); + o1.setTypeList1(Arrays.asList("tlv1", "tlv2")); + o1.writeTypeList2(Arrays.asList("tlv1", "tlv2")); + o1.setTranscoded("transcoded"); + + return o1; + } + + + /** + * Creates an ldap entry containing string values. + * + * @return ldap entry + */ + public static LdapEntry createLdapEntry() + { + final LdapAttribute typeArray1 = new LdapAttribute(SortBehavior.ORDERED); + typeArray1.setName("typeArray1"); + typeArray1.addStringValue("tav1", "tav2"); + + final LdapAttribute typeArray2 = new LdapAttribute(SortBehavior.ORDERED); + typeArray2.setName("typeArray2"); + typeArray2.addStringValue("tav1", "tav2"); + + final LdapAttribute col1 = new LdapAttribute(SortBehavior.ORDERED); + col1.setName("col1"); + col1.addStringValue("cv1", "cv2"); + + final LdapAttribute col2 = new LdapAttribute(SortBehavior.ORDERED); + col2.setName("col2"); + col2.addStringValue("cv1", "cv2"); + + final LdapAttribute typeCol1 = new LdapAttribute(SortBehavior.ORDERED); + typeCol1.setName("typeCol1"); + typeCol1.addStringValue("tcv1", "tcv2"); + + final LdapAttribute typeCol2 = new LdapAttribute(SortBehavior.ORDERED); + typeCol2.setName("typeCol2"); + typeCol2.addStringValue("tcv1", "tcv2"); + + final LdapAttribute typeSet1 = new LdapAttribute(SortBehavior.ORDERED); + typeSet1.setName("typeSet1"); + typeSet1.addStringValue("tsv1", "tsv2"); + + final LdapAttribute typeSet2 = new LdapAttribute(SortBehavior.ORDERED); + typeSet2.setName("typeSet2"); + typeSet2.addStringValue("tsv1", "tsv2"); + + final LdapAttribute typeList1 = new LdapAttribute(SortBehavior.ORDERED); + typeList1.setName("typeList1"); + typeList1.addStringValue("tlv1", "tlv2"); + + final LdapAttribute typeList2 = new LdapAttribute(SortBehavior.ORDERED); + typeList2.setName("typeList2"); + typeList2.addStringValue("tlv1", "tlv2"); + + final LdapEntry entry = new LdapEntry(); + entry.setDn("cn=String Entry,ou=people,dc=ldaptive,dc=org"); + entry.addAttribute( + new LdapAttribute("customname1", "customvalue1"), + new LdapAttribute("customname2", "customvalue1", "customvalue2"), + new LdapAttribute("type1", "tv1"), + new LdapAttribute("type2", "tv2"), + new LdapAttribute("stringthree", "tv3"), + typeArray1, + typeArray2, + col1, + col2, + typeCol1, + typeCol2, + typeSet1, + typeSet2, + typeList1, + typeList2, + new LdapAttribute("transcoded", "prefix-transcoded")); + + return entry; + } + + + /** Test class for the default ldap entry mapper. */ + @Entry( + dn = "cn=String Entry,ou=people,dc=ldaptive,dc=org", attributes = { + @Attribute(name = "customname1", values = "customvalue1"), + @Attribute(name = "customname2", values = {"customvalue1", "customvalue2"}), + @Attribute(name = "type1", property = "type1"), + @Attribute(name = "type2", property = "type2"), + @Attribute(name = "stringthree", property = "type3"), + @Attribute(name = "typeArray1", property = "typeArray1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeArray2", property = "typeArray2", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "col1", property = "col1"), + @Attribute(name = "col2", property = "col2"), + @Attribute(name = "typeCol1", property = "typeCol1"), + @Attribute(name = "typeCol2", property = "typeCol2"), + @Attribute(name = "typeSet1", property = "typeSet1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeSet2", property = "typeSet2", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeList1", property = "typeList1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeList2", property = "typeList2", sortBehavior = SortBehavior.ORDERED), + @Attribute( + name = "transcoded", property = "transcoded", transcoder = "org.ldaptive.beans.reflect.CustomObject$" + + "PrefixStringValueTranscoder" + ), + @Attribute(name = "nullArray1", property = "nullArray1"), + @Attribute(name = "nullList1", property = "nullList1")}) + public static class Default extends StringCustomObject {} + + + /** Test class for the spring ldap entry mapper. */ + @Entry( + dn = "cn=String Entry,ou=people,dc=ldaptive,dc=org", attributes = { + @Attribute(name = "customname1", values = "customvalue1"), + @Attribute(name = "customname2", values = {"customvalue1", "customvalue2"}), + @Attribute(name = "type1", property = "type1"), + @Attribute(name = "type2", property = "type2"), + @Attribute(name = "stringthree", property = "type3"), + @Attribute(name = "typeArray1", property = "typeArray1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeArray2", property = "typeArray2", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "col1", property = "col1"), + @Attribute(name = "col2", property = "col2"), + @Attribute(name = "typeCol1", property = "typeCol1"), + @Attribute(name = "typeCol2", property = "typeCol2"), + @Attribute(name = "typeSet1", property = "typeSet1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeSet2", property = "typeSet2", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeList1", property = "typeList1", sortBehavior = SortBehavior.ORDERED), + @Attribute(name = "typeList2", property = "typeList2", sortBehavior = SortBehavior.ORDERED), + @Attribute( + name = "transcoded", property = "transcoded", transcoder = "new org.ldaptive.beans.reflect.CustomObject$" + + "PrefixStringValueTranscoder(1)" + ), + @Attribute(name = "nullArray1", property = "nullArray1"), + @Attribute(name = "nullList1", property = "nullList1")}) + public static class Spring extends StringCustomObject + { + // CheckStyle:JavadocMethod OFF + // CheckStyle:LeftCurly OFF + public String getType2() { return type2; } + public void setType2(final String t) { type2 = t; } + public String[] getTypeArray2() { return typeArray2; } + public void setTypeArray2(final String[] t) { typeArray2 = t; } + public Collection getCol2() { return col2; } + public void setCol2(final Collection c) { col2 = c; } + public Collection<String> getTypeCol2() { return typeCol2; } + public void setTypeCol2(final Collection<String> c) { typeCol2 = c; } + public Set<String> getTypeSet2() { return typeSet2; } + public void setTypeSet2(final Set<String> s) { typeSet2 = s; } + public List<String> getTypeList2() { return typeList2; } + public void setTypeList2(final List<String> l) { typeList2 = l; } + // CheckStyle:LeftCurly ON + // CheckStyle:JavadocMethod ON + } +}
diff --git a/beans/src/test/resources/allschema.ldif b/beans/src/test/resources/allschema.ldif new file mode 100644 index 0000000..aca3e0d --- /dev/null +++ b/beans/src/test/resources/allschema.ldif
@@ -0,0 +1,2712 @@ +#This LDIF file was generated by Novell's ICE and the LDIF destination handler. +version: 1 + +dn: cn=schema +changetype: add +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.1 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.2 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.3 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.4 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.5 X-NDS_SYNTAX '21' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.6 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.7 X-NDS_SYNTAX '7' ) +ldapSyntaxes: ( 2.16.840.1.113719.1.1.5.1.6 X-NDS_SYNTAX '6' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.8 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.9 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.10 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 2.16.840.1.113719.1.1.5.1.22 X-NDS_SYNTAX '22' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.11 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_SYNTAX '1' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.13 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.14 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.15 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.16 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.17 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.18 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.19 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.20 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.21 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.22 X-NDS_SYNTAX '11' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.23 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.24 X-NDS_SYNTAX '24' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.25 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.26 X-NDS_SYNTAX '2' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.27 X-NDS_SYNTAX '8' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.28 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.2.840.113556.1.4.906 X-NDS_SYNTAX '29' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.54 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.56 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.57 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.29 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.30 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.31 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.32 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.33 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.55 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.34 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.35 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 2.16.840.1.113719.1.1.5.1.19 X-NDS_SYNTAX '19' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.36 X-NDS_SYNTAX '5' ) +ldapSyntaxes: ( 2.16.840.1.113719.1.1.5.1.17 X-NDS_SYNTAX '17' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.37 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 2.16.840.1.113719.1.1.5.1.13 X-NDS_SYNTAX '13' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.40 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.38 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.39 X-NDS_SYNTAX '3' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.41 X-NDS_SYNTAX '18' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.43 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.44 X-NDS_SYNTAX '4' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.42 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 2.16.840.1.113719.1.1.5.1.16 X-NDS_SYNTAX '16' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.58 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.45 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.46 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.47 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.48 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.49 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 2.16.840.1.113719.1.1.5.1.12 X-NDS_SYNTAX '12' ) +ldapSyntaxes: ( 2.16.840.1.113719.1.1.5.1.23 X-NDS_SYNTAX '23' ) +ldapSyntaxes: ( 2.16.840.1.113719.1.1.5.1.15 X-NDS_SYNTAX '15' ) +ldapSyntaxes: ( 2.16.840.1.113719.1.1.5.1.14 X-NDS_SYNTAX '14' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.50 X-NDS_SYNTAX '10' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.51 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.52 X-NDS_SYNTAX '9' ) +ldapSyntaxes: ( 2.16.840.1.113719.1.1.5.1.25 X-NDS_SYNTAX '25' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.53 X-NDS_SYNTAX '9' ) +objectClass: top +objectClass: subschema +objectClasses: ( 2.5.6.0 NAME 'Top' STRUCTURAL MUST objectClass MAY ( cAPublic + Key $ cAPrivateKey $ certificateValidityInterval $ authorityRevocation $ las + tReferencedTime $ equivalentToMe $ ACL $ backLink $ binderyProperty $ Obitua + ry $ Reference $ revision $ ndsCrossCertificatePair $ certificateRevocation + $ usedBy $ GUID $ otherGUID $ DirXML-Associations $ creatorsName $ modifiers + Name $ objectVersion $ auxClassCompatibility $ unknownBaseClass $ unknownAux + iliaryClass $ masvProposedLabel $ masvDefaultRange $ masvAuthorizedRange $ a + uditFileLink $ rbsAssignedRoles $ rbsOwnedCollections $ rbsAssignedRoles2 $ + rbsOwnedCollections2 ) X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '16#subtre + e#[Creator]#[Entry Rights]' ) +objectClasses: ( 1.3.6.1.4.1.42.2.27.1.2.1 NAME 'aliasObject' SUP Top STRUCTUR + AL MUST aliasedObjectName X-NDS_NAME 'Alias' X-NDS_NOT_CONTAINER '1' X-NDS_N + ONREMOVABLE '1' ) +objectClasses: ( 2.5.6.2 NAME 'Country' SUP Top STRUCTURAL MUST c MAY ( descri + ption $ searchGuide $ sssActiveServerList $ sssServerPolicyOverrideDN ) X-ND + S_NAMING 'c' X-NDS_CONTAINMENT ( 'Top' 'treeRoot' 'domain' ) X-NDS_NONREMOVA + BLE '1' ) +objectClasses: ( 2.5.6.3 NAME 'Locality' SUP Top STRUCTURAL MAY ( description + $ l $ seeAlso $ st $ street $ searchGuide $ sssActiveServerList $ sssServerP + olicyOverrideDN ) X-NDS_NAMING ( 'l' 'st' ) X-NDS_CONTAINMENT ( 'Country' 'o + rganizationalUnit' 'Locality' 'Organization' 'domain' ) X-NDS_NONREMOVABLE ' + 1' ) +objectClasses: ( 2.5.6.4 NAME 'Organization' SUP ( ndsLoginProperties $ ndsCon + tainerLoginProperties ) STRUCTURAL MUST o MAY ( description $ facsimileTelep + honeNumber $ l $ loginScript $ eMailAddress $ physicalDeliveryOfficeName $ p + ostalAddress $ postalCode $ postOfficeBox $ printJobConfiguration $ printerC + ontrol $ seeAlso $ st $ street $ telephoneNumber $ loginIntruderLimit $ intr + uderAttemptResetInterval $ detectIntruder $ lockoutAfterDetection $ intruder + LockoutResetInterval $ nNSDomain $ mailboxLocation $ mailboxID $ x121Address + $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ tele + xNumber $ teletexTerminalIdentifier $ internationaliSDNNumber $ businessCate + gory $ searchGuide $ rADIUSAttributeLists $ rADIUSDefaultProfile $ rADIUSDia + lAccessGroup $ rADIUSEnableDialAccess $ rADIUSServiceList $ sssActiveServerL + ist $ sssServerPolicyOverrideDN $ iPrintiCMClientFlags $ iPrintiCMClientProx + yURI $ iPrintiCMClientTrayURI $ iPrintiCMPrinterFlags $ iPrintiCMPrinterList + $ DFS-VLDB-Hosts $ VLDB-BackEnd-ID $ userPassword ) X-NDS_NAMING 'o' X-NDS_ + CONTAINMENT ( 'Top' 'treeRoot' 'Country' 'Locality' 'domain' ) X-NDS_NONREMO + VABLE '1' X-NDS_ACL_TEMPLATES ( '2#entry#[Self]#loginScript' '2#entry#[Self] + #printJobConfiguration') ) +objectClasses: ( 2.5.6.5 NAME 'organizationalUnit' SUP ( ndsLoginProperties $ + ndsContainerLoginProperties ) STRUCTURAL MUST ou MAY ( description $ facsimi + leTelephoneNumber $ l $ loginScript $ eMailAddress $ physicalDeliveryOfficeN + ame $ postalAddress $ postalCode $ postOfficeBox $ printJobConfiguration $ p + rinterControl $ seeAlso $ st $ street $ telephoneNumber $ loginIntruderLimit + $ intruderAttemptResetInterval $ detectIntruder $ lockoutAfterDetection $ i + ntruderLockoutResetInterval $ nNSDomain $ mailboxLocation $ mailboxID $ x121 + Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod + $ telexNumber $ teletexTerminalIdentifier $ internationaliSDNNumber $ busin + essCategory $ searchGuide $ rADIUSAttributeLists $ rADIUSDefaultProfile $ rA + DIUSDialAccessGroup $ rADIUSEnableDialAccess $ rADIUSServiceList $ sssActive + ServerList $ sssServerPolicyOverrideDN $ iPrintiCMClientFlags $ iPrintiCMCli + entProxyURI $ iPrintiCMClientTrayURI $ iPrintiCMPrinterFlags $ iPrintiCMPrin + terList $ DFS-VLDB-Hosts $ VLDB-BackEnd-ID $ userPassword ) X-NDS_NAMING 'ou + ' X-NDS_CONTAINMENT ( 'Locality' 'Organization' 'organizationalUnit' 'domain + ' ) X-NDS_NAME 'Organizational Unit' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLA + TES ( '2#entry#[Self]#loginScript' '2#entry#[Self]#printJobConfiguration') ) +objectClasses: ( 2.5.6.8 NAME 'organizationalRole' SUP Top STRUCTURAL MUST cn + MAY ( description $ facsimileTelephoneNumber $ l $ eMailAddress $ ou $ physi + calDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ roleOcc + upant $ seeAlso $ st $ street $ telephoneNumber $ mailboxLocation $ mailboxI + D $ x121Address $ registeredAddress $ destinationIndicator $ preferredDelive + ryMethod $ telexNumber $ teletexTerminalIdentifier $ internationaliSDNNumber + ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' + 'domain' ) X-NDS_NAME 'Organizational Role' X-NDS_NOT_CONTAINER '1' X-NDS_N + ONREMOVABLE '1' ) +objectClasses: ( 2.5.6.9 NAME ( 'groupOfNames' 'group' 'groupOfUniqueNames' ) + SUP Top STRUCTURAL MUST cn MAY ( description $ l $ member $ ou $ o $ owner $ + seeAlso $ groupID $ fullName $ eMailAddress $ mailboxLocation $ mailboxID $ + Profile $ profileMembership $ loginScript $ businessCategory $ nspmPassword + PolicyDN $ iPrintiCMClientFlags $ iPrintiCMClientProxyURI $ iPrintiCMClientT + rayURI $ iPrintiCMPrinterFlags $ iPrintiCMPrinterList ) X-NDS_NAMING 'cn' X- + NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME + 'Group' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' ) +objectClasses: ( 2.5.6.6 NAME 'Person' SUP ndsLoginProperties STRUCTURAL MUST + ( cn $ sn ) MAY ( description $ seeAlso $ telephoneNumber $ fullName $ given + Name $ initials $ generationQualifier $ uid $ assistant $ assistantPhone $ c + ity $ st $ company $ co $ directReports $ manager $ mailstop $ mobile $ pers + onalTitle $ pager $ workforceID $ instantMessagingID $ preferredName $ photo + $ jobCode $ siteLocation $ employeeStatus $ employeeType $ costCenter $ cos + tCenterDescription $ tollFreePhoneNumber $ otherPhoneNumber $ managerWorkfor + ceID $ roomNumber $ jackNumber $ departmentNumber $ vehicleInformation $ acc + essCardNumber $ isManager $ userPassword ) X-NDS_NAMING ( 'cn' 'uid' ) X-NDS + _CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONT + AINER '1' X-NDS_NONREMOVABLE '1' ) +objectClasses: ( 2.5.6.7 NAME 'organizationalPerson' SUP Person STRUCTURAL MAY + ( facsimileTelephoneNumber $ l $ eMailAddress $ ou $ physicalDeliveryOffice + Name $ postalAddress $ postalCode $ postOfficeBox $ st $ street $ title $ ma + ilboxLocation $ mailboxID $ uid $ mail $ employeeNumber $ destinationIndicat + or $ internationaliSDNNumber $ preferredDeliveryMethod $ registeredAddress $ + teletexTerminalIdentifier $ telexNumber $ x121Address $ businessCategory $ + roomNumber $ x500UniqueIdentifier ) X-NDS_NAMING ( 'cn' 'ou' 'uid' ) X-NDS_C + ONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME 'Orga + nizational Person' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' ) +objectClasses: ( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' SUP organization + alPerson STRUCTURAL MAY ( groupMembership $ ndsHomeDirectory $ loginAllowedT + imeMap $ loginDisabled $ loginExpirationTime $ loginGraceLimit $ loginGraceR + emaining $ loginIntruderAddress $ loginIntruderAttempts $ loginIntruderReset + Time $ loginMaximumSimultaneous $ loginScript $ loginTime $ networkAddressRe + striction $ networkAddress $ passwordsUsed $ passwordAllowChange $ passwordE + xpirationInterval $ passwordExpirationTime $ passwordMinimumLength $ passwor + dRequired $ passwordUniqueRequired $ printJobConfiguration $ privateKey $ Pr + ofile $ publicKey $ securityEquals $ accountBalance $ allowUnlimitedCredit $ + minimumAccountBalance $ messageServer $ Language $ ndsUID $ lockedByIntrude + r $ serverHolds $ lastLoginTime $ typeCreatorMap $ higherPrivileges $ printe + rControl $ securityFlags $ profileMembership $ Timezone $ sASServiceDN $ sAS + SecretStore $ sASSecretStoreKey $ sASSecretStoreData $ sASPKIStoreKeys $ use + rCertificate $ nDSPKIUserCertificateInfo $ nDSPKIKeystore $ rADIUSActiveConn + ections $ rADIUSAttributeLists $ rADIUSConcurrentLimit $ rADIUSConnectionHis + tory $ rADIUSDefaultProfile $ rADIUSDialAccessGroup $ rADIUSEnableDialAccess + $ rADIUSPassword $ rADIUSServiceList $ audio $ businessCategory $ carLicens + e $ departmentNumber $ employeeNumber $ employeeType $ displayName $ givenNa + me $ homePhone $ homePostalAddress $ initials $ jpegPhoto $ labeledUri $ mai + l $ manager $ mobile $ o $ pager $ ldapPhoto $ preferredLanguage $ roomNumbe + r $ secretary $ uid $ userSMIMECertificate $ x500UniqueIdentifier $ userPKCS + 12 $ sssProxyStoreKey $ sssProxyStoreSecrets $ sssServerPolicyOverrideDN $ i + PrintiCMPrinterFlags $ iPrintiCMPrinterList $ iPrintiCMClientFlags $ iPrinti + CMClientProxyURI $ iPrintiCMClientTrayURI ) X-NDS_NAME 'User' X-NDS_NOT_CONT + AINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '2#subtree#[Self]#[Al + l Attributes Rights]' '6#entry#[Self]#loginScript' '1#subtree#[Root Template + ]#[Entry Rights]' '2#entry#[Public]#messageServer' '2#entry#[Root Template]# + groupMembership' '6#entry#[Self]#printJobConfiguration' '2#entry#[Root Templ + ate]#networkAddress') ) +objectClasses: ( 2.5.6.14 NAME 'Device' SUP Top STRUCTURAL MUST cn MAY ( descr + iption $ l $ networkAddress $ ou $ o $ owner $ seeAlso $ serialNumber ) X-ND + S_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domai + n' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.4 NAME 'Computer' SUP Device STRUCT + URAL MAY ( operator $ server $ status ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREM + OVABLE '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.17 NAME 'Printer' SUP Device STRUCT + URAL MAY ( Cartridge $ printerConfiguration $ defaultQueue $ hostDevice $ pr + intServer $ Memory $ networkAddressRestriction $ notify $ operator $ pageDes + criptionLanguage $ queue $ status $ supportedTypefaces ) X-NDS_NOT_CONTAINER + '1' X-NDS_NONREMOVABLE '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.21 NAME 'Resource' SUP Top ABSTRACT + MUST cn MAY ( description $ hostResourceName $ l $ ou $ o $ seeAlso $ Uses + ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' + 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.20 NAME 'Queue' SUP Resource STRUCT + URAL MUST queueDirectory MAY ( Device $ operator $ server $ User $ networkAd + dress $ Volume $ hostServer ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' + X-NDS_ACL_TEMPLATES '2#subtree#[Root Template]#[All Attributes Rights]' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.3 NAME 'binderyQueue' SUP Queue STR + UCTURAL MUST binderyType X-NDS_NAMING ( 'cn' 'binderyType' ) X-NDS_NAME 'Bin + dery Queue' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLAT + ES '2#subtree#[Root Template]#[All Attributes Rights]' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.26 NAME 'Volume' SUP Resource STRUC + TURAL MUST hostServer MAY ( status $ DFS-Volume-Guid $ nssfsPool $ linuxNCPM + ountPoint ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLAT + ES ( '2#entry#[Root Template]#hostResourceName' '2#entry#[Root Template]#hos + tServer') ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.7 NAME 'directoryMap' SUP Resource + STRUCTURAL MUST hostServer MAY path X-NDS_NAME 'Directory Map' X-NDS_NOT_CON + TAINER '1' X-NDS_NONREMOVABLE '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.19 NAME 'Profile' SUP Top STRUCTURA + L MUST ( cn $ loginScript ) MAY ( description $ l $ ou $ o $ seeAlso $ fullN + ame ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUn + it' 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.22 NAME 'Server' SUP Top ABSTRACT M + UST cn MAY ( description $ hostDevice $ l $ ou $ o $ privateKey $ publicKey + $ Resource $ seeAlso $ status $ User $ Version $ networkAddress $ accountBal + ance $ allowUnlimitedCredit $ minimumAccountBalance $ fullName $ securityEqu + als $ securityFlags $ Timezone $ ndapClassPasswordMgmt $ ndapClassLoginMgmt + ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' + 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATE + S ( '2#entry#[Public]#networkAddress' '16#subtree#[Self]#[Entry Rights]') ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.10 NAME 'ncpServer' SUP Server STRU + CTURAL MAY ( operator $ supportedServices $ messagingServer $ dsRevision $ p + ermanentConfigParms $ ndsPredicateStatsDN $ languageId $ indexDefinition $ C + achedAttrsOnExtRefs $ NCPKeyMaterialName $ ldapServerDN $ httpServerDN $ emb + oxConfig $ sASServiceDN $ cACertificate $ nDSPKIPublicKey $ nDSPKIPrivateKey + $ nDSPKICertificateChain $ nDSPKIParentCADN $ nDSPKISDKeyID $ nDSPKISDKeySt + ruct $ snmpGroupDN $ wANMANWANPolicy $ wANMANLANAreaMembership $ wANMANCost + $ wANMANDefaultCost $ encryptionPolicyDN $ eDirCloneSource $ eDirCloneLock ) + X-NDS_NAME 'NCP Server' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-ND + S_ACL_TEMPLATES '2#entry#[Public]#messagingServer' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.18 NAME 'printServer' SUP Server ST + RUCTURAL MAY ( operator $ printer $ sAPName ) X-NDS_NAME 'Print Server' X-ND + S_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '2#subtree#[R + oot Template]#[All Attributes Rights]' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.31 NAME 'CommExec' SUP Server STRUC + TURAL MAY networkAddressRestriction X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVAB + LE '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.2 NAME 'binderyObject' SUP Top STRU + CTURAL MUST ( binderyObjectRestriction $ binderyType $ cn ) X-NDS_NAMING ( ' + cn' 'binderyType' ) X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' + 'domain' ) X-NDS_NAME 'Bindery Object' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMO + VABLE '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.15 NAME 'Partition' AUXILIARY MAY ( + Convergence $ partitionCreationTime $ Replica $ inheritedACL $ lowConvergen + ceSyncInterval $ receivedUpTo $ synchronizedUpTo $ authorityRevocation $ cer + tificateRevocation $ cAPrivateKey $ cAPublicKey $ ndsCrossCertificatePair $ + lowConvergenceResetTime $ highConvergenceSyncInterval $ partitionControl $ r + eplicaUpTo $ partitionStatus $ transitiveVector $ purgeVector $ synchronizat + ionTolerance $ obituaryNotify $ localReceivedUpTo $ federationControl $ sync + PanePoint $ syncWindowVector $ authoritative $ allowAliasToAncestor $ sASSec + urityDN $ masvLabel $ ndapPartitionPasswordMgmt $ ndapPartitionLoginMgmt $ p + rSyncPolicyDN $ dsEncryptedReplicationConfig ) X-NDS_NOT_CONTAINER '1' X-NDS + _NONREMOVABLE '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.0 NAME 'aFPServer' SUP Server STRUC + TURAL MAY ( serialNumber $ supportedConnections ) X-NDS_NAME 'AFP Server' X- + NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.27 NAME 'messagingServer' SUP Serve + r STRUCTURAL MAY ( messagingDatabaseLocation $ messageRoutingGroup $ Postmas + ter $ supportedServices $ messagingServerType $ supportedGateway ) X-NDS_NAM + E 'Messaging Server' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_AC + L_TEMPLATES ( '1#subtree#[Self]#[Entry Rights]' '2#subtree#[Self]#[All Attri + butes Rights]' '6#entry#[Self]#status' '2#entry#[Public]#messagingServerType + ' '2#entry#[Public]#messagingDatabaseLocation') ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.28 NAME 'messageRoutingGroup' SUP g + roupOfNames STRUCTURAL X-NDS_NAME 'Message Routing Group' X-NDS_NOT_CONTAINE + R '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '1#subtree#[Self]#[Entry + Rights]' '2#subtree#[Self]#[All Attributes Rights]') ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.29 NAME 'externalEntity' SUP Top ST + RUCTURAL MUST cn MAY ( description $ seeAlso $ facsimileTelephoneNumber $ l + $ eMailAddress $ ou $ physicalDeliveryOfficeName $ postalAddress $ postalCod + e $ postOfficeBox $ st $ street $ title $ externalName $ mailboxLocation $ m + ailboxID ) X-NDS_NAMING ( 'cn' 'ou' ) X-NDS_CONTAINMENT ( 'Organization' 'or + ganizationalUnit' 'domain' ) X-NDS_NAME 'External Entity' X-NDS_NOT_CONTAINE + R '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '2#entry#[Public]#externalN + ame' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.30 NAME 'List' SUP Top STRUCTURAL M + UST cn MAY ( description $ l $ member $ ou $ o $ eMailAddress $ mailboxLocat + ion $ mailboxID $ owner $ seeAlso $ fullName ) X-NDS_NAMING 'cn' X-NDS_CONTA + INMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONTAINER + '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '2#entry#[Root Template]#memb + er' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.32 NAME 'treeRoot' SUP Top STRUCTUR + AL MUST T MAY sssActiveServerList X-NDS_NAMING 'T' X-NDS_NAME 'Tree Root' X- + NDS_NONREMOVABLE '1' ) +objectClasses: ( 0.9.2342.19200300.100.4.13 NAME 'domain' SUP ( Top $ ndsLogin + Properties $ ndsContainerLoginProperties ) STRUCTURAL MUST dc MAY ( searchGu + ide $ o $ seeAlso $ businessCategory $ x121Address $ registeredAddress $ des + tinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalI + dentifier $ telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNu + mber $ street $ postOfficeBox $ postalCode $ postalAddress $ physicalDeliver + yOfficeName $ l $ associatedName $ description $ sssActiveServerList $ sssSe + rverPolicyOverrideDN $ userPassword ) X-NDS_NAMING 'dc' X-NDS_CONTAINMENT ( + 'Top' 'treeRoot' 'Country' 'Locality' 'Organization' 'organizationalUnit' 'd + omain' ) X-NDS_NONREMOVABLE '1' ) +objectClasses: ( 1.3.6.1.4.1.1466.344 NAME 'dcObject' AUXILIARY MUST dc X-NDS_ + NAMING 'dc' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.33 NAME 'ndsLoginProperties' SUP To + p ABSTRACT MAY ( groupMembership $ loginAllowedTimeMap $ loginDisabled $ log + inExpirationTime $ loginGraceLimit $ loginGraceRemaining $ loginIntruderAddr + ess $ loginIntruderAttempts $ loginIntruderResetTime $ loginMaximumSimultane + ous $ loginScript $ loginTime $ networkAddressRestriction $ networkAddress $ + passwordsUsed $ passwordAllowChange $ passwordExpirationInterval $ password + ExpirationTime $ passwordMinimumLength $ passwordRequired $ passwordUniqueRe + quired $ privateKey $ Profile $ publicKey $ securityEquals $ accountBalance + $ allowUnlimitedCredit $ minimumAccountBalance $ Language $ lockedByIntruder + $ serverHolds $ lastLoginTime $ higherPrivileges $ securityFlags $ profileM + embership $ Timezone $ loginActivationTime $ UTF8LoginScript $ loginScriptCh + arset $ sASNDSPasswordWindow $ sASLoginSecret $ sASLoginSecretKey $ sASEncry + ptionType $ sASLoginConfiguration $ sASLoginConfigurationKey $ sasLoginFailu + reDelay $ sasDefaultLoginSequence $ sasAuthorizedLoginSequences $ sasAllowab + leSubjectNames $ ndapPasswordMgmt $ ndapLoginMgmt $ nspmPasswordKey $ nspmPa + ssword $ pwdChangedTime $ pwdAccountLockedTime $ pwdFailureTime $ nspmDoNotE + xpirePassword $ nspmDistributionPassword $ nspmPreviousDistributionPassword + $ nspmPasswordHistory $ nspmAdministratorChangeCount $ nspmPasswordPolicyDN + $ nsimHint $ nsimPasswordReminder $ userPassword ) X-NDS_NOT_CONTAINER '1' X + -NDS_NONREMOVABLE '1' ) +objectClasses: ( 2.16.840.1.113719.1.141.6.1 NAME 'federationBoundary' AUXILIA + RY MUST federationBoundaryType MAY ( federationControl $ federationDNSName $ + federationSearchPath ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.34 NAME 'ndsContainerLoginPropertie + s' SUP Top ABSTRACT MAY ( loginIntruderLimit $ intruderAttemptResetInterval + $ detectIntruder $ lockoutAfterDetection $ intruderLockoutResetInterval $ sa + sLoginFailureDelay $ sasDefaultLoginSequence $ sasAuthorizedLoginSequences $ + ndapPasswordMgmt $ ndapLoginMgmt $ nspmPasswordPolicyDN ) X-NDS_NOT_CONTAIN + ER '1' X-NDS_NONREMOVABLE '1' ) +objectClasses: ( 2.16.840.1.113719.1.27.6.3 NAME 'ndsPredicateStats' SUP Top S + TRUCTURAL MUST ( cn $ ndsPredicateState $ ndsPredicateFlush ) MAY ( ndsPredi + cate $ ndsPredicateTimeout $ ndsPredicateUseValues ) X-NDS_NAMING 'cn' X-NDS + _CONTAINMENT ( 'Country' 'Locality' 'Organization' 'organizationalUnit' 'dom + ain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.400.1 NAME 'edirSchemaVersion' SUP To + p ABSTRACT MAY edirSchemaFlagVersion X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVA + BLE '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.47 NAME 'immediateSuperiorReference + ' AUXILIARY MAY ref X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.27.6.1 NAME 'ldapServer' SUP Top STRUCTUR + AL MUST cn MAY ( ldapHostServer $ ldapGroupDN $ ldapTraceLevel $ ldapServerB + indLimit $ ldapServerIdleTimeout $ lDAPUDPPort $ lDAPSearchSizeLimit $ lDAPS + earchTimeLimit $ lDAPLogLevel $ lDAPLogFilename $ lDAPBackupLogFilename $ lD + APLogSizeLimit $ Version $ searchSizeLimit $ searchTimeLimit $ ldapEnableTCP + $ ldapTCPPort $ ldapEnableSSL $ ldapSSLPort $ ldapKeyMaterialName $ filtere + dReplicaUsage $ extensionInfo $ nonStdClientSchemaCompatMode $ sslEnableMutu + alAuthentication $ ldapEnablePSearch $ ldapMaximumPSearchOperations $ ldapIg + norePSearchLimitsForEvents $ ldapTLSTrustedRootContainer $ ldapEnableMonitor + Events $ ldapMaximumMonitorEventsLoad $ ldapTLSRequired $ ldapTLSVerifyClien + tCertificate $ ldapConfigVersion $ ldapDerefAlias $ ldapNonStdAllUserAttrsMo + de $ ldapBindRestrictions $ ldapDefaultReferralBehavior $ ldapReferral $ lda + pSearchReferralUsage $ lDAPOtherReferralUsage $ ldapLBURPNumWriterThreads $ + ldapInterfaces $ ldapChainSecureRequired $ ldapStdCompliance ) X-NDS_NAMING + 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organiza + tion' 'domain' ) X-NDS_NAME 'LDAP Server' X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.27.6.2 NAME 'ldapGroup' SUP Top STRUCTURA + L MUST cn MAY ( ldapReferral $ ldapServerList $ ldapAllowClearTextPassword $ + ldapAnonymousIdentity $ lDAPSuffix $ ldapAttributeMap $ ldapClassMap $ ldap + SearchReferralUsage $ lDAPOtherReferralUsage $ transitionGroupDN $ ldapAttri + buteList $ ldapClassList $ ldapConfigVersion $ Version $ ldapDefaultReferral + Behavior $ ldapTransitionBackLink $ referralIncludeFilter $ referralExcludeF + ilter ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organiza + tionalUnit' 'Organization' 'domain' ) X-NDS_NAME 'LDAP Group' X-NDS_NOT_CONT + AINER '1' ) +objectClasses: ( 2.5.6.22 NAME 'pkiCA' AUXILIARY MAY ( cACertificate $ certifi + cateRevocationList $ authorityRevocationList $ crossCertificatePair $ attrib + uteCertificate $ publicKey $ privateKey $ networkAddress $ loginTime $ lastL + oginTime ) X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.5.6.21 NAME 'pkiUser' AUXILIARY MAY userCertificate X-NDS_N + OT_CONTAINER '1' ) +objectClasses: ( 2.5.6.15 NAME 'strongAuthenticationUser' AUXILIARY MAY userCe + rtificate X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.5.6.11 NAME 'applicationProcess' SUP Top STRUCTURAL MUST cn + MAY ( seeAlso $ ou $ l $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT + ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'domain' ) ) +objectClasses: ( 2.5.6.12 NAME 'applicationEntity' SUP Top STRUCTURAL MUST ( p + resentationAddress $ cn ) MAY ( supportedApplicationContext $ seeAlso $ ou $ + o $ l $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Loca + lity' 'organizationalUnit' 'Organization' 'domain' ) ) +objectClasses: ( 2.5.6.13 NAME 'dSA' SUP applicationEntity STRUCTURAL MAY know + ledgeInformation X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUni + t' 'Organization' 'domain' ) ) +objectClasses: ( 2.5.6.16 NAME 'certificationAuthority' AUXILIARY MUST ( autho + rityRevocationList $ certificateRevocationList $ cACertificate ) MAY crossCe + rtificatePair X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.5.6.18 NAME 'userSecurityInformation' AUXILIARY MAY support + edAlgorithms X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.5.6.20 NAME 'dmd' SUP ndsLoginProperties AUXILIARY MUST dmd + Name MAY ( searchGuide $ seeAlso $ businessCategory $ x121Address $ register + edAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ t + eletexTerminalIdentifier $ telephoneNumber $ internationaliSDNNumber $ facsi + mileTelephoneNumber $ street $ postOfficeBox $ postalCode $ postalAddress $ + physicalDeliveryOfficeName $ l $ description $ userPassword ) X-NDS_NOT_CONT + AINER '1' ) +objectClasses: ( 2.5.6.16.2 NAME 'certificationAuthority-V2' AUXILIARY MUST ( + authorityRevocationList $ certificateRevocationList $ cACertificate ) MAY ( + crossCertificatePair $ deltaRevocationList ) X-NDS_NAME 'certificationAuthor + ityVer2' X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.3.6.1 NAME 'httpServer' SUP Top STRUCTURA + L MUST cn MAY ( httpHostServerDN $ httpThreadsPerCPU $ httpIOBufferSize $ ht + tpRequestTimeout $ httpKeepAliveRequestTimeout $ httpSessionTimeout $ httpKe + yMaterialObject $ httpTraceLevel $ httpAuthRequiresTLS $ httpDefaultClearPor + t $ httpDefaultTLSPort ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'domain' 'Cou + ntry' 'Locality' 'organizationalUnit' 'Organization' ) X-NDS_NOT_CONTAINER ' + 1' ) +objectClasses: ( 2.16.840.1.113719.1.64.6.1.1 NAME 'Template' SUP Top STRUCTUR + AL MUST cn MAY ( trusteesOfNewObject $ newObjectSDSRights $ newObjectSFSRigh + ts $ setupScript $ runSetupScript $ membersOfTemplate $ volumeSpaceRestricti + ons $ setPasswordAfterCreate $ homeDirectoryRights $ accountBalance $ allowU + nlimitedCredit $ description $ eMailAddress $ facsimileTelephoneNumber $ gro + upMembership $ higherPrivileges $ ndsHomeDirectory $ l $ Language $ loginAll + owedTimeMap $ loginDisabled $ loginExpirationTime $ loginGraceLimit $ loginM + aximumSimultaneous $ loginScript $ mailboxID $ mailboxLocation $ member $ me + ssageServer $ minimumAccountBalance $ networkAddressRestriction $ newObjectS + SelfRights $ ou $ passwordAllowChange $ passwordExpirationInterval $ passwor + dExpirationTime $ passwordMinimumLength $ passwordRequired $ passwordUniqueR + equired $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOffi + ceBox $ Profile $ st $ street $ securityEquals $ securityFlags $ seeAlso $ t + elephoneNumber $ title $ assistant $ assistantPhone $ city $ company $ co $ + manager $ managerWorkforceID $ mailstop $ siteLocation $ employeeType $ cost + Center $ costCenterDescription $ tollFreePhoneNumber $ departmentNumber ) X- + NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'organizationalUnit' 'Organization' ) X- + NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.8.6.1 NAME 'homeInfo' AUXILIARY MAY ( hom + eCity $ homeEmailAddress $ homeFax $ homePhone $ homeState $ homePostalAddre + ss $ homeZipCode $ personalMobile $ spouse $ children ) X-NDS_NOT_CONTAINER + '1' ) +objectClasses: ( 2.16.840.1.113719.1.8.6.2 NAME 'contingentWorker' AUXILIARY M + AY ( vendorName $ vendorAddress $ vendorPhoneNumber ) X-NDS_NOT_CONTAINER '1 + ' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.45 NAME 'dynamicGroup' SUP ( groupO + fNames $ ndsLoginProperties ) STRUCTURAL MAY ( memberQueryURL $ excludedMemb + er $ dgIdentity $ dgAllowUnknown $ dgTimeOut $ dgAllowDuplicates $ userPassw + ord ) X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.46 NAME 'dynamicGroupAux' SUP ( gro + upOfNames $ ndsLoginProperties ) AUXILIARY MAY ( memberQueryURL $ excludedMe + mber $ dgIdentity $ dgAllowUnknown $ dgTimeOut $ dgAllowDuplicates $ userPas + sword ) X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.39.6.1.1 NAME 'sASSecurity' SUP Top STRUC + TURAL MUST cn MAY ( nDSPKITreeCADN $ masvPolicyDN $ sASLoginPolicyDN $ sASLo + ginMethodContainerDN $ sasPostLoginMethodContainerDN $ nspmPolicyAgentContai + nerDN ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Top' 'treeRoot' 'Country' 'Or + ganization' 'domain' ) X-NDS_NAME 'SAS:Security' ) +objectClasses: ( 2.16.840.1.113719.1.39.6.1.2 NAME 'sASService' SUP Resource S + TRUCTURAL MAY ( hostServer $ privateKey $ publicKey $ allowUnlimitedCredit $ + fullName $ lastLoginTime $ lockedByIntruder $ loginAllowedTimeMap $ loginDi + sabled $ loginExpirationTime $ loginIntruderAddress $ loginIntruderAttempts + $ loginIntruderResetTime $ loginMaximumSimultaneous $ loginTime $ networkAdd + ress $ networkAddressRestriction $ notify $ operator $ owner $ path $ securi + tyEquals $ securityFlags $ status $ Version $ nDSPKIKeyMaterialDN $ ndspkiKM + OExport ) X-NDS_NAMING 'cn' X-NDS_NAME 'SAS:Service' X-NDS_NOT_CONTAINER '1' + ) +objectClasses: ( 2.16.840.1.113719.1.48.6.1.1 NAME 'nDSPKICertificateAuthority + ' SUP Top STRUCTURAL MUST cn MAY ( hostServer $ nDSPKIPublicKey $ nDSPKIPriv + ateKey $ nDSPKIPublicKeyCertificate $ nDSPKICertificateChain $ nDSPKIParentC + A $ nDSPKIParentCADN $ nDSPKISubjectName $ cACertificate $ ndspkiCRLContaine + rDN $ ndspkiIssuedCertContainerDN $ ndspkiCRLConfigurationDNList $ ndspkiSec + urityRightsLevel ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecurity' X-NDS_N + AME 'NDSPKI:Certificate Authority' X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.48.6.1.2 NAME 'nDSPKIKeyMaterial' SUP Top + STRUCTURAL MUST cn MAY ( hostServer $ nDSPKIKeyFile $ nDSPKIPrivateKey $ nD + SPKIPublicKey $ nDSPKIPublicKeyCertificate $ nDSPKICertificateChain $ nDSPKI + SubjectName $ nDSPKIGivenName $ ndspkiAdditionalRoots $ nDSPKINotBefore $ nD + SPKINotAfter ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'sASSecurity' 'Organiza + tion' 'organizationalUnit' 'domain' ) X-NDS_NAME 'NDSPKI:Key Material' X-NDS + _NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.48.6.1.3 NAME 'nDSPKITrustedRoot' SUP Top + STRUCTURAL MUST cn MAY ndspkiTrustedRootList X-NDS_NAMING 'cn' X-NDS_CONTAI + NMENT ( 'sASSecurity' 'Organization' 'organizationalUnit' 'Country' 'Localit + y' 'domain' ) X-NDS_NAME 'NDSPKI:Trusted Root' ) +objectClasses: ( 2.16.840.1.113719.1.48.6.1.4 NAME 'nDSPKITrustedRootObject' S + UP Top STRUCTURAL MUST ( cn $ nDSPKITrustedRootCertificate ) MAY ( nDSPKISub + jectName $ nDSPKINotBefore $ nDSPKINotAfter $ externalName $ givenName $ sn + ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'nDSPKITrustedRoot' X-NDS_NAME 'NDSPKI + :Trusted Root Object' X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.48.6.1.101 NAME 'nDSPKISDKeyAccessPartiti + on' SUP Top STRUCTURAL MUST cn X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecur + ity' X-NDS_NAME 'NDSPKI:SD Key Access Partition' ) +objectClasses: ( 2.16.840.1.113719.1.48.6.1.102 NAME 'nDSPKISDKeyList' SUP Top + STRUCTURAL MUST cn MAY ( nDSPKISDKeyServerDN $ nDSPKISDKeyStruct $ nDSPKISD + KeyCert ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'nDSPKISDKeyAccessPartition' X + -NDS_NAME 'NDSPKI:SD Key List' ) +objectClasses: ( 2.16.840.1.113719.1.31.6.2.1 NAME 'mASVSecurityPolicy' SUP To + p STRUCTURAL MUST cn MAY ( description $ masvDomainPolicy $ masvPolicyUpdate + $ masvClearanceNames $ masvLabelNames $ masvLabelSecrecyLevelNames $ masvLa + belSecrecyCategoryNames $ masvLabelIntegrityLevelNames $ masvLabelIntegrityC + ategoryNames $ masvNDSAttributeLabels ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT + 'sASSecurity' X-NDS_NAME 'MASV:Security Policy' X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.39.42.2.0.1 NAME 'sASLoginMethodContainer + ' SUP Top STRUCTURAL MUST cn MAY description X-NDS_NAMING 'cn' X-NDS_CONTAIN + MENT ( 'sASSecurity' 'Country' 'Locality' 'organizationalUnit' 'Organization + ' ) X-NDS_NAME 'SAS:Login Method Container' ) +objectClasses: ( 2.16.840.1.113719.1.39.42.2.0.4 NAME 'sASLoginPolicy' SUP Top + STRUCTURAL MUST cn MAY ( description $ privateKey $ publicKey $ sASAllowNDS + PasswordWindow $ sASPolicyCredentials $ sASPolicyMethods $ sASPolicyObjectVe + rsion $ sASPolicyServiceSubtypes $ sASPolicyServices $ sASPolicyUsers $ sASL + oginSequence $ sASLoginPolicyUpdate $ sasNMASProductOptions $ sasPolicyMetho + ds $ sasPolicyServices $ sasPolicyUsers $ sasAllowNDSPasswordWindow $ sasLog + inFailureDelay $ sasDefaultLoginSequence $ sasAuthorizedLoginSequences $ sas + AuditConfiguration $ nspmPasswordPolicyDN ) X-NDS_NAMING 'cn' X-NDS_CONTAINM + ENT 'sASSecurity' X-NDS_NAME 'SAS:Login Policy' X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.39.42.2.0.7 NAME 'sASNMASBaseLoginMethod' + SUP Top ABSTRACT MUST cn MAY ( description $ sASLoginSecret $ sASLoginSecre + tKey $ sASEncryptionType $ sASLoginConfiguration $ sASLoginConfigurationKey + $ sASMethodIdentifier $ sASMethodVendor $ sASVendorSupport $ sASAdvisoryMeth + odGrade $ sASLoginClientMethodNetWare $ sASLoginServerMethodNetWare $ sASLog + inClientMethodWINNT $ sASLoginServerMethodWINNT $ sasCertificateSearchContai + ners $ sasNMASMethodConfigData $ sasMethodVersion $ sASLoginPolicyUpdate $ s + asLoginClientMethodSolaris $ sasLoginServerMethodSolaris $ sasLoginClientMet + hodLinux $ sasLoginServerMethodLinux $ sasLoginClientMethodTru64 $ sasLoginS + erverMethodTru64 $ sasLoginClientMethodAIX $ sasLoginServerMethodAIX $ sasLo + ginClientMethodHPUX $ sasLoginServerMethodHPUX $ sasLoginClientMethods390 $ + sasLoginServerMethods390 ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASLoginMeth + odContainer' X-NDS_NAME 'SAS:NMAS Base Login Method' ) +objectClasses: ( 2.16.840.1.113719.1.39.42.2.0.8 NAME 'sASNMASLoginMethod' SUP + sASNMASBaseLoginMethod STRUCTURAL X-NDS_NAME 'SAS:NMAS Login Method' ) +objectClasses: ( 2.16.840.1.113719.1.39.42.2.0.9 NAME 'rADIUSDialAccessSystem' + SUP Top STRUCTURAL MUST cn MAY ( publicKey $ privateKey $ rADIUSAgedInterva + l $ rADIUSClient $ rADIUSCommonNameResolution $ rADIUSConcurrentLimit $ rADI + USDASVersion $ rADIUSEnableCommonNameLogin $ rADIUSEnableDialAccess $ rADIUS + InterimAcctingTimeout $ rADIUSLookupContexts $ rADIUSMaxDASHistoryRecord $ r + ADIUSMaximumHistoryRecord $ rADIUSPasswordPolicy $ rADIUSPrivateKey $ rADIUS + ProxyContext $ rADIUSProxyDomain $ rADIUSProxyTarget $ rADIUSPublicKey $ sAS + LoginConfiguration $ sASLoginConfigurationKey ) X-NDS_NAMING 'cn' X-NDS_CONT + AINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' ) X-NDS_N + AME 'RADIUS:Dial Access System' X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.39.42.2.0.10 NAME 'rADIUSProfile' SUP Top + STRUCTURAL MUST cn MAY rADIUSAttributeList X-NDS_NAMING 'cn' X-NDS_CONTAINM + ENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' ) X-NDS_NAME + 'RADIUS:Profile' X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.39.42.2.0.11 NAME 'sasPostLoginMethodCont + ainer' SUP Top STRUCTURAL MUST cn MAY description X-NDS_NAMING 'cn' X-NDS_CO + NTAINMENT 'sASSecurity' ) +objectClasses: ( 2.16.840.1.113719.1.39.42.2.0.12 NAME 'sasPostLoginMethod' SU + P Top STRUCTURAL MUST cn MAY ( description $ sASLoginSecret $ sASLoginSecret + Key $ sASEncryptionType $ sASLoginConfiguration $ sASLoginConfigurationKey $ + sASMethodIdentifier $ sASMethodVendor $ sASVendorSupport $ sASAdvisoryMetho + dGrade $ sASLoginClientMethodNetWare $ sASLoginServerMethodNetWare $ sASLogi + nClientMethodWINNT $ sASLoginServerMethodWINNT $ sasMethodVersion $ sASLogin + PolicyUpdate $ sasLoginClientMethodSolaris $ sasLoginServerMethodSolaris $ s + asLoginClientMethodLinux $ sasLoginServerMethodLinux $ sasLoginClientMethodT + ru64 $ sasLoginServerMethodTru64 $ sasLoginClientMethodAIX $ sasLoginServerM + ethodAIX $ sasLoginClientMethodHPUX $ sasLoginServerMethodHPUX $ sasLoginCli + entMethods390 $ sasLoginServerMethods390 ) X-NDS_NAMING 'cn' X-NDS_CONTAINME + NT 'sasPostLoginMethodContainer' ) +objectClasses: ( 2.16.840.1.113719.1.6.6.1 NAME 'snmpGroup' SUP Top STRUCTURAL + MUST cn MAY ( Version $ snmpServerList $ snmpTrapDisable $ snmpTrapInterval + $ snmpTrapDescription $ snmpTrapConfig ) X-NDS_NAMING 'cn' X-NDS_CONTAINMEN + T ( 'Country' 'Locality' 'domain' 'organizationalUnit' 'Organization' ) X-ND + S_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.39.43.6.2 NAME 'nspmPasswordPolicyContain + er' SUP Top STRUCTURAL MUST cn MAY description X-NDS_NAMING 'cn' X-NDS_CONTA + INMENT ( 'sASSecurity' 'Country' 'domain' 'Locality' 'Organization' 'organiz + ationalUnit' ) ) +objectClasses: ( 2.16.840.1.113719.1.39.43.6.3 NAME 'nspmPolicyAgent' SUP Top + STRUCTURAL MUST cn MAY ( description $ nspmPolicyAgentNetWare $ nspmPolicyAg + entWINNT $ nspmPolicyAgentSolaris $ nspmPolicyAgentLinux $ nspmPolicyAgentAI + X $ nspmPolicyAgentHPUX ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'nspmPasswordP + olicyContainer' X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.39.43.6.1 NAME 'nspmPasswordPolicy' SUP T + op STRUCTURAL MUST cn MAY ( description $ nspmPolicyPrecedence $ nspmConfigu + rationOptions $ nspmChangePasswordMessage $ passwordExpirationInterval $ log + inGraceLimit $ nspmMinPasswordLifetime $ passwordUniqueRequired $ nspmPasswo + rdHistoryLimit $ nspmPasswordHistoryExpiration $ passwordAllowChange $ passw + ordRequired $ passwordMinimumLength $ nspmMaximumLength $ nspmCaseSensitive + $ nspmMinUpperCaseCharacters $ nspmMaxUpperCaseCharacters $ nspmMinLowerCase + Characters $ nspmMaxLowerCaseCharacters $ nspmNumericCharactersAllowed $ nsp + mNumericAsFirstCharacter $ nspmNumericAsLastCharacter $ nspmMinNumericCharac + ters $ nspmMaxNumericCharacters $ nspmSpecialCharactersAllowed $ nspmSpecial + AsFirstCharacter $ nspmSpecialAsLastCharacter $ nspmMinSpecialCharacters $ n + spmMaxSpecialCharacters $ nspmMaxRepeatedCharacters $ nspmMaxConsecutiveChar + acters $ nspmMinUniqueCharacters $ nspmDisallowedAttributeValues $ nspmExclu + deList $ nspmExtendedCharactersAllowed $ nspmExtendedAsFirstCharacter $ nspm + ExtendedAsLastCharacter $ nspmMinExtendedCharacters $ nspmMaxExtendedCharact + ers $ nspmUpperAsFirstCharacter $ nspmUpperAsLastCharacter $ nspmLowerAsFirs + tCharacter $ nspmLowerAsLastCharacter $ nspmComplexityRules $ pwdInHistory $ + nspmAdminsDoNotExpirePassword $ nspmPasswordACL $ nsimChallengeSetDN $ nsim + ForgottenAction $ nsimForgottenLoginConfig $ nsimAssignments $ nsimChallenge + SetGUID $ nsimPwdRuleEnforcement ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'ns + pmPasswordPolicyContainer' 'domain' 'Locality' 'Organization' 'organizationa + lUnit' 'Country' ) X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.39.43.6.2 NAME 'nspmPasswordAux' AUXILIAR + Y MAY ( publicKey $ privateKey $ loginGraceLimit $ loginGraceRemaining $ pas + swordExpirationTime $ passwordRequired $ nspmPasswordKey $ nspmPassword $ ns + pmDistributionPassword $ nspmPreviousDistributionPassword $ nspmPasswordHist + ory $ nspmAdministratorChangeCount $ nspmPasswordPolicyDN $ pwdChangedTime $ + pwdAccountLockedTime $ pwdFailureTime $ nspmDoNotExpirePassword ) X-NDS_NOT + _CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.12.6.1.0 NAME 'auditFileObject' SUP Top S + TRUCTURAL MUST ( cn $ auditPolicy $ auditContents ) MAY ( description $ audi + tPath $ auditLinkList $ auditType $ auditCurrentEncryptionKey $ auditAEncryp + tionKey $ auditBEncryptionKey ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Top' + 'Country' 'Locality' 'Organization' 'organizationalUnit' 'treeRoot' 'domain' + ) X-NDS_NAME 'Audit:File Object' X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.38.6.1.4 NAME 'wANMANLANArea' SUP Top STR + UCTURAL MUST cn MAY ( description $ l $ member $ o $ ou $ owner $ seeAlso $ + wANMANWANPolicy $ wANMANCost $ wANMANDefaultCost ) X-NDS_NAMING 'cn' X-NDS_C + ONTAINMENT ( 'Country' 'Locality' 'Organization' 'organizationalUnit' ) X-ND + S_NAME 'WANMAN:LAN Area' X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.135.6.37.1 NAME 'rbsCollection' SUP Top S + TRUCTURAL MUST cn MAY ( owner $ description $ rbsXMLInfo ) X-NDS_NAMING 'cn' + X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization + ' 'domain' ) ) +objectClasses: ( 2.16.840.1.113719.1.135.6.30.1 NAME 'rbsExternalScope' SUP To + p ABSTRACT MUST cn MAY ( rbsURL $ description $ rbsXMLInfo ) X-NDS_NAMING 'c + n' X-NDS_CONTAINMENT 'rbsCollection' X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.135.6.31.1 NAME 'rbsModule' SUP Top STRUC + TURAL MUST cn MAY ( rbsURL $ rbsPath $ rbsType $ description $ rbsXMLInfo ) + X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsCollection' ) +objectClasses: ( 2.16.840.1.113719.1.135.6.32.1 NAME 'rbsRole' SUP Top STRUCTU + RAL MUST cn MAY ( rbsContent $ rbsMember $ rbsTrusteeOf $ rbsGALabel $ rbsPa + rameters $ description $ rbsXMLInfo ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'r + bsCollection' ) +objectClasses: ( 2.16.840.1.113719.1.135.6.33.1 NAME 'rbsTask' SUP Top STRUCTU + RAL MUST cn MAY ( rbsContentMembership $ rbsType $ rbsTaskRights $ rbsEntryP + oint $ rbsParameters $ rbsTaskTemplates $ rbsTaskTemplatesURL $ description + $ rbsXMLInfo ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsModule' X-NDS_NOT_CON + TAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.135.6.34.1 NAME 'rbsBook' SUP rbsTask STR + UCTURAL MAY ( rbsTargetObjectType $ rbsPageMembership ) X-NDS_NOT_CONTAINER + '1' ) +objectClasses: ( 2.16.840.1.113719.1.135.6.35.1 NAME 'rbsScope' SUP groupOfNam + es STRUCTURAL MAY ( rbsContext $ rbsXMLInfo ) X-NDS_CONTAINMENT 'rbsRole' X- + NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.135.6.45.1 NAME 'rbsCollection2' SUP Top + STRUCTURAL MUST cn MAY ( rbsXMLInfo $ rbsParameters $ owner $ description ) + X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUn + it' 'Organization' 'domain' ) ) +objectClasses: ( 2.16.840.1.113719.1.135.6.38.1 NAME 'rbsExternalScope2' SUP T + op ABSTRACT MUST cn MAY ( rbsXMLInfo $ description ) X-NDS_NAMING 'cn' X-NDS + _CONTAINMENT 'rbsCollection2' X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.135.6.39.1 NAME 'rbsModule2' SUP Top STRU + CTURAL MUST cn MAY ( rbsXMLInfo $ rbsPath $ rbsType $ description ) X-NDS_NA + MING 'cn' X-NDS_CONTAINMENT 'rbsCollection2' ) +objectClasses: ( 2.16.840.1.113719.1.135.6.40.1 NAME 'rbsRole2' SUP Top STRUCT + URAL MUST cn MAY ( rbsXMLInfo $ rbsContent $ rbsMember $ rbsTrusteeOf $ rbsP + arameters $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsCollection + 2' ) +objectClasses: ( 2.16.840.1.113719.1.135.6.41.1 NAME 'rbsTask2' SUP Top STRUCT + URAL MUST cn MAY ( rbsXMLInfo $ rbsContentMembership $ rbsType $ rbsTaskRigh + ts $ rbsEntryPoint $ rbsParameters $ description ) X-NDS_NAMING 'cn' X-NDS_C + ONTAINMENT 'rbsModule2' X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.135.6.42.1 NAME 'rbsBook2' SUP rbsTask2 S + TRUCTURAL MAY ( rbsTargetObjectType $ rbsPageMembership ) X-NDS_NOT_CONTAINE + R '1' ) +objectClasses: ( 2.16.840.1.113719.1.135.6.43.1 NAME 'rbsScope2' SUP groupOfNa + mes STRUCTURAL MAY ( rbsContext $ rbsXMLInfo ) X-NDS_CONTAINMENT 'rbsRole2' + X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.49 NAME 'prSyncPolicy' SUP Top STRU + CTURAL MUST cn MAY prSyncAttributes X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'd + omain' 'Country' 'Locality' 'organizationalUnit' 'Organization' ) X-NDS_NOT_ + CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.50 NAME 'encryptionPolicy' SUP Top + STRUCTURAL MUST cn MAY ( attrEncryptionDefinition $ attrEncryptionRequiresSe + cure ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'domain' ' + organizationalUnit' 'Organization' ) X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.48.6.1.5 NAME 'ndspkiContainer' SUP Top S + TRUCTURAL MUST cn X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'ndspkiContainer' 's + ASSecurity' 'Organization' 'organizationalUnit' 'Country' 'Locality' 'nDSPKI + TrustedRoot' ) ) +objectClasses: ( 2.16.840.1.113719.1.48.6.1.6 NAME 'ndspkiCertificate' SUP Top + STRUCTURAL MUST ( cn $ userCertificate ) MAY ( nDSPKISubjectName $ nDSPKINo + tBefore $ nDSPKINotAfter $ externalName $ givenName $ sn ) X-NDS_NAMING 'cn' + X-NDS_CONTAINMENT ( 'sASSecurity' 'Organization' 'organizationalUnit' 'Coun + try' 'Locality' 'ndspkiContainer' 'nDSPKITrustedRoot' ) X-NDS_NOT_CONTAINER + '1' ) +objectClasses: ( 2.16.840.1.113719.1.48.6.1.7 NAME 'ndspkiCRLConfiguration' SU + P Top STRUCTURAL MUST cn MAY ( ndspkiCRLFileName $ ndspkiDirectory $ ndspkiS + tatus $ ndspkiIssueTime $ ndspkiNextIssueTime $ ndspkiAttemptTime $ ndspkiTi + meInterval $ ndspkiCRLMaxProcessingInterval $ ndspkiCRLNumber $ ndspkiDistri + butionPoints $ ndspkiDistributionPointDN $ ndspkiCADN $ ndspkiCRLProcessData + $ nDSPKIPublicKey $ nDSPKIPrivateKey $ nDSPKIPublicKeyCertificate $ nDSPKIC + ertificateChain $ nDSPKIParentCA $ nDSPKIParentCADN $ nDSPKISubjectName $ cA + Certificate $ hostServer ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'ndspkiContai + ner' ) +objectClasses: ( 2.5.6.19 NAME 'cRLDistributionPoint' SUP Top STRUCTURAL MUST + cn MAY ( authorityRevocationList $ authorityRevocationList;binary $ cACertif + icate $ certificateRevocationList $ certificateRevocationList;binary $ cross + CertificatePair $ deltaRevocationList $ deltaRevocationList;binary $ ndspkiC + RLConfigurationDN ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Localit + y' 'organizationalUnit' 'Organization' 'sASSecurity' 'domain' 'ndspkiCRLConf + iguration' ) X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.7.6.1 NAME 'notfTemplateCollection' SUP T + op STRUCTURAL MUST cn MAY ( notfSMTPEmailHost $ notfSMTPEmailFrom $ notfSMTP + EmailUserName $ sASSecretStore ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSec + urity' ) +objectClasses: ( 2.16.840.1.113719.1.7.6.2 NAME 'notfMergeTemplate' SUP Top ST + RUCTURAL MUST cn MAY ( notfMergeTemplateData $ notfMergeTemplateSubject ) X- + NDS_NAMING 'cn' X-NDS_CONTAINMENT 'notfTemplateCollection' X-NDS_NOT_CONTAIN + ER '1' ) +objectClasses: ( 2.16.840.1.113719.1.39.44.6.1 NAME 'nsimChallengeSet' SUP Top + STRUCTURAL MUST cn MAY ( description $ nsimRequiredQuestions $ nsimRandomQu + estions $ nsimNumberRandomQuestions $ nsimMinResponseLength $ nsimMaxRespons + eLength ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'nspmPasswordPolicyContainer + ' 'Country' 'domain' 'Locality' 'Organization' 'organizationalUnit' ) X-NDS_ + NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.266.6.1 NAME 'sssServerPolicies' SUP Top + STRUCTURAL MUST cn MAY ( sssCacheRefreshInterval $ sssEnableReadTimestamps $ + sssDisableMasterPasswords $ sssEnableAdminAccess $ sssAdminList $ sssAdminG + ALabel $ sssReadSecretPolicies ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSec + urity' ) +objectClasses: ( 2.16.840.1.113719.1.266.6.2 NAME 'sssServerPolicyOverride' SU + P Top STRUCTURAL MUST cn MAY ( sssCacheRefreshInterval $ sssEnableReadTimest + amps $ sssDisableMasterPasswords $ sssEnableAdminAccess $ sssAdminList $ sss + AdminGALabel $ sssReadSecretPolicies ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( + 'sssServerPolicies' 'Organization' 'organizationalUnit' 'Country' 'Locality + ' 'domain' ) X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.1.6.1.91 NAME 'nestedGroupAux' AUXILIARY + MAY ( groupMember $ excludedMember $ nestedConfig $ groupMembership ) X-NDS_ + NOT_CONTAINER '1' ) +objectClasses: ( 1.3.6.1.1.1.2.0 NAME 'posixAccount' AUXILIARY MUST ( cn $ uid + $ uidNumber $ gidNumber $ homeDirectory ) MAY ( loginShell $ gecos $ descri + ption ) X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 1.3.6.1.1.1.2.1 NAME 'shadowAccount' AUXILIARY MUST uid MAY ( + shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ + shadowExpire $ shadowFlag $ description ) X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 1.3.6.1.1.1.2.2 NAME 'posixGroup' AUXILIARY MUST ( cn $ gidNu + mber ) MAY ( memberUid $ description ) X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.196.6.0 NAME 'uamPosixWorkstation' SUP To + p STRUCTURAL MUST cn MAY ( groupMembership $ privateKey $ publicKey ) X-NDS_ + NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' + ) X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.196.6.1 NAME 'uamPosixConfig' SUP Top STR + UCTURAL MUST cn MAY ( description $ uamPosixWorkstationContexts ) X-NDS_NAMI + NG 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X + -NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.196.6.2 NAME 'uamPosixUser' AUXILIARY MAY + ( uamPosixSalt $ uamPosixPAMServiceExcludeList ) X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.196.6.3 NAME 'uamPosixGroup' AUXILIARY MA + Y ( uamPosixWorkstationList $ uamPosixPAMServiceExcludeList ) X-NDS_NOT_CONT + AINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.196.6.14 NAME 'uamPosixUidNumberInfo' AUX + ILIARY MUST ( uamPosixUidNumberStart $ uamPosixUidNumberEnd $ uamPosixUidNum + berLastAssigned $ uamPosixUidNumberDeletedMap $ uamPosixUidNumberReuse ) X-N + DS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.196.6.15 NAME 'uamPosixGidNumberInfo' AUX + ILIARY MUST ( uamPosixGidNumberStart $ uamPosixGidNumberEnd $ uamPosixGidNum + berLastAssigned $ uamPosixGidNumberDeletedMap $ uamPosixGidNumberReuse ) X-N + DS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.4.4.0.1 NAME 'iPrintDriverStore' SUP Serv + er STRUCTURAL MAY ( iPrintDriverStoreCustomers $ iPrintDriverStoreIPPURI ) X + -NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.4.4.0.2 NAME 'iPrintManager' SUP Server S + TRUCTURAL MAY ( iPrintManagerDBPath $ iPrintManagerDBSaveData $ iPrintManage + rDBSaveIndex $ iPrintManagerDBSaveTime $ iPrintManagerDBGenNum $ iPrintManag + erIDS $ iPrintManagerIPPURI $ iPrintManagerPOtoPAidMap $ iPrintManagerDefaul + tURI ) X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.4.4.0.3 NAME 'iPrintPrinter' SUP Device S + TRUCTURAL MAY ( iPrintPrinterOperatorRole $ iPrintPrinterUserRole $ iPrintPr + interIPPURI $ iPrintPrinterPAName $ iPrintPrinterManager $ iPrintPrinterCont + rolPage ) X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.138.6.1.1 NAME 'DFS-Junction' SUP Top STR + UCTURAL MUST ( cn $ DFS-Volume-Guid $ DFS-Volume-Context ) MAY Version X-NDS + _NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' ) X-NDS + _NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.219.6.1 NAME 'nssfsPool' SUP Resource STR + UCTURAL MUST ( hostServer $ hostResourceName $ nssfsPoolID ) MAY ( status $ + nssfsShared ) X-NDS_NOT_CONTAINER '1' ) +objectClasses: ( 2.16.840.1.113719.1.50.6.1.1 NAME 'SMSSMDRClass' SUP Resource + STRUCTURAL MAY ( SMSRegisteredService $ SMSProtocolAddress ) X-NDS_NAME 'SM + S SMDR Class' X-NDS_NOT_CONTAINER '1' ) +attributeTypes: ( 2.5.4.35 NAME 'userPassword' DESC 'Internal NDS policy force + s this to be single-valued' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} USAGE + directoryOperation ) +attributeTypes: ( 2.5.18.1 NAME 'createTimestamp' DESC 'Operational Attribute' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAG + E directoryOperation ) +attributeTypes: ( 2.5.18.2 NAME 'modifyTimestamp' DESC 'Operational Attribute' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAG + E directoryOperation ) +attributeTypes: ( 2.5.18.10 NAME 'subschemaSubentry' DESC 'Operational Attribu + te' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE directoryOperation ) +attributeTypes: ( 2.5.21.9 NAME 'structuralObjectClass' DESC 'Operational Attr + ibute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 SINGLE-VALUE NO-USER-MODIFICATIO + N USAGE directoryOperation ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.49 NAME 'subordinateCount' DESC 'Op + erational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-US + ER-MODIFICATION USAGE directoryOperation ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.48 NAME 'entryFlags' DESC 'Operatio + nal Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MOD + IFICATION USAGE directoryOperation ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.51 NAME 'federationBoundary' DESC ' + Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICA + TION USAGE directoryOperation ) +attributeTypes: ( 2.5.21.5 NAME 'attributeTypes' DESC 'Operational Attribute' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.3 USAGE directoryOperation ) +attributeTypes: ( 2.5.21.6 NAME 'objectClasses' DESC 'Operational Attribute' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.37 USAGE directoryOperation ) +attributeTypes: ( 1.3.6.1.4.1.4203.666.1.33 NAME 'entryDN' DESC 'Operational A + ttribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICA + TION USAGE directoryOperation ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.2 NAME 'ACL' SYNTAX 2.16.840.1.113 + 719.1.1.5.1.17 X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' ) +attributeTypes: ( 2.5.4.1 NAME 'aliasedObjectName' SYNTAX 1.3.6.1.4.1.1466.115 + .121.1.12 SINGLE-VALUE X-NDS_NAME 'Aliased Object Name' X-NDS_NONREMOVABLE ' + 1' X-NDS_FILTERED_REQUIRED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.6 NAME 'backLink' SYNTAX 2.16.840. + 1.113719.1.1.5.1.23 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME + 'Back Link' X-NDS_SERVER_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_ + NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.8 NAME 'binderyProperty' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOpera + tion X-NDS_NAME 'Bindery Property' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_ + NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.7 NAME 'binderyObjectRestriction' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE + directoryOperation X-NDS_NAME 'Bindery Object Restriction' X-NDS_NOT_SCHED_ + SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.9 NAME 'binderyType' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.36{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE direc + toryOperation X-NDS_NAME 'Bindery Type' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X + -NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.11 NAME 'cAPrivateKey' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE dir + ectoryOperation X-NDS_NAME 'CA Private Key' X-NDS_NONREMOVABLE '1' X-NDS_HID + DEN '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.12 NAME 'cAPublicKey' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE dire + ctoryOperation X-NDS_NAME 'CA Public Key' X-NDS_PUBLIC_READ '1' X-NDS_NONREM + OVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.10 NAME 'Cartridge' SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.15{64512} X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.5.4.3 NAME ( 'cn' 'commonName' ) SYNTAX 1.3.6.1.4.1.1466.1 + 15.121.1.15{64} X-NDS_NAME 'CN' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' + X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.78 NAME 'printerConfiguration' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.5{64512} SINGLE-VALUE X-NDS_NAME 'Printer Con + figuration' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.15 NAME 'Convergence' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.27{1} SINGLE-VALUE X-NDS_UPPER_BOUND '1' X-NDS_NONREMO + VABLE '1' ) +attributeTypes: ( 2.5.4.6 NAME ( 'c' 'countryName' ) SYNTAX 1.3.6.1.4.1.1466.1 + 15.121.1.15{2} SINGLE-VALUE X-NDS_NAME 'C' X-NDS_LOWER_BOUND '2' X-NDS_UPPER + _BOUND '2' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.18 NAME 'defaultQueue' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Default Queue' X-NDS_SERV + ER_READ '1' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.5.4.13 NAME ( 'description' 'multiLineDescription' ) SYNTA + X 1.3.6.1.4.1.1466.115.121.1.15{1024} X-NDS_NAME 'Description' X-NDS_LOWER_B + OUND '1' X-NDS_UPPER_BOUND '1024' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.64 NAME 'partitionCreationTime' SY + NTAX 2.16.840.1.113719.1.1.5.1.19 SINGLE-VALUE NO-USER-MODIFICATION USAGE di + rectoryOperation X-NDS_NAME 'Partition Creation Time' X-NDS_PUBLIC_READ '1' + X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.5.4.23 NAME 'facsimileTelephoneNumber' SYNTAX 1.3.6.1.4.1. + 1466.115.121.1.22{64512} X-NDS_NAME 'Facsimile Telephone Number' X-NDS_NONRE + MOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.117 NAME 'highConvergenceSyncInter + val' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'High Conv + ergence Sync Interval' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.25 NAME 'groupMembership' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Group Membership' X-NDS_NAME_VALUE_ + ACCESS '1' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.26 NAME 'ndsHomeDirectory' SYNTAX + 2.16.840.1.113719.1.1.5.1.15{255} SINGLE-VALUE X-NDS_NAME 'Home Directory' X + -NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '255' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.27 NAME 'hostDevice' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Host Device' X-NDS_NONREMOV + ABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.28 NAME 'hostResourceName' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'Host Resource + Name' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.29 NAME 'hostServer' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Host Server' X-NDS_NONREMOV + ABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.30 NAME 'inheritedACL' SYNTAX 2.16 + .840.1.113719.1.1.5.1.17 NO-USER-MODIFICATION USAGE directoryOperation X-NDS + _NAME 'Inherited ACL' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.5.4.7 NAME ( 'l' 'localityname' ) SYNTAX 1.3.6.1.4.1.1466. + 115.121.1.15{128} X-NDS_NAME 'L' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '12 + 8' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.39 NAME 'loginAllowedTimeMap' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.5{42} SINGLE-VALUE X-NDS_NAME 'Login Allowed T + ime Map' X-NDS_LOWER_BOUND '42' X-NDS_UPPER_BOUND '42' X-NDS_NONREMOVABLE '1 + ' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.40 NAME 'loginDisabled' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Login Disabled' X-NDS_NON + REMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.41 NAME 'loginExpirationTime' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_NAME 'Login Expiration T + ime' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.42 NAME 'loginGraceLimit' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Login Grace Limit' X-N + DS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.43 NAME 'loginGraceRemaining' SYNT + AX 2.16.840.1.113719.1.1.5.1.22 SINGLE-VALUE X-NDS_NAME 'Login Grace Remaini + ng' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.44 NAME 'loginIntruderAddress' SYN + TAX 2.16.840.1.113719.1.1.5.1.12 SINGLE-VALUE X-NDS_NAME 'Login Intruder Add + ress' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.45 NAME 'loginIntruderAttempts' SY + NTAX 2.16.840.1.113719.1.1.5.1.22 SINGLE-VALUE X-NDS_NAME 'Login Intruder At + tempts' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.46 NAME 'loginIntruderLimit' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Login Intruder Limi + t' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.31 NAME 'intruderAttemptResetInter + val' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Intruder + Attempt Reset Interval' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.47 NAME 'loginIntruderResetTime' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_NAME 'Login Intruder + Reset Time' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.48 NAME 'loginMaximumSimultaneous' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Login Maximum + Simultaneous' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.49 NAME 'loginScript' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'Login Script' X-NDS_NONREMO + VABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.50 NAME 'loginTime' SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_NAME 'Login Time' X-NDS_NOT_SCHED_ + SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.5.4.31 NAME ( 'member' 'uniqueMember' ) SYNTAX 1.3.6.1.4.1 + .1466.115.121.1.12 X-NDS_NAME 'Member' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.52 NAME 'Memory' SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.22 NAME 'eMailAddress' SYNTAX 2.16 + .840.1.113719.1.1.5.1.14{64512} X-NDS_NAME 'EMail Address' X-NDS_PUBLIC_READ + '1' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.55 NAME 'networkAddress' SYNTAX 2. + 16.840.1.113719.1.1.5.1.12 X-NDS_NAME 'Network Address' X-NDS_NONREMOVABLE ' + 1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.56 NAME 'networkAddressRestriction + ' SYNTAX 2.16.840.1.113719.1.1.5.1.12 X-NDS_NAME 'Network Address Restrictio + n' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.57 NAME 'notify' SYNTAX 2.16.840.1 + .113719.1.1.5.1.25 X-NDS_NAME 'Notify' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.114 NAME 'Obituary' SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation + X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.5.4.0 NAME 'objectClass' SYNTAX 1.3.6.1.4.1.1466.115.121.1 + .38 X-NDS_NAME 'Object Class' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X + -NDS_FILTERED_REQUIRED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.59 NAME 'operator' SYNTAX 1.3.6.1. + 4.1.1466.115.121.1.12 X-NDS_NAME 'Operator' X-NDS_SERVER_READ '1' X-NDS_NONR + EMOVABLE '1' ) +attributeTypes: ( 2.5.4.11 NAME ( 'ou' 'organizationalUnitName' ) SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'OU' X-NDS_LOWER_BOUND '1' X-NDS_UPP + ER_BOUND '64' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.5.4.10 NAME ( 'o' 'organizationname' ) SYNTAX 1.3.6.1.4.1. + 1466.115.121.1.15{64} X-NDS_NAME 'O' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND + '64' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.5.4.32 NAME 'owner' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X + -NDS_NAME 'Owner' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.63 NAME 'pageDescriptionLanguage' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{64} X-NDS_NAME 'Page Description Langua + ge' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.65 NAME 'passwordsUsed' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NAME 'Passw + ords Used' X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.66 NAME 'passwordAllowChange' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Password Allow Chan + ge' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.67 NAME 'passwordExpirationInterva + l' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Password Ex + piration Interval' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.68 NAME 'passwordExpirationTime' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_NAME 'Password Expira + tion Time' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.69 NAME 'passwordMinimumLength' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Password Minimum + Length' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.70 NAME 'passwordRequired' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Password Required' X-N + DS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.71 NAME 'passwordUniqueRequired' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Password Unique + Required' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.72 NAME 'path' SYNTAX 2.16.840.1.1 + 13719.1.1.5.1.15{64512} X-NDS_NAME 'Path' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.5.4.19 NAME 'physicalDeliveryOfficeName' SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.15{128} X-NDS_NAME 'Physical Delivery Office Name' X-NDS_LO + WER_BOUND '1' X-NDS_UPPER_BOUND '128' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.5.4.16 NAME 'postalAddress' SYNTAX 1.3.6.1.4.1.1466.115.12 + 1.1.41{64512} X-NDS_NAME 'Postal Address' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.5.4.17 NAME 'postalCode' SYNTAX 1.3.6.1.4.1.1466.115.121.1 + .15{40} X-NDS_NAME 'Postal Code' X-NDS_UPPER_BOUND '40' X-NDS_NONREMOVABLE ' + 1' ) +attributeTypes: ( 2.5.4.18 NAME 'postOfficeBox' SYNTAX 1.3.6.1.4.1.1466.115.12 + 1.1.15{40} X-NDS_NAME 'Postal Office Box' X-NDS_UPPER_BOUND '40' X-NDS_NONRE + MOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.80 NAME 'printJobConfiguration' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'Print Job Configu + ration' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.79 NAME 'printerControl' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'Printer Control' X-NDS_N + ONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.82 NAME 'privateKey' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE direc + toryOperation X-NDS_NAME 'Private Key' X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN ' + 1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.83 NAME 'Profile' SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.84 NAME 'publicKey' SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE direct + oryOperation X-NDS_NAME 'Public Key' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABL + E '1' X-NDS_FILTERED_OPERATIONAL '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.85 NAME 'queue' SYNTAX 2.16.840.1. + 113719.1.1.5.1.25 X-NDS_NAME 'Queue' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.86 NAME 'queueDirectory' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE X-NDS_NAME 'Queue Directory' X + -NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '255' X-NDS_SERVER_READ '1' X-NDS_NON + REMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.115 NAME 'Reference' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_ + NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-N + DS_HIDDEN '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.88 NAME 'Replica' SYNTAX 2.16.840. + 1.113719.1.1.5.1.16{64512} NO-USER-MODIFICATION USAGE directoryOperation X-N + DS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.89 NAME 'Resource' SYNTAX 1.3.6.1. + 4.1.1466.115.121.1.12 X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.5.4.33 NAME 'roleOccupant' SYNTAX 1.3.6.1.4.1.1466.115.121 + .1.12 X-NDS_NAME 'Role Occupant' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.116 NAME 'higherPrivileges' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Higher Privileges' X-NDS_SERVER_R + EAD '1' X-NDS_NAME_VALUE_ACCESS '1' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.92 NAME 'securityEquals' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Security Equals' X-NDS_SERVER_READ ' + 1' X-NDS_NAME_VALUE_ACCESS '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRE + D '1' ) +attributeTypes: ( 2.5.4.34 NAME 'seeAlso' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 + X-NDS_NAME 'See Also' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.5.4.5 NAME 'serialNumber' SYNTAX 1.3.6.1.4.1.1466.115.121. + 1.44{64} X-NDS_NAME 'Serial Number' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND + '64' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.95 NAME 'server' SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.12 X-NDS_NAME 'Server' X-NDS_SERVER_READ '1' X-NDS_NONREMOV + ABLE '1' ) +attributeTypes: ( 2.5.4.8 NAME ( 'st' 'stateOrProvinceName' ) SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.15{128} X-NDS_NAME 'S' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_B + OUND '128' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.98 NAME 'status' SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Status' X-NDS_PUBLIC_READ '1' X + -NDS_NONREMOVABLE '1' X-NDS_FILTERED_OPERATIONAL '1' ) +attributeTypes: ( 2.5.4.9 NAME 'street' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1 + 28} X-NDS_NAME 'SA' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' X-NDS_NONR + EMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.102 NAME 'supportedTypefaces' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'Supported Typefaces' X-NDS_ + LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.101 NAME 'supportedServices' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'Supported Services' X-NDS_LO + WER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.5.4.4 NAME ( 'sn' 'surname' ) SYNTAX 1.3.6.1.4.1.1466.115. + 121.1.15{64} X-NDS_NAME 'Surname' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '6 + 4' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.5.4.20 NAME 'telephoneNumber' SYNTAX 1.3.6.1.4.1.1466.115. + 121.1.50{64512} X-NDS_NAME 'Telephone Number' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.5.4.12 NAME 'title' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{6 + 4} X-NDS_NAME 'Title' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NON + REMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.111 NAME 'User' SYNTAX 1.3.6.1.4.1 + .1466.115.121.1.12 X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.112 NAME 'Version' SYNTAX 1.3.6.1. + 4.1.1466.115.121.1.15{64} SINGLE-VALUE X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOU + ND '64' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.1 NAME 'accountBalance' SYNTAX 2.1 + 6.840.1.113719.1.1.5.1.22 SINGLE-VALUE X-NDS_NAME 'Account Balance' X-NDS_NO + NREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.4 NAME 'allowUnlimitedCredit' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Allow Unlimited Cre + dit' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.118 NAME 'lowConvergenceResetTime' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE USAGE directoryOperation + X-NDS_NAME 'Low Convergence Reset Time' X-NDS_NONREMOVABLE '1' X-NDS_READ_FI + LTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.54 NAME 'minimumAccountBalance' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Minimum Account + Balance' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.104 NAME 'lowConvergenceSyncInterv + al' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Low Conver + gence Sync Interval' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.21 NAME 'Device' SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.12 X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.53 NAME 'messageServer' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Message Server' X-NDS_NO + NREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.34 NAME 'Language' SYNTAX 2.16.840 + .1.113719.1.1.5.1.6{64512} SINGLE-VALUE X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.100 NAME 'supportedConnections' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Supported Connec + tions' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.107 NAME 'typeCreatorMap' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'Type Creator Map' X-NDS + _NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.108 NAME 'ndsUID' SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'UID' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.24 NAME 'groupID' SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'GID' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.110 NAME 'unknownBaseClass' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{32} SINGLE-VALUE USAGE directoryOperation X-N + DS_NAME 'Unknown Base Class' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32' X- + NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED + '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.87 NAME 'receivedUpTo' SYNTAX 2.16 + .840.1.113719.1.1.5.1.19 NO-USER-MODIFICATION USAGE directoryOperation X-NDS + _NAME 'Received Up To' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_RE + AD_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.33 NAME 'synchronizedUpTo' SYNTAX + 2.16.840.1.113719.1.1.5.1.19 NO-USER-MODIFICATION USAGE directoryOperation X + -NDS_NAME 'Synchronized Up To' X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X- + NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED + '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.5 NAME 'authorityRevocation' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USA + GE directoryOperation X-NDS_NAME 'Authority Revocation' X-NDS_NONREMOVABLE ' + 1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.13 NAME 'certificateRevocation' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION + USAGE directoryOperation X-NDS_NAME 'Certificate Revocation' X-NDS_NONREMOVA + BLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.17 NAME 'ndsCrossCertificatePair' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.5{64512} X-NDS_NAME 'Cross Certificate Pai + r' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.37 NAME 'lockedByIntruder' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Locked By Intruder' X- + NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.77 NAME 'printer' SYNTAX 2.16.840. + 1.113719.1.1.5.1.25 X-NDS_NAME 'Printer' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.20 NAME 'detectIntruder' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Detect Intruder' X-NDS_N + ONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.38 NAME 'lockoutAfterDetection' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Lockout After Det + ection' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.32 NAME 'intruderLockoutResetInter + val' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Intruder + Lockout Reset Interval' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.96 NAME 'serverHolds' SYNTAX 2.16. + 840.1.113719.1.1.5.1.23 X-NDS_NAME 'Server Holds' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.91 NAME 'sAPName' SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.15{47} SINGLE-VALUE X-NDS_NAME 'SAP Name' X-NDS_LOWER_BOUN + D '1' X-NDS_UPPER_BOUND '47' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.113 NAME 'Volume' SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.35 NAME 'lastLoginTime' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directory + Operation X-NDS_NAME 'Last Login Time' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X- + NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.81 NAME 'printServer' SYNTAX 2.16. + 840.1.113719.1.1.5.1.25 SINGLE-VALUE X-NDS_NAME 'Print Server' X-NDS_NONREMO + VABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.119 NAME 'nNSDomain' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.15{128} X-NDS_NAME 'NNS Domain' X-NDS_LOWER_BOUND '1' X + -NDS_UPPER_BOUND '128' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.120 NAME 'fullName' SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.15{127} X-NDS_NAME 'Full Name' X-NDS_UPPER_BOUND '127' X + -NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.121 NAME 'partitionControl' SYNTAX + 2.16.840.1.113719.1.1.5.1.25 NO-USER-MODIFICATION USAGE directoryOperation + X-NDS_NAME 'Partition Control' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' + X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.122 NAME 'revision' SYNTAX 2.16.84 + 0.1.113719.1.1.5.1.22 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOpera + tion X-NDS_NAME 'Revision' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDI + ATE '1' X-NDS_SCHED_SYNC_NEVER '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERE + D '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.123 NAME 'certificateValidityInter + val' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{4294967295} SINGLE-VALUE X-NDS_NAM + E 'Certificate Validity Interval' X-NDS_LOWER_BOUND '60' X-NDS_UPPER_BOUND ' + -1' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.124 NAME 'externalSynchronizer' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'External Synchronizer' + X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.125 NAME 'messagingDatabaseLocatio + n' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE X-NDS_NAME 'Messa + ging Database Location' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.126 NAME 'messageRoutingGroup' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Message Routing Group' X-NDS_N + ONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.127 NAME 'messagingServer' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Messaging Server' X-NDS_NONREMOVAB + LE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.128 NAME 'Postmaster' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.12 X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.162 NAME 'mailboxLocation' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Mailbox Location' X-N + DS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.163 NAME 'mailboxID' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.15{8} SINGLE-VALUE X-NDS_NAME 'Mailbox ID' X-NDS_LOWER_ + BOUND '1' X-NDS_UPPER_BOUND '8' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' + ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.164 NAME 'externalName' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'External Name' X- + NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.165 NAME 'securityFlags' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Security Flags' X-NDS_N + ONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.166 NAME 'messagingServerType' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.15{32} SINGLE-VALUE X-NDS_NAME 'Messaging Ser + ver Type' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32' X-NDS_NONREMOVABLE '1 + ' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.167 NAME 'lastReferencedTime' SYNT + AX 2.16.840.1.113719.1.1.5.1.19 SINGLE-VALUE USAGE directoryOperation X-NDS_ + NAME 'Last Referenced Time' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDI + ATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.5.4.42 NAME 'givenName' SYNTAX 1.3.6.1.4.1.1466.115.121.1. + 15{32} X-NDS_NAME 'Given Name' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32' + X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.5.4.43 NAME 'initials' SYNTAX 1.3.6.1.4.1.1466.115.121.1.1 + 5{8} X-NDS_NAME 'Initials' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '8' X-NDS + _PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.5.4.44 NAME 'generationQualifier' SYNTAX 1.3.6.1.4.1.1466. + 115.121.1.15{8} SINGLE-VALUE X-NDS_NAME 'Generational Qualifier' X-NDS_LOWER + _BOUND '1' X-NDS_UPPER_BOUND '8' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1 + ' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.171 NAME 'profileMembership' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Profile Membership' X-NDS_NAME_V + ALUE_ACCESS '1' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.172 NAME 'dsRevision' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'DS Revision' X-NDS_PUBLIC_ + READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_OPERATIONAL '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.173 NAME 'supportedGateway' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{4096} X-NDS_NAME 'Supported Gateway' X-NDS_LO + WER_BOUND '1' X-NDS_UPPER_BOUND '4096' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.174 NAME 'equivalentToMe' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Equivalent To Me' X-NDS_SERVER_READ + '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.175 NAME 'replicaUpTo' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperati + on X-NDS_NAME 'Replica Up To' X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-N + DS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED ' + 1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.176 NAME 'partitionStatus' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOpe + ration X-NDS_NAME 'Partition Status' X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC + '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FIL + TERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.177 NAME 'permanentConfigParms' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'Permanent Config Parms + ' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABL + E '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.178 NAME 'Timezone' SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_S + CHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.179 NAME 'binderyRestrictionLevel' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE USAGE directoryOperation + X-NDS_NAME 'Bindery Restriction Level' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X- + NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.180 NAME 'transitiveVector' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOp + eration X-NDS_NAME 'Transitive Vector' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED + _SYNC_IMMEDIATE '1' X-NDS_SCHED_SYNC_NEVER '1' X-NDS_NONREMOVABLE '1' X-NDS_ + READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.181 NAME 'T' SYNTAX 1.3.6.1.4.1.14 + 66.115.121.1.15{32} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32' X-NDS_NONRE + MOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.183 NAME 'purgeVector' SYNTAX 2.16 + .840.1.113719.1.1.5.1.19 NO-USER-MODIFICATION USAGE directoryOperation X-NDS + _NAME 'Purge Vector' X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SC + HED_SYNC_IMMEDIATE '1' X-NDS_SCHED_SYNC_NEVER '1' X-NDS_NONREMOVABLE '1' X-N + DS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.184 NAME 'synchronizationTolerance + ' SYNTAX 2.16.840.1.113719.1.1.5.1.19 USAGE directoryOperation X-NDS_NAME 'S + ynchronization Tolerance' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS + _READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.185 NAME 'passwordManagement' SYNT + AX 2.16.840.1.113719.1.1.5.1.0 SINGLE-VALUE USAGE directoryOperation X-NDS_N + AME 'Password Management' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.186 NAME 'usedBy' SYNTAX 2.16.840. + 1.113719.1.1.5.1.15{64512} NO-USER-MODIFICATION USAGE directoryOperation X-N + DS_NAME 'Used By' X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERE + D_REQUIRED '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.187 NAME 'Uses' SYNTAX 2.16.840.1. + 113719.1.1.5.1.15{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS + _SERVER_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.500 NAME 'obituaryNotify' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOper + ation X-NDS_NAME 'Obituary Notify' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQ + UIRED '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.501 NAME 'GUID' SYNTAX 1.3.6.1.4.1 + .1466.115.121.1.40{16} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOper + ation X-NDS_LOWER_BOUND '16' X-NDS_UPPER_BOUND '16' X-NDS_PUBLIC_READ '1' X- + NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.502 NAME 'otherGUID' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.40{16} USAGE directoryOperation X-NDS_NAME 'Other GUID' + X-NDS_LOWER_BOUND '16' X-NDS_UPPER_BOUND '16' X-NDS_PUBLIC_READ '1' X-NDS_N + ONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.503 NAME 'auxiliaryClassFlag' SYNT + AX 2.16.840.1.113719.1.1.5.1.0 SINGLE-VALUE NO-USER-MODIFICATION USAGE direc + toryOperation X-NDS_NAME 'Auxiliary Class Flag' X-NDS_NONREMOVABLE '1' X-NDS + _READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.504 NAME 'unknownAuxiliaryClass' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} USAGE directoryOperation X-NDS_NAME + 'Unknown Auxiliary Class' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32' X-NDS + _NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' + ) +attributeTypes: ( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userId' ) SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'uniqueID' X-NDS_LOWER_BOUND '1' X + -NDS_UPPER_BOUND '64' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 0.9.2342.19200300.100.1.25 NAME 'dc' SYNTAX 1.3.6.1.4.1.1466 + .115.121.1.26{64} X-NDS_NAME 'dc' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '6 + 4' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.507 NAME 'auxClassObjectClassBacku + p' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 NO-USER-MODIFICATION USAGE directory + Operation X-NDS_NAME 'AuxClass Object Class Backup' X-NDS_NONREMOVABLE '1' X + -NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.508 NAME 'localReceivedUpTo' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryO + peration X-NDS_NAME 'Local Received Up To' X-NDS_PUBLIC_READ '1' X-NDS_NEVER + _SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_RE + AD_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.141.4.4 NAME 'federationControl' SYNTAX + 2.16.840.1.113719.1.1.5.1.15{64512} USAGE directoryOperation X-NDS_NONREMOVA + BLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.141.4.2 NAME 'federationSearchPath' SYNT + AX 2.16.840.1.113719.1.1.5.1.6{64512} SINGLE-VALUE USAGE directoryOperation + X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.141.4.3 NAME 'federationDNSName' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE USAGE directoryOperation X-NDS_PU + BLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_ + FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.141.4.1 NAME 'federationBoundaryType' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE d + irectoryOperation X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_R + EAD_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.14.4.1.4 NAME 'DirXML-Associations' SYNT + AX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NONREMOVABLE '1' X-NDS_FILTERED + _REQUIRED '1' ) +attributeTypes: ( 2.5.18.3 NAME 'creatorsName' SYNTAX 1.3.6.1.4.1.1466.115.121 + .1.15{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ND + S_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.5.18.4 NAME 'modifiersName' SYNTAX 1.3.6.1.4.1.1466.115.12 + 1.1.15{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-N + DS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.300 NAME 'languageId' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.15{64512} X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.35 NAME 'ndsPredicate' SYNTAX 2.16. + 840.1.113719.1.1.5.1.12 X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.36 NAME 'ndsPredicateState' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.37 NAME 'ndsPredicateFlush' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.38 NAME 'ndsPredicateTimeout' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.27{2147483647} SINGLE-VALUE X-NDS_UPPER_BOUND ' + 2147483647' X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.40 NAME 'ndsPredicateStatsDN' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.39 NAME 'ndsPredicateUseValues' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.601 NAME 'syncPanePoint' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE d + irectoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED + _SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.600 NAME 'syncWindowVector' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAG + E directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SC + HED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.602 NAME 'objectVersion' SYNTAX 2. + 16.840.1.113719.1.1.5.1.19 SINGLE-VALUE NO-USER-MODIFICATION USAGE directory + Operation X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED ' + 1' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.52 NAME 'memberQueryURL' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'memberQuery' X-NDS_NONREMOVABL + E '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.302 NAME 'excludedMember' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.12 X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.525 NAME 'auxClassCompatibility' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.38 NO-USER-MODIFICATION USAGE directoryOper + ation X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.518 NAME 'ndsAgentPassword' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAG + E directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE ' + 1' X-NDS_HIDDEN '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.519 NAME 'ndsOperationCheckpoint' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_N + OT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.520 NAME 'localReferral' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-N + DS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED ' + 1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.521 NAME 'treeReferral' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NOT_SCHED_S + YNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.522 NAME 'schemaResetLock' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X + -NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED + '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.523 NAME 'modifiedACLEntry' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.12 USAGE directoryOperation X-NDS_NOT_SCHED_SYNC + _IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.524 NAME 'monitoredConnection' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NOT_ + SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.526 NAME 'localFederationBoundary' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE USAGE directoryOperation + X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERE + D '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.527 NAME 'replicationFilter' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation + X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTER + ED '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.296 NAME 'loginActivationTime' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_NONREMOVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.687 NAME 'UpdateInProgress' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.27 X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREM + OVABLE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.400.1 NAME 'edirSchemaFlagVersion' S + YNTAX 2.16.840.1.113719.1.1.5.1.0 SINGLE-VALUE NO-USER-MODIFICATION USAGE di + rectoryOperation X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN '1' X-NDS_READ_FILTERED + '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.512 NAME 'indexDefinition' SYNTAX + 2.16.840.1.113719.1.1.5.1.6{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.513 NAME 'ndsStatusRepair' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.514 NAME 'ndsStatusExternalReferen + ce' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIA + TE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.515 NAME 'ndsStatusObituary' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.516 NAME 'ndsStatusSchema' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.517 NAME 'ndsStatusLimber' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.511 NAME 'authoritative' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' + ) +attributeTypes: ( 2.16.840.1.113730.3.1.34 NAME 'ref' SYNTAX 1.3.6.1.4.1.1466. + 115.121.1.26{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.546 NAME 'CachedAttrsOnExtRefs' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_SERVER_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.547 NAME 'ExtRefLastUpdatedTime' S + YNTAX 2.16.840.1.113719.1.1.5.1.19 SINGLE-VALUE NO-USER-MODIFICATION USAGE d + irectoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED + _SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.688 NAME 'NCPKeyMaterialName' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.713 NAME 'UTF8LoginScript' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.714 NAME 'loginScriptCharset' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.1.192 NAME 'lDAPLogLevel' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.27{32768} SINGLE-VALUE X-NDS_NAME 'LDAP Log Level' + X-NDS_UPPER_BOUND '32768' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.12 NAME 'lDAPUDPPort' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.27{65535} SINGLE-VALUE X-NDS_NAME 'LDAP UDP Port' X-NDS + _UPPER_BOUND '65535' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.204 NAME 'lDAPLogFilename' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'LDAP Log Filen + ame' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.205 NAME 'lDAPBackupLogFilename' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'LDAP Bac + kup Log Filename' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.206 NAME 'lDAPLogSizeLimit' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.27{4294967295} SINGLE-VALUE X-NDS_NAME 'LDAP Log + Size Limit' X-NDS_LOWER_BOUND '2048' X-NDS_UPPER_BOUND '-1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.194 NAME 'lDAPSearchSizeLimit' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.27{2147483647} SINGLE-VALUE X-NDS_NAME 'LDAP + Search Size Limit' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '2147483647' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.195 NAME 'lDAPSearchTimeLimit' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.27{2147483647} SINGLE-VALUE X-NDS_NAME 'LDAP + Search Time Limit' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '2147483647' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.207 NAME 'lDAPSuffix' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.12 X-NDS_NAME 'LDAP Suffix' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.70 NAME 'ldapConfigVersion' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.14 NAME 'ldapReferral' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'LDAP Referral' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.73 NAME 'ldapDefaultReferralBehavio + r' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.23 NAME 'ldapSearchReferralUsage' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'LDAP:searchRefe + rralUsage' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.24 NAME 'lDAPOtherReferralUsage' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'LDAP:otherReferr + alUsage' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.1 NAME 'ldapHostServer' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'LDAP Host Server' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.2 NAME 'ldapGroupDN' SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'LDAP Group' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.3 NAME 'ldapTraceLevel' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.27{32768} SINGLE-VALUE X-NDS_NAME 'LDAP Screen Level' + X-NDS_UPPER_BOUND '32768' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.4 NAME 'searchSizeLimit' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.27{2147483647} SINGLE-VALUE X-NDS_UPPER_BOUND '21474 + 83647' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.5 NAME 'searchTimeLimit' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.27{2147483647} SINGLE-VALUE X-NDS_UPPER_BOUND '21474 + 83647' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.6 NAME 'ldapServerBindLimit' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.27{4294967295} SINGLE-VALUE X-NDS_NAME 'LDAP Ser + ver Bind Limit' X-NDS_UPPER_BOUND '-1' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.7 NAME 'ldapServerIdleTimeout' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.27{4294967295} SINGLE-VALUE X-NDS_NAME 'LDAP S + erver Idle Timeout' X-NDS_UPPER_BOUND '-1' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.8 NAME 'ldapEnableTCP' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'LDAP Enable TCP' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.10 NAME 'ldapEnableSSL' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'LDAP Enable SSL' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.11 NAME 'ldapTCPPort' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.27{65535} SINGLE-VALUE X-NDS_NAME 'LDAP TCP Port' X-NDS + _UPPER_BOUND '65535' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.13 NAME 'ldapSSLPort' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.27{65535} SINGLE-VALUE X-NDS_NAME 'LDAP SSL Port' X-NDS + _UPPER_BOUND '65535' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.21 NAME 'filteredReplicaUsage' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.22 NAME 'ldapKeyMaterialName' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'LDAP:keyMate + rialName' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.42 NAME 'extensionInfo' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.45 NAME 'nonStdClientSchemaCompatMo + de' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.46 NAME 'sslEnableMutualAuthenticat + ion' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.62 NAME 'ldapEnablePSearch' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.63 NAME 'ldapMaximumPSearchOperatio + ns' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.64 NAME 'ldapIgnorePSearchLimitsFor + Events' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.65 NAME 'ldapTLSTrustedRootContaine + r' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.66 NAME 'ldapEnableMonitorEvents' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.67 NAME 'ldapMaximumMonitorEventsLo + ad' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.68 NAME 'ldapTLSRequired' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.69 NAME 'ldapTLSVerifyClientCertifi + cate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.71 NAME 'ldapDerefAlias' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.72 NAME 'ldapNonStdAllUserAttrsMode + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.75 NAME 'ldapBindRestrictions' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.79 NAME 'ldapInterfaces' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.80 NAME 'ldapChainSecureRequired' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.82 NAME 'ldapStdCompliance' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.15 NAME 'ldapServerList' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'LDAP Server List' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.16 NAME 'ldapAttributeMap' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'LDAP Attribute + Map v11' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.17 NAME 'ldapClassMap' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'LDAP Class Map v11' + ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.18 NAME 'ldapAllowClearTextPassword + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'LDAP Allow Cl + ear Text Password' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.19 NAME 'ldapAnonymousIdentity' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'LDAP Anonymous Id + entity' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.52 NAME 'ldapAttributeList' SYNTAX + 2.16.840.1.113719.1.1.5.1.6{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.53 NAME 'ldapClassList' SYNTAX 2.16 + .840.1.113719.1.1.5.1.6{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.56 NAME 'transitionGroupDN' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.74 NAME 'ldapTransitionBackLink' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.78 NAME 'ldapLBURPNumWriterThreads' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.20 NAME 'ldapServerDN' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.12 X-NDS_NAME 'LDAP Server' ) +attributeTypes: ( 0.9.2342.19200300.100.1.3 NAME 'mail' SYNTAX 1.3.6.1.4.1.146 + 6.115.121.1.15{64512} X-NDS_NAME 'Internet EMail Address' X-NDS_PUBLIC_READ + '1' ) +attributeTypes: ( 2.16.840.1.113730.3.1.3 NAME 'employeeNumber' SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.15{64512} X-NDS_NAME 'NSCP:employeeNumber' ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.76 NAME 'referralExcludeFilter' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.27.4.77 NAME 'referralIncludeFilter' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.5.4.36 NAME 'userCertificate' SYNTAX 1.3.6.1.4.1.1466.115. + 121.1.5{64512} X-NDS_NAME 'userCertificate' X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.5.4.37 NAME 'cACertificate' SYNTAX 1.3.6.1.4.1.1466.115.12 + 1.1.5{64512} X-NDS_NAME 'cACertificate' X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.5.4.38 NAME 'authorityRevocationList' SYNTAX 1.3.6.1.4.1.1 + 466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.5.4.39 NAME 'certificateRevocationList' SYNTAX 1.3.6.1.4.1 + .1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.5.4.53 NAME 'deltaRevocationList' SYNTAX 1.3.6.1.4.1.1466. + 115.121.1.40{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.5.4.40 NAME 'crossCertificatePair' SYNTAX 1.3.6.1.4.1.1466 + .115.121.1.5{64512} X-NDS_NAME 'crossCertificatePair' X-NDS_PUBLIC_READ '1' + ) +attributeTypes: ( 2.5.4.58 NAME 'attributeCertificate' SYNTAX 1.3.6.1.4.1.1466 + .115.121.1.40{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.5.4.2 NAME 'knowledgeInformation' SYNTAX 1.3.6.1.4.1.1466. + 115.121.1.15{32768} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32768' ) +attributeTypes: ( 2.5.4.14 NAME 'searchGuide' SYNTAX 1.3.6.1.4.1.1466.115.121. + 1.25{64512} X-NDS_NAME 'searchGuide' ) +attributeTypes: ( 2.5.4.15 NAME 'businessCategory' SYNTAX 1.3.6.1.4.1.1466.115 + .121.1.15{128} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' ) +attributeTypes: ( 2.5.4.21 NAME 'telexNumber' SYNTAX 1.3.6.1.4.1.1466.115.121. + 1.52{64512} X-NDS_NAME 'telexNumber' ) +attributeTypes: ( 2.5.4.22 NAME 'teletexTerminalIdentifier' SYNTAX 1.3.6.1.4.1 + .1466.115.121.1.51{64512} X-NDS_NAME 'teletexTerminalIdentifier' ) +attributeTypes: ( 2.5.4.24 NAME 'x121Address' SYNTAX 1.3.6.1.4.1.1466.115.121. + 1.36{15} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '15' ) +attributeTypes: ( 2.5.4.25 NAME 'internationaliSDNNumber' SYNTAX 1.3.6.1.4.1.1 + 466.115.121.1.36{16} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '16' ) +attributeTypes: ( 2.5.4.26 NAME 'registeredAddress' SYNTAX 1.3.6.1.4.1.1466.11 + 5.121.1.41{64512} X-NDS_NAME 'registeredAddress' ) +attributeTypes: ( 2.5.4.27 NAME 'destinationIndicator' SYNTAX 1.3.6.1.4.1.1466 + .115.121.1.44{128} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' ) +attributeTypes: ( 2.5.4.28 NAME 'preferredDeliveryMethod' SYNTAX 1.3.6.1.4.1.1 + 466.115.121.1.14{64512} SINGLE-VALUE X-NDS_NAME 'preferredDeliveryMethod' ) +attributeTypes: ( 2.5.4.29 NAME 'presentationAddress' SYNTAX 1.3.6.1.4.1.1466. + 115.121.1.43{64512} SINGLE-VALUE X-NDS_NAME 'presentationAddress' ) +attributeTypes: ( 2.5.4.30 NAME 'supportedApplicationContext' SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.38{64512} X-NDS_NAME 'supportedApplicationContext' ) +attributeTypes: ( 2.5.4.45 NAME 'x500UniqueIdentifier' SYNTAX 1.3.6.1.4.1.1466 + .115.121.1.6{64512} X-NDS_NAME 'x500UniqueIdentifier' ) +attributeTypes: ( 2.5.4.46 NAME 'dnQualifier' SYNTAX 1.3.6.1.4.1.1466.115.121. + 1.44{64512} ) +attributeTypes: ( 2.5.4.47 NAME 'enhancedSearchGuide' SYNTAX 1.3.6.1.4.1.1466. + 115.121.1.21{64512} X-NDS_NAME 'enhancedSearchGuide' ) +attributeTypes: ( 2.5.4.48 NAME 'protocolInformation' SYNTAX 1.3.6.1.4.1.1466. + 115.121.1.42{64512} X-NDS_NAME 'protocolInformation' ) +attributeTypes: ( 2.5.4.51 NAME 'houseIdentifier' SYNTAX 1.3.6.1.4.1.1466.115. + 121.1.15{32768} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32768' ) +attributeTypes: ( 2.5.4.52 NAME 'supportedAlgorithms' SYNTAX 1.3.6.1.4.1.1466. + 115.121.1.49{64512} X-NDS_NAME 'supportedAlgorithms' ) +attributeTypes: ( 2.5.4.54 NAME 'dmdName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 + {32768} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32768' ) +attributeTypes: ( 0.9.2342.19200300.100.1.6 NAME 'roomNumber' SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.15{64512} ) +attributeTypes: ( 0.9.2342.19200300.100.1.38 NAME 'associatedName' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 2.5.4.49 NAME 'dn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SING + LE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.3.4.1 NAME 'httpServerDN' SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.12 ) +attributeTypes: ( 2.16.840.1.113719.1.3.4.2 NAME 'httpHostServerDN' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.3.4.3 NAME 'httpThreadsPerCPU' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.3.4.4 NAME 'httpIOBufferSize' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.3.4.5 NAME 'httpRequestTimeout' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.3.4.6 NAME 'httpKeepAliveRequestTimeout' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.3.4.7 NAME 'httpSessionTimeout' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.3.4.8 NAME 'httpKeyMaterialObject' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.3.4.9 NAME 'httpTraceLevel' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.3.4.10 NAME 'httpAuthRequiresTLS' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.3.4.11 NAME 'httpDefaultClearPort' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.3.4.12 NAME 'httpDefaultTLSPort' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.295 NAME 'emboxConfig' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.54.4.1.1 NAME 'trusteesOfNewObject' SYNT + AX 2.16.840.1.113719.1.1.5.1.17 X-NDS_NAME 'Trustees Of New Object' X-NDS_NO + T_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.55.4.1.1 NAME 'newObjectSDSRights' SYNTA + X 2.16.840.1.113719.1.1.5.1.17 X-NDS_NAME 'New Object\27s DS Rights' X-NDS_N + OT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.56.4.1.1 NAME 'newObjectSFSRights' SYNTA + X 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'New Object\27s FS Rights' + X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.57.4.1.1 NAME 'setupScript' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'Setup Script' X-NDS_NOT_SCH + ED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.58.4.1.1 NAME 'runSetupScript' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Run Setup Script' X-NDS_ + NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.59.4.1.1 NAME 'membersOfTemplate' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Members Of Template' X-NDS_NOT_SC + HED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.60.4.1.1 NAME 'volumeSpaceRestrictions' + SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'Volume Space Restrict + ions' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.61.4.1.1 NAME 'setPasswordAfterCreate' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Set Password Aft + er Create' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.62.4.1.1 NAME 'homeDirectoryRights' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.27 X-NDS_NAME 'Home Directory Rights' X-NDS_NO + T_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.63.4.1.1 NAME 'newObjectSSelfRights' SYN + TAX 2.16.840.1.113719.1.1.5.1.17 X-NDS_NAME 'New Object\27s Self Rights' X-N + DS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.1 NAME 'digitalMeID' SYNTAX 2.16.840 + .1.113719.1.1.5.1.15{64512} SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.2 NAME 'assistant' SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.12 ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.3 NAME 'assistantPhone' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.50{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.4 NAME 'city' SYNTAX 1.3.6.1.4.1.146 + 6.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.5 NAME 'company' SYNTAX 1.3.6.1.4.1. + 1466.115.121.1.15{64512} ) +attributeTypes: ( 0.9.2342.19200300.100.1.43 NAME 'co' SYNTAX 1.3.6.1.4.1.1466 + .115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.6 NAME 'directReports' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 0.9.2342.19200300.100.1.10 NAME 'manager' SYNTAX 1.3.6.1.4.1 + .1466.115.121.1.12 ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.7 NAME 'mailstop' SYNTAX 1.3.6.1.4.1 + .1466.115.121.1.15{64512} ) +attributeTypes: ( 0.9.2342.19200300.100.1.41 NAME 'mobile' SYNTAX 1.3.6.1.4.1. + 1466.115.121.1.50{64512} ) +attributeTypes: ( 0.9.2342.19200300.100.1.40 NAME 'personalTitle' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 0.9.2342.19200300.100.1.42 NAME 'pager' SYNTAX 1.3.6.1.4.1.1 + 466.115.121.1.50{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.8 NAME 'workforceID' SYNTAX 1.3.6.1. + 4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.9 NAME 'instantMessagingID' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.10 NAME 'preferredName' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 0.9.2342.19200300.100.1.7 NAME 'photo' SYNTAX 1.3.6.1.4.1.14 + 66.115.121.1.40{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.11 NAME 'jobCode' SYNTAX 1.3.6.1.4.1 + .1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.12 NAME 'siteLocation' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.13 NAME 'employeeStatus' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113730.3.1.4 NAME 'employeeType' SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.14 NAME 'costCenter' SYNTAX 1.3.6.1. + 4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.15 NAME 'costCenterDescription' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.16 NAME 'tollFreePhoneNumber' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.50{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.17 NAME 'otherPhoneNumber' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.50{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.18 NAME 'managerWorkforceID' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.19 NAME 'jackNumber' SYNTAX 1.3.6.1. + 4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113730.3.1.2 NAME 'departmentNumber' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.20 NAME 'vehicleInformation' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.21 NAME 'accessCardNumber' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.32 NAME 'isManager' SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.22 NAME 'homeCity' SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.23 NAME 'homeEmailAddress' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 1.3.6.1.4.1.1466.101.120.31 NAME 'homeFax' SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.50{64512} ) +attributeTypes: ( 0.9.2342.19200300.100.1.20 NAME 'homePhone' SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.50{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.24 NAME 'homeState' SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.15{64512} ) +attributeTypes: ( 0.9.2342.19200300.100.1.39 NAME 'homePostalAddress' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.41{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.25 NAME 'homeZipCode' SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.26 NAME 'personalMobile' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.50{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.27 NAME 'children' SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.28 NAME 'spouse' SYNTAX 1.3.6.1.4.1. + 1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.29 NAME 'vendorName' SYNTAX 1.3.6.1. + 4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.30 NAME 'vendorAddress' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.8.4.31 NAME 'vendorPhoneNumber' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.50{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.303 NAME 'dgIdentity' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME_VALUE_ACCESS '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.304 NAME 'dgTimeOut' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.305 NAME 'dgAllowUnknown' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.306 NAME 'dgAllowDuplicates' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.546 NAME 'allowAliasToAncestor' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.39.4.1.1 NAME 'sASSecurityDN' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'SAS:Security DN' X-NDS_S + ERVER_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.4.1.2 NAME 'sASServiceDN' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'SAS:Service DN' X-NDS_SER + VER_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.4.1.3 NAME 'sASSecretStore' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'SAS:SecretStore' ) +attributeTypes: ( 2.16.840.1.113719.1.39.4.1.4 NAME 'sASSecretStoreKey' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation + X-NDS_NAME 'SAS:SecretStore:Key' X-NDS_HIDDEN '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.4.1.5 NAME 'sASSecretStoreData' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NAME ' + SAS:SecretStore:Data' X-NDS_HIDDEN '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.4.1.6 NAME 'sASPKIStoreKeys' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NAME 'SAS + :PKIStore:Keys' X-NDS_HIDDEN '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.1 NAME 'nDSPKIPublicKey' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Public K + ey' X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.2 NAME 'nDSPKIPrivateKey' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Private + Key' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.3 NAME 'nDSPKIPublicKeyCertificat + e' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSP + KI:Public Key Certificate' X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.4 NAME 'nDSPKICertificateChain' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'NDSPKI:Certificate Ch + ain' X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.5 NAME 'nDSPKIParentCA' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Parent CA + ' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.6 NAME 'nDSPKIParentCADN' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'NDSPKI:Parent CA DN' + ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.7 NAME 'nDSPKIKeyFile' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Key File' + ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.8 NAME 'nDSPKISubjectName' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Subjec + t Name' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.11 NAME 'nDSPKIGivenName' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Given N + ame' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.9 NAME 'nDSPKIKeyMaterialDN' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'NDSPKI:Key Material DN' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.10 NAME 'nDSPKITreeCADN' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'NDSPKI:Tree CA DN' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.12 NAME 'nDSPKIUserCertificateInf + o' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'NDSPKI:userCertifi + cateInfo' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.13 NAME 'nDSPKITrustedRootCertifi + cate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'N + DSPKI:Trusted Root Certificate' X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.14 NAME 'nDSPKINotBefore' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Not Bef + ore' X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.15 NAME 'nDSPKINotAfter' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Not Afte + r' X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.101 NAME 'nDSPKISDKeyServerDN' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'NDSPKI:SD Key Server DN' X-ND + S_SERVER_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.102 NAME 'nDSPKISDKeyStruct' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'NDSPKI:SD Key Struct' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.103 NAME 'nDSPKISDKeyCert' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:SD Key + Cert' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.104 NAME 'nDSPKISDKeyID' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:SD Key I + D' ) +attributeTypes: ( 2.16.840.1.113719.1.39.4.1.105 NAME 'nDSPKIKeystore' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NAME 'ND + SPKI:Keystore' X-NDS_HIDDEN '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.4.1.106 NAME 'ndspkiAdditionalRoots' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.31.4.2.3 NAME 'masvLabel' SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.31.4.2.4 NAME 'masvProposedLabel' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.31.4.2.5 NAME 'masvDefaultRange' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.31.4.2.6 NAME 'masvAuthorizedRange' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.31.4.2.7 NAME 'masvDomainPolicy' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.31.4.1.8 NAME 'masvClearanceNames' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.31.4.1.9 NAME 'masvLabelNames' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.31.4.1.10 NAME 'masvLabelSecrecyLevelNam + es' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.31.4.1.11 NAME 'masvLabelSecrecyCategory + Names' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.31.4.1.12 NAME 'masvLabelIntegrityLevelN + ames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.31.4.1.13 NAME 'masvLabelIntegrityCatego + ryNames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.31.4.1.14 NAME 'masvPolicyUpdate' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_ + SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.31.4.1.16 NAME 'masvNDSAttributeLabels' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.31.4.1.15 NAME 'masvPolicyDN' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHE + D_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.2 NAME 'sASLoginSequence' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_NAME 'SAS:Login Sequence' X-ND + S_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.8 NAME 'sASLoginPolicyUpdate' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'SAS:Login Poli + cy Update' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.38 NAME 'sasNMASProductOptions + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ + '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.74 NAME 'sasAuditConfiguration + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.14 NAME 'sASNDSPasswordWindow' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'SAS:NDS Passw + ord Window' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.15 NAME 'sASPolicyCredentials' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'SAS:Po + licy Credentials' X-NDS_SERVER_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.16 NAME 'sASPolicyMethods' SYN + TAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'SAS:Policy Methods' X-ND + S_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.17 NAME 'sASPolicyObjectVersio + n' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'SAS:Policy + Object Version' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.18 NAME 'sASPolicyServiceSubty + pes' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'SAS:Policy Servi + ce Subtypes' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.19 NAME 'sASPolicyServices' SY + NTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'SAS:Policy Services' X- + NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.20 NAME 'sASPolicyUsers' SYNTA + X 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'SAS:Policy Users' X-NDS_NO + T_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.21 NAME 'sASAllowNDSPasswordWi + ndow' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'SAS:Allow + NDS Password Window' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.9 NAME 'sASMethodIdentifier' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'SAS:Meth + od Identifier' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.10 NAME 'sASMethodVendor' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'SAS:Method + Vendor' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.11 NAME 'sASAdvisoryMethodGrad + e' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'SAS: + Advisory Method Grade' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE + '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.12 NAME 'sASVendorSupport' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'SAS:Vendor + Support' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.13 NAME 'sasCertificateSearchC + ontainers' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_PUBLIC_READ '1' X-NDS_ + NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.70 NAME 'sasNMASMethodConfigDa + ta' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_RE + AD '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.22 NAME 'sASLoginClientMethodN + etWare' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'SAS:Log + in Client Method NetWare' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIA + TE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.23 NAME 'sASLoginServerMethodN + etWare' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'SAS:Log + in Server Method NetWare' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIA + TE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.24 NAME 'sASLoginClientMethodW + INNT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'SAS:Login + Client Method WINNT' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE ' + 1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.25 NAME 'sASLoginServerMethodW + INNT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'SAS:Login + Server Method WINNT' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE ' + 1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.26 NAME 'sasLoginClientMethodS + olaris' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ ' + 1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.27 NAME 'sasLoginServerMethodS + olaris' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ ' + 1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.28 NAME 'sasLoginClientMethodL + inux' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' + X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.29 NAME 'sasLoginServerMethodL + inux' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' + X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.30 NAME 'sasLoginClientMethodT + ru64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' + X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.31 NAME 'sasLoginServerMethodT + ru64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' + X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.32 NAME 'sasLoginClientMethodA + IX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X + -NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.33 NAME 'sasLoginServerMethodA + IX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X + -NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.34 NAME 'sasLoginClientMethodH + PUX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' + X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.35 NAME 'sasLoginServerMethodH + PUX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' + X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.1000 NAME 'sasLoginClientMetho + ds390' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1 + ' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.1001 NAME 'sasLoginServerMetho + ds390' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1 + ' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.36 NAME 'sASLoginMethodContain + erDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'SAS:Logi + n Method Container DN' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE + '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.37 NAME 'sASLoginPolicyDN' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'SAS:Login Policy + DN' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.63 NAME 'sasPostLoginMethodCon + tainerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_REA + D '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.38 NAME 'rADIUSActiveConnectio + ns' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Active Co + nnections' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.39 NAME 'rADIUSAgedInterval' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Aged Int + erval' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.40 NAME 'rADIUSAttributeList' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'RADIUS: + Attribute List' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.41 NAME 'rADIUSAttributeLists' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Attribute Li + sts' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.42 NAME 'rADIUSClient' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Client' X-NDS_NOT_SC + HED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.43 NAME 'rADIUSCommonNameResol + ution' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS: + Common Name Resolution' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.44 NAME 'rADIUSConcurrentLimit + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Concu + rrent Limit' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.45 NAME 'rADIUSConnectionHisto + ry' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Connectio + n History' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.46 NAME 'rADIUSDASVersion' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:DAS Versio + n' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.47 NAME 'rADIUSDefaultProfile' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'RADIUS + :Default Profile' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.48 NAME 'rADIUSDialAccessGroup + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'RADIUS:Dial + Access Group' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.49 NAME 'rADIUSEnableCommonNam + eLogin' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'RADIUS: + Enable Common Name Login' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.50 NAME 'rADIUSEnableDialAcces + s' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'RADIUS:Enabl + e Dial Access' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.51 NAME 'rADIUSInterimAcctingT + imeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS + :Interim Accting Timeout' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.52 NAME 'rADIUSLookupContexts' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'RADIUS:Lookup Contexts' X- + NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.53 NAME 'rADIUSMaxDASHistoryRe + cord' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:M + ax DAS History Record' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.54 NAME 'rADIUSMaximumHistoryR + ecord' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS: + Maximum History Record' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.55 NAME 'rADIUSPassword' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'RADIUS:Passw + ord' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.56 NAME 'rADIUSPasswordPolicy' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Passwo + rd Policy' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.57 NAME 'rADIUSPrivateKey' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'RADIUS:Pri + vate Key' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.58 NAME 'rADIUSProxyContext' S + YNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'RADIUS:Proxy Context' + X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.59 NAME 'rADIUSProxyDomain' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Proxy Domain' X + -NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.60 NAME 'rADIUSProxyTarget' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Proxy Target' X + -NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.61 NAME 'rADIUSPublicKey' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'RADIUS:Publ + ic Key' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.62 NAME 'rADIUSServiceList' SY + NTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'RADIUS:Service List' X- + NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.3 NAME 'sASLoginSecret' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'SAS:Login Secret' X-NDS_SE + RVER_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.4 NAME 'sASLoginSecretKey' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'SAS:Login Secret Key' X + -NDS_SERVER_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.5 NAME 'sASEncryptionType' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'SAS:Encryption Ty + pe' X-NDS_SERVER_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.6 NAME 'sASLoginConfiguration' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'SAS:Login Configura + tion' X-NDS_SERVER_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.7 NAME 'sASLoginConfigurationK + ey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'SAS:Login Config + uration Key' X-NDS_SERVER_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.73 NAME 'sasDefaultLoginSequen + ce' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_RE + AD '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.64 NAME 'sasAuthorizedLoginSeq + uences' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.69 NAME 'sasAllowableSubjectNa + mes' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.71 NAME 'sasLoginFailureDelay' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.42.1.0.72 NAME 'sasMethodVersion' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.6.4.1 NAME 'snmpGroupDN' SYNTAX 1.3.6.1. + 4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.6.4.2 NAME 'snmpServerList' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 2.16.840.1.113719.1.6.4.3 NAME 'snmpTrapConfig' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.6.4.4 NAME 'snmpTrapDescription' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.6.4.5 NAME 'snmpTrapInterval' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.6.4.6 NAME 'snmpTrapDisable' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.528 NAME 'ndapPartitionPasswordMgm + t' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IM + MEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.529 NAME 'ndapClassPasswordMgmt' S + YNTAX 2.16.840.1.113719.1.1.5.1.0 X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.530 NAME 'ndapPasswordMgmt' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE ' + 1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.537 NAME 'ndapPartitionLoginMgmt' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMED + IATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.538 NAME 'ndapClassLoginMgmt' SYNT + AX 2.16.840.1.113719.1.1.5.1.0 X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.539 NAME 'ndapLoginMgmt' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' + ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.1 NAME 'nspmPasswordKey' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X + -NDS_HIDDEN '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.2 NAME 'nspmPassword' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-ND + S_HIDDEN '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.3 NAME 'nspmDistributionPassword + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOp + eration X-NDS_HIDDEN '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.4 NAME 'nspmPasswordHistory' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_HIDD + EN '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.5 NAME 'nspmAdministratorChangeC + ount' SYNTAX 2.16.840.1.113719.1.1.5.1.22 SINGLE-VALUE USAGE directoryOperat + ion X-NDS_HIDDEN '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.6 NAME 'nspmPasswordPolicyDN' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_ + NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.7 NAME 'nspmPreviousDistribution + Password' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE dir + ectoryOperation X-NDS_HIDDEN '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.8 NAME 'nspmDoNotExpirePassword' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.42.2.27.8.1.16 NAME 'pwdChangedTime' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryO + peration ) +attributeTypes: ( 1.3.6.1.4.1.42.2.27.8.1.17 NAME 'pwdAccountLockedTime' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE dire + ctoryOperation ) +attributeTypes: ( 1.3.6.1.4.1.42.2.27.8.1.19 NAME 'pwdFailureTime' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.24 NO-USER-MODIFICATION USAGE directoryOperation ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.100 NAME 'nspmConfigurationOptio + ns' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_I + MMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.102 NAME 'nspmChangePasswordMess + age' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHE + D_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.103 NAME 'nspmPasswordHistoryLim + it' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_I + MMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.104 NAME 'nspmPasswordHistoryExp + iration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_S + YNC_IMMEDIATE '1' ) +attributeTypes: ( 1.3.6.1.4.1.42.2.27.8.1.4 NAME 'pwdInHistory' SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.105 NAME 'nspmMinPasswordLifetim + e' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IM + MEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.106 NAME 'nspmAdminsDoNotExpireP + assword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SY + NC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.107 NAME 'nspmPasswordACL' SYNTA + X 2.16.840.1.113719.1.1.5.1.17 ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.200 NAME 'nspmMaximumLength' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIAT + E '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.201 NAME 'nspmMinUpperCaseCharac + ters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC + _IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.202 NAME 'nspmMaxUpperCaseCharac + ters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC + _IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.203 NAME 'nspmMinLowerCaseCharac + ters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC + _IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.204 NAME 'nspmMaxLowerCaseCharac + ters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC + _IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.205 NAME 'nspmNumericCharactersA + llowed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYN + C_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.206 NAME 'nspmNumericAsFirstChar + acter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC + _IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.207 NAME 'nspmNumericAsLastChara + cter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_ + IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.208 NAME 'nspmMinNumericCharacte + rs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_I + MMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.209 NAME 'nspmMaxNumericCharacte + rs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_I + MMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.210 NAME 'nspmSpecialCharactersA + llowed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYN + C_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.211 NAME 'nspmSpecialAsFirstChar + acter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC + _IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.212 NAME 'nspmSpecialAsLastChara + cter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_ + IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.213 NAME 'nspmMinSpecialCharacte + rs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_I + MMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.214 NAME 'nspmMaxSpecialCharacte + rs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_I + MMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.215 NAME 'nspmMaxRepeatedCharact + ers' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_ + IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.216 NAME 'nspmMaxConsecutiveChar + acters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SY + NC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.217 NAME 'nspmMinUniqueCharacter + s' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IM + MEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.218 NAME 'nspmDisallowedAttribut + eValues' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} X-NDS_NOT_SCHED_SYNC_IM + MEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.219 NAME 'nspmExcludeList' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE ' + 1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.220 NAME 'nspmCaseSensitive' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE + '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.221 NAME 'nspmPolicyPrecedence' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMED + IATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.222 NAME 'nspmExtendedCharacters + Allowed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SY + NC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.223 NAME 'nspmExtendedAsFirstCha + racter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYN + C_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.224 NAME 'nspmExtendedAsLastChar + acter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC + _IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.225 NAME 'nspmMinExtendedCharact + ers' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_ + IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.226 NAME 'nspmMaxExtendedCharact + ers' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_ + IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.227 NAME 'nspmUpperAsFirstCharac + ter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_I + MMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.228 NAME 'nspmUpperAsLastCharact + er' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IM + MEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.229 NAME 'nspmLowerAsFirstCharac + ter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_I + MMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.230 NAME 'nspmLowerAsLastCharact + er' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IM + MEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.231 NAME 'nspmComplexityRules' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIA + TE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.300 NAME 'nspmPolicyAgentContain + erDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1 + ' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.301 NAME 'nspmPolicyAgentNetWare + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-N + DS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.302 NAME 'nspmPolicyAgentWINNT' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS + _NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.303 NAME 'nspmPolicyAgentSolaris + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-N + DS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.304 NAME 'nspmPolicyAgentLinux' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS + _NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.305 NAME 'nspmPolicyAgentAIX' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_N + OT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.43.4.306 NAME 'nspmPolicyAgentHPUX' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_ + NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 0.9.2342.19200300.100.1.55 NAME 'audio' SYNTAX 1.3.6.1.4.1.1 + 466.115.121.1.40{64512} ) +attributeTypes: ( 2.16.840.1.113730.3.1.1 NAME 'carLicense' SYNTAX 1.3.6.1.4.1 + .1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113730.3.1.241 NAME 'displayName' SYNTAX 1.3.6.1. + 4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 0.9.2342.19200300.100.1.60 NAME 'jpegPhoto' SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.40{64512} ) +attributeTypes: ( 1.3.6.1.4.1.250.1.57 NAME 'labeledUri' SYNTAX 1.3.6.1.4.1.14 + 66.115.121.1.15{64512} ) +attributeTypes: ( 0.9.2342.19200300.100.1.7 NAME 'ldapPhoto' SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.40{64512} ) +attributeTypes: ( 2.16.840.1.113730.3.1.39 NAME 'preferredLanguage' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE ) +attributeTypes: ( 0.9.2342.19200300.100.1.21 NAME 'secretary' SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.12 ) +attributeTypes: ( 2.16.840.1.113730.3.1.40 NAME 'userSMIMECertificate' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} ) +attributeTypes: ( 2.16.840.1.113730.3.1.216 NAME 'userPKCS12' SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.40{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.12.4.1.0 NAME 'auditAEncryptionKey' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'Audit:A Enc + ryption Key' ) +attributeTypes: ( 2.16.840.1.113719.1.12.4.2.0 NAME 'auditBEncryptionKey' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'Audit:B Enc + ryption Key' ) +attributeTypes: ( 2.16.840.1.113719.1.12.4.3.0 NAME 'auditContents' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Audit:Contents' ) +attributeTypes: ( 2.16.840.1.113719.1.12.4.4.0 NAME 'auditType' SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Audit:Type' ) +attributeTypes: ( 2.16.840.1.113719.1.12.4.5.0 NAME 'auditCurrentEncryptionKey + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'Audit + :Current Encryption Key' ) +attributeTypes: ( 2.16.840.1.113719.1.12.4.6.0 NAME 'auditFileLink' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Audit:File Link' ) +attributeTypes: ( 2.16.840.1.113719.1.12.4.7.0 NAME 'auditLinkList' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Audit:Link List' ) +attributeTypes: ( 2.16.840.1.113719.1.12.4.8.0 NAME 'auditPath' SYNTAX 2.16.84 + 0.1.113719.1.1.5.1.15{64512} SINGLE-VALUE X-NDS_NAME 'Audit:Path' ) +attributeTypes: ( 2.16.840.1.113719.1.12.4.9.0 NAME 'auditPolicy' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'Audit:Policy' ) +attributeTypes: ( 2.16.840.1.113719.1.38.4.1.1 NAME 'wANMANWANPolicy' SYNTAX 2 + .16.840.1.113719.1.1.5.1.13{64512} X-NDS_NAME 'WANMAN:WAN Policy' X-NDS_NOT_ + SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.38.4.1.2 NAME 'wANMANLANAreaMembership' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'WANMAN:LAN Are + a Membership' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.38.4.1.3 NAME 'wANMANCost' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'WANMAN:Cost' X-NDS_NOT_SCHED_SYNC + _IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.38.4.1.4 NAME 'wANMANDefaultCost' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'WANMAN:Default Cost' + X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.30 NAME 'rbsAssignedRoles' SYNTAX + 2.16.840.1.113719.1.1.5.1.25 ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.31 NAME 'rbsContent' SYNTAX 2.16.8 + 40.1.113719.1.1.5.1.25 ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.32 NAME 'rbsContentMembership' SYN + TAX 2.16.840.1.113719.1.1.5.1.25 ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.33 NAME 'rbsEntryPoint' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.34 NAME 'rbsMember' SYNTAX 2.16.84 + 0.1.113719.1.1.5.1.25 ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.35 NAME 'rbsOwnedCollections' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.36 NAME 'rbsPath' SYNTAX 2.16.840. + 1.113719.1.1.5.1.25 ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.37 NAME 'rbsParameters' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.26{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.38 NAME 'rbsTaskRights' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.40{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.39 NAME 'rbsTrusteeOf' SYNTAX 2.16 + .840.1.113719.1.1.5.1.25 ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.40 NAME 'rbsType' SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.15{256} SINGLE-VALUE X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOU + ND '256' ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.41 NAME 'rbsURL' SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.40{64512} SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.42 NAME 'rbsTaskTemplates' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.43 NAME 'rbsTaskTemplatesURL' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.44 NAME 'rbsGALabel' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.45 NAME 'rbsPageMembership' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.26{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.46 NAME 'rbsTargetObjectType' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.47 NAME 'rbsContext' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.48 NAME 'rbsXMLInfo' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.51 NAME 'rbsAssignedRoles2' SYNTAX + 2.16.840.1.113719.1.1.5.1.25 ) +attributeTypes: ( 2.16.840.1.113719.1.135.4.52 NAME 'rbsOwnedCollections2' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.540 NAME 'prSyncPolicyDN' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_SERVER_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.541 NAME 'prSyncAttributes' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_SERVER_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.542 NAME 'dsEncryptedReplicationCo + nfig' SYNTAX 2.16.840.1.113719.1.1.5.1.19 ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.543 NAME 'encryptionPolicyDN' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.544 NAME 'attrEncryptionRequiresSe + cure' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.545 NAME 'attrEncryptionDefinition + ' SYNTAX 2.16.840.1.113719.1.1.5.1.6{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE ' + 1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.16 NAME 'ndspkiCRLFileName' SYNTA + X 2.16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.17 NAME 'ndspkiStatus' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.27 X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.18 NAME 'ndspkiIssueTime' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.19 NAME 'ndspkiNextIssueTime' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.20 NAME 'ndspkiAttemptTime' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.21 NAME 'ndspkiTimeInterval' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.22 NAME 'ndspkiCRLMaxProcessingIn + terval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_PUBLIC_READ + '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.23 NAME 'ndspkiCRLNumber' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.24 NAME 'ndspkiDistributionPoints + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.25 NAME 'ndspkiCRLProcessData' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.26 NAME 'ndspkiCRLConfigurationDN + List' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.27 NAME 'ndspkiCADN' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.28 NAME 'ndspkiCRLContainerDN' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.29 NAME 'ndspkiIssuedCertContaine + rDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' + ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.30 NAME 'ndspkiDistributionPointD + N' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.31 NAME 'ndspkiCRLConfigurationDN + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.32 NAME 'ndspkiDirectory' SYNTAX + 2.16.840.1.113719.1.1.5.1.15{64512} ) +attributeTypes: ( 2.5.4.38 NAME 'authorityRevocationList;binary' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'ndspkiAuthorityRevocationLis + t' X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.5.4.39 NAME 'certificateRevocationList;binary' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'ndspkiCertificateRevocatio + nList' X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.5.4.53 NAME 'deltaRevocationList;binary' SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'ndspkiDeltaRevocationList' X-NDS + _PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.36 NAME 'ndspkiTrustedRootList' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.37 NAME 'ndspkiSecurityRightsLeve + l' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.48.4.1.38 NAME 'ndspkiKMOExport' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.7.4.1 NAME 'notfSMTPEmailHost' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIA + TE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.7.4.2 NAME 'notfSMTPEmailFrom' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIA + TE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.7.4.3 NAME 'notfSMTPEmailUserName' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMM + EDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.7.4.5 NAME 'notfMergeTemplateData' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMM + EDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.7.4.6 NAME 'notfMergeTemplateSubject' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_ + IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.44.4.1 NAME 'nsimRequiredQuestions' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC + _IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.44.4.2 NAME 'nsimRandomQuestions' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_I + MMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.44.4.3 NAME 'nsimNumberRandomQuestion + s' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IM + MEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.44.4.4 NAME 'nsimMinResponseLength' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDI + ATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.44.4.5 NAME 'nsimMaxResponseLength' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDI + ATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.44.4.6 NAME 'nsimForgottenLoginConfig + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMME + DIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.44.4.7 NAME 'nsimForgottenAction' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_I + MMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.44.4.8 NAME 'nsimAssignments' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.44.4.9 NAME 'nsimChallengeSetDN' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE + '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.44.4.10 NAME 'nsimChallengeSetGUID' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1 + ' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.44.4.11 NAME 'nsimPwdRuleEnforcement' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMED + IATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.44.4.12 NAME 'nsimHint' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.39.44.4.13 NAME 'nsimPasswordReminder' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.266.4.4 NAME 'sssProxyStoreKey' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X- + NDS_HIDDEN '1' ) +attributeTypes: ( 2.16.840.1.113719.1.266.4.5 NAME 'sssProxyStoreSecrets' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_HIDDE + N '1' ) +attributeTypes: ( 2.16.840.1.113719.1.266.4.6 NAME 'sssActiveServerList' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.40{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.266.4.7 NAME 'sssCacheRefreshInterval' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.266.4.8 NAME 'sssAdminList' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 2.16.840.1.113719.1.266.4.9 NAME 'sssAdminGALabel' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.266.4.10 NAME 'sssEnableReadTimestamps' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.266.4.11 NAME 'sssDisableMasterPasswords + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.266.4.12 NAME 'sssEnableAdminAccess' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.266.4.13 NAME 'sssReadSecretPolicies' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.266.4.14 NAME 'sssServerPolicyOverrideDN + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.531 NAME 'eDirCloneSource' SYNTAX + 2.16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDI + ATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.532 NAME 'eDirCloneKeys' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOpera + tion X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_HIDDEN '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.1.533 NAME 'eDirCloneLock' SYNTAX 2. + 16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIAT + E '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.711 NAME 'groupMember' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.12 X-NDS_NAME_VALUE_ACCESS '1' ) +attributeTypes: ( 2.16.840.1.113719.1.1.4.712 NAME 'nestedConfig' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.1.1.1.0 NAME 'uidNumber' SYNTAX 1.3.6.1.4.1.1466.115 + .121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 1.3.6.1.1.1.1.1 NAME 'gidNumber' SYNTAX 1.3.6.1.4.1.1466.115 + .121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 1.3.6.1.1.1.1.2 NAME 'gecos' SYNTAX 1.3.6.1.4.1.1466.115.121 + .1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 1.3.6.1.1.1.1.3 NAME 'homeDirectory' SYNTAX 1.3.6.1.4.1.1466 + .115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 1.3.6.1.1.1.1.4 NAME 'loginShell' SYNTAX 1.3.6.1.4.1.1466.11 + 5.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 1.3.6.1.1.1.1.5 NAME 'shadowLastChange' SYNTAX 1.3.6.1.4.1.1 + 466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 1.3.6.1.1.1.1.6 NAME 'shadowMin' SYNTAX 1.3.6.1.4.1.1466.115 + .121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 1.3.6.1.1.1.1.7 NAME 'shadowMax' SYNTAX 1.3.6.1.4.1.1466.115 + .121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 1.3.6.1.1.1.1.8 NAME 'shadowWarning' SYNTAX 1.3.6.1.4.1.1466 + .115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 1.3.6.1.1.1.1.9 NAME 'shadowInactive' SYNTAX 1.3.6.1.4.1.146 + 6.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 1.3.6.1.1.1.1.10 NAME 'shadowExpire' SYNTAX 1.3.6.1.4.1.1466 + .115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 1.3.6.1.1.1.1.11 NAME 'shadowFlag' SYNTAX 1.3.6.1.4.1.1466.1 + 15.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 1.3.6.1.1.1.1.12 NAME 'memberUid' SYNTAX 1.3.6.1.4.1.1466.11 + 5.121.1.26{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.196.4.0 NAME 'uamPosixWorkstationList' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 2.16.840.1.113719.1.196.4.1 NAME 'uamPosixWorkstationContext + s' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 2.16.840.1.113719.1.196.4.2 NAME 'uamPosixSalt' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.26{12} SINGLE-VALUE X-NDS_LOWER_BOUND '2' X-NDS_UPPER_ + BOUND '12' ) +attributeTypes: ( 2.16.840.1.113719.1.196.4.3 NAME 'uamPosixPAMServiceExcludeL + ist' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} ) +attributeTypes: ( 2.16.840.1.113719.1.196.6.4 NAME 'uamPosixUidNumberStart' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.196.6.5 NAME 'uamPosixUidNumberEnd' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.196.6.6 NAME 'uamPosixUidNumberLastAssig + ned' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.196.6.7 NAME 'uamPosixUidNumberDeletedMa + p' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_UPPER_BOUN + D '64512' ) +attributeTypes: ( 2.16.840.1.113719.1.196.6.8 NAME 'uamPosixUidNumberReuse' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.196.6.9 NAME 'uamPosixGidNumberStart' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.196.6.10 NAME 'uamPosixGidNumberEnd' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.196.6.11 NAME 'uamPosixGidNumberLastAssi + gned' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.196.6.12 NAME 'uamPosixGidNumberDeletedM + ap' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_UPPER_BOU + ND '64512' ) +attributeTypes: ( 2.16.840.1.113719.1.196.6.13 NAME 'uamPosixGidNumberReuse' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.1.1 NAME 'iPrintDriverStoreCustomers + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.1.2 NAME 'iPrintDriverStoreIPPURI' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC + _IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.2.1 NAME 'iPrintManagerDBGenNum' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIAT + E '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.2.2 NAME 'iPrintManagerDBPath' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMM + EDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.2.3 NAME 'iPrintManagerDBSaveData' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIA + TE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.2.4 NAME 'iPrintManagerDBSaveIndex' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDI + ATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.2.5 NAME 'iPrintManagerDBSaveTime' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDI + ATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.2.6 NAME 'iPrintManagerIDS' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' + ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.2.7 NAME 'iPrintManagerIPPURI' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMM + EDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.2.8 NAME 'iPrintManagerPOtoPAidMap' + SYNTAX 2.16.840.1.113719.1.1.5.1.25 X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.2.9 NAME 'iPrintManagerDefaultURI' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC + _IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.3.1 NAME 'iPrintPrinterIPPURI' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMM + EDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.3.2 NAME 'iPrintPrinterManager' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE + '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.3.3 NAME 'iPrintPrinterOperatorRole' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SY + NC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.3.4 NAME 'iPrintPrinterPAName' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMM + EDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.3.5 NAME 'iPrintPrinterUserRole' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_I + MMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.3.6 NAME 'iPrintPrinterControlPage' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYN + C_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.4.2 NAME 'iPrintiCMClientFlags' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE + '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.4.3 NAME 'iPrintiCMClientProxyURI' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC + _IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.4.4 NAME 'iPrintiCMClientTrayURI' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_ + IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.4.5 NAME 'iPrintiCMPrinterFlags' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIAT + E '1' ) +attributeTypes: ( 2.16.840.1.113719.1.4.5.4.6 NAME 'iPrintiCMPrinterList' SYNT + AX 2.16.840.1.113719.1.1.5.1.25 X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.138.4.1.1 NAME 'DFS-VLDB-Hosts' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.12 X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.138.4.1.2 NAME 'DFS-Volume-Context' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.138.4.1.3 NAME 'DFS-Volume-Guid' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' ) +attributeTypes: ( 2.16.840.1.113719.1.138.4.1.7 NAME 'VLDB-BackEnd-ID' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-ND + S_NOT_SCHED_SYNC_IMMEDIATE '1' ) +attributeTypes: ( 2.16.840.1.113719.1.219.4.1 NAME 'nssfsPool' SYNTAX 1.3.6.1. + 4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.219.4.2 NAME 'nssfsPoolID' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.219.4.3 NAME 'nssfsShared' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113719.1.451.4.1.1 NAME 'linuxNCPMountPoint' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.15{4096} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOU + ND '4096' ) +attributeTypes: ( 2.16.840.1.113719.1.50.4.1.1 NAME 'SMSRegisteredService' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'SMS Registered Service' + ) +attributeTypes: ( 2.16.840.1.113719.1.50.4.1.2 NAME 'SMSProtocolAddress' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'SMS Protocol Address' ) +modifyTimestamp: 20080721090905Z
diff --git a/beans/src/test/resources/ldaptive-gen.properties b/beans/src/test/resources/ldaptive-gen.properties new file mode 100644 index 0000000..24256e2 --- /dev/null +++ b/beans/src/test/resources/ldaptive-gen.properties
@@ -0,0 +1,9 @@ +# test properties +org.ldaptive.packageName=edu.vt.middleware.ldap.beans +org.ldaptive.useOptionalAttributes=true +org.ldaptive.useOperationalAttributes=true +org.ldaptive.objectClasses=virginiaTechPerson,virginiaTechGroup,virginiaTechService,virginiaTechEntitlement +org.ldaptive.excludedNames=userPassword +org.ldaptive.ldapUrl=ldap://directory.vt.edu +org.ldaptive.typeMappings=1.3.6.1.4.1.1466.115.121.1.5=[B,1.3.6.1.4.1.1466.115.121.1.24=java.lang.String.class +org.ldaptive.nameMappings=c=countryName,l=localityName
diff --git a/beans/src/test/resources/subschema.ldif b/beans/src/test/resources/subschema.ldif new file mode 100644 index 0000000..464d2e7 --- /dev/null +++ b/beans/src/test/resources/subschema.ldif
@@ -0,0 +1,1875 @@ +# extended LDIF +# +# LDAPv3 +# base <cn=Subschema> with scope baseObject +# filter: (objectclass=*) +# requesting: + * +# + +# Subschema +dn: cn=Subschema +structuralObjectClass: subentry +objectClass: top +objectClass: subentry +objectClass: subschema +objectClass: extensibleObject +cn: Subschema +createTimestamp: 20131216122842Z +modifyTimestamp: 20131216122842Z +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' X-NOT-HUMAN-READABLE + 'TRUE' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' X-NOT-HUMAN-READABL + E 'TRUE' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' X-BINARY-TRANS + FER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' X-BINARY- + TRANSFER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' X-BINARY + -TRANSFER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' ) +ldapSyntaxes: ( 1.3.6.1.4.1.4203.666.11.10.2.1 DESC 'X.509 AttributeCertificat + e' X-BINARY-TRANSFER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' ) +ldapSyntaxes: ( 1.2.36.79672281.1.5.0 DESC 'RDN' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number + ' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' X-NOT-HUMAN-READABLE + 'TRUE' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' X-BIN + ARY-TRANSFER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' ) +ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' ) +ldapSyntaxes: ( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' ) +ldapSyntaxes: ( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' ) +ldapSyntaxes: ( 1.3.6.1.1.16.1 DESC 'UUID' ) +matchingRules: ( 1.3.6.1.1.16.3 NAME 'UUIDOrderingMatch' SYNTAX 1.3.6.1.1.16.1 + ) +matchingRules: ( 1.3.6.1.1.16.2 NAME 'UUIDMatch' SYNTAX 1.3.6.1.1.16.1 ) +matchingRules: ( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.27 ) +matchingRules: ( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.27 ) +matchingRules: ( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.26 ) +matchingRules: ( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) +matchingRules: ( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.26 ) +matchingRules: ( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.26 ) +matchingRules: ( 2.5.13.38 NAME 'certificateListExactMatch' SYNTAX 1.3.6.1.1.1 + 5.5 ) +matchingRules: ( 2.5.13.34 NAME 'certificateExactMatch' SYNTAX 1.3.6.1.1.15.1 + ) +matchingRules: ( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.38 ) +matchingRules: ( 2.5.13.29 NAME 'integerFirstComponentMatch' SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.27 ) +matchingRules: ( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' SYNTAX 1.3.6.1. + 4.1.1466.115.121.1.24 ) +matchingRules: ( 2.5.13.27 NAME 'generalizedTimeMatch' SYNTAX 1.3.6.1.4.1.1466 + .115.121.1.24 ) +matchingRules: ( 2.5.13.23 NAME 'uniqueMemberMatch' SYNTAX 1.3.6.1.4.1.1466.11 + 5.121.1.34 ) +matchingRules: ( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.58 ) +matchingRules: ( 2.5.13.20 NAME 'telephoneNumberMatch' SYNTAX 1.3.6.1.4.1.1466 + .115.121.1.50 ) +matchingRules: ( 2.5.13.19 NAME 'octetStringSubstringsMatch' SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.40 ) +matchingRules: ( 2.5.13.18 NAME 'octetStringOrderingMatch' SYNTAX 1.3.6.1.4.1. + 1466.115.121.1.40 ) +matchingRules: ( 2.5.13.17 NAME 'octetStringMatch' SYNTAX 1.3.6.1.4.1.1466.115 + .121.1.40 ) +matchingRules: ( 2.5.13.16 NAME 'bitStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.1 + 21.1.6 ) +matchingRules: ( 2.5.13.15 NAME 'integerOrderingMatch' SYNTAX 1.3.6.1.4.1.1466 + .115.121.1.27 ) +matchingRules: ( 2.5.13.14 NAME 'integerMatch' SYNTAX 1.3.6.1.4.1.1466.115.121 + .1.27 ) +matchingRules: ( 2.5.13.13 NAME 'booleanMatch' SYNTAX 1.3.6.1.4.1.1466.115.121 + .1.7 ) +matchingRules: ( 2.5.13.11 NAME 'caseIgnoreListMatch' SYNTAX 1.3.6.1.4.1.1466. + 115.121.1.41 ) +matchingRules: ( 2.5.13.10 NAME 'numericStringSubstringsMatch' SYNTAX 1.3.6.1. + 4.1.1466.115.121.1.58 ) +matchingRules: ( 2.5.13.9 NAME 'numericStringOrderingMatch' SYNTAX 1.3.6.1.4.1 + .1466.115.121.1.36 ) +matchingRules: ( 2.5.13.8 NAME 'numericStringMatch' SYNTAX 1.3.6.1.4.1.1466.11 + 5.121.1.36 ) +matchingRules: ( 2.5.13.7 NAME 'caseExactSubstringsMatch' SYNTAX 1.3.6.1.4.1.1 + 466.115.121.1.58 ) +matchingRules: ( 2.5.13.6 NAME 'caseExactOrderingMatch' SYNTAX 1.3.6.1.4.1.146 + 6.115.121.1.15 ) +matchingRules: ( 2.5.13.5 NAME 'caseExactMatch' SYNTAX 1.3.6.1.4.1.1466.115.12 + 1.1.15 ) +matchingRules: ( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' SYNTAX 1.3.6.1.4.1. + 1466.115.121.1.58 ) +matchingRules: ( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' SYNTAX 1.3.6.1.4.1.14 + 66.115.121.1.15 ) +matchingRules: ( 2.5.13.2 NAME 'caseIgnoreMatch' SYNTAX 1.3.6.1.4.1.1466.115.1 + 21.1.15 ) +matchingRules: ( 1.2.36.79672281.1.13.3 NAME 'rdnMatch' SYNTAX 1.2.36.79672281 + .1.5.0 ) +matchingRules: ( 2.5.13.1 NAME 'distinguishedNameMatch' SYNTAX 1.3.6.1.4.1.146 + 6.115.121.1.12 ) +matchingRules: ( 2.5.13.0 NAME 'objectIdentifierMatch' SYNTAX 1.3.6.1.4.1.1466 + .115.121.1.38 ) +matchingRuleUse: ( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' APPLIES ( s + upportedLDAPVersion $ entryTtl $ uidNumber $ gidNumber $ olcConcurrency $ olc + ConnMaxPending $ olcConnMaxPendingAuth $ olcIdleTimeout $ olcIndexSubstrIfMin + Len $ olcIndexSubstrIfMaxLen $ olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ + olcIndexIntLen $ olcListenerThreads $ olcLocalSSF $ olcMaxDerefDepth $ olcRe + plicationInterval $ olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcTh + reads $ olcToolThreads $ olcWriteTimeout $ olcDbCacheFree $ olcDbCacheSize $ + olcDbDNcacheSize $ olcDbIDLcacheSize $ olcDbSearchStack $ olcDbShmKey $ olcDb + MaxReaders $ olcDbMaxSize $ mailPreferenceOption ) ) +matchingRuleUse: ( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' APPLIES ( + supportedLDAPVersion $ entryTtl $ uidNumber $ gidNumber $ olcConcurrency $ ol + cConnMaxPending $ olcConnMaxPendingAuth $ olcIdleTimeout $ olcIndexSubstrIfMi + nLen $ olcIndexSubstrIfMaxLen $ olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep + $ olcIndexIntLen $ olcListenerThreads $ olcLocalSSF $ olcMaxDerefDepth $ olcR + eplicationInterval $ olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcT + hreads $ olcToolThreads $ olcWriteTimeout $ olcDbCacheFree $ olcDbCacheSize $ + olcDbDNcacheSize $ olcDbIDLcacheSize $ olcDbSearchStack $ olcDbShmKey $ olcD + bMaxReaders $ olcDbMaxSize $ mailPreferenceOption ) ) +matchingRuleUse: ( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' APPLIE + S ( altServer $ olcDbConfig $ c $ mail $ dc $ associatedDomain $ email $ aRec + ord $ mDRecord $ mXRecord $ nSRecord $ sOARecord $ cNAMERecord $ janetMailbox + $ mailForwardingAddress $ mailPreferredAddress $ mailAlias $ mailAccount $ m + ailExternalAddress ) ) +matchingRuleUse: ( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' APPLIES + ( altServer $ olcDbConfig $ c $ mail $ dc $ associatedDomain $ email $ aReco + rd $ mDRecord $ mXRecord $ nSRecord $ sOARecord $ cNAMERecord $ janetMailbox + $ mailForwardingAddress $ mailPreferredAddress $ mailAlias $ mailAccount $ ma + ilExternalAddress ) ) +matchingRuleUse: ( 2.5.13.38 NAME 'certificateListExactMatch' APPLIES ( author + ityRevocationList $ certificateRevocationList $ deltaRevocationList ) ) +matchingRuleUse: ( 2.5.13.34 NAME 'certificateExactMatch' APPLIES ( userCertif + icate $ cACertificate $ credential ) ) +matchingRuleUse: ( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' APPLIE + S ( supportedControl $ supportedExtension $ supportedFeatures $ ldapSyntaxes + $ supportedApplicationContext ) ) +matchingRuleUse: ( 2.5.13.29 NAME 'integerFirstComponentMatch' APPLIES ( suppo + rtedLDAPVersion $ entryTtl $ uidNumber $ gidNumber $ olcConcurrency $ olcConn + MaxPending $ olcConnMaxPendingAuth $ olcIdleTimeout $ olcIndexSubstrIfMinLen + $ olcIndexSubstrIfMaxLen $ olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olc + IndexIntLen $ olcListenerThreads $ olcLocalSSF $ olcMaxDerefDepth $ olcReplic + ationInterval $ olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcThread + s $ olcToolThreads $ olcWriteTimeout $ olcDbCacheFree $ olcDbCacheSize $ olcD + bDNcacheSize $ olcDbIDLcacheSize $ olcDbSearchStack $ olcDbShmKey $ olcDbMaxR + eaders $ olcDbMaxSize $ mailPreferenceOption ) ) +matchingRuleUse: ( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' APPLIES ( cre + ateTimestamp $ modifyTimestamp ) ) +matchingRuleUse: ( 2.5.13.27 NAME 'generalizedTimeMatch' APPLIES ( createTimes + tamp $ modifyTimestamp ) ) +matchingRuleUse: ( 2.5.13.24 NAME 'protocolInformationMatch' APPLIES protocolI + nformation ) +matchingRuleUse: ( 2.5.13.23 NAME 'uniqueMemberMatch' APPLIES uniqueMember ) +matchingRuleUse: ( 2.5.13.22 NAME 'presentationAddressMatch' APPLIES presentat + ionAddress ) +matchingRuleUse: ( 2.5.13.20 NAME 'telephoneNumberMatch' APPLIES ( telephoneNu + mber $ homePhone $ mobile $ pager $ localPhone $ homeMobile $ localMobile $ h + omePager $ localPager ) ) +matchingRuleUse: ( 2.5.13.18 NAME 'octetStringOrderingMatch' APPLIES ( userPas + sword $ olcDbCryptKey $ networkPassword ) ) +matchingRuleUse: ( 2.5.13.17 NAME 'octetStringMatch' APPLIES ( userPassword $ + olcDbCryptKey $ networkPassword ) ) +matchingRuleUse: ( 2.5.13.16 NAME 'bitStringMatch' APPLIES x500UniqueIdentifie + r ) +matchingRuleUse: ( 2.5.13.15 NAME 'integerOrderingMatch' APPLIES ( supportedLD + APVersion $ entryTtl $ uidNumber $ gidNumber $ olcConcurrency $ olcConnMaxPen + ding $ olcConnMaxPendingAuth $ olcIdleTimeout $ olcIndexSubstrIfMinLen $ olcI + ndexSubstrIfMaxLen $ olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcIndexI + ntLen $ olcListenerThreads $ olcLocalSSF $ olcMaxDerefDepth $ olcReplicationI + nterval $ olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcThreads $ ol + cToolThreads $ olcWriteTimeout $ olcDbCacheFree $ olcDbCacheSize $ olcDbDNcac + heSize $ olcDbIDLcacheSize $ olcDbSearchStack $ olcDbShmKey $ olcDbMaxReaders + $ olcDbMaxSize $ mailPreferenceOption ) ) +matchingRuleUse: ( 2.5.13.14 NAME 'integerMatch' APPLIES ( supportedLDAPVersio + n $ entryTtl $ uidNumber $ gidNumber $ olcConcurrency $ olcConnMaxPending $ o + lcConnMaxPendingAuth $ olcIdleTimeout $ olcIndexSubstrIfMinLen $ olcIndexSubs + trIfMaxLen $ olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcIndexIntLen $ + olcListenerThreads $ olcLocalSSF $ olcMaxDerefDepth $ olcReplicationInterval + $ olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcThreads $ olcToolThr + eads $ olcWriteTimeout $ olcDbCacheFree $ olcDbCacheSize $ olcDbDNcacheSize $ + olcDbIDLcacheSize $ olcDbSearchStack $ olcDbShmKey $ olcDbMaxReaders $ olcDb + MaxSize $ mailPreferenceOption ) ) +matchingRuleUse: ( 2.5.13.13 NAME 'booleanMatch' APPLIES ( hasSubordinates $ o + lcAddContentAcl $ olcGentleHUP $ olcHidden $ olcLastMod $ olcMirrorMode $ olc + Monitoring $ olcReadOnly $ olcReverseLookup $ olcSyncUseSubentry $ olcDbCheck + sum $ olcDbNoSync $ olcDbDirtyRead $ olcDbLinearIndex $ olcAccessLogSuccess $ + deceasedFlag ) ) +matchingRuleUse: ( 2.5.13.11 NAME 'caseIgnoreListMatch' APPLIES ( postalAddres + s $ registeredAddress $ homePostalAddress $ localPostalAddress ) ) +matchingRuleUse: ( 2.5.13.9 NAME 'numericStringOrderingMatch' APPLIES ( x121Ad + dress $ internationaliSDNNumber ) ) +matchingRuleUse: ( 2.5.13.8 NAME 'numericStringMatch' APPLIES ( x121Address $ + internationaliSDNNumber ) ) +matchingRuleUse: ( 2.5.13.7 NAME 'caseExactSubstringsMatch' APPLIES ( serialNu + mber $ destinationIndicator $ dnQualifier ) ) +matchingRuleUse: ( 2.5.13.6 NAME 'caseExactOrderingMatch' APPLIES ( supportedS + ASLMechanisms $ vendorName $ vendorVersion $ ref $ name $ cn $ uid $ labeledU + RI $ description $ olcConfigFile $ olcConfigDir $ olcAccess $ olcAllows $ olc + ArgsFile $ olcAttributeOptions $ olcAttributeTypes $ olcAuthIDRewrite $ olcAu + thzPolicy $ olcAuthzRegexp $ olcBackend $ olcDatabase $ olcDisallows $ olcDit + ContentRules $ olcExtraAttrs $ olcInclude $ olcLdapSyntaxes $ olcLimits $ olc + LogFile $ olcLogLevel $ olcModuleLoad $ olcModulePath $ olcObjectClasses $ ol + cObjectIdentifier $ olcOverlay $ olcPasswordCryptSaltFormat $ olcPasswordHash + $ olcPidFile $ olcPlugin $ olcPluginLogFile $ olcReferral $ olcReplica $ olc + ReplicaArgsFile $ olcReplicaPidFile $ olcReplogFile $ olcRequires $ olcRestri + ct $ olcRootDSE $ olcRootPW $ olcSaslAuxprops $ olcSaslHost $ olcSaslRealm $ + olcSaslSecProps $ olcSecurity $ olcServerID $ olcSizeLimit $ olcSortVals $ ol + cSubordinate $ olcSyncrepl $ olcTCPBuffer $ olcTimeLimit $ olcTLSCACertificat + eFile $ olcTLSCACertificatePath $ olcTLSCertificateFile $ olcTLSCertificateKe + yFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ olcTLSCRLFile $ olcTLSRandFile $ + olcTLSVerifyClient $ olcTLSDHParamFile $ olcTLSProtocolMin $ olcUpdateRef $ + olcDbDirectory $ olcDbCheckpoint $ olcDbCryptFile $ olcDbPageSize $ olcDbInde + x $ olcDbLockDetect $ olcDbMode $ olcAnonReplaceAttrPair $ olcAuthStatsAttrPa + ir $ olcdynuupidAttrPair $ olcdynvtaffilAttrPair $ olcAuditlogFile $ olcAcces + sLogOps $ olcAccessLogPurge $ olcAccessLogOld $ olcAccessLogOldAttr $ olcAcce + ssLogBase $ knowledgeInformation $ sn $ serialNumber $ c $ l $ st $ street $ + o $ ou $ title $ businessCategory $ postalCode $ postOfficeBox $ physicalDeli + veryOfficeName $ destinationIndicator $ givenName $ initials $ generationQual + ifier $ dnQualifier $ houseIdentifier $ dmdName $ pseudonym $ textEncodedORAd + dress $ info $ drink $ roomNumber $ userClass $ host $ documentIdentifier $ d + ocumentTitle $ documentVersion $ documentLocation $ personalTitle $ co $ uniq + ueIdentifier $ organizationalStatus $ buildingName $ documentPublisher $ carL + icense $ departmentNumber $ displayName $ employeeNumber $ employeeType $ pre + ferredLanguage $ eduPersonAffiliation $ eduPersonNickname $ eduPersonPrimaryA + ffiliation $ eduPersonPrincipalName $ academicLevel $ alternateID $ amateurRa + dioCallsign $ campus $ changePasswordQuestion $ creationDate $ expirationDate + $ instantMessagingID $ lastModification $ passwordExpired $ personData $ res + ponsibleID $ suppressedAttribute $ uupid $ videoConferenceAddress $ uuaid $ a + ddressType $ city $ country $ mailStop $ stateOrProvince $ street1 $ street2 + $ groupData $ lateModification $ url $ uugid $ serviceType $ serviceData $ us + er $ uusid $ vACL $ wACL $ bannerID $ dateOfBirth $ groupAddDate $ groupExpir + eDate $ groupVisibility $ serviceAddDate $ serviceExpireDate $ vtAuthNID $ un + listedHomePostalAddress $ unlistedHomePhone $ middleName $ department $ meeti + ngTime $ joinability $ leaveability $ viewablePersonAttribute $ accountState + $ degreeType $ lastEnrollmentTerm $ major $ nextEnrollmentTerm $ undergraduat + eLevel $ groupType $ unixUID $ certificate $ bannerPIDM $ previousVirginiaTec + hID $ virginiaTechID $ majorCode $ bannerName $ legalName $ passwordState $ l + astEnrollmentTermCode $ nextEnrollmentTermCode $ suppressDisplay $ personType + $ accountCreationDate $ accountExpirationDate $ accountShelveDate $ classLev + el $ classLevelCode $ suppressMembers $ entitlement $ suppressEmployeeDisplay + $ guestId $ authId $ gender $ employeeOffCampus $ suppressedUupid $ virginia + TechAffiliation $ udcIdentifier $ studentLevel $ studentLevelCode $ confident + ialFlag $ accountRecoveryMaintenanceDate $ passwordExpirationDate ) ) +matchingRuleUse: ( 2.5.13.5 NAME 'caseExactMatch' APPLIES ( supportedSASLMecha + nisms $ vendorName $ vendorVersion $ ref $ name $ cn $ uid $ labeledURI $ des + cription $ olcConfigFile $ olcConfigDir $ olcAccess $ olcAllows $ olcArgsFile + $ olcAttributeOptions $ olcAttributeTypes $ olcAuthIDRewrite $ olcAuthzPolic + y $ olcAuthzRegexp $ olcBackend $ olcDatabase $ olcDisallows $ olcDitContentR + ules $ olcExtraAttrs $ olcInclude $ olcLdapSyntaxes $ olcLimits $ olcLogFile + $ olcLogLevel $ olcModuleLoad $ olcModulePath $ olcObjectClasses $ olcObjectI + dentifier $ olcOverlay $ olcPasswordCryptSaltFormat $ olcPasswordHash $ olcPi + dFile $ olcPlugin $ olcPluginLogFile $ olcReferral $ olcReplica $ olcReplicaA + rgsFile $ olcReplicaPidFile $ olcReplogFile $ olcRequires $ olcRestrict $ olc + RootDSE $ olcRootPW $ olcSaslAuxprops $ olcSaslHost $ olcSaslRealm $ olcSaslS + ecProps $ olcSecurity $ olcServerID $ olcSizeLimit $ olcSortVals $ olcSubordi + nate $ olcSyncrepl $ olcTCPBuffer $ olcTimeLimit $ olcTLSCACertificateFile $ + olcTLSCACertificatePath $ olcTLSCertificateFile $ olcTLSCertificateKeyFile $ + olcTLSCipherSuite $ olcTLSCRLCheck $ olcTLSCRLFile $ olcTLSRandFile $ olcTLSV + erifyClient $ olcTLSDHParamFile $ olcTLSProtocolMin $ olcUpdateRef $ olcDbDir + ectory $ olcDbCheckpoint $ olcDbCryptFile $ olcDbPageSize $ olcDbIndex $ olcD + bLockDetect $ olcDbMode $ olcAnonReplaceAttrPair $ olcAuthStatsAttrPair $ olc + dynuupidAttrPair $ olcdynvtaffilAttrPair $ olcAuditlogFile $ olcAccessLogOps + $ olcAccessLogPurge $ olcAccessLogOld $ olcAccessLogOldAttr $ olcAccessLogBas + e $ knowledgeInformation $ sn $ serialNumber $ c $ l $ st $ street $ o $ ou $ + title $ businessCategory $ postalCode $ postOfficeBox $ physicalDeliveryOffi + ceName $ destinationIndicator $ givenName $ initials $ generationQualifier $ + dnQualifier $ houseIdentifier $ dmdName $ pseudonym $ textEncodedORAddress $ + info $ drink $ roomNumber $ userClass $ host $ documentIdentifier $ documentT + itle $ documentVersion $ documentLocation $ personalTitle $ co $ uniqueIdenti + fier $ organizationalStatus $ buildingName $ documentPublisher $ carLicense $ + departmentNumber $ displayName $ employeeNumber $ employeeType $ preferredLa + nguage $ eduPersonAffiliation $ eduPersonNickname $ eduPersonPrimaryAffiliati + on $ eduPersonPrincipalName $ academicLevel $ alternateID $ amateurRadioCalls + ign $ campus $ changePasswordQuestion $ creationDate $ expirationDate $ insta + ntMessagingID $ lastModification $ passwordExpired $ personData $ responsible + ID $ suppressedAttribute $ uupid $ videoConferenceAddress $ uuaid $ addressTy + pe $ city $ country $ mailStop $ stateOrProvince $ street1 $ street2 $ groupD + ata $ lateModification $ url $ uugid $ serviceType $ serviceData $ user $ uus + id $ vACL $ wACL $ bannerID $ dateOfBirth $ groupAddDate $ groupExpireDate $ + groupVisibility $ serviceAddDate $ serviceExpireDate $ vtAuthNID $ unlistedHo + mePostalAddress $ unlistedHomePhone $ middleName $ department $ meetingTime $ + joinability $ leaveability $ viewablePersonAttribute $ accountState $ degree + Type $ lastEnrollmentTerm $ major $ nextEnrollmentTerm $ undergraduateLevel $ + groupType $ unixUID $ certificate $ bannerPIDM $ previousVirginiaTechID $ vi + rginiaTechID $ majorCode $ bannerName $ legalName $ passwordState $ lastEnrol + lmentTermCode $ nextEnrollmentTermCode $ suppressDisplay $ personType $ accou + ntCreationDate $ accountExpirationDate $ accountShelveDate $ classLevel $ cla + ssLevelCode $ suppressMembers $ entitlement $ suppressEmployeeDisplay $ guest + Id $ authId $ gender $ employeeOffCampus $ suppressedUupid $ virginiaTechAffi + liation $ udcIdentifier $ studentLevel $ studentLevelCode $ confidentialFlag + $ accountRecoveryMaintenanceDate $ passwordExpirationDate ) ) +matchingRuleUse: ( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' APPLIES ( serialN + umber $ destinationIndicator $ dnQualifier ) ) +matchingRuleUse: ( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' APPLIES ( supported + SASLMechanisms $ vendorName $ vendorVersion $ ref $ name $ cn $ uid $ labeled + URI $ description $ olcConfigFile $ olcConfigDir $ olcAccess $ olcAllows $ ol + cArgsFile $ olcAttributeOptions $ olcAttributeTypes $ olcAuthIDRewrite $ olcA + uthzPolicy $ olcAuthzRegexp $ olcBackend $ olcDatabase $ olcDisallows $ olcDi + tContentRules $ olcExtraAttrs $ olcInclude $ olcLdapSyntaxes $ olcLimits $ ol + cLogFile $ olcLogLevel $ olcModuleLoad $ olcModulePath $ olcObjectClasses $ o + lcObjectIdentifier $ olcOverlay $ olcPasswordCryptSaltFormat $ olcPasswordHas + h $ olcPidFile $ olcPlugin $ olcPluginLogFile $ olcReferral $ olcReplica $ ol + cReplicaArgsFile $ olcReplicaPidFile $ olcReplogFile $ olcRequires $ olcRestr + ict $ olcRootDSE $ olcRootPW $ olcSaslAuxprops $ olcSaslHost $ olcSaslRealm $ + olcSaslSecProps $ olcSecurity $ olcServerID $ olcSizeLimit $ olcSortVals $ o + lcSubordinate $ olcSyncrepl $ olcTCPBuffer $ olcTimeLimit $ olcTLSCACertifica + teFile $ olcTLSCACertificatePath $ olcTLSCertificateFile $ olcTLSCertificateK + eyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ olcTLSCRLFile $ olcTLSRandFile + $ olcTLSVerifyClient $ olcTLSDHParamFile $ olcTLSProtocolMin $ olcUpdateRef $ + olcDbDirectory $ olcDbCheckpoint $ olcDbCryptFile $ olcDbPageSize $ olcDbInd + ex $ olcDbLockDetect $ olcDbMode $ olcAnonReplaceAttrPair $ olcAuthStatsAttrP + air $ olcdynuupidAttrPair $ olcdynvtaffilAttrPair $ olcAuditlogFile $ olcAcce + ssLogOps $ olcAccessLogPurge $ olcAccessLogOld $ olcAccessLogOldAttr $ olcAcc + essLogBase $ knowledgeInformation $ sn $ serialNumber $ c $ l $ st $ street $ + o $ ou $ title $ businessCategory $ postalCode $ postOfficeBox $ physicalDel + iveryOfficeName $ destinationIndicator $ givenName $ initials $ generationQua + lifier $ dnQualifier $ houseIdentifier $ dmdName $ pseudonym $ textEncodedORA + ddress $ info $ drink $ roomNumber $ userClass $ host $ documentIdentifier $ + documentTitle $ documentVersion $ documentLocation $ personalTitle $ co $ uni + queIdentifier $ organizationalStatus $ buildingName $ documentPublisher $ car + License $ departmentNumber $ displayName $ employeeNumber $ employeeType $ pr + eferredLanguage $ eduPersonAffiliation $ eduPersonNickname $ eduPersonPrimary + Affiliation $ eduPersonPrincipalName $ academicLevel $ alternateID $ amateurR + adioCallsign $ campus $ changePasswordQuestion $ creationDate $ expirationDat + e $ instantMessagingID $ lastModification $ passwordExpired $ personData $ re + sponsibleID $ suppressedAttribute $ uupid $ videoConferenceAddress $ uuaid $ + addressType $ city $ country $ mailStop $ stateOrProvince $ street1 $ street2 + $ groupData $ lateModification $ url $ uugid $ serviceType $ serviceData $ u + ser $ uusid $ vACL $ wACL $ bannerID $ dateOfBirth $ groupAddDate $ groupExpi + reDate $ groupVisibility $ serviceAddDate $ serviceExpireDate $ vtAuthNID $ u + nlistedHomePostalAddress $ unlistedHomePhone $ middleName $ department $ meet + ingTime $ joinability $ leaveability $ viewablePersonAttribute $ accountState + $ degreeType $ lastEnrollmentTerm $ major $ nextEnrollmentTerm $ undergradua + teLevel $ groupType $ unixUID $ certificate $ bannerPIDM $ previousVirginiaTe + chID $ virginiaTechID $ majorCode $ bannerName $ legalName $ passwordState $ + lastEnrollmentTermCode $ nextEnrollmentTermCode $ suppressDisplay $ personTyp + e $ accountCreationDate $ accountExpirationDate $ accountShelveDate $ classLe + vel $ classLevelCode $ suppressMembers $ entitlement $ suppressEmployeeDispla + y $ guestId $ authId $ gender $ employeeOffCampus $ suppressedUupid $ virgini + aTechAffiliation $ udcIdentifier $ studentLevel $ studentLevelCode $ confiden + tialFlag $ accountRecoveryMaintenanceDate $ passwordExpirationDate ) ) +matchingRuleUse: ( 2.5.13.2 NAME 'caseIgnoreMatch' APPLIES ( supportedSASLMech + anisms $ vendorName $ vendorVersion $ ref $ name $ cn $ uid $ labeledURI $ de + scription $ olcConfigFile $ olcConfigDir $ olcAccess $ olcAllows $ olcArgsFil + e $ olcAttributeOptions $ olcAttributeTypes $ olcAuthIDRewrite $ olcAuthzPoli + cy $ olcAuthzRegexp $ olcBackend $ olcDatabase $ olcDisallows $ olcDitContent + Rules $ olcExtraAttrs $ olcInclude $ olcLdapSyntaxes $ olcLimits $ olcLogFile + $ olcLogLevel $ olcModuleLoad $ olcModulePath $ olcObjectClasses $ olcObject + Identifier $ olcOverlay $ olcPasswordCryptSaltFormat $ olcPasswordHash $ olcP + idFile $ olcPlugin $ olcPluginLogFile $ olcReferral $ olcReplica $ olcReplica + ArgsFile $ olcReplicaPidFile $ olcReplogFile $ olcRequires $ olcRestrict $ ol + cRootDSE $ olcRootPW $ olcSaslAuxprops $ olcSaslHost $ olcSaslRealm $ olcSasl + SecProps $ olcSecurity $ olcServerID $ olcSizeLimit $ olcSortVals $ olcSubord + inate $ olcSyncrepl $ olcTCPBuffer $ olcTimeLimit $ olcTLSCACertificateFile $ + olcTLSCACertificatePath $ olcTLSCertificateFile $ olcTLSCertificateKeyFile $ + olcTLSCipherSuite $ olcTLSCRLCheck $ olcTLSCRLFile $ olcTLSRandFile $ olcTLS + VerifyClient $ olcTLSDHParamFile $ olcTLSProtocolMin $ olcUpdateRef $ olcDbDi + rectory $ olcDbCheckpoint $ olcDbCryptFile $ olcDbPageSize $ olcDbIndex $ olc + DbLockDetect $ olcDbMode $ olcAnonReplaceAttrPair $ olcAuthStatsAttrPair $ ol + cdynuupidAttrPair $ olcdynvtaffilAttrPair $ olcAuditlogFile $ olcAccessLogOps + $ olcAccessLogPurge $ olcAccessLogOld $ olcAccessLogOldAttr $ olcAccessLogBa + se $ knowledgeInformation $ sn $ serialNumber $ c $ l $ st $ street $ o $ ou + $ title $ businessCategory $ postalCode $ postOfficeBox $ physicalDeliveryOff + iceName $ destinationIndicator $ givenName $ initials $ generationQualifier $ + dnQualifier $ houseIdentifier $ dmdName $ pseudonym $ textEncodedORAddress $ + info $ drink $ roomNumber $ userClass $ host $ documentIdentifier $ document + Title $ documentVersion $ documentLocation $ personalTitle $ co $ uniqueIdent + ifier $ organizationalStatus $ buildingName $ documentPublisher $ carLicense + $ departmentNumber $ displayName $ employeeNumber $ employeeType $ preferredL + anguage $ eduPersonAffiliation $ eduPersonNickname $ eduPersonPrimaryAffiliat + ion $ eduPersonPrincipalName $ academicLevel $ alternateID $ amateurRadioCall + sign $ campus $ changePasswordQuestion $ creationDate $ expirationDate $ inst + antMessagingID $ lastModification $ passwordExpired $ personData $ responsibl + eID $ suppressedAttribute $ uupid $ videoConferenceAddress $ uuaid $ addressT + ype $ city $ country $ mailStop $ stateOrProvince $ street1 $ street2 $ group + Data $ lateModification $ url $ uugid $ serviceType $ serviceData $ user $ uu + sid $ vACL $ wACL $ bannerID $ dateOfBirth $ groupAddDate $ groupExpireDate $ + groupVisibility $ serviceAddDate $ serviceExpireDate $ vtAuthNID $ unlistedH + omePostalAddress $ unlistedHomePhone $ middleName $ department $ meetingTime + $ joinability $ leaveability $ viewablePersonAttribute $ accountState $ degre + eType $ lastEnrollmentTerm $ major $ nextEnrollmentTerm $ undergraduateLevel + $ groupType $ unixUID $ certificate $ bannerPIDM $ previousVirginiaTechID $ v + irginiaTechID $ majorCode $ bannerName $ legalName $ passwordState $ lastEnro + llmentTermCode $ nextEnrollmentTermCode $ suppressDisplay $ personType $ acco + untCreationDate $ accountExpirationDate $ accountShelveDate $ classLevel $ cl + assLevelCode $ suppressMembers $ entitlement $ suppressEmployeeDisplay $ gues + tId $ authId $ gender $ employeeOffCampus $ suppressedUupid $ virginiaTechAff + iliation $ udcIdentifier $ studentLevel $ studentLevelCode $ confidentialFlag + $ accountRecoveryMaintenanceDate $ passwordExpirationDate ) ) +matchingRuleUse: ( 2.5.13.1 NAME 'distinguishedNameMatch' APPLIES ( creatorsNa + me $ modifiersName $ subschemaSubentry $ entryDN $ namingContexts $ aliasedOb + jectName $ dynamicSubtrees $ distinguishedName $ seeAlso $ olcDefaultSearchBa + se $ olcRootDN $ olcSchemaDN $ olcSuffix $ olcUpdateDN $ olcRelay $ olcAccess + LogDB $ member $ owner $ roleOccupant $ manager $ documentAuthor $ secretary + $ associatedName $ dITRedirect $ eduPersonOrgDN $ eduPersonOrgUnitDN $ addres + s $ administrator $ contactPerson $ memberOf $ userOfService $ physicalAddres + s $ viewableGroup $ isMemberOf $ responsiblePerson $ allowedService $ viewer + $ groupMembership $ entitled $ sponsor $ serviceDN ) ) +matchingRuleUse: ( 2.5.13.0 NAME 'objectIdentifierMatch' APPLIES ( supportedCo + ntrol $ supportedExtension $ supportedFeatures $ supportedApplicationContext + ) ) +attributeTypes: ( 2.5.4.0 NAME 'objectClass' DESC 'RFC4512: object classes of + the entity' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1. + 38 ) +attributeTypes: ( 2.5.21.9 NAME 'structuralObjectClass' DESC 'RFC4512: structu + ral object class of entry' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1. + 1466.115.121.1.38 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation + ) +attributeTypes: ( 2.5.18.1 NAME 'createTimestamp' DESC 'RFC4512: time which ob + ject was created' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrder + ingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATI + ON USAGE directoryOperation ) +attributeTypes: ( 2.5.18.2 NAME 'modifyTimestamp' DESC 'RFC4512: time which ob + ject was last modified' EQUALITY generalizedTimeMatch ORDERING generalizedTim + eOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODI + FICATION USAGE directoryOperation ) +attributeTypes: ( 2.5.18.3 NAME 'creatorsName' DESC 'RFC4512: name of creator' + EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE- + VALUE NO-USER-MODIFICATION USAGE directoryOperation ) +attributeTypes: ( 2.5.18.4 NAME 'modifiersName' DESC 'RFC4512: name of last mo + difier' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 + SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation ) +attributeTypes: ( 2.5.18.9 NAME 'hasSubordinates' DESC 'X.501: entry has child + ren' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE N + O-USER-MODIFICATION USAGE directoryOperation ) +attributeTypes: ( 2.5.18.10 NAME 'subschemaSubentry' DESC 'RFC4512: name of co + ntrolling subschema entry' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1 + .1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation + ) +attributeTypes: ( 1.3.6.1.1.20 NAME 'entryDN' DESC 'DN of the entry' EQUALITY + distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-U + SER-MODIFICATION USAGE directoryOperation ) +attributeTypes: ( 1.3.6.1.1.16.4 NAME 'entryUUID' DESC 'UUID of the entry' EQU + ALITY UUIDMatch ORDERING UUIDOrderingMatch SYNTAX 1.3.6.1.1.16.1 SINGLE-VALUE + NO-USER-MODIFICATION USAGE directoryOperation ) +attributeTypes: ( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer' DESC 'RFC4512: a + lternative servers' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE dSAOperation ) +attributeTypes: ( 1.3.6.1.4.1.1466.101.120.5 NAME 'namingContexts' DESC 'RFC45 + 12: naming contexts' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dSAOperation + ) +attributeTypes: ( 1.3.6.1.4.1.1466.101.120.13 NAME 'supportedControl' DESC 'RF + C4512: supported controls' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOper + ation ) +attributeTypes: ( 1.3.6.1.4.1.1466.101.120.7 NAME 'supportedExtension' DESC 'R + FC4512: supported extended operations' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 U + SAGE dSAOperation ) +attributeTypes: ( 1.3.6.1.4.1.1466.101.120.15 NAME 'supportedLDAPVersion' DESC + 'RFC4512: supported LDAP versions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 USAG + E dSAOperation ) +attributeTypes: ( 1.3.6.1.4.1.1466.101.120.14 NAME 'supportedSASLMechanisms' D + ESC 'RFC4512: supported SASL mechanisms' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 + USAGE dSAOperation ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.3.5 NAME 'supportedFeatures' DESC 'RFC451 + 2: features supported by the server' EQUALITY objectIdentifierMatch SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation ) +attributeTypes: ( 1.3.6.1.1.4 NAME 'vendorName' DESC 'RFC3045: name of impleme + ntation vendor' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 + SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation ) +attributeTypes: ( 1.3.6.1.1.5 NAME 'vendorVersion' DESC 'RFC3045: version of i + mplementation' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 S + INGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation ) +attributeTypes: ( 2.5.21.4 NAME 'matchingRules' DESC 'RFC4512: matching rules' + EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121 + .1.30 USAGE directoryOperation ) +attributeTypes: ( 2.5.21.5 NAME 'attributeTypes' DESC 'RFC4512: attribute type + s' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.1 + 21.1.3 USAGE directoryOperation ) +attributeTypes: ( 2.5.21.6 NAME 'objectClasses' DESC 'RFC4512: object classes' + EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121 + .1.37 USAGE directoryOperation ) +attributeTypes: ( 2.5.21.8 NAME 'matchingRuleUse' DESC 'RFC4512: matching rule + uses' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.1 + 15.121.1.31 USAGE directoryOperation ) +attributeTypes: ( 1.3.6.1.4.1.1466.101.120.16 NAME 'ldapSyntaxes' DESC 'RFC451 + 2: LDAP syntaxes' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.54 USAGE directoryOperation ) +attributeTypes: ( 2.5.4.1 NAME ( 'aliasedObjectName' 'aliasedEntryName' ) DESC + 'RFC4512: name of aliased object' EQUALITY distinguishedNameMatch SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113730.3.1.34 NAME 'ref' DESC 'RFC3296: subordina + te referral URL' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 + USAGE distributedOperation ) +attributeTypes: ( 1.3.6.1.4.1.1466.101.119.3 NAME 'entryTtl' DESC 'RFC2589: en + try time-to-live' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-M + ODIFICATION USAGE dSAOperation ) +attributeTypes: ( 1.3.6.1.4.1.1466.101.119.4 NAME 'dynamicSubtrees' DESC 'RFC2 + 589: dynamic subtrees' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICAT + ION USAGE dSAOperation ) +attributeTypes: ( 2.5.4.49 NAME 'distinguishedName' DESC 'RFC4519: common supe + rtype of DN attributes' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.14 + 66.115.121.1.12 ) +attributeTypes: ( 2.5.4.41 NAME 'name' DESC 'RFC4519: common supertype of name + attributes' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{32768} ) +attributeTypes: ( 2.5.4.3 NAME ( 'cn' 'commonName' ) DESC 'RFC4519: common nam + e(s) for which the entity is known by' SUP name ) +attributeTypes: ( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userid' ) DESC 'RFC4 + 519: user identifier' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMat + ch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) +attributeTypes: ( 1.3.6.1.1.1.1.0 NAME 'uidNumber' DESC 'RFC2307: An integer u + niquely identifying a user in an administrative domain' EQUALITY integerMatch + ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VA + LUE ) +attributeTypes: ( 1.3.6.1.1.1.1.1 NAME 'gidNumber' DESC 'RFC2307: An integer u + niquely identifying a group in an administrative domain' EQUALITY integerMatc + h ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-V + ALUE ) +attributeTypes: ( 2.5.4.35 NAME 'userPassword' DESC 'RFC4519/2307: password of + user' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} ) +attributeTypes: ( 1.3.6.1.4.1.250.1.57 NAME 'labeledURI' DESC 'RFC2079: Unifor + m Resource Identifier with optional label' EQUALITY caseExactMatch SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 2.5.4.13 NAME 'description' DESC 'RFC4519: descriptive infor + mation' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.15{1024} ) +attributeTypes: ( 2.5.4.34 NAME 'seeAlso' DESC 'RFC4519: DN of related object' + SUP distinguishedName ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.78 NAME 'olcConfigFile' DESC 'Fi + le for slapd configuration directives' EQUALITY caseIgnoreMatch SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.79 NAME 'olcConfigDir' DESC 'Dir + ectory for slapd configuration backend' EQUALITY caseIgnoreMatch SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.1 NAME 'olcAccess' DESC 'Access + Control List' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X + -ORDERED 'VALUES' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.86 NAME 'olcAddContentAcl' DESC + 'Check ACLs against content of Add ops' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 S + INGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.2 NAME 'olcAllows' DESC 'Allowed + set of deprecated features' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466 + .115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.3 NAME 'olcArgsFile' DESC 'File + for slapd command line options' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1 + 466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.5 NAME 'olcAttributeOptions' EQU + ALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.4 NAME 'olcAttributeTypes' DESC + 'OpenLDAP attributeTypes' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstring + sMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.6 NAME 'olcAuthIDRewrite' EQUALI + TY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.7 NAME 'olcAuthzPolicy' EQUALITY + caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.8 NAME 'olcAuthzRegexp' EQUALITY + caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.9 NAME 'olcBackend' DESC 'A type + of backend' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SI + NGLE-VALUE X-ORDERED 'SIBLINGS' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.10 NAME 'olcConcurrency' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.11 NAME 'olcConnMaxPending' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.12 NAME 'olcConnMaxPendingAuth' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.13 NAME 'olcDatabase' DESC 'The + backend type for a database instance' SUP olcBackend SINGLE-VALUE X-ORDERED ' + SIBLINGS' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.14 NAME 'olcDefaultSearchBase' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.15 NAME 'olcDisallows' EQUALITY + caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.16 NAME 'olcDitContentRules' DES + C 'OpenLDAP DIT content rules' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubs + tringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.20 NAME 'olcExtraAttrs' EQUALI + TY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.17 NAME 'olcGentleHUP' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.17 NAME 'olcHidden' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.18 NAME 'olcIdleTimeout' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.19 NAME 'olcInclude' SUP labeled + URI ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.20 NAME 'olcIndexSubstrIfMinLen' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.21 NAME 'olcIndexSubstrIfMaxLen' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.22 NAME 'olcIndexSubstrAnyLen' S + YNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.23 NAME 'olcIndexSubstrAnyStep' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.84 NAME 'olcIndexIntLen' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.4 NAME 'olcLastMod' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.85 NAME 'olcLdapSyntaxes' DESC ' + OpenLDAP ldapSyntax' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatc + h SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.5 NAME 'olcLimits' EQUALITY ca + seIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.93 NAME 'olcListenerThreads' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.26 NAME 'olcLocalSSF' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.27 NAME 'olcLogFile' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.28 NAME 'olcLogLevel' EQUALITY c + aseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.6 NAME 'olcMaxDerefDepth' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.16 NAME 'olcMirrorMode' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.30 NAME 'olcModuleLoad' EQUALITY + caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.31 NAME 'olcModulePath' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.18 NAME 'olcMonitoring' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.32 NAME 'olcObjectClasses' DESC + 'OpenLDAP object classes' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstring + sMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.33 NAME 'olcObjectIdentifier' EQ + UALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.14 + 66.115.121.1.15 X-ORDERED 'VALUES' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.34 NAME 'olcOverlay' SUP olcData + base SINGLE-VALUE X-ORDERED 'SIBLINGS' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.35 NAME 'olcPasswordCryptSaltFor + mat' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.36 NAME 'olcPasswordHash' EQUALI + TY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.37 NAME 'olcPidFile' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.38 NAME 'olcPlugin' EQUALITY cas + eIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.39 NAME 'olcPluginLogFile' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.40 NAME 'olcReadOnly' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.41 NAME 'olcReferral' SUP labele + dURI SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.7 NAME 'olcReplica' SUP labele + dURI EQUALITY caseIgnoreMatch X-ORDERED 'VALUES' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.43 NAME 'olcReplicaArgsFile' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.44 NAME 'olcReplicaPidFile' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.45 NAME 'olcReplicationInterval' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.46 NAME 'olcReplogFile' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.47 NAME 'olcRequires' EQUALITY c + aseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.48 NAME 'olcRestrict' EQUALITY c + aseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.49 NAME 'olcReverseLookup' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.8 NAME 'olcRootDN' EQUALITY di + stinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.51 NAME 'olcRootDSE' EQUALITY ca + seIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.9 NAME 'olcRootPW' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.89 NAME 'olcSaslAuxprops' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.53 NAME 'olcSaslHost' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.54 NAME 'olcSaslRealm' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.56 NAME 'olcSaslSecProps' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.58 NAME 'olcSchemaDN' EQUALITY d + istinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.59 NAME 'olcSecurity' EQUALITY c + aseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.81 NAME 'olcServerID' EQUALITY c + aseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.60 NAME 'olcSizeLimit' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.61 NAME 'olcSockbufMaxIncoming' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.62 NAME 'olcSockbufMaxIncomingAu + th' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.83 NAME 'olcSortVals' DESC 'Attr + ibutes whose values will always be sorted' EQUALITY caseIgnoreMatch SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.15 NAME 'olcSubordinate' SYNTA + X 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.10 NAME 'olcSuffix' EQUALITY d + istinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.19 NAME 'olcSyncUseSubentry' D + ESC 'Store sync context in a subentry' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SI + NGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.11 NAME 'olcSyncrepl' EQUALITY + caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.90 NAME 'olcTCPBuffer' DESC 'Cus + tom TCP buffer size' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.66 NAME 'olcThreads' SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.67 NAME 'olcTimeLimit' SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.68 NAME 'olcTLSCACertificateFile + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.69 NAME 'olcTLSCACertificatePath + ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.70 NAME 'olcTLSCertificateFile' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.71 NAME 'olcTLSCertificateKeyFil + e' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.72 NAME 'olcTLSCipherSuite' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.73 NAME 'olcTLSCRLCheck' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.82 NAME 'olcTLSCRLFile' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.74 NAME 'olcTLSRandFile' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.75 NAME 'olcTLSVerifyClient' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.77 NAME 'olcTLSDHParamFile' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.87 NAME 'olcTLSProtocolMin' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.80 NAME 'olcToolThreads' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.12 NAME 'olcUpdateDN' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.13 NAME 'olcUpdateRef' SUP lab + eledURI EQUALITY caseIgnoreMatch ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.0.88 NAME 'olcWriteTimeout' SYNTAX + 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.1 NAME 'olcDbDirectory' DESC ' + Directory for database content' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1 + 466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.11 NAME 'olcDbCacheFree' DESC + 'Number of extra entries to free when max is reached' SYNTAX 1.3.6.1.4.1.1466 + .115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.1 NAME 'olcDbCacheSize' DESC ' + Entry cache size in entries' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALU + E ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.2 NAME 'olcDbCheckpoint' DESC + 'Database checkpoint interval in kbytes and minutes' SYNTAX 1.3.6.1.4.1.1466. + 115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.16 NAME 'olcDbChecksum' DESC ' + Enable database checksum validation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SING + LE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.13 NAME 'olcDbCryptFile' DESC + 'Pathname of file containing the DB encryption key' SYNTAX 1.3.6.1.4.1.1466.1 + 15.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.14 NAME 'olcDbCryptKey' DESC ' + DB encryption key' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.3 NAME 'olcDbConfig' DESC 'Ber + keleyDB DB_CONFIG configuration directives' SYNTAX 1.3.6.1.4.1.1466.115.121.1 + .26 X-ORDERED 'VALUES' ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.4 NAME 'olcDbNoSync' DESC 'Dis + able synchronous database writes' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE- + VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.15 NAME 'olcDbPageSize' DESC ' + Page size of specified DB, in Kbytes' EQUALITY caseExactMatch SYNTAX 1.3.6.1. + 4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.5 NAME 'olcDbDirtyRead' DESC ' + Allow reads of uncommitted data' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-V + ALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.12 NAME 'olcDbDNcacheSize' DES + C 'DN cache size' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.6 NAME 'olcDbIDLcacheSize' DES + C 'IDL cache size in IDLs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE + ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.2 NAME 'olcDbIndex' DESC 'Attr + ibute index parameters' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115. + 121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.7 NAME 'olcDbLinearIndex' DESC + 'Index attributes one at a time' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE- + VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.8 NAME 'olcDbLockDetect' DESC + 'Deadlock detection algorithm' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VA + LUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.0.3 NAME 'olcDbMode' DESC 'Unix + permissions of database files' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VA + LUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.9 NAME 'olcDbSearchStack' DESC + 'Depth of search stack in IDLs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE- + VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.1.10 NAME 'olcDbShmKey' DESC 'Ke + y for shared memory region' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE + ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.12.1 NAME 'olcDbMaxReaders' DESC + 'Maximum number of threads that may access the DB concurrently' SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.12.2 NAME 'olcDbMaxSize' DESC 'M + aximum size of DB in bytes' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE + ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.2.5.1 NAME 'olcRelay' DESC 'Relay + DN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.3.1 NAME 'olcAnonReplaceAttrPair' DESC 'a + ttribute to find and replace' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.3.3 NAME 'olcAuthStatsAttrPair' DESC 'hos + t and port to send authentication statistics' SYNTAX 1.3.6.1.4.1.1466.115.121 + .1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.3.7 NAME 'olcdynuupidAttrPair' DESC 'attr + ibute to find and replace' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.3.7.1 NAME 'olcdynvtaffilAttrPair' DESC ' + attribute to find and replace' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.3.15.1 NAME 'olcAuditlogFile' DESC + 'Filename for auditlogging' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.3.4.1 NAME 'olcAccessLogDB' DESC ' + Suffix of database for log content' SUP distinguishedName SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.3.4.2 NAME 'olcAccessLogOps' DESC + 'Operation types to log' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115 + .121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.3.4.3 NAME 'olcAccessLogPurge' DES + C 'Log cleanup parameters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE + ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.3.4.4 NAME 'olcAccessLogSuccess' D + ESC 'Log successful ops only' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALU + E ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.3.4.5 NAME 'olcAccessLogOld' DESC + 'Log old values when modifying entries matching the filter' SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.3.4.6 NAME 'olcAccessLogOldAttr' D + ESC 'Log old values of these attributes even if unmodified' EQUALITY caseIgno + reMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.4203.1.12.2.3.3.4.7 NAME 'olcAccessLogBase' DESC + 'Operation types to log under a specific branch' EQUALITY caseIgnoreMatch SY + NTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 2.5.4.2 NAME 'knowledgeInformation' DESC 'RFC2256: knowledge + information' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{3 + 2768} ) +attributeTypes: ( 2.5.4.4 NAME ( 'sn' 'surname' ) DESC 'RFC2256: last (family) + name(s) for which the entity is known by' SUP name ) +attributeTypes: ( 2.5.4.5 NAME 'serialNumber' DESC 'RFC2256: serial number of + the entity' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX + 1.3.6.1.4.1.1466.115.121.1.44{64} ) +attributeTypes: ( 2.5.4.6 NAME ( 'c' 'countryName' ) DESC 'RFC4519: two-letter + ISO-3166 country code' SUP name SYNTAX 1.3.6.1.4.1.1466.115.121.1.11 SINGLE- + VALUE ) +attributeTypes: ( 2.5.4.7 NAME ( 'l' 'localityName' ) DESC 'RFC2256: locality + which this object resides in' SUP name ) +attributeTypes: ( 2.5.4.8 NAME ( 'st' 'stateOrProvinceName' ) DESC 'RFC2256: s + tate or province which this object resides in' SUP name ) +attributeTypes: ( 2.5.4.9 NAME ( 'street' 'streetAddress' ) DESC 'RFC2256: str + eet address of this object' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstri + ngsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) +attributeTypes: ( 2.5.4.10 NAME ( 'o' 'organizationName' ) DESC 'RFC2256: orga + nization this object belongs to' SUP name ) +attributeTypes: ( 2.5.4.11 NAME ( 'ou' 'organizationalUnitName' ) DESC 'RFC225 + 6: organizational unit this object belongs to' SUP name ) +attributeTypes: ( 2.5.4.12 NAME 'title' DESC 'RFC2256: title associated with t + he entity' SUP name ) +attributeTypes: ( 2.5.4.14 NAME 'searchGuide' DESC 'RFC2256: search guide, dep + recated by enhancedSearchGuide' SYNTAX 1.3.6.1.4.1.1466.115.121.1.25 ) +attributeTypes: ( 2.5.4.15 NAME 'businessCategory' DESC 'RFC2256: business cat + egory' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.15{128} ) +attributeTypes: ( 2.5.4.16 NAME 'postalAddress' DESC 'RFC2256: postal address' + EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.41 ) +attributeTypes: ( 2.5.4.17 NAME 'postalCode' DESC 'RFC2256: postal code' EQUAL + ITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466. + 115.121.1.15{40} ) +attributeTypes: ( 2.5.4.18 NAME 'postOfficeBox' DESC 'RFC2256: Post Office Box + ' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.15{40} ) +attributeTypes: ( 2.5.4.19 NAME 'physicalDeliveryOfficeName' DESC 'RFC2256: Ph + ysical Delivery Office Name' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstr + ingsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) +attributeTypes: ( 2.5.4.20 NAME 'telephoneNumber' DESC 'RFC2256: Telephone Num + ber' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNT + AX 1.3.6.1.4.1.1466.115.121.1.50{32} ) +attributeTypes: ( 2.5.4.21 NAME 'telexNumber' DESC 'RFC2256: Telex Number' SYN + TAX 1.3.6.1.4.1.1466.115.121.1.52 ) +attributeTypes: ( 2.5.4.22 NAME 'teletexTerminalIdentifier' DESC 'RFC2256: Tel + etex Terminal Identifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.51 ) +attributeTypes: ( 2.5.4.23 NAME ( 'facsimileTelephoneNumber' 'fax' ) DESC 'RFC + 2256: Facsimile (Fax) Telephone Number' SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 + ) +attributeTypes: ( 2.5.4.24 NAME 'x121Address' DESC 'RFC2256: X.121 Address' EQ + UALITY numericStringMatch SUBSTR numericStringSubstringsMatch SYNTAX 1.3.6.1. + 4.1.1466.115.121.1.36{15} ) +attributeTypes: ( 2.5.4.25 NAME 'internationaliSDNNumber' DESC 'RFC2256: inter + national ISDN number' EQUALITY numericStringMatch SUBSTR numericStringSubstri + ngsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{16} ) +attributeTypes: ( 2.5.4.26 NAME 'registeredAddress' DESC 'RFC2256: registered + postal address' SUP postalAddress SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 ) +attributeTypes: ( 2.5.4.27 NAME 'destinationIndicator' DESC 'RFC2256: destinat + ion indicator' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNT + AX 1.3.6.1.4.1.1466.115.121.1.44{128} ) +attributeTypes: ( 2.5.4.28 NAME 'preferredDeliveryMethod' DESC 'RFC2256: prefe + rred delivery method' SYNTAX 1.3.6.1.4.1.1466.115.121.1.14 SINGLE-VALUE ) +attributeTypes: ( 2.5.4.29 NAME 'presentationAddress' DESC 'RFC2256: presentat + ion address' EQUALITY presentationAddressMatch SYNTAX 1.3.6.1.4.1.1466.115.12 + 1.1.43 SINGLE-VALUE ) +attributeTypes: ( 2.5.4.30 NAME 'supportedApplicationContext' DESC 'RFC2256: s + upported application context' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.38 ) +attributeTypes: ( 2.5.4.31 NAME 'member' DESC 'RFC2256: member of a group' SUP + distinguishedName ) +attributeTypes: ( 2.5.4.32 NAME 'owner' DESC 'RFC2256: owner (of the object)' + SUP distinguishedName ) +attributeTypes: ( 2.5.4.33 NAME 'roleOccupant' DESC 'RFC2256: occupant of role + ' SUP distinguishedName ) +attributeTypes: ( 2.5.4.36 NAME 'userCertificate' DESC 'RFC2256: X.509 user ce + rtificate, use ;binary' EQUALITY certificateExactMatch SYNTAX 1.3.6.1.4.1.146 + 6.115.121.1.8 ) +attributeTypes: ( 2.5.4.37 NAME 'cACertificate' DESC 'RFC2256: X.509 CA certif + icate, use ;binary' EQUALITY certificateExactMatch SYNTAX 1.3.6.1.4.1.1466.11 + 5.121.1.8 ) +attributeTypes: ( 2.5.4.38 NAME 'authorityRevocationList' DESC 'RFC2256: X.509 + authority revocation list, use ;binary' SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 + ) +attributeTypes: ( 2.5.4.39 NAME 'certificateRevocationList' DESC 'RFC2256: X.5 + 09 certificate revocation list, use ;binary' SYNTAX 1.3.6.1.4.1.1466.115.121. + 1.9 ) +attributeTypes: ( 2.5.4.40 NAME 'crossCertificatePair' DESC 'RFC2256: X.509 cr + oss certificate pair, use ;binary' SYNTAX 1.3.6.1.4.1.1466.115.121.1.10 ) +attributeTypes: ( 2.5.4.42 NAME ( 'givenName' 'gn' ) DESC 'RFC2256: first name + (s) for which the entity is known by' SUP name ) +attributeTypes: ( 2.5.4.43 NAME 'initials' DESC 'RFC2256: initials of some or + all of names, but not the surname(s).' SUP name ) +attributeTypes: ( 2.5.4.44 NAME 'generationQualifier' DESC 'RFC2256: name qual + ifier indicating a generation' SUP name ) +attributeTypes: ( 2.5.4.45 NAME 'x500UniqueIdentifier' DESC 'RFC2256: X.500 un + ique identifier' EQUALITY bitStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 + ) +attributeTypes: ( 2.5.4.46 NAME 'dnQualifier' DESC 'RFC2256: DN qualifier' EQU + ALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubst + ringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 ) +attributeTypes: ( 2.5.4.47 NAME 'enhancedSearchGuide' DESC 'RFC2256: enhanced + search guide' SYNTAX 1.3.6.1.4.1.1466.115.121.1.21 ) +attributeTypes: ( 2.5.4.48 NAME 'protocolInformation' DESC 'RFC2256: protocol + information' EQUALITY protocolInformationMatch SYNTAX 1.3.6.1.4.1.1466.115.12 + 1.1.42 ) +attributeTypes: ( 2.5.4.50 NAME 'uniqueMember' DESC 'RFC2256: unique member of + a group' EQUALITY uniqueMemberMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 ) +attributeTypes: ( 2.5.4.51 NAME 'houseIdentifier' DESC 'RFC2256: house identif + ier' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.15{32768} ) +attributeTypes: ( 2.5.4.52 NAME 'supportedAlgorithms' DESC 'RFC2256: supported + algorithms' SYNTAX 1.3.6.1.4.1.1466.115.121.1.49 ) +attributeTypes: ( 2.5.4.53 NAME 'deltaRevocationList' DESC 'RFC2256: delta rev + ocation list; use ;binary' SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 ) +attributeTypes: ( 2.5.4.54 NAME 'dmdName' DESC 'RFC2256: name of DMD' SUP name + ) +attributeTypes: ( 2.5.4.65 NAME 'pseudonym' DESC 'X.520(4th): pseudonym for th + e object' SUP name ) +attributeTypes: ( 0.9.2342.19200300.100.1.3 NAME ( 'mail' 'rfc822Mailbox' ) DE + SC 'RFC1274: RFC822 Mailbox' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5 + SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} ) +attributeTypes: ( 0.9.2342.19200300.100.1.25 NAME ( 'dc' 'domainComponent' ) D + ESC 'RFC1274/2247: domain component' EQUALITY caseIgnoreIA5Match SUBSTR caseI + gnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) +attributeTypes: ( 0.9.2342.19200300.100.1.37 NAME 'associatedDomain' DESC 'RFC + 1274: domain associated with object' EQUALITY caseIgnoreIA5Match SUBSTR caseI + gnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) +attributeTypes: ( 1.2.840.113549.1.9.1 NAME ( 'email' 'emailAddress' 'pkcs9ema + il' ) DESC 'RFC3280: legacy attribute for email addresses in DNs' EQUALITY ca + seIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466. + 115.121.1.26{128} ) +attributeTypes: ( 0.9.2342.19200300.100.1.2 NAME 'textEncodedORAddress' EQUALI + TY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.1 + 15.121.1.15{256} ) +attributeTypes: ( 0.9.2342.19200300.100.1.4 NAME 'info' DESC 'RFC1274: general + information' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTA + X 1.3.6.1.4.1.1466.115.121.1.15{2048} ) +attributeTypes: ( 0.9.2342.19200300.100.1.5 NAME ( 'drink' 'favouriteDrink' ) + DESC 'RFC1274: favorite drink' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubs + tringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) +attributeTypes: ( 0.9.2342.19200300.100.1.6 NAME 'roomNumber' DESC 'RFC1274: r + oom number' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15{256} ) +attributeTypes: ( 0.9.2342.19200300.100.1.7 NAME 'photo' DESC 'RFC1274: photo + (G3 fax)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.23{25000} ) +attributeTypes: ( 0.9.2342.19200300.100.1.8 NAME 'userClass' DESC 'RFC1274: ca + tegory of user' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYN + TAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) +attributeTypes: ( 0.9.2342.19200300.100.1.9 NAME 'host' DESC 'RFC1274: host co + mputer' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3. + 6.1.4.1.1466.115.121.1.15{256} ) +attributeTypes: ( 0.9.2342.19200300.100.1.10 NAME 'manager' DESC 'RFC1274: DN + of manager' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1 + .12 ) +attributeTypes: ( 0.9.2342.19200300.100.1.11 NAME 'documentIdentifier' DESC 'R + FC1274: unique identifier of document' EQUALITY caseIgnoreMatch SUBSTR caseIg + noreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) +attributeTypes: ( 0.9.2342.19200300.100.1.12 NAME 'documentTitle' DESC 'RFC127 + 4: title of document' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMat + ch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) +attributeTypes: ( 0.9.2342.19200300.100.1.13 NAME 'documentVersion' DESC 'RFC1 + 274: version of document' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstring + sMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) +attributeTypes: ( 0.9.2342.19200300.100.1.14 NAME 'documentAuthor' DESC 'RFC12 + 74: DN of author of document' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1. + 4.1.1466.115.121.1.12 ) +attributeTypes: ( 0.9.2342.19200300.100.1.15 NAME 'documentLocation' DESC 'RFC + 1274: location of document original' EQUALITY caseIgnoreMatch SUBSTR caseIgno + reSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) +attributeTypes: ( 0.9.2342.19200300.100.1.20 NAME ( 'homePhone' 'homeTelephone + Number' ) DESC 'RFC1274: home telephone number' EQUALITY telephoneNumberMatch + SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) +attributeTypes: ( 0.9.2342.19200300.100.1.21 NAME 'secretary' DESC 'RFC1274: D + N of secretary' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.1 + 21.1.12 ) +attributeTypes: ( 0.9.2342.19200300.100.1.22 NAME 'otherMailbox' SYNTAX 1.3.6. + 1.4.1.1466.115.121.1.39 ) +attributeTypes: ( 0.9.2342.19200300.100.1.26 NAME 'aRecord' EQUALITY caseIgnor + eIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) +attributeTypes: ( 0.9.2342.19200300.100.1.27 NAME 'mDRecord' EQUALITY caseIgno + reIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) +attributeTypes: ( 0.9.2342.19200300.100.1.28 NAME 'mXRecord' EQUALITY caseIgno + reIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) +attributeTypes: ( 0.9.2342.19200300.100.1.29 NAME 'nSRecord' EQUALITY caseIgno + reIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) +attributeTypes: ( 0.9.2342.19200300.100.1.30 NAME 'sOARecord' EQUALITY caseIgn + oreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) +attributeTypes: ( 0.9.2342.19200300.100.1.31 NAME 'cNAMERecord' EQUALITY caseI + gnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) +attributeTypes: ( 0.9.2342.19200300.100.1.38 NAME 'associatedName' DESC 'RFC12 + 74: DN of entry associated with domain' EQUALITY distinguishedNameMatch SYNTA + X 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 0.9.2342.19200300.100.1.39 NAME 'homePostalAddress' DESC 'RF + C1274: home postal address' EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreLis + tSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 ) +attributeTypes: ( 0.9.2342.19200300.100.1.40 NAME 'personalTitle' DESC 'RFC127 + 4: personal title' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) +attributeTypes: ( 0.9.2342.19200300.100.1.41 NAME ( 'mobile' 'mobileTelephoneN + umber' ) DESC 'RFC1274: mobile telephone number' EQUALITY telephoneNumberMatc + h SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 + ) +attributeTypes: ( 0.9.2342.19200300.100.1.42 NAME ( 'pager' 'pagerTelephoneNum + ber' ) DESC 'RFC1274: pager telephone number' EQUALITY telephoneNumberMatch S + UBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) +attributeTypes: ( 0.9.2342.19200300.100.1.43 NAME ( 'co' 'friendlyCountryName' + ) DESC 'RFC1274: friendly country name' EQUALITY caseIgnoreMatch SUBSTR case + IgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 0.9.2342.19200300.100.1.44 NAME 'uniqueIdentifier' DESC 'RFC + 1274: unique identifer' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115. + 121.1.15{256} ) +attributeTypes: ( 0.9.2342.19200300.100.1.45 NAME 'organizationalStatus' DESC + 'RFC1274: organizational status' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSu + bstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) +attributeTypes: ( 0.9.2342.19200300.100.1.46 NAME 'janetMailbox' DESC 'RFC1274 + : Janet mailbox' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMa + tch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} ) +attributeTypes: ( 0.9.2342.19200300.100.1.47 NAME 'mailPreferenceOption' DESC + 'RFC1274: mail preference option' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ) +attributeTypes: ( 0.9.2342.19200300.100.1.48 NAME 'buildingName' DESC 'RFC1274 + : name of building' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) +attributeTypes: ( 0.9.2342.19200300.100.1.49 NAME 'dSAQuality' DESC 'RFC1274: + DSA Quality' SYNTAX 1.3.6.1.4.1.1466.115.121.1.19 SINGLE-VALUE ) +attributeTypes: ( 0.9.2342.19200300.100.1.50 NAME 'singleLevelQuality' DESC 'R + FC1274: Single Level Quality' SYNTAX 1.3.6.1.4.1.1466.115.121.1.13 SINGLE-VAL + UE ) +attributeTypes: ( 0.9.2342.19200300.100.1.51 NAME 'subtreeMinimumQuality' DESC + 'RFC1274: Subtree Mininum Quality' SYNTAX 1.3.6.1.4.1.1466.115.121.1.13 SING + LE-VALUE ) +attributeTypes: ( 0.9.2342.19200300.100.1.52 NAME 'subtreeMaximumQuality' DESC + 'RFC1274: Subtree Maximun Quality' SYNTAX 1.3.6.1.4.1.1466.115.121.1.13 SING + LE-VALUE ) +attributeTypes: ( 0.9.2342.19200300.100.1.53 NAME 'personalSignature' DESC 'RF + C1274: Personal Signature (G3 fax)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.23 ) +attributeTypes: ( 0.9.2342.19200300.100.1.54 NAME 'dITRedirect' DESC 'RFC1274: + DIT Redirect' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.12 + 1.1.12 ) +attributeTypes: ( 0.9.2342.19200300.100.1.55 NAME 'audio' DESC 'RFC1274: audio + (u-law)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.4{25000} ) +attributeTypes: ( 0.9.2342.19200300.100.1.56 NAME 'documentPublisher' DESC 'RF + C1274: publisher of document' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubst + ringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 2.16.840.1.113730.3.1.1 NAME 'carLicense' DESC 'RFC2798: veh + icle license or registration plate' EQUALITY caseIgnoreMatch SUBSTR caseIgnor + eSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 2.16.840.1.113730.3.1.2 NAME 'departmentNumber' DESC 'RFC279 + 8: identifies a department within an organization' EQUALITY caseIgnoreMatch S + UBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 2.16.840.1.113730.3.1.241 NAME 'displayName' DESC 'RFC2798: + preferred name to be used when displaying entries' EQUALITY caseIgnoreMatch S + UBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-V + ALUE ) +attributeTypes: ( 2.16.840.1.113730.3.1.3 NAME 'employeeNumber' DESC 'RFC2798: + numerically identifies an employee within an organization' EQUALITY caseIgno + reMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 + SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113730.3.1.4 NAME 'employeeType' DESC 'RFC2798: t + ype of employment for a person' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSub + stringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 0.9.2342.19200300.100.1.60 NAME 'jpegPhoto' DESC 'RFC2798: a + JPEG image' SYNTAX 1.3.6.1.4.1.1466.115.121.1.28 ) +attributeTypes: ( 2.16.840.1.113730.3.1.39 NAME 'preferredLanguage' DESC 'RFC2 + 798: preferred written or spoken language for a person' EQUALITY caseIgnoreMa + tch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SIN + GLE-VALUE ) +attributeTypes: ( 2.16.840.1.113730.3.1.40 NAME 'userSMIMECertificate' DESC 'R + FC2798: PKCS#7 SignedData used to support S/MIME' SYNTAX 1.3.6.1.4.1.1466.115 + .121.1.5 ) +attributeTypes: ( 2.16.840.1.113730.3.1.216 NAME 'userPKCS12' DESC 'RFC2798: p + ersonal identity information, a PKCS #12 PFX' SYNTAX 1.3.6.1.4.1.1466.115.121 + .1.5 ) +attributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.1 NAME 'eduPersonAffiliation' DESC 'e + duPerson per Internet2 and EDUCAUSE' EQUALITY caseIgnoreMatch SUBSTR caseIgno + reSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.2 NAME 'eduPersonNickname' DESC 'eduP + erson per Internet2 and EDUCAUSE' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreS + ubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.3 NAME 'eduPersonOrgDN' DESC 'eduPers + on per Internet2 and EDUCAUSE' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.4 NAME 'eduPersonOrgUnitDN' DESC 'edu + Person per Internet2 and EDUCAUSE' EQUALITY distinguishedNameMatch SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.5 NAME 'eduPersonPrimaryAffiliation' + DESC 'eduPerson per Internet2 and EDUCAUSE' EQUALITY caseIgnoreMatch SUBSTR c + aseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.6 NAME 'eduPersonPrincipalName' DESC + 'eduPerson per Internet2 and EDUCAUSE' EQUALITY caseIgnoreMatch SUBSTR caseIg + noreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.1 NAME 'academicLevel' DESC 'This is th + e degree level currently being sought by a person' EQUALITY caseIgnoreMatch S + UBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-V + ALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.2 NAME 'address' DESC 'A list of all th + e addresses, identified by address dn, currently known for this person' EQUAL + ITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.3 NAME 'alternateID' DESC 'This is a li + st of other VT systems a person has access to as well as their ID on that sys + tem' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.4 NAME 'amateurRadioCallsign' DESC 'The + amateur radio callsigns this person uses' EQUALITY caseIgnoreMatch SUBSTR ca + seIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.5 NAME 'campus' DESC 'The name of the c + ampus this person is currently affiliated with. For instance the campus a stu + dent is attending, or the campus at which a staff member works' EQUALITY case + IgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121. + 1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.6 NAME 'changePasswordQuestion' DESC 'Q + uestion/answer pairs to verify a user identity in order to allow a program to + reset a forgotten password' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstr + ingsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.7 NAME 'creationDate' DESC 'This is the + date the person was added to the directory' EQUALITY caseIgnoreMatch SUBSTR + caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.8 NAME 'mailForwardingAddress' DESC 'Th + is is a person\27s email forwarding address' EQUALITY caseIgnoreIA5Match SUBS + TR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.9 NAME 'expirationDate' DESC 'This is t + he date the entry will expire' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubs + tringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.10 NAME 'instantMessagingID' DESC 'This + is a list of a person\27s instant messaging Ids' EQUALITY caseIgnoreMatch SU + BSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.12 NAME 'lastModification' DESC 'This i + tem records what service last changed an attribute, which attribute it change + d, when it was changed, and what its old value was' EQUALITY caseIgnoreMatch + SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.13 NAME 'passwordExpired' DESC 'This is + a true/false flag indicating whether the password has expired' EQUALITY case + IgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121. + 1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.14 NAME 'personData' DESC 'This field a + llows additional information about a person to be stored' EQUALITY caseIgnore + Match SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.15 NAME 'publicKey' DESC 'A user\27s pu + blic key' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.16 NAME 'responsibleID' DESC 'The UUPID + of the person responsible for this person\27s inclusion in the directory' EQ + UALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.14 + 66.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.17 NAME 'suppressedAttribute' DESC 'The + user attributes a person wants to suppress from public display' EQUALITY cas + eIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121 + .1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.19 NAME 'uupid' DESC 'Universally uniqu + e personal identifier; replaces current PID.' EQUALITY caseIgnoreMatch SUBSTR + caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE + ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.20 NAME 'videoConferenceAddress' DESC ' + This is an identifier used by video conferencing systems/users to look up peo + ple who have conferencing capability' EQUALITY caseIgnoreMatch SUBSTR caseIgn + oreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.21 NAME 'uuaid' DESC 'This is the uniqu + e identifier for this address object' EQUALITY caseIgnoreMatch SUBSTR caseIgn + oreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes:: KCAxLjMuNi4xLjQuMS42NzYwLjYuMS4yMiBOQU1FICdhZGRyZXNzVHlwZScgR + EVTQyAnVGhlIHR5cGUgb2YgdGhlIGFkZHJlc3M6IGhvbWUgLSBpbmRpY2F0ZXMgdGhpcyBpcyBhIH + BlcnNvblwyN3MgcGVybWFuZW50IG1haWxpbmcgYWRkcmVzcy4gVGhpcyB3b3VsZCBiZSBhbiBlbXB + sb3llZVwyN3MgaG9tZSwgb3IgYSBzdHVkZW50XDI3cyBwZXJtYW5lbnQgbWFpbGluZyBhZGRyZXNz + IChtb3N0IGxpa2VseSB0aGVpciBwYXJlbnQgb3IgZ3VhcmRpYW5cMjdzIGFkZHJlc3MpLlxuXG5sb + 2NhbCAtIGluZGljYXRlcyB0aGlzIGlzIGEgcGVyc29uXDI3cyB0ZW1wb3JhcnkgYWRkcmVzcy4gVG + hpcyBpcyB1c2VkIGZvciBhIHN0dWRlbnRcMjdzIGFkZHJlc3Mgd2hpbGUgdGhleSBhcmUgYWN0aXZ + lbHkgYXR0ZW5kaW5nIFZUIChtb3N0IGxpa2VseSBhIHN0dWRlbnRcMjdzIGRvcm0gb3IgYXBhcnRt + ZW50IGFkZHJlc3MpLlxuXG5vZmZpY2UgLSBpbmRpY2F0ZXMgdGhpcyBpcyBhIHBlcnNvblwyN3MgY + nVzaW5lc3MgYWRkcmVzcy4gVGhpcyBtYXkgYmUgYW4gZW1wbG95ZWVcMjdzIG9mZmljZSBhZGRyZX + NzIG9yIGEgdmVuZG9yXDI3cyBidXNpbmVzcyBhZGRyZXNzLlxuXG5tZWV0aW5nIOKAkyBpbmRpY2F + 0ZXMgdGhlIGxvY2F0aW9uIHdoZXJlIGEgZ2l2ZW4gZ3JvdXAgbWVldHMuJyBFUVVBTElUWSBjYXNl + SWdub3JlTWF0Y2ggU1VCU1RSIGNhc2VJZ25vcmVTdWJzdHJpbmdzTWF0Y2ggU1lOVEFYIDEuMy42L + jEuNC4xLjE0NjYuMTE1LjEyMS4xLjE1IFNJTkdMRS1WQUxVRSAp +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.23 NAME 'city' DESC 'The city the stree + t or post office box is in' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstri + ngsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.24 NAME 'country' DESC 'The two letter + abbreviation for the country that this address is in (ISO 3166 code)' EQUALIT + Y caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.11 + 5.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.25 NAME 'mailStop' DESC 'Used for inter + nal mail routing information. Do not use for Post Office Box information.' E + QUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1 + 466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.28 NAME 'stateOrProvince' DESC 'The abb + reviated state or province this address is in.' EQUALITY caseIgnoreMatch SUBS + TR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALU + E ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.29 NAME 'street1' DESC 'This is the fir + st line of a person\27s street address. Normally this would be the house numb + er and road they live on' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstring + sMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.30 NAME 'street2' DESC 'This is the sec + ond line of a person\27s street address. Normally this would be used for apar + tment numbers' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNT + AX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.36 NAME 'administrator' DESC 'These are + the DNs of the people who may administer this group' EQUALITY distinguishedN + ameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.37 NAME 'contactPerson' DESC 'The DN of + the person to who should recieve correspondence for this group.' EQUALITY di + stinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.40 NAME 'groupData' DESC 'This field al + lows a group to store additional information about the group, which may be di + splayed along with other group information' EQUALITY caseIgnoreMatch SUBSTR c + aseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.41 NAME 'lateModification' DESC 'Used t + o track the last modification made to this entry.' EQUALITY caseIgnoreMatch S + UBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-V + ALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.43 NAME 'url' DESC 'The URL for this gr + oup\27s web site.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.44 NAME 'uugid' DESC 'This Universally + Unique Group Identifier is the unique identifier of a group within the direct + ory' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.45 NAME 'credential' DESC 'A services a + uthentication credential' SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.46 NAME 'serviceType' DESC 'The type of + service this is, possible values are public, personal, private' EQUALITY cas + eIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121 + .1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.47 NAME 'serviceData' DESC 'A free-for- + all field that service may use to store service specific information.' EQUALI + TY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.1 + 15.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.48 NAME 'user' DESC 'A list of Member o + bject memberDNs representing the users of this service.' EQUALITY caseIgnoreM + atch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.49 NAME 'uusid' DESC 'This Universally + Unique Service Id is the unique identifier of a service within the directory' + EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1 + .1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.50 NAME 'vACL' DESC 'The list of person + attributes this service may view.' EQUALITY caseIgnoreMatch SUBSTR caseIgnor + eSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.51 NAME 'wACL' DESC 'The list of person + attributes a service may write to.' EQUALITY caseIgnoreMatch SUBSTR caseIgno + reSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.52 NAME 'bannerID' DESC 'A person\27s I + D in banner (not their PIDM)' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubst + ringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.53 NAME 'dateOfBirth' DESC 'A person\27 + s date of birth' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SY + NTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.54 NAME 'groupAddDate' DESC 'This is th + e date the person was added to a group' EQUALITY caseIgnoreMatch SUBSTR caseI + gnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.55 NAME 'groupExpireDate' DESC 'This is + the date the person is to expire from a group' EQUALITY caseIgnoreMatch SUBS + TR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.56 NAME 'groupVisibility' DESC 'This fi + eld indicates what type of public visibility a person wants within a group. + A value of public means this member may be displayed in any group membership + listing. A value of group means this member may only be displayed in a member + ship listing which is exposed only to other people in this group. A value of + private means this member may never be listed in a viewable group membership + listing' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.57 NAME 'memberOf' DESC 'These are the + groups a member belongs to' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4. + 1.1466.115.121.1.12 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.58 NAME 'serviceAddDate' DESC 'This is + the date the person was added to a service' EQUALITY caseIgnoreMatch SUBSTR c + aseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.59 NAME 'serviceExpireDate' DESC 'This + is the date the person expires from a service' EQUALITY caseIgnoreMatch SUBST + R caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.60 NAME 'userOfService' DESC 'A list of + the services this person is a user of' EQUALITY distinguishedNameMatch SYNTA + X 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.61 NAME 'vtAuthNID' DESC 'the VT authni + d' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.62 NAME 'unlistedHomePostalAddress' DES + C 'a suppressed postal address' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSub + stringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.63 NAME 'unlistedHomePhone' DESC 'a sup + pressed postal address' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsM + atch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.64 NAME 'middleName' DESC 'The middle n + ame(s) of a person' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.65 NAME 'department' DESC 'The home dep + artment this person works in on campus' EQUALITY caseIgnoreMatch SUBSTR caseI + gnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.66 NAME 'meetingTime' DESC 'A list of t + he times this group meets' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstrin + gsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.67 NAME 'physicalAddress' DESC 'The loc + ation this group meets' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.14 + 66.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.68 NAME 'joinability' DESC 'Indicates w + hether a group can be joined without adminstrative approval or not' EQUALITY + caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115. + 121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.69 NAME 'leaveability' DESC 'Indicates + whether a group can be left without adminstrative approval or not' EQUALITY c + aseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.1 + 21.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.70 NAME 'viewableGroup' DESC 'This is t + he list of groups that a service may view in the directory' EQUALITY distingu + ishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.71 NAME 'viewablePersonAttribute' DESC + 'This is a list of virginiaTechPerson attributes that this service may view' + EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1. + 1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.72 NAME 'facsimileNumber' DESC 'The fax + number for this address' SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.73 NAME 'accountState' DESC 'This is th + e current authentication state of the person\27s account' EQUALITY caseIgnore + Match SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 S + INGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.74 NAME 'degreeType' DESC 'The type of + degree a student is seeking' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstr + ingsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.75 NAME 'lastEnrollmentTerm' DESC 'Huma + n readable form of the last academic term a student was enrolled in' EQUALITY + caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115 + .121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.76 NAME 'major' DESC 'The academic majo + r of this person' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch S + YNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.77 NAME 'nextEnrollmentTerm' DESC 'The + next academic term a student is enrolled in' EQUALITY caseIgnoreMatch SUBSTR + caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.78 NAME 'undergraduateLevel' DESC 'The + current grade level of an undergraduate student' EQUALITY caseIgnoreMatch SUB + STR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VAL + UE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.79 NAME 'groupType' DESC 'The fax numbe + r for this address' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.80 NAME 'localPhone' DESC 'The local ph + one number of this person' EQUALITY telephoneNumberMatch SUBSTR telephoneNumb + erSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.81 NAME 'localPostalAddress' DESC 'This + is the local postal address for this person' EQUALITY caseIgnoreListMatch SU + BSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 SINGL + E-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.82 NAME 'unixUID' DESC 'a person\27s un + ix id' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.83 NAME 'networkPassword' DESC 'The net + work password' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.84 NAME 'certificate' DESC 'The public + certificate of the service' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.85 NAME 'bannerPIDM' DESC 'The 8 digit + Banner PIDM number for this person' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4 + .1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.86 NAME 'previousVirginiaTechID' DESC ' + The Virginia Tech ID a person had prior to their current one assuming that th + ey have a Virginia Tech ID and that it was changed' EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.87 NAME 'virginiaTechID' DESC 'This is + the 9 digit Virginia Tech ID number from Banner, sometimes known as the Banne + r ID number' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SI + NGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.88 NAME 'isMemberOf' DESC 'A list of th + e groups, identified by the groups DN, this person is a member of' SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.89 NAME 'responsiblePerson' DESC 'This + is the DN of the person who is responsible for this person\27s inclusion in t + he directory and their access to services.' EQUALITY distinguishedNameMatch S + YNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.90 NAME 'allowedService' DESC 'The serv + ice DNs of the services that may view this group and its membership' SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.91 NAME 'mailPreferredAddress' DESC 'Th + is is a person\27s preferred email address' EQUALITY caseIgnoreIA5Match SUBST + R caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SING + LE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.92 NAME 'majorCode' DESC 'The academic + major code of this person' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstrin + gsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.93 NAME 'bannerName' DESC 'The banner n + ame of this person (spriden table)' EQUALITY caseIgnoreMatch SUBSTR caseIgnor + eSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.93.1 NAME 'legalName' DESC 'the spaiden + name of a person' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.94 NAME 'passwordState' DESC 'Indicates + the current state of a person\27s password, which may be either active or ex + pired' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6 + .1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.95 NAME 'mailAlias' DESC 'These are the + e-mail alias(es) of a person' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreI + A5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.96 NAME 'mailAccount' DESC 'This is the + name of the person\27s email account in the mail system' EQUALITY caseIgnore + IA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121. + 1.26{256} SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.97 NAME 'lastEnrollmentTermCode' DESC ' + The last academic term code a student was enrolled in' EQUALITY caseIgnoreMat + ch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SING + LE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.98 NAME 'nextEnrollmentTermCode' DESC ' + The human readable form of the next academic term a student is enrolled in' E + QUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1 + 466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.99 NAME 'suppressDisplay' DESC 'Whether + this person\27s entire record should be suppressed from public view' EQUALIT + Y caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.11 + 5.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.100 NAME 'viewer' DESC 'The DNs that ma + y view this group and its membership' EQUALITY distinguishedNameMatch SYNTAX + 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.101 NAME 'groupMembership' DESC 'A list + of the group DNs this person is a member of' EQUALITY distinguishedNameMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.102 NAME 'homeMobile' DESC 'The cellula + r phone number of the person associated with the address whose address type i + s home.' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.103 NAME 'localMobile' DESC 'The cellul + ar phone number of the person associated with the address whose address type + is local.' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatc + h SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.104 NAME 'homePager' DESC 'The pager nu + mber of the person associated with the address whose address type is home.' E + QUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.50 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.105 NAME 'localPager' DESC 'The pager n + umber of the person associated associated with the address whose address type + is local.' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMat + ch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.106 NAME 'homeFax' DESC 'This should be + the fax number associated with the address whose address type is home.' SYNT + AX 1.3.6.1.4.1.1466.115.121.1.22 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.107 NAME 'localFax' DESC 'This should b + e the fax number associated with the address whose address type is local.' SY + NTAX 1.3.6.1.4.1.1466.115.121.1.22 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.108 NAME 'personType' DESC 'This is the + type of person.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch S + YNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.109 NAME 'accountCreationDate' DESC 'Th + is is the date the person\27s account was created ' EQUALITY caseIgnoreMatch + SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE- + VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.110 NAME 'accountExpirationDate' DESC ' + This is the date the person\27s account will expire' EQUALITY caseIgnoreMatch + SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE + -VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.111 NAME 'accountShelveDate' DESC 'This + is the date the person\27s account will be moved to a Shelved state' EQUALIT + Y caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.11 + 5.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.112 NAME 'classLevel' DESC 'The Banner + class level' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.113 NAME 'classLevelCode' DESC 'The Ban + ner class level code' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMat + ch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.114 NAME 'suppressMembers' DESC 'Whethe + r this group\27s membership should be suppressed from public view' EQUALITY c + aseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.1 + 21.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.115 NAME 'entitled' DESC 'A DN that rep + resents the entry with this virginiaTechEntitlement' EQUALITY distinguishedNa + meMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.116 NAME 'sponsor' DESC 'The DN that is + sponsoring this virginiaTechEntitlement' EQUALITY distinguishedNameMatch SYN + TAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.117 NAME 'entitlement' DESC 'A string t + hat identifies the virginiaTechEntitlement' EQUALITY caseIgnoreMatch SUBSTR c + aseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.118 NAME 'suppressEmployeeDisplay' DESC + 'Whether this employee is suppressed' EQUALITY caseIgnoreMatch SUBSTR caseIg + noreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.119 NAME 'serviceDN' DESC 'The DN of th + e service certificate' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.146 + 6.115.121.1.12 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.120 NAME 'guestId' DESC 'The guest iden + tifier for authentication' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstrin + gsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.121 NAME 'authId' DESC 'The authenticat + ion identifier(s)' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.122 NAME 'gender' DESC 'The gender of t + he person' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.123 NAME 'employeeOffCampus' DESC 'Whet + her an employee is off campus or not' EQUALITY caseIgnoreMatch SUBSTR caseIgn + oreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.124 NAME 'suppressedUupid' DESC 'The su + ppressed uupid.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SY + NTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.125 NAME ( 'virginiaTechAffiliation' 'v + tAffiliation' ) DESC 'Specifies the person\27s relationship(s) to Virginia Te + ch in specific categories such as VT-STUDENT, VT-FACULTY, VT-STAFF, VT-ALUM, + etc' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1 + .4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.126 NAME 'udcIdentifier' DESC 'the Sun + Gard UDC Identifier' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatc + h SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.127 NAME 'mailExternalAddress' DESC 'Th + is is a person\27s external email address' EQUALITY caseIgnoreIA5Match SUBSTR + caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.128 NAME 'studentLevel' DESC 'The curre + nt student level' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch S + YNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.129 NAME 'studentLevelCode' DESC 'The c + urrent student level code' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstrin + gsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.130 NAME 'confidentialFlag' DESC 'Wheth + er this person is confidential' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSub + stringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.131 NAME 'accountRecoveryMaintenanceDat + e' DESC 'This is the last date the person\27s account recovery options were m + aintained' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.132 NAME 'deceasedFlag' DESC 'Whether t + his person is deceased' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121 + .1.7 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.6760.6.1.133 NAME 'passwordExpirationDate' DESC + 'This is the date the password will expire' EQUALITY caseIgnoreMatch SUBSTR c + aseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +objectClasses: ( 2.5.6.0 NAME 'top' DESC 'top of the superclass chain' ABSTRAC + T MUST objectClass ) +objectClasses: ( 1.3.6.1.4.1.1466.101.120.111 NAME 'extensibleObject' DESC 'RF + C4512: extensible object' SUP top AUXILIARY ) +objectClasses: ( 2.5.6.1 NAME 'alias' DESC 'RFC4512: an alias' SUP top STRUCTU + RAL MUST aliasedObjectName ) +objectClasses: ( 2.16.840.1.113730.3.2.6 NAME 'referral' DESC 'namedref: named + subordinate referral' SUP top STRUCTURAL MUST ref ) +objectClasses: ( 1.3.6.1.4.1.4203.1.4.1 NAME ( 'OpenLDAProotDSE' 'LDAProotDSE' + ) DESC 'OpenLDAP Root DSE object' SUP top STRUCTURAL MAY cn ) +objectClasses: ( 2.5.17.0 NAME 'subentry' DESC 'RFC3672: subentry' SUP top STR + UCTURAL MUST ( cn $ subtreeSpecification ) ) +objectClasses: ( 2.5.20.1 NAME 'subschema' DESC 'RFC4512: controlling subschem + a (sub)entry' AUXILIARY MAY ( dITStructureRules $ nameForms $ dITContentRules + $ objectClasses $ attributeTypes $ matchingRules $ matchingRuleUse ) ) +objectClasses: ( 1.3.6.1.4.1.1466.101.119.2 NAME 'dynamicObject' DESC 'RFC2589 + : Dynamic Object' SUP top AUXILIARY ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.0.0 NAME 'olcConfig' DESC 'OpenLDAP + configuration object' SUP top ABSTRACT ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.0.1 NAME 'olcGlobal' DESC 'OpenLDAP + Global configuration options' SUP olcConfig STRUCTURAL MAY ( cn $ olcConfigF + ile $ olcConfigDir $ olcAllows $ olcArgsFile $ olcAttributeOptions $ olcAuthI + DRewrite $ olcAuthzPolicy $ olcAuthzRegexp $ olcConcurrency $ olcConnMaxPendi + ng $ olcConnMaxPendingAuth $ olcDisallows $ olcGentleHUP $ olcIdleTimeout $ o + lcIndexSubstrIfMaxLen $ olcIndexSubstrIfMinLen $ olcIndexSubstrAnyLen $ olcIn + dexSubstrAnyStep $ olcIndexIntLen $ olcLocalSSF $ olcLogFile $ olcLogLevel $ + olcPasswordCryptSaltFormat $ olcPasswordHash $ olcPidFile $ olcPluginLogFile + $ olcReadOnly $ olcReferral $ olcReplogFile $ olcRequires $ olcRestrict $ olc + ReverseLookup $ olcRootDSE $ olcSaslAuxprops $ olcSaslHost $ olcSaslRealm $ o + lcSaslSecProps $ olcSecurity $ olcServerID $ olcSizeLimit $ olcSockbufMaxInco + ming $ olcSockbufMaxIncomingAuth $ olcTCPBuffer $ olcThreads $ olcTimeLimit $ + olcTLSCACertificateFile $ olcTLSCACertificatePath $ olcTLSCertificateFile $ + olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ olcTLSRandFil + e $ olcTLSVerifyClient $ olcTLSDHParamFile $ olcTLSCRLFile $ olcToolThreads $ + olcWriteTimeout $ olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses + $ olcDitContentRules $ olcLdapSyntaxes ) ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.0.2 NAME 'olcSchemaConfig' DESC 'Op + enLDAP schema object' SUP olcConfig STRUCTURAL MAY ( cn $ olcObjectIdentifier + $ olcLdapSyntaxes $ olcAttributeTypes $ olcObjectClasses $ olcDitContentRule + s ) ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.0.3 NAME 'olcBackendConfig' DESC 'O + penLDAP Backend-specific options' SUP olcConfig STRUCTURAL MUST olcBackend ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.0.4 NAME 'olcDatabaseConfig' DESC ' + OpenLDAP Database-specific options' SUP olcConfig STRUCTURAL MUST olcDatabase + MAY ( olcHidden $ olcSuffix $ olcSubordinate $ olcAccess $ olcAddContentAcl + $ olcLastMod $ olcLimits $ olcMaxDerefDepth $ olcPlugin $ olcReadOnly $ olcRe + plica $ olcReplicaArgsFile $ olcReplicaPidFile $ olcReplicationInterval $ olc + ReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ olcSchemaDN + $ olcSecurity $ olcSizeLimit $ olcSyncUseSubentry $ olcSyncrepl $ olcTimeLimi + t $ olcUpdateDN $ olcUpdateRef $ olcMirrorMode $ olcMonitoring $ olcExtraAttr + s ) ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.0.5 NAME 'olcOverlayConfig' DESC 'O + penLDAP Overlay-specific options' SUP olcConfig STRUCTURAL MUST olcOverlay ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.0.6 NAME 'olcIncludeFile' DESC 'Ope + nLDAP configuration include file' SUP olcConfig STRUCTURAL MUST olcInclude MA + Y ( cn $ olcRootDSE ) ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.0.7 NAME 'olcFrontendConfig' DESC ' + OpenLDAP frontend configuration' AUXILIARY MAY ( olcDefaultSearchBase $ olcPa + sswordHash $ olcSortVals ) ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.0.8 NAME 'olcModuleList' DESC 'Open + LDAP dynamic module info' SUP olcConfig STRUCTURAL MAY ( cn $ olcModulePath $ + olcModuleLoad ) ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.2.2.1 NAME 'olcLdifConfig' DESC 'LD + IF backend configuration' SUP olcDatabaseConfig STRUCTURAL MUST olcDbDirector + y ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.2.4.1 NAME 'olcMonitorConfig' DESC + 'Monitor backend configuration' SUP olcDatabaseConfig STRUCTURAL ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.2.1.1 NAME 'olcBdbConfig' DESC 'BDB + backend configuration' SUP olcDatabaseConfig STRUCTURAL MUST olcDbDirectory + MAY ( olcDbCacheSize $ olcDbCheckpoint $ olcDbConfig $ olcDbCryptFile $ olcDb + CryptKey $ olcDbNoSync $ olcDbDirtyRead $ olcDbIDLcacheSize $ olcDbIndex $ ol + cDbLinearIndex $ olcDbLockDetect $ olcDbMode $ olcDbSearchStack $ olcDbShmKey + $ olcDbCacheFree $ olcDbDNcacheSize $ olcDbPageSize ) ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.2.1.2 NAME 'olcHdbConfig' DESC 'HDB + backend configuration' SUP olcDatabaseConfig STRUCTURAL MUST olcDbDirectory + MAY ( olcDbCacheSize $ olcDbCheckpoint $ olcDbConfig $ olcDbCryptFile $ olcDb + CryptKey $ olcDbNoSync $ olcDbDirtyRead $ olcDbIDLcacheSize $ olcDbIndex $ ol + cDbLinearIndex $ olcDbLockDetect $ olcDbMode $ olcDbSearchStack $ olcDbShmKey + $ olcDbCacheFree $ olcDbDNcacheSize $ olcDbPageSize ) ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.2.12.1 NAME 'olcMdbConfig' DESC 'MD + B backend configuration' SUP olcDatabaseConfig STRUCTURAL MUST olcDbDirectory + MAY ( olcDbCheckpoint $ olcDbNoSync $ olcDbIndex $ olcDbMaxReaders $ olcDbMa + xsize $ olcDbMode $ olcDbSearchStack ) ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.2.5.1 NAME 'olcRelayConfig' DESC 'R + elay backend configuration' SUP olcDatabaseConfig STRUCTURAL MAY olcRelay ) +objectClasses: ( 1.3.6.1.4.1.6760.6.3.2 NAME 'olcAnonReplaceConfig' DESC 'Anon + ymous Replace config' SUP olcOverlayConfig STRUCTURAL MAY olcAnonReplaceAttrP + air ) +objectClasses: ( 1.3.6.1.4.1.6760.6.3.4 NAME 'olcAuthStatsConfig' DESC 'Authen + tication Statistics config' SUP olcOverlayConfig STRUCTURAL MAY olcAuthStatsA + ttrPair ) +objectClasses: ( 1.3.6.1.4.1.6760.6.3.8 NAME 'olcdynuupidConfig' DESC 'Anonymo + us Replace config' SUP olcOverlayConfig STRUCTURAL MAY olcdynuupidAttrPair ) +objectClasses: ( 1.3.6.1.4.1.6760.6.3.8.1 NAME 'olcdynvtaffilConfig' DESC 'Ano + nymous Replace config' SUP olcOverlayConfig STRUCTURAL MAY olcdynvtaffilAttrP + air ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.3.15.1 NAME 'olcAuditlogConfig' DES + C 'Auditlog configuration' SUP olcOverlayConfig STRUCTURAL MAY olcAuditlogFil + e ) +objectClasses: ( 1.3.6.1.4.1.4203.1.12.2.4.3.4.1 NAME 'olcAccessLogConfig' DES + C 'Access log configuration' SUP olcOverlayConfig STRUCTURAL MUST olcAccessLo + gDB MAY ( olcAccessLogOps $ olcAccessLogPurge $ olcAccessLogSuccess $ olcAcce + ssLogOld $ olcAccessLogOldAttr $ olcAccessLogBase ) ) +objectClasses: ( 2.5.6.2 NAME 'country' DESC 'RFC2256: a country' SUP top STRU + CTURAL MUST c MAY ( searchGuide $ description ) ) +objectClasses: ( 2.5.6.3 NAME 'locality' DESC 'RFC2256: a locality' SUP top ST + RUCTURAL MAY ( street $ seeAlso $ searchGuide $ st $ l $ description ) ) +objectClasses: ( 2.5.6.4 NAME 'organization' DESC 'RFC2256: an organization' S + UP top STRUCTURAL MUST o MAY ( userPassword $ searchGuide $ seeAlso $ busines + sCategory $ x121Address $ registeredAddress $ destinationIndicator $ preferre + dDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ telephoneNumber $ + internationaliSDNNumber $ facsimileTelephoneNumber $ street $ postOfficeBox + $ postalCode $ postalAddress $ physicalDeliveryOfficeName $ st $ l $ descript + ion ) ) +objectClasses: ( 2.5.6.5 NAME 'organizationalUnit' DESC 'RFC2256: an organizat + ional unit' SUP top STRUCTURAL MUST ou MAY ( userPassword $ searchGuide $ see + Also $ businessCategory $ x121Address $ registeredAddress $ destinationIndica + tor $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ tel + ephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $ street $ + postOfficeBox $ postalCode $ postalAddress $ physicalDeliveryOfficeName $ st + $ l $ description ) ) +objectClasses: ( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top STRUCT + URAL MUST ( sn $ cn ) MAY ( userPassword $ telephoneNumber $ seeAlso $ descri + ption ) ) +objectClasses: ( 2.5.6.7 NAME 'organizationalPerson' DESC 'RFC2256: an organiz + ational person' SUP person STRUCTURAL MAY ( title $ x121Address $ registeredA + ddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ telet + exTerminalIdentifier $ telephoneNumber $ internationaliSDNNumber $ facsimileT + elephoneNumber $ street $ postOfficeBox $ postalCode $ postalAddress $ physic + alDeliveryOfficeName $ ou $ st $ l ) ) +objectClasses: ( 2.5.6.8 NAME 'organizationalRole' DESC 'RFC2256: an organizat + ional role' SUP top STRUCTURAL MUST cn MAY ( x121Address $ registeredAddress + $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTermi + nalIdentifier $ telephoneNumber $ internationaliSDNNumber $ facsimileTelephon + eNumber $ seeAlso $ roleOccupant $ preferredDeliveryMethod $ street $ postOff + iceBox $ postalCode $ postalAddress $ physicalDeliveryOfficeName $ ou $ st $ + l $ description ) ) +objectClasses: ( 2.5.6.9 NAME 'groupOfNames' DESC 'RFC2256: a group of names ( + DNs)' SUP top STRUCTURAL MUST ( member $ cn ) MAY ( businessCategory $ seeAls + o $ owner $ ou $ o $ description ) ) +objectClasses: ( 2.5.6.10 NAME 'residentialPerson' DESC 'RFC2256: an residenti + al person' SUP person STRUCTURAL MUST l MAY ( businessCategory $ x121Address + $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexN + umber $ teletexTerminalIdentifier $ telephoneNumber $ internationaliSDNNumber + $ facsimileTelephoneNumber $ preferredDeliveryMethod $ street $ postOfficeBo + x $ postalCode $ postalAddress $ physicalDeliveryOfficeName $ st $ l ) ) +objectClasses: ( 2.5.6.11 NAME 'applicationProcess' DESC 'RFC2256: an applicat + ion process' SUP top STRUCTURAL MUST cn MAY ( seeAlso $ ou $ l $ description + ) ) +objectClasses: ( 2.5.6.12 NAME 'applicationEntity' DESC 'RFC2256: an applicati + on entity' SUP top STRUCTURAL MUST ( presentationAddress $ cn ) MAY ( support + edApplicationContext $ seeAlso $ ou $ o $ l $ description ) ) +objectClasses: ( 2.5.6.13 NAME 'dSA' DESC 'RFC2256: a directory system agent ( + a server)' SUP applicationEntity STRUCTURAL MAY knowledgeInformation ) +objectClasses: ( 2.5.6.14 NAME 'device' DESC 'RFC2256: a device' SUP top STRUC + TURAL MUST cn MAY ( serialNumber $ seeAlso $ owner $ ou $ o $ l $ description + ) ) +objectClasses: ( 2.5.6.15 NAME 'strongAuthenticationUser' DESC 'RFC2256: a str + ong authentication user' SUP top AUXILIARY MUST userCertificate ) +objectClasses: ( 2.5.6.16 NAME 'certificationAuthority' DESC 'RFC2256: a certi + ficate authority' SUP top AUXILIARY MUST ( authorityRevocationList $ certific + ateRevocationList $ cACertificate ) MAY crossCertificatePair ) +objectClasses: ( 2.5.6.17 NAME 'groupOfUniqueNames' DESC 'RFC2256: a group of + unique names (DN and Unique Identifier)' SUP top STRUCTURAL MUST ( uniqueMemb + er $ cn ) MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) ) +objectClasses: ( 2.5.6.18 NAME 'userSecurityInformation' DESC 'RFC2256: a user + security information' SUP top AUXILIARY MAY supportedAlgorithms ) +objectClasses: ( 2.5.6.16.2 NAME 'certificationAuthority-V2' SUP certification + Authority AUXILIARY MAY deltaRevocationList ) +objectClasses: ( 2.5.6.19 NAME 'cRLDistributionPoint' SUP top STRUCTURAL MUST + cn MAY ( certificateRevocationList $ authorityRevocationList $ deltaRevocatio + nList ) ) +objectClasses: ( 2.5.6.20 NAME 'dmd' SUP top STRUCTURAL MUST dmdName MAY ( use + rPassword $ searchGuide $ seeAlso $ businessCategory $ x121Address $ register + edAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ te + letexTerminalIdentifier $ telephoneNumber $ internationaliSDNNumber $ facsimi + leTelephoneNumber $ street $ postOfficeBox $ postalCode $ postalAddress $ phy + sicalDeliveryOfficeName $ st $ l $ description ) ) +objectClasses: ( 2.5.6.21 NAME 'pkiUser' DESC 'RFC2587: a PKI user' SUP top AU + XILIARY MAY userCertificate ) +objectClasses: ( 2.5.6.22 NAME 'pkiCA' DESC 'RFC2587: PKI certificate authorit + y' SUP top AUXILIARY MAY ( authorityRevocationList $ certificateRevocationLis + t $ cACertificate $ crossCertificatePair ) ) +objectClasses: ( 2.5.6.23 NAME 'deltaCRL' DESC 'RFC2587: PKI user' SUP top AUX + ILIARY MAY deltaRevocationList ) +objectClasses: ( 1.3.6.1.4.1.250.3.15 NAME 'labeledURIObject' DESC 'RFC2079: o + bject that contains the URI attribute type' SUP top AUXILIARY MAY labeledURI + ) +objectClasses: ( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject' DESC ' + RFC1274: simple security object' SUP top AUXILIARY MUST userPassword ) +objectClasses: ( 1.3.6.1.4.1.1466.344 NAME 'dcObject' DESC 'RFC2247: domain co + mponent object' SUP top AUXILIARY MUST dc ) +objectClasses: ( 1.3.6.1.1.3.1 NAME 'uidObject' DESC 'RFC2377: uid object' SUP + top AUXILIARY MUST uid ) +objectClasses: ( 0.9.2342.19200300.100.4.4 NAME ( 'pilotPerson' 'newPilotPerso + n' ) SUP person STRUCTURAL MAY ( userid $ textEncodedORAddress $ rfc822Mailbo + x $ favouriteDrink $ roomNumber $ userClass $ homeTelephoneNumber $ homePosta + lAddress $ secretary $ personalTitle $ preferredDeliveryMethod $ businessCate + gory $ janetMailbox $ otherMailbox $ mobileTelephoneNumber $ pagerTelephoneNu + mber $ organizationalStatus $ mailPreferenceOption $ personalSignature ) ) +objectClasses: ( 0.9.2342.19200300.100.4.5 NAME 'account' SUP top STRUCTURAL M + UST userid MAY ( description $ seeAlso $ localityName $ organizationName $ or + ganizationalUnitName $ host ) ) +objectClasses: ( 0.9.2342.19200300.100.4.6 NAME 'document' SUP top STRUCTURAL + MUST documentIdentifier MAY ( commonName $ description $ seeAlso $ localityNa + me $ organizationName $ organizationalUnitName $ documentTitle $ documentVers + ion $ documentAuthor $ documentLocation $ documentPublisher ) ) +objectClasses: ( 0.9.2342.19200300.100.4.7 NAME 'room' SUP top STRUCTURAL MUST + commonName MAY ( roomNumber $ description $ seeAlso $ telephoneNumber ) ) +objectClasses: ( 0.9.2342.19200300.100.4.9 NAME 'documentSeries' SUP top STRUC + TURAL MUST commonName MAY ( description $ seeAlso $ telephonenumber $ localit + yName $ organizationName $ organizationalUnitName ) ) +objectClasses: ( 0.9.2342.19200300.100.4.13 NAME 'domain' SUP top STRUCTURAL M + UST domainComponent MAY ( associatedName $ organizationName $ description $ b + usinessCategory $ seeAlso $ searchGuide $ userPassword $ localityName $ state + OrProvinceName $ streetAddress $ physicalDeliveryOfficeName $ postalAddress $ + postalCode $ postOfficeBox $ streetAddress $ facsimileTelephoneNumber $ inte + rnationalISDNNumber $ telephoneNumber $ teletexTerminalIdentifier $ telexNumb + er $ preferredDeliveryMethod $ destinationIndicator $ registeredAddress $ x12 + 1Address ) ) +objectClasses: ( 0.9.2342.19200300.100.4.14 NAME 'RFC822localPart' SUP domain + STRUCTURAL MAY ( commonName $ surname $ description $ seeAlso $ telephoneNumb + er $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox + $ streetAddress $ facsimileTelephoneNumber $ internationalISDNNumber $ teleph + oneNumber $ teletexTerminalIdentifier $ telexNumber $ preferredDeliveryMethod + $ destinationIndicator $ registeredAddress $ x121Address ) ) +objectClasses: ( 0.9.2342.19200300.100.4.15 NAME 'dNSDomain' SUP domain STRUCT + URAL MAY ( ARecord $ MDRecord $ MXRecord $ NSRecord $ SOARecord $ CNAMERecord + ) ) +objectClasses: ( 0.9.2342.19200300.100.4.17 NAME 'domainRelatedObject' DESC 'R + FC1274: an object related to an domain' SUP top AUXILIARY MUST associatedDoma + in ) +objectClasses: ( 0.9.2342.19200300.100.4.18 NAME 'friendlyCountry' SUP country + STRUCTURAL MUST friendlyCountryName ) +objectClasses: ( 0.9.2342.19200300.100.4.20 NAME 'pilotOrganization' SUP ( org + anization $ organizationalUnit ) STRUCTURAL MAY buildingName ) +objectClasses: ( 0.9.2342.19200300.100.4.21 NAME 'pilotDSA' SUP dsa STRUCTURAL + MAY dSAQuality ) +objectClasses: ( 0.9.2342.19200300.100.4.22 NAME 'qualityLabelledData' SUP top + AUXILIARY MUST dsaQuality MAY ( subtreeMinimumQuality $ subtreeMaximumQualit + y ) ) +objectClasses: ( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' DESC 'RFC2798: I + nternet Organizational Person' SUP organizationalPerson STRUCTURAL MAY ( audi + o $ businessCategory $ carLicense $ departmentNumber $ displayName $ employee + Number $ employeeType $ givenName $ homePhone $ homePostalAddress $ initials + $ jpegPhoto $ labeledURI $ mail $ manager $ mobile $ o $ pager $ photo $ room + Number $ secretary $ uid $ userCertificate $ x500uniqueIdentifier $ preferred + Language $ userSMIMECertificate $ userPKCS12 ) ) +objectClasses: ( 1.3.6.1.4.1.4203.1.4.3 NAME 'OpenLDAPorg' DESC 'OpenLDAP Orga + nizational Object' SUP organization STRUCTURAL MAY ( buildingName $ displayNa + me $ labeledURI ) ) +objectClasses: ( 1.3.6.1.4.1.4203.1.4.4 NAME 'OpenLDAPou' DESC 'OpenLDAP Organ + izational Unit Object' SUP organizationalUnit STRUCTURAL MAY ( buildingName $ + displayName $ labeledURI $ o ) ) +objectClasses: ( 1.3.6.1.4.1.4203.1.4.5 NAME 'OpenLDAPperson' DESC 'OpenLDAP P + erson' SUP ( pilotPerson $ inetOrgPerson ) STRUCTURAL MUST ( uid $ cn ) MAY ( + givenName $ labeledURI $ o ) ) +objectClasses: ( 1.3.6.1.4.1.4203.1.4.6 NAME 'OpenLDAPdisplayableObject' DESC + 'OpenLDAP Displayable Object' AUXILIARY MAY displayName ) +objectClasses: ( 1.3.6.1.4.1.5923.1.1.2 NAME 'eduPerson' SUP inetOrgPerson STR + UCTURAL MAY ( eduPersonAffiliation $ eduPersonNickname $ eduPersonOrgDN $ edu + PersonOrgUnitDN $ eduPersonPrimaryAffiliation $ eduPersonPrincipalName ) ) +objectClasses: ( 1.3.6.1.4.1.6760.6.2.2 NAME 'virginiaTechAddress' DESC 'A obj + ect representing the address of a person.' STRUCTURAL MUST ( addressType $ ci + ty $ postalCode $ uuaid ) MAY ( country $ mailStop $ mobile $ pager $ postOff + iceBox $ stateOrProvince $ street1 $ street2 $ telephoneNumber $ facsimileTel + ephoneNumber ) ) +objectClasses: ( 1.3.6.1.4.1.6760.6.2.4 NAME 'virginiaTechGroup' DESC 'A group + of people.' STRUCTURAL MUST ( contactPerson $ creationDate $ uid $ uugid ) M + AY ( administrator $ displayName $ emailAddress $ expirationDate $ groupData + $ groupMembership $ labeledURI $ manager $ meetingTime $ member $ physicalAdd + ress $ suppressDisplay $ suppressMembers $ url $ viewer ) ) +objectClasses: ( 1.3.6.1.4.1.6760.6.2.5 NAME 'virginiaTechService' DESC 'A ser + vice which uses the directory.' STRUCTURAL MUST ( accountState $ administrato + r $ certificate $ contactPerson $ creationDate $ serviceDN $ serviceType $ ui + d $ uusid ) MAY ( expirationDate $ userPassword $ viewablePersonAttribute ) ) +objectClasses: ( 1.3.6.1.4.1.6760.6.2.6 NAME 'virginiaTechEntitlement' DESC 'A + n entitlement at Virginia Tech.' STRUCTURAL MUST ( creationDate $ entitlement + $ manager $ uid ) MAY ( entitled $ expirationDate $ sponsor $ viewer ) ) +objectClasses: ( 1.3.6.1.4.1.6760.6.2.1 NAME 'virginiaTechPerson' DESC 'A pers + on at Virginia Tech' SUP eduPerson STRUCTURAL MUST ( cn $ creationDate $ eduP + ersonAffiliation $ eduPersonPrimaryAffiliation $ personType $ sn $ uid ) MAY + ( accountCreationDate $ accountExpirationDate $ accountRecoveryMaintenanceDat + e $ accountShelveDate $ accountState $ address $ amateurRadioCallsign $ authI + d $ bannerName $ legalName $ bannerPIDM $ c $ campus $ classLevel $ classLeve + lCode $ confidentialFlag $ dateOfBirth $ degreeType $ deceasedFlag $ departme + nt $ departmentNumber $ displayName $ eduPersonPrincipalName $ employeeOffCam + pus $ expirationDate $ facsimileTelephoneNumber $ gender $ givenName $ groupA + ddDate $ groupExpireDate $ groupMembership $ guestId $ homeFax $ homeMobile $ + homePager $ homePhone $ homePostalAddress $ initials $ instantMessagingID $ + jpegPhoto $ l $ labeledURI $ lastEnrollmentTerm $ lastEnrollmentTermCode $ lo + calFax $ localMobile $ localPager $ localPhone $ localPostalAddress $ mail $ + mailAccount $ mailAlias $ mailExternalAddress $ mailForwardingAddress $ mailP + referredAddress $ mailStop $ major $ majorCode $ middleName $ mobile $ networ + kPassword $ nextEnrollmentTerm $ nextEnrollmentTermCode $ pager $ passwordExp + irationDate $ postalAddress $ postalCode $ postOfficeBox $ preferredLanguage + $ previousVirginiaTechID $ passwordState $ publicKey $ responsiblePerson $ st + $ street $ studentLevel $ studentLevelCode $ suppressedAttribute $ suppresse + dUupid $ suppressEmployeeDisplay $ suppressDisplay $ telephoneNumber $ title + $ udcIdentifier $ undergraduateLevel $ unixUID $ userCertificate $ userPasswo + rd $ userSMIMECertificate $ uupid $ virginiaTechAffiliation $ virginiaTechID + ) ) +entryDN: cn=Subschema +subschemaSubentry: cn=Subschema + +# search result +search: 2 +result: 0 Success + +# numResponses: 2 +# numEntries: 1
diff --git a/core/pom.xml b/core/pom.xml new file mode 100644 index 0000000..753d3ba --- /dev/null +++ b/core/pom.xml
@@ -0,0 +1,35 @@ +<?xml version='1.0' encoding='UTF-8'?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>ldaptive</artifactId> + <packaging>jar</packaging> + <name>LDAPTIVE CORE</name> + <description>Ldaptive API</description> + <parent> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-parent</artifactId> + <version>1.2.3</version> + </parent> + + <dependencies> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + </dependency> + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + </dependency> + </dependencies> + +</project>
diff --git a/core/src/main/java/org/ldaptive/AbstractConfig.java b/core/src/main/java/org/ldaptive/AbstractConfig.java new file mode 100644 index 0000000..ca7d613 --- /dev/null +++ b/core/src/main/java/org/ldaptive/AbstractConfig.java
@@ -0,0 +1,62 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides common implementations for configuration objects. + * + * @author Middleware Services + */ +public abstract class AbstractConfig +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Whether this config has been marked immutable. */ + private boolean immutable; + + + /** Make this config immutable. */ + public void makeImmutable() + { + immutable = true; + } + + + /** + * Verifies if this config is immutable. + * + * @throws IllegalStateException if this config is immutable + */ + public void checkImmutable() + { + if (immutable) { + throw new IllegalStateException("Cannot modify immutable object"); + } + } + + + /** + * Verifies that a string is not null or empty. + * + * @param s to verify + * @param allowNull whether null strings are valid + * + * @throws IllegalArgumentException if the string is null or empty + */ + protected void checkStringInput(final String s, final boolean allowNull) + { + if (allowNull) { + if (s != null && "".equals(s)) { + throw new IllegalArgumentException("Input cannot be empty"); + } + } else { + if (s == null || "".equals(s)) { + throw new IllegalArgumentException("Input cannot be null or empty"); + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/AbstractLdapBean.java b/core/src/main/java/org/ldaptive/AbstractLdapBean.java new file mode 100644 index 0000000..006f00c --- /dev/null +++ b/core/src/main/java/org/ldaptive/AbstractLdapBean.java
@@ -0,0 +1,44 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.io.Serializable; + +/** + * Provides common implementations for ldap beans. + * + * @author Middleware Services + */ +public abstract class AbstractLdapBean implements Serializable +{ + + /** serial version uid. */ + private static final long serialVersionUID = 4715681585273172940L; + + /** Sort behavior. */ + private final SortBehavior sortBehavior; + + + /** + * Creates a new abstract ldap bean. + * + * @param sb sort behavior + */ + public AbstractLdapBean(final SortBehavior sb) + { + if (sb == null) { + throw new IllegalArgumentException("Sort behavior cannot be null"); + } + sortBehavior = sb; + } + + + /** + * Returns the sort behavior for this ldap bean. + * + * @return sort behavior + */ + public SortBehavior getSortBehavior() + { + return sortBehavior; + } +}
diff --git a/core/src/main/java/org/ldaptive/AbstractOperation.java b/core/src/main/java/org/ldaptive/AbstractOperation.java new file mode 100644 index 0000000..b565087 --- /dev/null +++ b/core/src/main/java/org/ldaptive/AbstractOperation.java
@@ -0,0 +1,285 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; +import org.ldaptive.handler.AbstractRetryOperationExceptionHandler; +import org.ldaptive.handler.Handler; +import org.ldaptive.handler.HandlerResult; +import org.ldaptive.handler.OperationExceptionHandler; +import org.ldaptive.handler.OperationResponseHandler; +import org.ldaptive.referral.ReferralHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides common implementation for ldap operations. + * + * @param <Q> type of ldap request + * @param <S> type of ldap response + * + * @author Middleware Services + */ +public abstract class AbstractOperation<Q extends Request, S> implements Operation<Q, S> +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Connection to perform operation. */ + private final Connection connection; + + /** Handler to handle operation exceptions. */ + private OperationExceptionHandler<Q, S> operationExceptionHandler = new ReopenOperationExceptionHandler(); + + /** Handlers to handle operation responses. */ + private OperationResponseHandler<Q, S>[] operationResponseHandlers; + + + /** + * Creates a new abstract operation. + * + * @param conn to use for this operation + */ + public AbstractOperation(final Connection conn) + { + connection = conn; + } + + + /** + * Returns the connection used for this operation. + * + * @return connection + */ + protected Connection getConnection() + { + return connection; + } + + + /** + * Returns the operation exception handler. + * + * @return operation exception handler + */ + public OperationExceptionHandler<Q, S> getOperationExceptionHandler() + { + return operationExceptionHandler; + } + + + /** + * Sets the operation exception handler. + * + * @param handler operation exception handler + */ + public void setOperationExceptionHandler(final OperationExceptionHandler<Q, S> handler) + { + operationExceptionHandler = handler; + } + + + /** + * Returns the operation response handlers. + * + * @return operation response handlers + */ + public OperationResponseHandler<Q, S>[] getOperationResponseHandlers() + { + return operationResponseHandlers; + } + + + /** + * Sets the operation response handlers. + * + * @param handlers operation response handlers + */ + @SuppressWarnings("unchecked") + public void setOperationResponseHandlers(final OperationResponseHandler<Q, S>... handlers) + { + operationResponseHandlers = handlers; + } + + + /** + * Call the provider specific implementation of this ldap operation. + * + * @param request ldap request + * + * @return ldap response + * + * @throws LdapException if the invocation fails + */ + protected abstract Response<S> invoke(final Q request) + throws LdapException; + + + @Override + public Response<S> execute(final Q request) + throws LdapException + { + logger.debug("execute request={} with connection={}", request, connection); + + Response<S> response = null; + try { + response = invoke(request); + } catch (OperationException e) { + if (operationExceptionHandler == null) { + throw e; + } + logger.debug("Error performing LDAP operation, invoking exception handler: {}", operationExceptionHandler, e); + + final HandlerResult<Response<S>> hr = operationExceptionHandler.handle(connection, request, response); + if (hr.getAbort()) { + throw e; + } + response = hr.getResult(); + } + + if (ResultCode.REFERRAL == response.getResultCode()) { + @SuppressWarnings("unchecked") + final ReferralHandler<Q, S> handler = request.getReferralHandler(); + if (handler != null) { + logger.debug("Encountered referral, invoking referral handler: {}", handler); + + final HandlerResult<Response<S>> hr = handler.handle(connection, request, response); + response = hr.getResult(); + } + } + + // execute response handlers + final HandlerResult<Response<S>> hr = executeHandlers(getOperationResponseHandlers(), request, response); + + logger.debug("execute response={} for request={} with connection={}", hr.getResult(), request, connection); + return hr.getResult(); + } + + + /** + * Processes each handler and returns a handler result containing a result processed by all handlers. If any handler + * indicates that the operation should be aborted, that flag is returned to the operation after all handlers have been + * invoked. + * + * @param <Q> type of request + * @param <S> type of response + * @param handlers to invoke + * @param request the operation was performed with + * @param result from the operation + * + * @return handler result + * + * @throws LdapException if an error occurs processing a handler + */ + protected <Q extends Request, S> HandlerResult<S> executeHandlers( + final Handler<Q, S>[] handlers, + final Q request, + final S result) + throws LdapException + { + S processed = result; + boolean abort = false; + if (handlers != null && handlers.length > 0) { + for (Handler<Q, S> handler : handlers) { + if (handler != null) { + try { + final HandlerResult<S> hr = handler.handle(getConnection(), request, processed); + if (hr != null) { + if (hr.getAbort()) { + abort = true; + } + processed = hr.getResult(); + } + } catch (Exception e) { + logger.warn("{} threw unexpected exception", handler, e); + } + } + } + } + return new HandlerResult<>(processed, abort); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::connection=%s, operationExceptionHandler=%s, " + + "operationResponseHandlers=%s]", + getClass().getName(), + hashCode(), + connection, + operationExceptionHandler, + Arrays.toString(operationResponseHandlers)); + } + + + /** + * Exception handler that invokes {@link Connection#reopen(BindRequest)} when an operation exception occurs and then + * invokes the operation again. + */ + public class ReopenOperationExceptionHandler extends AbstractRetryOperationExceptionHandler<Q, S> + { + + /** Bind request to use when reopening a connection. */ + private final BindRequest bindRequest; + + + /** Default constructor. */ + public ReopenOperationExceptionHandler() + { + bindRequest = null; + } + + + /** + * Creates a new reopen operation exception handler. + * + * @param request to bind with on reopen + */ + public ReopenOperationExceptionHandler(final BindRequest request) + { + bindRequest = request; + } + + + @Override + protected void handleInternal(final Connection conn, final Q request, final Response<S> response) + throws LdapException + { + logger.warn("Operation exception encountered, reopening connection"); + if (bindRequest != null) { + conn.reopen(bindRequest); + } else { + conn.reopen(); + } + } + + + @Override + protected HandlerResult<Response<S>> createResult( + final Connection conn, + final Q request, + final Response<S> response) + throws LdapException + { + return new HandlerResult<>(invoke(request)); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::retry=%s, retryWait=%s, retryBackoff=%s, bindRequest=%s]", + getClass().getName(), + hashCode(), + getRetry(), + getRetryWait(), + getRetryBackoff(), + bindRequest); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/AbstractRequest.java b/core/src/main/java/org/ldaptive/AbstractRequest.java new file mode 100644 index 0000000..fcb78d2 --- /dev/null +++ b/core/src/main/java/org/ldaptive/AbstractRequest.java
@@ -0,0 +1,82 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.ldaptive.control.RequestControl; +import org.ldaptive.handler.IntermediateResponseHandler; +import org.ldaptive.referral.ReferralHandler; + +/** + * Contains the data common to all request objects. + * + * @author Middleware Services + */ +public abstract class AbstractRequest implements Request +{ + + /** Request controls. */ + private RequestControl[] controls; + + /** Referral handler. */ + private ReferralHandler referralHandler; + + /** Intermediate response handlers. */ + private IntermediateResponseHandler[] intermediateResponseHandlers; + + + @Override + public RequestControl[] getControls() + { + return controls; + } + + + /** + * Sets the controls for this request. + * + * @param c controls to set + */ + public void setControls(final RequestControl... c) + { + controls = c; + } + + + @Override + public ReferralHandler getReferralHandler() + { + return referralHandler; + } + + + /** + * Sets the referral handler. + * + * @param handler referral handler + */ + @SuppressWarnings("unchecked") + public void setReferralHandler(final ReferralHandler handler) + { + if (handler != null) { + handler.initializeRequest(this); + } + referralHandler = handler; + } + + + @Override + public IntermediateResponseHandler[] getIntermediateResponseHandlers() + { + return intermediateResponseHandlers; + } + + + /** + * Sets the intermediate response handlers. + * + * @param handlers intermediate response handlers + */ + public void setIntermediateResponseHandlers(final IntermediateResponseHandler... handlers) + { + intermediateResponseHandlers = handlers; + } +}
diff --git a/core/src/main/java/org/ldaptive/ActivePassiveConnectionStrategy.java b/core/src/main/java/org/ldaptive/ActivePassiveConnectionStrategy.java new file mode 100644 index 0000000..9128800 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ActivePassiveConnectionStrategy.java
@@ -0,0 +1,31 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Connection strategy that returns URLs ordered exactly the way they are configured. This means that the first URL will + * always be attempted first, followed by each URL in the list. + * + * @author Middleware Services + */ +public class ActivePassiveConnectionStrategy implements ConnectionStrategy +{ + + + /** + * Return the URLs in the order they are provided, so that the first URL is always tried first, then the second, and + * so forth. + * + * @param metadata which can be used to produce the URL list + * + * @return list of URLs to attempt connections to + */ + @Override + public String[] getLdapUrls(final ConnectionFactoryMetadata metadata) + { + if (metadata == null || metadata.getLdapUrl() == null) { + return null; + } + + return metadata.getLdapUrl().split(" "); + } +}
diff --git a/core/src/main/java/org/ldaptive/AddOperation.java b/core/src/main/java/org/ldaptive/AddOperation.java new file mode 100644 index 0000000..500a704 --- /dev/null +++ b/core/src/main/java/org/ldaptive/AddOperation.java
@@ -0,0 +1,30 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Executes an ldap add operation. + * + * @author Middleware Services + */ +public class AddOperation extends AbstractOperation<AddRequest, Void> +{ + + + /** + * Creates a new add operation. + * + * @param conn connection + */ + public AddOperation(final Connection conn) + { + super(conn); + } + + + @Override + protected Response<Void> invoke(final AddRequest request) + throws LdapException + { + return getConnection().getProviderConnection().add(request); + } +}
diff --git a/core/src/main/java/org/ldaptive/AddRequest.java b/core/src/main/java/org/ldaptive/AddRequest.java new file mode 100644 index 0000000..e6dbc49 --- /dev/null +++ b/core/src/main/java/org/ldaptive/AddRequest.java
@@ -0,0 +1,98 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; +import java.util.Collection; + +/** + * Contains the data required to perform an ldap add operation. + * + * @author Middleware Services + */ +public class AddRequest extends AbstractRequest +{ + + /** DN to create. */ + private String createDn; + + /** Attributes to add to the newly created entry. */ + private Collection<LdapAttribute> attributes; + + + /** Default constructor. */ + public AddRequest() {} + + + /** + * Creates a new add request. + * + * @param dn to create + * @param attrs attributes to add + */ + public AddRequest(final String dn, final Collection<LdapAttribute> attrs) + { + setDn(dn); + setLdapAttributes(attrs); + } + + + /** + * Returns the DN to create. + * + * @return DN + */ + public String getDn() + { + return createDn; + } + + + /** + * Sets the DN to create. + * + * @param dn to create + */ + public void setDn(final String dn) + { + createDn = dn; + } + + + /** + * Returns the attributes to add. + * + * @return attributes + */ + public Collection<LdapAttribute> getLdapAttributes() + { + return attributes; + } + + + /** + * Sets the attributes to add. + * + * @param attrs to add + */ + public void setLdapAttributes(final Collection<LdapAttribute> attrs) + { + attributes = attrs; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::createDn=%s, attributes=%s, controls=%s, " + + "referralHandler=%s, intermediateResponseHandlers=%s]", + getClass().getName(), + hashCode(), + createDn, + attributes, + Arrays.toString(getControls()), + getReferralHandler(), + Arrays.toString(getIntermediateResponseHandlers())); + } +}
diff --git a/core/src/main/java/org/ldaptive/AttributeModification.java b/core/src/main/java/org/ldaptive/AttributeModification.java new file mode 100644 index 0000000..54ccf5a --- /dev/null +++ b/core/src/main/java/org/ldaptive/AttributeModification.java
@@ -0,0 +1,84 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Contains the data required to modify an ldap attribute. + * + * @author Middleware Services + */ +public class AttributeModification +{ + + /** Type of modification to perform. */ + private AttributeModificationType attrMod; + + /** Attribute to modify. */ + private LdapAttribute attribute; + + /** Default constructor. */ + public AttributeModification() {} + + + /** + * Creates a new attribute modification. + * + * @param type attribute modification type + * @param attr to modify + */ + public AttributeModification(final AttributeModificationType type, final LdapAttribute attr) + { + setAttributeModificationType(type); + setAttribute(attr); + } + + + /** + * Returns the attribute modification type. + * + * @return attribute modification type + */ + public AttributeModificationType getAttributeModificationType() + { + return attrMod; + } + + + /** + * Sets the attribute modification type. + * + * @param type attribute modification type + */ + public void setAttributeModificationType(final AttributeModificationType type) + { + attrMod = type; + } + + + /** + * Returns the ldap attribute. + * + * @return ldap attribute + */ + public LdapAttribute getAttribute() + { + return attribute; + } + + + /** + * Sets the ldap attribute. + * + * @param attr ldap attribute + */ + public void setAttribute(final LdapAttribute attr) + { + attribute = attr; + } + + + @Override + public String toString() + { + return String.format("[%s@%d::attrMod=%s, attribute=%s]", getClass().getName(), hashCode(), attrMod, attribute); + } +}
diff --git a/core/src/main/java/org/ldaptive/AttributeModificationType.java b/core/src/main/java/org/ldaptive/AttributeModificationType.java new file mode 100644 index 0000000..09a4021 --- /dev/null +++ b/core/src/main/java/org/ldaptive/AttributeModificationType.java
@@ -0,0 +1,19 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Enum to define the type of attribute modification. + * + * @author Middleware Services + */ +public enum AttributeModificationType { + + /** add an attribute. */ + ADD, + + /** replace an attribute. */ + REPLACE, + + /** remove an attribute. */ + REMOVE +}
diff --git a/core/src/main/java/org/ldaptive/BindConnectionInitializer.java b/core/src/main/java/org/ldaptive/BindConnectionInitializer.java new file mode 100644 index 0000000..07975dd --- /dev/null +++ b/core/src/main/java/org/ldaptive/BindConnectionInitializer.java
@@ -0,0 +1,183 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; +import org.ldaptive.control.RequestControl; +import org.ldaptive.sasl.SaslConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Initializes a connection by performing a bind operation. Useful if you need all connections to bind as the same + * principal. + * + * @author Middleware Services + */ +public class BindConnectionInitializer implements ConnectionInitializer +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** DN to bind as before performing operations. */ + private String bindDn; + + /** Credential for the bind DN. */ + private Credential bindCredential; + + /** Configuration for bind SASL authentication. */ + private SaslConfig bindSaslConfig; + + /** Bind controls. */ + private RequestControl[] bindControls; + + + /** Default constructor. */ + public BindConnectionInitializer() {} + + + /** + * Creates a new bind connection initializer. + * + * @param dn bind dn + * @param credential bind credential + */ + public BindConnectionInitializer(final String dn, final Credential credential) + { + setBindDn(dn); + setBindCredential(credential); + } + + + /** + * Returns the bind DN. + * + * @return DN to bind as + */ + public String getBindDn() + { + return bindDn; + } + + + /** + * Sets the bind DN to authenticate as before performing operations. + * + * @param dn to bind as + */ + public void setBindDn(final String dn) + { + logger.trace("setting bindDn: {}", dn); + bindDn = dn; + } + + + /** + * Returns the credential used with the bind DN. + * + * @return bind DN credential + */ + public Credential getBindCredential() + { + return bindCredential; + } + + + /** + * Sets the credential of the bind DN. + * + * @param credential to use with bind DN + */ + public void setBindCredential(final Credential credential) + { + logger.trace("setting bindCredential: <suppressed>"); + bindCredential = credential; + } + + + /** + * Returns the bind sasl config. + * + * @return sasl config + */ + public SaslConfig getBindSaslConfig() + { + return bindSaslConfig; + } + + + /** + * Sets the bind sasl config. + * + * @param config sasl config + */ + public void setBindSaslConfig(final SaslConfig config) + { + logger.trace("setting bindSaslConfig: {}", config); + bindSaslConfig = config; + } + + + /** + * Returns the bind controls. + * + * @return controls + */ + public RequestControl[] getBindControls() + { + return bindControls; + } + + + /** + * Sets the bind controls. + * + * @param c controls to set + */ + public void setBindControls(final RequestControl... c) + { + logger.trace("setting bindControls: {}", Arrays.toString(c)); + bindControls = c; + } + + + @Override + public Response<Void> initialize(final Connection c) + throws LdapException + { + final BindRequest request = new BindRequest(); + request.setDn(bindDn); + request.setCredential(bindCredential); + request.setSaslConfig(bindSaslConfig); + request.setControls(bindControls); + + final BindOperation op = new BindOperation(c); + op.setOperationExceptionHandler(null); + return op.execute(request); + } + + + /** + * Returns whether this connection initializer contains any configuration data. + * + * @return whether all properties are null + */ + public boolean isEmpty() + { + return bindDn == null && bindCredential == null && bindSaslConfig == null && bindControls == null; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::bindDn=%s, bindSaslConfig=%s, bindControls=%s]", + getClass().getName(), + hashCode(), + bindDn, + bindSaslConfig, + Arrays.toString(bindControls)); + } +}
diff --git a/core/src/main/java/org/ldaptive/BindOperation.java b/core/src/main/java/org/ldaptive/BindOperation.java new file mode 100644 index 0000000..563aeb5 --- /dev/null +++ b/core/src/main/java/org/ldaptive/BindOperation.java
@@ -0,0 +1,30 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Executes an ldap bind operation. + * + * @author Middleware Services + */ +public class BindOperation extends AbstractOperation<BindRequest, Void> +{ + + + /** + * Creates a new bind operation. + * + * @param conn connection + */ + public BindOperation(final Connection conn) + { + super(conn); + } + + + @Override + protected Response<Void> invoke(final BindRequest request) + throws LdapException + { + return getConnection().getProviderConnection().bind(request); + } +}
diff --git a/core/src/main/java/org/ldaptive/BindRequest.java b/core/src/main/java/org/ldaptive/BindRequest.java new file mode 100644 index 0000000..1c6634f --- /dev/null +++ b/core/src/main/java/org/ldaptive/BindRequest.java
@@ -0,0 +1,149 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; +import org.ldaptive.sasl.SaslConfig; + +/** + * Contains the data required to perform an ldap bind operation. + * + * @author Middleware Services + */ +public class BindRequest extends AbstractRequest +{ + + /** DN to bind as before performing operations. */ + private String bindDn; + + /** Credential for the bind DN. */ + private Credential bindCredential; + + /** Configuration for SASL authentication. */ + private SaslConfig saslConfig; + + + /** Default constructor. */ + public BindRequest() {} + + + /** + * Creates a new bind request. + * + * @param dn to bind as + * @param credential to bind with + */ + public BindRequest(final String dn, final Credential credential) + { + setDn(dn); + setCredential(credential); + } + + + /** + * Creates a new bind request. + * + * @param dn to bind as + * @param credential to bind with + * @param config sasl configuration + */ + public BindRequest(final String dn, final Credential credential, final SaslConfig config) + { + setDn(dn); + setCredential(credential); + setSaslConfig(config); + } + + + /** + * Creates a new bind request. + * + * @param config sasl configuration + */ + public BindRequest(final SaslConfig config) + { + setSaslConfig(config); + } + + + /** + * Returns the bind DN. + * + * @return DN to bind as + */ + public String getDn() + { + return bindDn; + } + + + /** + * Sets the bind DN to authenticate as before performing operations. + * + * @param dn to bind as + */ + public void setDn(final String dn) + { + bindDn = dn; + } + + + /** + * Returns the credential used with the bind DN. + * + * @return bind DN credential + */ + public Credential getCredential() + { + return bindCredential; + } + + + /** + * Sets the credential of the bind DN. + * + * @param credential to use with bind DN + */ + public void setCredential(final Credential credential) + { + bindCredential = credential; + } + + + /** + * Returns the sasl config. + * + * @return sasl config + */ + public SaslConfig getSaslConfig() + { + return saslConfig; + } + + + /** + * Sets the sasl config. + * + * @param config sasl config + */ + public void setSaslConfig(final SaslConfig config) + { + saslConfig = config; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::bindDn=%s, saslConfig=%s, controls=%s, referralHandler=%s, " + + "intermediateResponseHandlers=%s]", + getClass().getName(), + hashCode(), + bindDn, + saslConfig, + Arrays.toString(getControls()), + getReferralHandler(), + Arrays.toString(getIntermediateResponseHandlers())); + } +}
diff --git a/core/src/main/java/org/ldaptive/CompareOperation.java b/core/src/main/java/org/ldaptive/CompareOperation.java new file mode 100644 index 0000000..168c304 --- /dev/null +++ b/core/src/main/java/org/ldaptive/CompareOperation.java
@@ -0,0 +1,30 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Executes an ldap compare operation. + * + * @author Middleware Services + */ +public class CompareOperation extends AbstractOperation<CompareRequest, Boolean> +{ + + + /** + * Creates a new compare operation. + * + * @param conn connection + */ + public CompareOperation(final Connection conn) + { + super(conn); + } + + + @Override + protected Response<Boolean> invoke(final CompareRequest request) + throws LdapException + { + return getConnection().getProviderConnection().compare(request); + } +}
diff --git a/core/src/main/java/org/ldaptive/CompareRequest.java b/core/src/main/java/org/ldaptive/CompareRequest.java new file mode 100644 index 0000000..adb6f34 --- /dev/null +++ b/core/src/main/java/org/ldaptive/CompareRequest.java
@@ -0,0 +1,98 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; + +/** + * Contains the data required to perform an ldap compare operation. + * + * @author Middleware Services + */ +public class CompareRequest extends AbstractRequest +{ + + /** DN to compare. */ + private String compareDn = ""; + + /** Attribute to compare. */ + private LdapAttribute attribute; + + + /** Default constructor. */ + public CompareRequest() {} + + + /** + * Creates a new compare request. + * + * @param dn containing the attribute to compare + * @param attr attribute to compare + */ + public CompareRequest(final String dn, final LdapAttribute attr) + { + setDn(dn); + setAttribute(attr); + } + + + /** + * Returns the DN to compare. + * + * @return DN + */ + public String getDn() + { + return compareDn; + } + + + /** + * Sets the DN to compare. + * + * @param dn to compare + */ + public void setDn(final String dn) + { + compareDn = dn; + } + + + /** + * Returns the attribute containing the value to compare. If this attribute contains multiple values, only the first + * value as return by the underlying collection is used. + * + * @return attribute to compare + */ + public LdapAttribute getAttribute() + { + return attribute; + } + + + /** + * Sets the attribute to compare. + * + * @param attr attribute to compare + */ + public void setAttribute(final LdapAttribute attr) + { + attribute = attr; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::compareDn=%s, attribute=%s, controls=%s, " + + "referralHandler=%s, intermediateResponseHandlers=%s]", + getClass().getName(), + hashCode(), + compareDn, + attribute != null ? "userPassword".equals(attribute.getName()) ? "<suppressed>" : attribute : null, + Arrays.toString(getControls()), + getReferralHandler(), + Arrays.toString(getIntermediateResponseHandlers())); + } +}
diff --git a/core/src/main/java/org/ldaptive/Connection.java b/core/src/main/java/org/ldaptive/Connection.java new file mode 100644 index 0000000..8bfa9d4 --- /dev/null +++ b/core/src/main/java/org/ldaptive/Connection.java
@@ -0,0 +1,106 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.ldaptive.control.RequestControl; +import org.ldaptive.provider.ProviderConnection; + +/** + * Interface for ldap connection implementations. + * + * @author Middleware Services + */ +public interface Connection extends AutoCloseable +{ + + + /** + * Returns the connection config for this connection. The config may be read-only. + * + * @return connection config + */ + ConnectionConfig getConnectionConfig(); + + + /** + * This will establish a connection to the LDAP. This connection should be closed using {@link #close()}. + * + * @return response associated with the {@link ConnectionInitializer} or an empty response if no connection + * initializer was configured + * + * @throws IllegalStateException if the connection is already open + * @throws LdapException if the LDAP cannot be reached + */ + Response<Void> open() + throws LdapException; + + + /** + * This will establish a connection to the LDAP using the supplied bind request. This connection should be closed + * using {@link #close()}. + * + * @param request containing bind information + * + * @return response associated with the bind operation + * + * @throws IllegalStateException if the connection is already open + * @throws LdapException if the LDAP cannot be reached + */ + Response<Void> open(BindRequest request) + throws LdapException; + + + /** + * Returns whether {@link #open(BindRequest)} was successfully invoked on this connection and {@link #close()} has not + * been invoked. This method does not indicate the viability of this connection for use. + * + * @return whether this connection is open + */ + boolean isOpen(); + + + /** + * Returns the provider connection to invoke the provider specific implementation. Must be called after a successful + * call to {@link #open()}. + * + * @return provider connection + */ + ProviderConnection getProviderConnection(); + + + /** This will close the connection to the LDAP. */ + void close(); + + + /** + * This will close the connection to the LDAP using the supplied controls. + * + * @param controls request controls + */ + void close(RequestControl[] controls); + + + /** + * This will close an existing connection to the LDAP and establish a new connection to the LDAP. + * + * @return response associated with the {@link ConnectionInitializer} or an empty response if no connection + * initializer was configured + * + * @throws LdapException if the LDAP cannot be reached + */ + Response<Void> reopen() + throws LdapException; + + + /** + * This will close an existing connection to the LDAP and establish a new connection to the LDAP using the supplied + * bind request. + * + * @param request containing bind information + * + * @return response associated with the bind operation + * + * @throws LdapException if the LDAP cannot be reached + */ + Response<Void> reopen(BindRequest request) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/ConnectionConfig.java b/core/src/main/java/org/ldaptive/ConnectionConfig.java new file mode 100644 index 0000000..e700399 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ConnectionConfig.java
@@ -0,0 +1,294 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.time.Duration; +import org.ldaptive.ssl.SslConfig; + +/** + * Contains all the configuration data needed to control connections. + * + * @author Middleware Services + */ +public class ConnectionConfig extends AbstractConfig +{ + + /** URL to the LDAP(s). */ + private String ldapUrl; + + /** Duration of time that connects will block. */ + private Duration connectTimeout; + + /** Duration of time to wait for responses. */ + private Duration responseTimeout; + + /** Configuration for SSL and startTLS connections. */ + private SslConfig sslConfig; + + /** Connect to LDAP using SSL protocol. */ + private boolean useSSL; + + /** Connect to LDAP using startTLS. */ + private boolean useStartTLS; + + /** Connection initializer to execute on {@link Connection#open()}. */ + private ConnectionInitializer connectionInitializer; + + /** Connection strategy. */ + private ConnectionStrategy connectionStrategy = new DefaultConnectionStrategy(); + + + /** Default constructor. */ + public ConnectionConfig() {} + + + /** + * Creates a new connection config. + * + * @param url to connect to + */ + public ConnectionConfig(final String url) + { + setLdapUrl(url); + } + + + /** + * Returns the ldap url. + * + * @return ldap url + */ + public String getLdapUrl() + { + return ldapUrl; + } + + + /** + * Sets the ldap url. + * + * @param url of the ldap + */ + public void setLdapUrl(final String url) + { + checkImmutable(); + checkStringInput(url, true); + logger.trace("setting ldapUrl: {}", url); + ldapUrl = url; + } + + + /** + * Returns the connect timeout. If this value is null, then the provider default will be used. + * + * @return timeout + */ + public Duration getConnectTimeout() + { + return connectTimeout; + } + + + /** + * Sets the maximum amount of time that connects will block. + * + * @param time timeout for connects + */ + public void setConnectTimeout(final Duration time) + { + checkImmutable(); + if (time != null && time.isNegative()) { + throw new IllegalArgumentException("Connect timeout cannot be negative"); + } + logger.trace("setting connectTimeout: {}", time); + connectTimeout = time; + } + + + /** + * Returns the response timeout. If this value is null, then the provider default will be used. + * + * @return timeout + */ + public Duration getResponseTimeout() + { + return responseTimeout; + } + + + /** + * Sets the maximum amount of time that operations will wait for a response. + * + * @param time timeout for responses + */ + public void setResponseTimeout(final Duration time) + { + checkImmutable(); + if (time != null && time.isNegative()) { + throw new IllegalArgumentException("Connect timeout cannot be negative"); + } + logger.trace("setting responseTimeout: {}", time); + responseTimeout = time; + } + + + /** + * Returns the ssl config. + * + * @return ssl config + */ + public SslConfig getSslConfig() + { + return sslConfig; + } + + + /** + * Sets the ssl config. + * + * @param config ssl config + */ + public void setSslConfig(final SslConfig config) + { + checkImmutable(); + logger.trace("setting sslConfig: {}", config); + sslConfig = config; + } + + + /** + * Returns whether the SSL protocol will be used for connections. + * + * @return whether the SSL protocol will be used + */ + public boolean getUseSSL() + { + return useSSL; + } + + + /** + * Sets whether the SSL protocol will be used for connections. + * + * @param b whether the SSL protocol will be used + */ + public void setUseSSL(final boolean b) + { + checkImmutable(); + logger.trace("setting useSSL: {}", b); + useSSL = b; + } + + + /** + * Returns whether startTLS will be used for connections. + * + * @return whether startTLS will be used + */ + public boolean getUseStartTLS() + { + return useStartTLS; + } + + + /** + * Sets whether startTLS will be used for connections. + * + * @param b whether startTLS will be used + */ + public void setUseStartTLS(final boolean b) + { + checkImmutable(); + logger.trace("setting useStartTLS: {}", b); + useStartTLS = b; + } + + + /** + * Returns the connection initializer. + * + * @return connection initializer + */ + public ConnectionInitializer getConnectionInitializer() + { + return connectionInitializer; + } + + + /** + * Sets the connection initializer. + * + * @param initializer connection initializer + */ + public void setConnectionInitializer(final ConnectionInitializer initializer) + { + checkImmutable(); + logger.trace("setting connectionInitializer: {}", initializer); + connectionInitializer = initializer; + } + + + /** + * Returns the connection strategy. + * + * @return strategy for making connections + */ + public ConnectionStrategy getConnectionStrategy() + { + return connectionStrategy; + } + + + /** + * Sets the connection strategy. + * + * @param strategy for making connections + */ + public void setConnectionStrategy(final ConnectionStrategy strategy) + { + checkImmutable(); + logger.trace("setting connectionStrategy: {}", strategy); + connectionStrategy = strategy; + } + + + /** + * Returns a connection config initialized with the supplied config. + * + * @param config connection config to read properties from + * + * @return connection config + */ + public static ConnectionConfig newConnectionConfig(final ConnectionConfig config) + { + final ConnectionConfig cc = new ConnectionConfig(); + cc.setLdapUrl(config.getLdapUrl()); + cc.setConnectTimeout(config.getConnectTimeout()); + cc.setResponseTimeout(config.getResponseTimeout()); + cc.setSslConfig(config.getSslConfig()); + cc.setUseSSL(config.getUseSSL()); + cc.setUseStartTLS(config.getUseStartTLS()); + cc.setConnectionInitializer(config.getConnectionInitializer()); + cc.setConnectionStrategy(config.getConnectionStrategy()); + return cc; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::ldapUrl=%s, connectTimeout=%s, responseTimeout=%s, " + + "sslConfig=%s, useSSL=%s, useStartTLS=%s, connectionInitializer=%s, connectionStrategy=%s]", + getClass().getName(), + hashCode(), + ldapUrl, + connectTimeout, + responseTimeout, + sslConfig, + useSSL, + useStartTLS, + connectionInitializer, + connectionStrategy); + } +}
diff --git a/core/src/main/java/org/ldaptive/ConnectionFactory.java b/core/src/main/java/org/ldaptive/ConnectionFactory.java new file mode 100644 index 0000000..5ee1cea --- /dev/null +++ b/core/src/main/java/org/ldaptive/ConnectionFactory.java
@@ -0,0 +1,22 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Factory for creating connections. + * + * @author Middleware Services + */ +public interface ConnectionFactory +{ + + + /** + * Creates a new connection. + * + * @return connection + * + * @throws LdapException if a connection cannot be returned + */ + Connection getConnection() + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/ConnectionFactoryManager.java b/core/src/main/java/org/ldaptive/ConnectionFactoryManager.java new file mode 100644 index 0000000..8de7d68 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ConnectionFactoryManager.java
@@ -0,0 +1,27 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Interface for objects that manage an instance of connection factory. + * + * @author Middleware Services + */ +public interface ConnectionFactoryManager +{ + + + /** + * Returns the connection factory. + * + * @return connection factory + */ + ConnectionFactory getConnectionFactory(); + + + /** + * Sets the connection factory. + * + * @param cf connection factory + */ + void setConnectionFactory(ConnectionFactory cf); +}
diff --git a/core/src/main/java/org/ldaptive/ConnectionFactoryMetadata.java b/core/src/main/java/org/ldaptive/ConnectionFactoryMetadata.java new file mode 100644 index 0000000..d492327 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ConnectionFactoryMetadata.java
@@ -0,0 +1,27 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Interface to describe the state of the connection factory. Used by {@link ConnectionStrategy} to produce LDAP URLs. + * + * @author Middleware Services + */ +public interface ConnectionFactoryMetadata +{ + + + /** + * Returns the LDAP URL the provider connection factory is using. May be space delimited for multiple URLs. + * + * @return ldap url + */ + String getLdapUrl(); + + + /** + * Returns the number of times the provider connection factory has created a connection. + * + * @return connection count + */ + int getConnectionCount(); +}
diff --git a/core/src/main/java/org/ldaptive/ConnectionInitializer.java b/core/src/main/java/org/ldaptive/ConnectionInitializer.java new file mode 100644 index 0000000..bed8337 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ConnectionInitializer.java
@@ -0,0 +1,24 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Provides an interface for initializing connections after they are opened. + * + * @author Middleware Services + */ +public interface ConnectionInitializer +{ + + + /** + * Initialize the supplied connection. + * + * @param conn connection to initialize + * + * @return response associated with the initialization or an empty response + * + * @throws LdapException if initialization fails + */ + Response<Void> initialize(Connection conn) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/ConnectionStrategy.java b/core/src/main/java/org/ldaptive/ConnectionStrategy.java new file mode 100644 index 0000000..0c88640 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ConnectionStrategy.java
@@ -0,0 +1,22 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Interface to describe various connection strategies. Each strategy returns an ordered list of URLs to attempt when + * opening a connection. + * + * @author Middleware Services + */ +public interface ConnectionStrategy +{ + + + /** + * Returns an ordered list of URLs to attempt to open. + * + * @param metadata which can be used to produce the URL list + * + * @return array of ldap URLs + */ + String[] getLdapUrls(ConnectionFactoryMetadata metadata); +}
diff --git a/core/src/main/java/org/ldaptive/Credential.java b/core/src/main/java/org/ldaptive/Credential.java new file mode 100644 index 0000000..e07a585 --- /dev/null +++ b/core/src/main/java/org/ldaptive/Credential.java
@@ -0,0 +1,93 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.nio.charset.StandardCharsets; + +/** + * Provides convenience methods for converting the various types of passwords into a byte array. + * + * @author Middleware Services + */ +public class Credential +{ + + /** Credential stored as a byte array. */ + private final byte[] bytes; + + + /** + * Creates a new credential. + * + * @param password converted from UTF-8 to a byte array + */ + public Credential(final String password) + { + bytes = password.getBytes(StandardCharsets.UTF_8); + } + + + /** + * Creates a new credential. + * + * @param password converted from UTF-8 to a byte array + */ + public Credential(final char[] password) + { + bytes = new String(password).getBytes(StandardCharsets.UTF_8); + } + + + /** + * Creates a new credential. + * + * @param password to store + */ + public Credential(final byte[] password) + { + bytes = password; + } + + + /** + * Returns this credential as a byte array. + * + * @return credential bytes + */ + public byte[] getBytes() + { + return bytes; + } + + + /** + * Returns this credential as a string. + * + * @return credential string + */ + public String getString() + { + return new String(bytes, StandardCharsets.UTF_8); + } + + + /** + * Returns this credential as a character array. + * + * @return credential characters + */ + public char[] getChars() + { + return getString().toCharArray(); + } + + + @Override + public String toString() + { + return String.format( + "[%s@%d::bytes=%s]", + getClass().getName(), + hashCode(), + new String(bytes, StandardCharsets.UTF_8)); + } +}
diff --git a/core/src/main/java/org/ldaptive/DefaultConnectionFactory.java b/core/src/main/java/org/ldaptive/DefaultConnectionFactory.java new file mode 100644 index 0000000..1f459ee --- /dev/null +++ b/core/src/main/java/org/ldaptive/DefaultConnectionFactory.java
@@ -0,0 +1,409 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.ldaptive.control.RequestControl; +import org.ldaptive.provider.Provider; +import org.ldaptive.provider.ProviderConnection; +import org.ldaptive.provider.ProviderConnectionFactory; +import org.ldaptive.provider.jndi.JndiProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Creates connections for performing ldap operations. + * + * @author Middleware Services + */ +public class DefaultConnectionFactory implements ConnectionFactory +{ + + /** Ldap provider class name. */ + public static final String PROVIDER = "org.ldaptive.provider"; + + /** Static reference to the default ldap provider. */ + protected static final Provider<?> DEFAULT_PROVIDER = getDefaultProvider(); + + /** Provider used by this factory. */ + private Provider<?> provider = DEFAULT_PROVIDER.newInstance(); + + /** Connection configuration used by this factory. */ + private ConnectionConfig config; + + + /** Default constructor. */ + public DefaultConnectionFactory() {} + + + /** + * Creates a new default connection factory. + * + * @param ldapUrl to connect to + */ + public DefaultConnectionFactory(final String ldapUrl) + { + setConnectionConfig(new ConnectionConfig(ldapUrl)); + } + + + /** + * Creates a new default connection factory. + * + * @param cc connection configuration + */ + public DefaultConnectionFactory(final ConnectionConfig cc) + { + setConnectionConfig(cc); + } + + + /** + * Creates a new default connection factory. + * + * @param cc connection configuration + * @param p provider + */ + public DefaultConnectionFactory(final ConnectionConfig cc, final Provider<?> p) + { + setConnectionConfig(cc); + setProvider(p); + } + + + /** + * Returns the connection config. + * + * @return connection config + */ + public ConnectionConfig getConnectionConfig() + { + return config; + } + + + /** + * Sets the connection config. Once invoked the supplied connection config is made immutable. See {@link + * ConnectionConfig#makeImmutable()}. + * + * @param cc connection config + */ + public void setConnectionConfig(final ConnectionConfig cc) + { + config = cc; + config.makeImmutable(); + } + + + /** + * Returns the ldap provider. + * + * @return ldap provider + */ + public Provider<?> getProvider() + { + return provider; + } + + + /** + * Sets the ldap provider. + * + * @param p ldap provider to set + */ + public void setProvider(final Provider<?> p) + { + provider = p; + } + + + /** + * Creates a new connection. Connections returned from this method must be opened before they can perform ldap + * operations. + * + * @return connection + */ + @Override + public Connection getConnection() + { + return new DefaultConnection(config, provider.getConnectionFactory(config)); + } + + + /** + * Creates a new connection. Connections returned from this method must be opened before they can be used. + * + * @param ldapUrl to connect to + * + * @return connection + */ + public static Connection getConnection(final String ldapUrl) + { + final Provider<?> p = DEFAULT_PROVIDER.newInstance(); + final ConnectionConfig cc = new ConnectionConfig(ldapUrl); + cc.makeImmutable(); + return new DefaultConnection(cc, p.getConnectionFactory(cc)); + } + + + /** + * Creates a new connection. Connections returned from this method must be opened before they can be used. + * + * @param cc connection configuration + * + * @return connection + */ + public static Connection getConnection(final ConnectionConfig cc) + { + final Provider<?> p = DEFAULT_PROVIDER.newInstance(); + cc.makeImmutable(); + return new DefaultConnection(cc, p.getConnectionFactory(cc)); + } + + + /** + * The {@link #PROVIDER} property is checked and that class is loaded if provided. Otherwise the JNDI provider is + * returned. + * + * @return default provider + */ + public static Provider<?> getDefaultProvider() + { + Provider<?> p; + final String providerClass = System.getProperty(PROVIDER); + if (providerClass != null) { + final Logger l = LoggerFactory.getLogger(DefaultConnectionFactory.class); + try { + l.info("Setting ldap provider to {}", providerClass); + p = (Provider<?>) Class.forName(providerClass).newInstance(); + } catch (Exception e) { + l.error("Error instantiating {}", providerClass, e); + throw new IllegalStateException(e); + } + } else { + // set the default ldap provider to JNDI + p = new JndiProvider(); + } + return p; + } + + + @Override + public String toString() + { + return String.format("[%s@%d::provider=%s, config=%s]", getClass().getName(), hashCode(), provider, config); + } + + + /** Default implementation for managing a connection to an LDAP. */ + protected static class DefaultConnection implements Connection + { + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Connection configuration. */ + private final ConnectionConfig config; + + /** Connection factory. */ + private final ProviderConnectionFactory<?> providerConnectionFactory; + + /** Provider connection. */ + private ProviderConnection providerConnection; + + + /** + * Creates a new default connection. + * + * @param cc connection configuration + * @param cf provider connection factory + */ + public DefaultConnection(final ConnectionConfig cc, final ProviderConnectionFactory<?> cf) + { + config = cc; + providerConnectionFactory = cf; + } + + + @Override + public ConnectionConfig getConnectionConfig() + { + return config; + } + + + /** + * Returns the provider specific connection. Must be called after a successful call to {@link #open()}. + * + * @return provider connection + * + * @throws IllegalStateException if the connection is not open + */ + @Override + public ProviderConnection getProviderConnection() + { + if (!isOpen()) { + throw new IllegalStateException("Connection is not open"); + } + return providerConnection; + } + + + /** + * This will establish a connection if one does not already exist. This connection should be closed using {@link + * #close()}. + * + * @return response associated with the {@link ConnectionInitializer} or an empty response if no connection + * initializer was configured + * + * @throws IllegalStateException if the connection is already open + * @throws LdapException if the LDAP cannot be reached + */ + @Override + public synchronized Response<Void> open() + throws LdapException + { + if (isOpen()) { + throw new IllegalStateException("Connection already open"); + } + providerConnection = providerConnectionFactory.create(); + if (config.getConnectionInitializer() != null) { + return config.getConnectionInitializer().initialize(this); + } else { + return new Response<>(null, null); + } + } + + + /** + * This will establish a connection if one does not already exist and bind to the LDAP using the supplied bind + * request. This connection should be closed using {@link #close()}. + * + * @param request bind request + * + * @return response associated with the bind operation + * + * @throws IllegalStateException if the connection is already open + * @throws LdapException if the LDAP cannot be reached + */ + @Override + public synchronized Response<Void> open(final BindRequest request) + throws LdapException + { + if (isOpen()) { + throw new IllegalStateException("Connection already open"); + } + providerConnection = providerConnectionFactory.create(); + return providerConnection.bind(request); + } + + + /** + * Returns whether the underlying provider connection is not null. + * + * @return whether the provider connection has been initialized + */ + @Override + public boolean isOpen() + { + return providerConnection != null; + } + + + @Override + public synchronized void close() + { + try { + if (isOpen()) { + providerConnection.close(null); + } + } catch (LdapException e) { + logger.warn("Error closing connection with the LDAP", e); + } finally { + providerConnection = null; + } + } + + + @Override + public synchronized void close(final RequestControl[] controls) + { + try { + if (isOpen()) { + providerConnection.close(controls); + } + } catch (LdapException e) { + logger.warn("Error closing connection with the LDAP", e); + } finally { + providerConnection = null; + } + } + + + @Override + public synchronized Response<Void> reopen() + throws LdapException + { + try { + if (providerConnection != null) { + providerConnection.close(null); + } + } catch (LdapException e) { + logger.warn("Error closing connection with the LDAP", e); + } finally { + providerConnection = null; + } + + providerConnection = providerConnectionFactory.create(); + if (config.getConnectionInitializer() != null) { + return config.getConnectionInitializer().initialize(this); + } else { + return new Response<>(null, null); + } + } + + + @Override + public synchronized Response<Void> reopen(final BindRequest request) + throws LdapException + { + try { + if (providerConnection != null) { + providerConnection.close(null); + } + } catch (LdapException e) { + logger.warn("Error closing connection with the LDAP", e); + } finally { + providerConnection = null; + } + + providerConnection = providerConnectionFactory.create(); + return providerConnection.bind(request); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::config=%s, providerConnectionFactory=%s, " + + "providerConnection=%s]", + getClass().getName(), + hashCode(), + config, + providerConnectionFactory, + providerConnection); + } + + + @Override + protected void finalize() + throws Throwable + { + try { + close(); + } finally { + super.finalize(); + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/DefaultConnectionStrategy.java b/core/src/main/java/org/ldaptive/DefaultConnectionStrategy.java new file mode 100644 index 0000000..b2445e9 --- /dev/null +++ b/core/src/main/java/org/ldaptive/DefaultConnectionStrategy.java
@@ -0,0 +1,28 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Connection strategy that returns the exact URL that is returned from {@link ConnectionFactoryMetadata#getLdapUrl()}. + * + * @author Middleware Services + */ +public class DefaultConnectionStrategy implements ConnectionStrategy +{ + + + /** + * Returns an array containing a single entry URL obtained from {@link ConnectionFactoryMetadata#getLdapUrl()}. + * + * @param metadata which can be used to produce the URL list + * + * @return list of URLs to attempt connections to + */ + @Override + public String[] getLdapUrls(final ConnectionFactoryMetadata metadata) + { + if (metadata == null || metadata.getLdapUrl() == null) { + return null; + } + return new String[] {metadata.getLdapUrl()}; + } +}
diff --git a/core/src/main/java/org/ldaptive/DeleteOperation.java b/core/src/main/java/org/ldaptive/DeleteOperation.java new file mode 100644 index 0000000..a75397c --- /dev/null +++ b/core/src/main/java/org/ldaptive/DeleteOperation.java
@@ -0,0 +1,30 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Executes an ldap delete operation. + * + * @author Middleware Services + */ +public class DeleteOperation extends AbstractOperation<DeleteRequest, Void> +{ + + + /** + * Creates a new delete operation. + * + * @param conn connection + */ + public DeleteOperation(final Connection conn) + { + super(conn); + } + + + @Override + protected Response<Void> invoke(final DeleteRequest request) + throws LdapException + { + return getConnection().getProviderConnection().delete(request); + } +}
diff --git a/core/src/main/java/org/ldaptive/DeleteRequest.java b/core/src/main/java/org/ldaptive/DeleteRequest.java new file mode 100644 index 0000000..611b547 --- /dev/null +++ b/core/src/main/java/org/ldaptive/DeleteRequest.java
@@ -0,0 +1,69 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; + +/** + * Contains the data required to perform an ldap delete operation. + * + * @author Middleware Services + */ +public class DeleteRequest extends AbstractRequest +{ + + /** DN to delete. */ + private String deleteDn; + + + /** Default constructor. */ + public DeleteRequest() {} + + + /** + * Creates a new delete request. + * + * @param dn to delete + */ + public DeleteRequest(final String dn) + { + setDn(dn); + } + + + /** + * Returns the DN to delete. + * + * @return DN + */ + public String getDn() + { + return deleteDn; + } + + + /** + * Sets the DN to delete. + * + * @param dn to delete + */ + public void setDn(final String dn) + { + deleteDn = dn; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::deleteDn=%s, controls=%s, referralHandler=%s, " + + "intermediateResponseHandlers=%s]", + getClass().getName(), + hashCode(), + deleteDn, + Arrays.toString(getControls()), + getReferralHandler(), + Arrays.toString(getIntermediateResponseHandlers())); + } +}
diff --git a/core/src/main/java/org/ldaptive/DerefAliases.java b/core/src/main/java/org/ldaptive/DerefAliases.java new file mode 100644 index 0000000..f5122d4 --- /dev/null +++ b/core/src/main/java/org/ldaptive/DerefAliases.java
@@ -0,0 +1,26 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Enum to define how aliases are dereferenced. + * + * @author Middleware Services + */ +public enum DerefAliases { + + /** never dereference aliases. */ + NEVER, + + /** + * dereference when searching the entries beneath the starting point but not when searching for the starting entry. + */ + SEARCHING, + + /** + * dereference when searching for the starting entry but not when searching the entries beneath the starting point. + */ + FINDING, + + /** dereference when searching for the starting entry and when searching the entries beneath the starting point. */ + ALWAYS +}
diff --git a/core/src/main/java/org/ldaptive/DnParser.java b/core/src/main/java/org/ldaptive/DnParser.java new file mode 100644 index 0000000..9859081 --- /dev/null +++ b/core/src/main/java/org/ldaptive/DnParser.java
@@ -0,0 +1,338 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import org.ldaptive.asn1.DERParser; +import org.ldaptive.asn1.OctetStringType; +import org.ldaptive.asn1.ParseHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Parses DNs following the rules in <a href="http://www.ietf.org/rfc/rfc4514.txt">RFC 4514</a>. Attempts to be as + * generous as possible in the format of allowed DNs. + * + * @author Middleware Services + */ +public final class DnParser +{ + + /** Logger for this class. */ + private static final Logger LOGGER = LoggerFactory.getLogger(DnParser.class); + + /** Hexadecimal radix. */ + private static final int HEX_RADIX = 16; + + + /** Default constructor. */ + private DnParser() {} + + + /** + * Returns the RDN values for the attribute type with the supplied name. + * + * @param dn to parse + * @param name of the attribute type to return values for + * + * @return DN attribute values + */ + public static Collection<String> getValues(final String dn, final String name) + { + final Collection<String> values = new ArrayList<>(); + convertDnToAttributes(dn).stream().filter( + la -> la.getName().equalsIgnoreCase(name)).forEach(la -> values.addAll(la.getStringValues())); + return values; + } + + + /** + * Returns the RDN value for the attribute type with the supplied name. If the component has multiple values, the + * first one is returned. + * + * @param dn to parse + * @param name of the attribute to return value for + * + * @return DN attribute value + */ + public static String getValue(final String dn, final String name) + { + final Collection<String> values = getValues(dn, name); + if (values.isEmpty()) { + return ""; + } + return values.iterator().next(); + } + + + /** + * Returns a string representation of the supplied DN beginning at the supplied index. The leftmost RDN component + * begins at index 0. + * + * @param dn to parse + * @param beginIndex index of first RDN to include in the result in the range [0, N-1] where N is the number of + * elements in the DN + * + * @return DN from the supplied beginIndex + * + * @throws IndexOutOfBoundsException if beginIndex is less than 0 or greater than the number of RDNs + */ + public static String substring(final String dn, final int beginIndex) + { + if (beginIndex < 0) { + throw new IndexOutOfBoundsException("beginIndex cannot be negative"); + } + + final List<LdapAttribute> attrs = convertDnToAttributes(dn); + if (beginIndex >= attrs.size()) { + throw new IndexOutOfBoundsException("beginIndex cannot be larger than the number of RDNs"); + } + + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < attrs.size(); i++) { + if (i >= beginIndex) { + final LdapAttribute la = attrs.get(i); + sb.append(la.getName()).append("=").append(la.getStringValue()).append(","); + } + } + if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ',') { + sb.deleteCharAt(sb.length() - 1); + } + return sb.toString(); + } + + + /** + * Returns a string representation of the supplied DN beginning at beginIndex (inclusive) and ending at endIndex + * (exclusive). The leftmost RDN component begins at index 0. Where n is the number of RDNs, both beginIndex and + * endIndex are on the range [0, N-1]. + * + * @param dn to parse + * @param beginIndex index of first RDN to include in the result in the range [0, N-2] where N is the number of + * elements in the DN + * @param endIndex index of last RDN to include in the result in the range [1, N-1] where N is the number of + * elements in the RDN + * + * @return DN from beginIndex (inclusive) to endIndex (exclusive) + * + * @throws IndexOutOfBoundsException if beginIndex is less than 0, if beginIndex is greater than endIndex, or + * endIndex is greater than the number of RDNs + */ + public static String substring(final String dn, final int beginIndex, final int endIndex) + { + if (beginIndex < 0) { + throw new IndexOutOfBoundsException("beginIndex cannot be negative"); + } + if (beginIndex > endIndex) { + throw new IndexOutOfBoundsException("beginIndex cannot be larger than endIndex"); + } + + final List<LdapAttribute> attrs = convertDnToAttributes(dn); + if (endIndex > attrs.size()) { + throw new IndexOutOfBoundsException("endIndex cannot be larger than the number of RDNs"); + } + + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < attrs.size(); i++) { + if (i >= beginIndex && i < endIndex) { + final LdapAttribute la = attrs.get(i); + sb.append(la.getName()).append("=").append(la.getStringValue()).append(","); + } + } + if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ',') { + sb.deleteCharAt(sb.length() - 1); + } + return sb.toString(); + } + + + /** + * Parses the supplied DN and converts each RDN into a {@link LdapAttribute}. + * + * @param dn to parse + * + * @return list of ldap attributes for each RDN + */ + public static List<LdapAttribute> convertDnToAttributes(final String dn) + { + LOGGER.debug("parsing DN: {}", dn); + + final List<LdapAttribute> attributes = new ArrayList<>(); + if (dn.isEmpty()) { + return attributes; + } + + int pos = 0; + while (pos < dn.length()) { + final int endAttrNamePos = readToChar(dn, new char[] {'='}, pos); + final String attrName = dn.substring(pos, endAttrNamePos); + LOGGER.trace("read attribute name: [{}]", attrName); + pos = endAttrNamePos; + // error if char isn't an '=' + if (pos >= dn.length() || dn.charAt(pos++) != '=') { + throw new IllegalArgumentException("Invalid DN: " + dn); + } + + final int endAttrValuePos = readToChar(dn, new char[] {'+', ','}, pos); + String attrValue = dn.substring(pos, endAttrValuePos); + LOGGER.trace("read attribute value: [{}]", attrValue); + attrValue = attrValue.trim(); + // error if attribute value is empty + if (attrValue.isEmpty()) { + throw new IllegalArgumentException("Invalid DN: " + dn); + } + if (attrValue.startsWith("#")) { + final DERParser parser = new DERParser(); + final OctetStringHandler handler = new OctetStringHandler(); + parser.registerHandler("/OCTSTR", handler); + + final String hexData = attrValue.substring(1, attrValue.length()); + parser.parse(ByteBuffer.wrap(decodeHexValue(hexData.toCharArray()))); + attributes.add(new LdapAttribute(attrName.trim(), handler.getDecodedValue())); + } else { + attributes.add(new LdapAttribute(attrName.trim(), decodeStringValue(attrValue))); + } + pos = endAttrValuePos + 1; + } + LOGGER.debug("parsed DN into: {}", attributes); + return attributes; + } + + + /** + * Decodes the supplied hexadecimal value. + * + * @param value hex to decode + * + * @return decoded bytes + */ + protected static byte[] decodeHexValue(final char[] value) + { + if (value == null || value.length == 0) { + throw new IllegalArgumentException("Invalid HEX value: value cannot be null or empty"); + } + return LdapUtils.hexDecode(value); + } + + + /** + * Decodes the supplied string attribute value. Unescapes escaped characters. If escaped character is a hex value, it + * is decoded. + * + * @param value to decode + * + * @return decoded string + */ + protected static String decodeStringValue(final String value) + { + final StringBuilder sb = new StringBuilder(); + int pos = 0; + final StringBuilder hexValue = new StringBuilder(); + while (pos < value.length()) { + char c = value.charAt(pos); + boolean appendHex = false; + boolean appendValue = false; + switch (c) { + + case '\\': + if (pos + 1 < value.length()) { + c = value.charAt(++pos); + // if hexadecimal character add to buffer to decode later + if (Character.digit(c, HEX_RADIX) != -1) { + if (pos + 1 < value.length()) { + hexValue.append(c).append(value.charAt(++pos)); + if (pos + 1 == value.length()) { + appendHex = true; + } + } else { + throw new IllegalArgumentException("Invalid HEX value: " + c); + } + } else { + appendHex = hexValue.length() > 0; + appendValue = true; + } + } + break; + + default: + appendHex = hexValue.length() > 0; + appendValue = true; + break; + } + if (appendHex) { + sb.append(LdapUtils.utf8Encode(decodeHexValue(hexValue.toString().toCharArray()))); + hexValue.setLength(0); + } + if (appendValue) { + sb.append(c); + } + + pos++; + } + return sb.toString(); + } + + + /** + * Reads the supplied string starting at the supplied position until one of the supplied characters is found. + * Characters escaped with '\' are ignored. + * + * @param s to read + * @param chars to match + * @param pos to start reading at + * + * @return string index that matched a character or the last index in the string + */ + private static int readToChar(final String s, final char[] chars, final int pos) + { + int i = pos; + while (i < s.length()) { + boolean match = false; + final char sChar = s.charAt(i); + // ignore escaped characters + if (sChar == '\\' && i + 1 < s.length()) { + i++; + } else { + for (char c : chars) { + if (c == s.charAt(i)) { + match = true; + } + } + if (match) { + break; + } + } + i++; + } + return i; + } + + + /** Parse handler for decoding octet strings. */ + private static class OctetStringHandler implements ParseHandler + { + + /** Decoded octet string. */ + private String decoded; + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + decoded = OctetStringType.decode(encoded); + } + + + /** + * Returns the decoded octet string value. + * + * @return decoded octet string + */ + public String getDecodedValue() + { + return decoded; + } + } +}
diff --git a/core/src/main/java/org/ldaptive/DnsSrvConnectionStrategy.java b/core/src/main/java/org/ldaptive/DnsSrvConnectionStrategy.java new file mode 100644 index 0000000..02c1316 --- /dev/null +++ b/core/src/main/java/org/ldaptive/DnsSrvConnectionStrategy.java
@@ -0,0 +1,449 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.concurrent.ThreadLocalRandom; +import javax.naming.Context; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * DNS SRV connection strategy. Queries a DNS server for SRV records and uses those records to construct a list of URLs. + * A time to live can be set to control how often the DNS server is consulted. See http://www.ietf.org/rfc/rfc2782.txt. + * + * @author Middleware Services + */ +public class DnsSrvConnectionStrategy implements ConnectionStrategy +{ + + /** JNDI context factory for DNS. */ + private static final String DNS_CONTEXT_FACTORY = "com.sun.jndi.dns.DnsContextFactory"; + + /** JNDI context factory for DNS. */ + private static final String DNS_PROVIDER_URL = "dns:"; + + /** Default time to live for DNS results. Value is {@value}. */ + private static final long DEFAULT_TTL = 60L * 60L * 1000L; + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** JNDI environment. */ + private Map<String, Object> jndiEnv = new HashMap<>(); + + /** Time to live for SRV records in milliseconds. */ + private long srvTtl; + + /** SRV records from the last DNS lookup. */ + private List<SrvRecord> srvRecords; + + + /** Creates a new DNS SRV connection strategy. */ + public DnsSrvConnectionStrategy() + { + this(null, DEFAULT_TTL); + } + + + /** + * Creates a new DNS SRV connection strategy. + * + * @param ttl time to live in milliseconds for SRV records + */ + public DnsSrvConnectionStrategy(final long ttl) + { + this(null, ttl); + } + + + /** + * Creates a new DNS SRV connection strategy. + * + * @param env JNDI environment + * @param ttl time to live in milliseconds for SRV records + */ + public DnsSrvConnectionStrategy(final Map<String, Object> env, final long ttl) + { + if (env != null) { + setJndiEnvironment(env); + } + setTimeToLive(ttl); + } + + + /** + * Returns the JNDI environment used for DNS lookup. + * + * @return jndi environment + */ + public Map<String, Object> getJndiEnvironment() + { + return jndiEnv; + } + + + /** + * Returns the time that DNS lookups will be cached. + * + * @return time to live in milliseconds + */ + public long getTimeToLive() + { + return srvTtl; + } + + + /** + * Sets the JNDI environment used for DNS lookups. If no {@link Context#INITIAL_CONTEXT_FACTORY} is set, it is + * defaulted to {@link #DNS_CONTEXT_FACTORY}. If no {@link Context#PROVIDER_URL} is set, it is defaulted to {@link + * #DNS_PROVIDER_URL}. + * + * @param env jndi environment or null + */ + public void setJndiEnvironment(final Map<String, Object> env) + { + jndiEnv = new HashMap<>(env); + } + + + /** + * Sets the time that DNS lookups will be cached. + * + * @param ttl time to live in milliseconds + */ + public void setTimeToLive(final long ttl) + { + srvTtl = ttl; + } + + + /** + * Returns a list of URLs retrieved from DNS SRV records. The LDAP URL in the supplied metadata can be a space + * delimited list of DNS servers, each will be tried in order. + * + * @param metadata which can be used to produce the URL list + * + * @return list of URLs to attempt connections to + */ + @Override + public String[] getLdapUrls(final ConnectionFactoryMetadata metadata) + { + if (metadata == null || metadata.getLdapUrl() == null) { + return null; + } + if (srvRecords == null || + srvRecords.isEmpty() || + System.currentTimeMillis() >= srvRecords.get(0).getExpirationTime()) { + try { + srvRecords = sortSrvRecords(retrieveDNSRecords(metadata.getLdapUrl(), jndiEnv, srvTtl)); + } catch (NamingException e) { + throw new IllegalArgumentException("Could not retrieve DNS SRV record for " + metadata.getLdapUrl(), e); + } + if (srvRecords.isEmpty()) { + throw new IllegalArgumentException("No DNS SRV records found for " + metadata.getLdapUrl()); + } + logger.debug("Retrieved SRV records from DNS: {}", srvRecords); + } else { + logger.debug("Using SRV records from internal cache: {}", srvRecords); + } + + final String[] urls = new String[srvRecords.size()]; + for (int i = 0; i < srvRecords.size(); i++) { + urls[i] = srvRecords.get(i).getLdapURL(); + } + return urls; + } + + + /** + * Uses JNDI to retrieve the DNS SRV record from the supplied url. The supplied properties are passed into the JNDI + * context. + * + * @param name of the SRV records + * @param props for the JNDI context + * @param ttl time to live for each SRV record + * + * @return list of LDAP URLs + * + * @throws NamingException if the DNS record cannot be retrieved + */ + protected List<SrvRecord> retrieveDNSRecords(final String name, final Map<String, Object> props, final long ttl) + throws NamingException + { + final List<SrvRecord> records = new ArrayList<>(); + DirContext context = null; + NamingEnumeration<?> en = null; + try { + // CheckStyle:IllegalType OFF + final Hashtable<String, Object> env = new Hashtable<>(props); + // CheckStyle:IllegalType ON + if (!env.containsKey(Context.INITIAL_CONTEXT_FACTORY)) { + env.put(Context.INITIAL_CONTEXT_FACTORY, DNS_CONTEXT_FACTORY); + } + if (!env.containsKey(Context.PROVIDER_URL)) { + env.put(Context.PROVIDER_URL, DNS_PROVIDER_URL); + } + context = new InitialDirContext(env); + + final Attributes attrs = context.getAttributes(name, new String[] {"SRV", }); + if (attrs != null) { + final Attribute attr = attrs.get("SRV"); + if (attr != null) { + en = attr.getAll(); + + final long expTime = System.currentTimeMillis() + ttl; + while (en.hasMore()) { + records.add(new SrvRecord((String) en.next(), expTime)); + } + } + } + } finally { + if (en != null) { + en.close(); + } + if (context != null) { + context.close(); + } + } + return records; + } + + + /** + * Sorts the supplied SRV records according to RFC 2782. Records with the lowest priority are first. Records with the + * same priority are arranged by weight with higher weights having a greater chance to be ordered first. + * + * @param records to sort + * + * @return sorted records + */ + protected List<SrvRecord> sortSrvRecords(final List<SrvRecord> records) + { + // group records and order them by priority + final Map<Long, List<SrvRecord>> priorityRecords = new TreeMap<>(); + for (SrvRecord record : records) { + final List<SrvRecord> priority; + if (!priorityRecords.containsKey(record.getPriority())) { + priority = new ArrayList<>(); + priorityRecords.put(record.getPriority(), priority); + } else { + priority = priorityRecords.get(record.getPriority()); + } + priority.add(record); + } + + // order records by priority then by weight + // unweighted records are ordered last + final List<SrvRecord> sortedRecords = new ArrayList<>(); + for (Map.Entry<Long, List<SrvRecord>> entry : priorityRecords.entrySet()) { + final Map<Long, SrvRecord> weighted = new HashMap<>(); + final List<SrvRecord> unweighted = new ArrayList<>(); + long totalWeight = 0; + for (SrvRecord record : entry.getValue()) { + if (record.getWeight() == 0) { + unweighted.add(record); + } else { + totalWeight += record.getWeight(); + weighted.put(totalWeight, record); + } + } + + while (!weighted.isEmpty()) { + SrvRecord record = null; + final Iterator<Long> i = weighted.keySet().iterator(); + final long random = ThreadLocalRandom.current().nextLong(totalWeight + 1); + while (i.hasNext()) { + final Long weight = i.next(); + if (weight >= random) { + record = weighted.get(weight); + totalWeight -= record.getWeight(); + i.remove(); + break; + } + } + sortedRecords.add(record); + } + if (!unweighted.isEmpty()) { + sortedRecords.addAll(unweighted); + } + } + + return sortedRecords; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::jndiEnv=%s, srvTtl=%s, srvRecords=%s]", + getClass().getName(), + hashCode(), + jndiEnv, + srvTtl, + srvRecords); + } + + + /** SRV record. */ + protected static class SrvRecord + { + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1201; + + /** SRV priority. */ + private final long priority; + + /** SRV weight. */ + private final long weight; + + /** SRV port. */ + private final int port; + + /** SRV target. */ + private final String target; + + /** expiration time. */ + private final long expirationTime; + + + /** + * Creates a new SRV record. + * + * @param record from DNS + * @param time that this record should expire + */ + public SrvRecord(final String record, final long time) + { + final String[] parts = record.split(" "); + int i = 0; + priority = Long.parseLong(parts[i++]); + weight = Long.parseLong(parts[i++]); + port = Integer.parseInt(parts[i++]); + target = parts[i].endsWith(".") ? parts[i].substring(0, parts[i].length() - 1) : parts[i]; + expirationTime = time; + } + + + /** + * Returns the priority. + * + * @return priority + */ + public long getPriority() + { + return priority; + } + + + /** + * Returns the weight. + * + * @return weight + */ + public long getWeight() + { + return weight; + } + + + /** + * Returns the port. + * + * @return port + */ + public int getPort() + { + return port; + } + + + /** + * Returns the target. + * + * @return target + */ + public String getTarget() + { + return target; + } + + + /** + * Returns the target properly formatted as an LDAP URL. + * + * @return LDAP URL + */ + public String getLdapURL() + { + return String.format("ldap://%s:%s", target, port); + } + + + /** + * Returns the time in milliseconds that this record should expire. + * + * @return expiration time + */ + public long getExpirationTime() + { + return expirationTime; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof SrvRecord) { + final SrvRecord v = (SrvRecord) o; + return LdapUtils.areEqual(priority, v.priority) && + LdapUtils.areEqual(weight, v.weight) && + LdapUtils.areEqual(port, v.port) && + LdapUtils.areEqual(target, v.target) && + LdapUtils.areEqual(expirationTime, v.expirationTime); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, priority, weight, port, target, expirationTime); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::priority=%s, weight=%s, port=%s, target=%s, " + + "expirationTime=%s]", + getClass().getName(), + hashCode(), + priority, + weight, + port, + target, + expirationTime); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/LdapAttribute.java b/core/src/main/java/org/ldaptive/LdapAttribute.java new file mode 100644 index 0000000..08124f4 --- /dev/null +++ b/core/src/main/java/org/ldaptive/LdapAttribute.java
@@ -0,0 +1,853 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.io.Serializable; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.TreeSet; +import java.util.stream.Collectors; +import org.ldaptive.io.ValueTranscoder; + +/** + * Simple bean representing an ldap attribute. Contains a name and a collection of values. + * + * @author Middleware Services + */ +public class LdapAttribute extends AbstractLdapBean +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 313; + + /** serial version uid. */ + private static final long serialVersionUID = -3902233717232754155L; + + /** Name for this attribute. */ + private String attributeName; + + /** Values for this attribute. */ + private final LdapAttributeValues<?> attributeValues; + + + /** Default constructor. */ + public LdapAttribute() + { + this(SortBehavior.getDefaultSortBehavior(), false); + } + + + /** + * Creates a new ldap attribute. + * + * @param sb sort behavior of this attribute + */ + public LdapAttribute(final SortBehavior sb) + { + this(sb, false); + } + + + /** + * Creates a new ldap attribute. + * + * @param binary whether this attribute contains binary values + */ + public LdapAttribute(final boolean binary) + { + this(SortBehavior.getDefaultSortBehavior(), binary); + } + + + /** + * Creates a new ldap attribute. + * + * @param sb sort behavior of this attribute + * @param binary whether this attribute contains binary values + */ + public LdapAttribute(final SortBehavior sb, final boolean binary) + { + super(sb); + if (binary) { + attributeValues = new LdapAttributeValues<>(byte[].class); + } else { + attributeValues = new LdapAttributeValues<>(String.class); + } + } + + + /** + * Creates a new ldap attribute. + * + * @param name of this attribute + */ + public LdapAttribute(final String name) + { + this(); + setName(name); + } + + + /** + * Creates a new ldap attribute. + * + * @param name of this attribute + * @param values of this attribute + */ + public LdapAttribute(final String name, final String... values) + { + this(false); + setName(name); + addStringValue(values); + } + + + /** + * Creates a new ldap attribute. + * + * @param name of this attribute + * @param values of this attribute + */ + public LdapAttribute(final String name, final byte[]... values) + { + this(true); + setName(name); + addBinaryValue(values); + } + + + /** + * Returns the name of this attribute. Includes options if they exist. + * + * @return attribute name + */ + public String getName() + { + return getName(true); + } + + + /** + * Returns the name of this attribute with or without options. + * + * @param withOptions whether options should be included in the name + * + * @return attribute name + */ + public String getName(final boolean withOptions) + { + if (withOptions) { + return attributeName; + } else { + final int optionIndex = attributeName.indexOf(";"); + return optionIndex > 0 ? attributeName.substring(0, optionIndex) : attributeName; + } + } + + + /** + * Sets the name of this attribute. + * + * @param name to set + */ + public void setName(final String name) + { + attributeName = name; + } + + + /** + * Returns the options for this attribute. Returns an empty array if attribute contains no options. + * + * @return options parsed from the attribute name + */ + public String[] getOptions() + { + String[] options = null; + if (attributeName.indexOf(";") > 0) { + final String[] split = attributeName.split(";"); + if (split.length > 1) { + options = new String[split.length - 1]; + System.arraycopy(split, 1, options, 0, options.length); + } + } + return options != null ? options : new String[0]; + } + + + /** + * Returns the values of this attribute as strings. Binary data is base64 encoded. The return collection cannot be + * modified. + * + * @return collection of string attribute values + */ + public Collection<String> getStringValues() + { + return attributeValues.getStringValues(); + } + + + /** + * Returns a single string value of this attribute. See {@link #getStringValues()}. + * + * @return single string attribute value + */ + public String getStringValue() + { + final Collection<String> values = getStringValues(); + if (values.isEmpty()) { + return null; + } + return values.iterator().next(); + } + + + /** + * Returns the values of this attribute as byte arrays. String data is UTF-8 encoded. The return collection cannot be + * modified. + * + * @return collection of byte array attribute values + */ + public Collection<byte[]> getBinaryValues() + { + return attributeValues.getBinaryValues(); + } + + + /** + * Returns a single byte array value of this attribute. See {@link #getBinaryValues()}. + * + * @return single byte array attribute value + */ + public byte[] getBinaryValue() + { + final Collection<byte[]> values = getBinaryValues(); + if (values.isEmpty()) { + return null; + } + return values.iterator().next(); + } + + + /** + * Returns whether this ldap attribute contains a value of type byte[]. + * + * @return whether this ldap attribute contains a value of type byte[] + */ + public boolean isBinary() + { + return attributeValues.isType(byte[].class); + } + + + /** + * Returns the values of this attribute decoded by the supplied transcoder. + * + * @param <T> type of decoded attributes + * @param transcoder to decode attribute values with + * + * @return collection of decoded attribute values + */ + public <T> Collection<T> getValues(final ValueTranscoder<T> transcoder) + { + final Collection<T> values = createSortBehaviorCollection(transcoder.getType()); + if (isBinary()) { + values.addAll(getBinaryValues().stream().map(transcoder::decodeBinaryValue).collect(Collectors.toList())); + } else { + values.addAll(getStringValues().stream().map(transcoder::decodeStringValue).collect(Collectors.toList())); + } + return values; + } + + + /** + * Returns a single decoded value of this attribute. See {@link #getValues(ValueTranscoder)}. + * + * @param <T> type of decoded attributes + * @param transcoder to decode attribute values with + * + * @return single decoded attribute value + */ + public <T> T getValue(final ValueTranscoder<T> transcoder) + { + final Collection<T> t = getValues(transcoder); + if (t.isEmpty()) { + return null; + } + return t.iterator().next(); + } + + + /** + * Adds the supplied string as a value for this attribute. + * + * @param value to add + * + * @throws NullPointerException if value is null + */ + public void addStringValue(final String... value) + { + for (String s : value) { + attributeValues.add(s); + } + } + + + /** + * Adds all the strings in the supplied collection as values for this attribute. See {@link + * #addStringValue(String...)}. + * + * @param values to add + */ + public void addStringValues(final Collection<String> values) + { + values.forEach(this::addStringValue); + } + + + /** + * Adds the supplied byte array as a value for this attribute. + * + * @param value to add + * + * @throws NullPointerException if value is null + */ + public void addBinaryValue(final byte[]... value) + { + for (byte[] b : value) { + attributeValues.add(b); + } + } + + + /** + * Adds all the byte arrays in the supplied collection as values for this attribute. See {@link + * #addBinaryValue(byte[][])}. + * + * @param values to add + */ + public void addBinaryValues(final Collection<byte[]> values) + { + values.forEach(this::addBinaryValue); + } + + + /** + * Adds the supplied values for this attribute by encoding them with the supplied transcoder. + * + * @param <T> type attribute to encode + * @param transcoder to encode value with + * @param value to encode and add + * + * @throws NullPointerException if value is null + */ + @SuppressWarnings("unchecked") + public <T> void addValue(final ValueTranscoder<T> transcoder, final T... value) + { + for (T t : value) { + if (isBinary()) { + attributeValues.add(transcoder.encodeBinaryValue(t)); + } else { + attributeValues.add(transcoder.encodeStringValue(t)); + } + } + } + + + /** + * Adds all the values in the supplied collection for this attribute by encoding them with the supplied transcoder. + * See {@link #addValue(ValueTranscoder, Object...)}. + * + * @param <T> type attribute to encode + * @param transcoder to encode value with + * @param values to encode and add + */ + @SuppressWarnings("unchecked") + public <T> void addValues(final ValueTranscoder<T> transcoder, final Collection<T> values) + { + for (T value : values) { + addValue(transcoder, value); + } + } + + + /** + * Removes the supplied value from the attribute values if it exists. + * + * @param value to remove + */ + public void removeStringValue(final String... value) + { + for (String s : value) { + attributeValues.remove(s); + } + } + + + /** + * Removes the supplied values from the attribute values if they exists. See {@link #removeStringValue(String...)}. + * + * @param values to remove + */ + public void removeStringValues(final Collection<String> values) + { + values.forEach(this::removeStringValue); + } + + + /** + * Removes the supplied value from the attribute values if it exists. + * + * @param value to remove + */ + public void removeBinaryValue(final byte[]... value) + { + for (byte[] b : value) { + attributeValues.remove(b); + } + } + + + /** + * Removes the supplied values from the attribute values if they exists. See {@link #removeBinaryValue(byte[][])}. + * + * @param values to remove + */ + public void removeBinaryValues(final Collection<byte[]> values) + { + values.forEach(this::removeBinaryValue); + } + + + /** + * Returns the number of values in this ldap attribute. + * + * @return number of values in this ldap attribute + */ + public int size() + { + return attributeValues.size(); + } + + + /** Removes all the values in this ldap attribute. */ + public void clear() + { + attributeValues.clear(); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof LdapAttribute) { + final LdapAttribute v = (LdapAttribute) o; + return LdapUtils.areEqual( + attributeName != null ? attributeName.toLowerCase() : null, + v.attributeName != null ? v.attributeName.toLowerCase() : null) && + LdapUtils.areEqual(attributeValues, v.attributeValues); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + attributeName != null ? attributeName.toLowerCase() : null, + attributeValues); + } + + + @Override + public String toString() + { + return String.format("[%s%s]", attributeName, attributeValues); + } + + + /** + * Returns an implementation of collection for the sort behavior of this bean. This implementation returns HashSet for + * {@link SortBehavior#UNORDERED}, LinkedHashSet for {@link SortBehavior#ORDERED}, and TreeSet for {@link + * SortBehavior#SORTED}. + * + * @param <E> contained in the collection + * @param c type contained in the collection + * + * @return collection corresponding to the sort behavior + */ + protected <E> Collection<E> createSortBehaviorCollection(final Class<E> c) + { + Collection<E> values = null; + if (SortBehavior.UNORDERED == getSortBehavior()) { + values = new HashSet<>(); + } else if (SortBehavior.ORDERED == getSortBehavior()) { + values = new LinkedHashSet<>(); + } else if (SortBehavior.SORTED == getSortBehavior()) { + if (!c.isAssignableFrom(Comparable.class)) { + values = new TreeSet<>(getComparator(c)); + } else { + values = new TreeSet<>(); + } + } + return values; + } + + + /** + * Returns a comparator for the supplied class type. Should not be invoked for classes that have a natural ordering. + * Returns a comparator that uses {@link Object#toString()} for unknown types. + * + * @param <E> type of class + * @param c type to compare + * + * @return comparator for use with the supplied type + */ + private static <E> Comparator<E> getComparator(final Class<E> c) + { + if (c.isAssignableFrom(byte[].class)) { + return + (o1, o2) -> { + final ByteBuffer bb1 = ByteBuffer.wrap((byte[]) o1); + final ByteBuffer bb2 = ByteBuffer.wrap((byte[]) o2); + return bb1.compareTo(bb2); + }; + } else { + return + (o1, o2) -> o1.toString().compareTo(o2.toString()); + } + } + + + /** + * Creates a new ldap attribute. The collection of values is inspected for either String or byte[] and the appropriate + * attribute is created. + * + * @param sb sort behavior + * @param name of this attribute + * @param values of this attribute + * + * @return ldap attribute + * + * @throws IllegalArgumentException if values contains something other than String or byte[] + */ + public static LdapAttribute createLdapAttribute( + final SortBehavior sb, + final String name, + final Collection<Object> values) + { + final Collection<String> stringValues = new ArrayList<>(); + final Collection<byte[]> binaryValues = new ArrayList<>(); + for (Object value : values) { + if (value instanceof byte[]) { + binaryValues.add((byte[]) value); + } else if (value instanceof String) { + stringValues.add((String) value); + } else { + throw new IllegalArgumentException("Values must contain either String or byte[]"); + } + } + + LdapAttribute la; + if (!binaryValues.isEmpty()) { + la = new LdapAttribute(sb, true); + la.setName(name); + la.addBinaryValues(binaryValues); + } else { + la = new LdapAttribute(sb, false); + la.setName(name); + la.addStringValues(stringValues); + } + return la; + } + + + /** + * Escapes the supplied string value per RFC 4514 section 2.4. + * + * @param value to escape + * + * @return escaped value + */ + public static String escapeValue(final String value) + { + final int len = value.length(); + final StringBuilder sb = new StringBuilder(len); + char ch; + for (int i = 0; i < len; i++) { + ch = value.charAt(i); + switch (ch) { + + case '"': + case '#': + case '+': + case ',': + case ';': + case '<': + case '=': + case '>': + case '\\': + sb.append('\\').append(ch); + break; + + case ' ': + // escape first space and last space + if (i == 0 || i + 1 == len) { + sb.append('\\').append(ch); + } else { + sb.append(ch); + } + break; + + case 0: + // escape null + sb.append("\\00"); + break; + + default: + // escape non-printable ASCII characters + // CheckStyle:MagicNumber OFF + if (ch < ' ' || ch == 127) { + sb.append(LdapUtils.hexEncode(ch)); + } else { + sb.append(ch); + } + // CheckStyle:MagicNumber ON + break; + } + } + return sb.toString(); + } + + + /** + * Simple bean for ldap attribute values. + * + * @param <T> type of values + * + * @author Middleware Services + */ + private class LdapAttributeValues<T> implements Serializable + { + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 317; + + /** serial version uid. */ + private static final long serialVersionUID = 8075255677989836494L; + + /** Type of values. */ + private final Class<T> type; + + /** Collection of values. */ + private final Collection<T> values; + + + /** + * Creates a new ldap attribute values. + * + * @param t type of values + * + * @throws IllegalArgumentException if t is not a String or byte[] + */ + LdapAttributeValues(final Class<T> t) + { + if (!(t.isAssignableFrom(String.class) || t.isAssignableFrom(byte[].class))) { + throw new IllegalArgumentException("Only String and byte[] values are supported"); + } + type = t; + values = createSortBehaviorCollection(type); + } + + + /** + * Returns whether this ldap attribute values is of the supplied type. + * + * @param c type to check + * + * @return whether this ldap attribute values is of the supplied type + */ + public boolean isType(final Class<?> c) + { + return type.isAssignableFrom(c); + } + + + /** + * Returns the values in string format. If the type of this values is String, values are returned as is. If the type + * of this values is byte[], values are base64 encoded. See {@link #convertValuesToString(Collection)}. + * + * @return unmodifiable collection + */ + @SuppressWarnings("unchecked") + public Collection<String> getStringValues() + { + if (isType(String.class)) { + return Collections.unmodifiableCollection((Collection<String>) values); + } + return Collections.unmodifiableCollection(convertValuesToString((Collection<byte[]>) values)); + } + + + /** + * Returns the values in binary format. If the type of this values is byte[], values are returned as is. If the type + * of this values is String, values are UTF-8 encoded. See {@link #convertValuesToByteArray(Collection)}. + * + * @return unmodifiable collection + */ + @SuppressWarnings("unchecked") + public Collection<byte[]> getBinaryValues() + { + if (isType(byte[].class)) { + return Collections.unmodifiableCollection((Collection<byte[]>) values); + } + return Collections.unmodifiableCollection(convertValuesToByteArray((Collection<String>) values)); + } + + + /** + * Adds the supplied object to this values. + * + * @param o to add + * + * @throws IllegalArgumentException if o is null or if o is not the correct type + */ + public void add(final Object o) + { + checkValue(o); + values.add(type.cast(o)); + } + + + /** + * Removes the supplied object from this values if it exists. + * + * @param o to remove + * + * @throws IllegalArgumentException if o is null or if o is not the correct type + */ + public void remove(final Object o) + { + checkValue(o); + values.remove(type.cast(o)); + } + + + /** + * Determines if the supplied object is acceptable to use in this values. + * + * @param o object to check + * + * @throws IllegalArgumentException if o is null or if o is not the correct type + */ + private void checkValue(final Object o) + { + if (o == null) { + throw new IllegalArgumentException("Value cannot be null"); + } + if (!isType(o.getClass())) { + throw new IllegalArgumentException( + String.format( + "Attribute %s does not support values of type %s", + attributeName, + o.getClass().isArray() ? o.getClass().getComponentType() : o.getClass().getName())); + } + } + + + /** + * Returns the number of values. + * + * @return number of values + */ + public int size() + { + return values.size(); + } + + + /** Removes all the values. */ + public void clear() + { + values.clear(); + } + + + @Override + @SuppressWarnings("unchecked") + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof LdapAttributeValues) { + final LdapAttributeValues v = (LdapAttributeValues) o; + if (type != v.type) { + return false; + } + if (isType(byte[].class)) { + return LdapUtils.areEqual( + convertValuesToString((Collection<byte[]>) values), + convertValuesToString((Collection<byte[]>) v.values)); + } else { + return LdapUtils.areEqual(values, v.values); + } + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, values); + } + + + @Override + public String toString() + { + return getStringValues().toString(); + } + + + /** + * Base64 encodes the supplied collection of values. + * + * @param v values to encode + * + * @return collection of string values + */ + protected Collection<String> convertValuesToString(final Collection<byte[]> v) + { + final Collection<String> c = createSortBehaviorCollection(String.class); + c.addAll(v.stream().map(LdapUtils::base64Encode).collect(Collectors.toList())); + return c; + } + + + /** + * UTF-8 encodes the supplied collection of values. + * + * @param v values to encode + * + * @return collection of byte array values + */ + protected Collection<byte[]> convertValuesToByteArray(final Collection<String> v) + { + final Collection<byte[]> c = createSortBehaviorCollection(byte[].class); + c.addAll(v.stream().map(LdapUtils::utf8Encode).collect(Collectors.toList())); + return c; + } + } +}
diff --git a/core/src/main/java/org/ldaptive/LdapEntry.java b/core/src/main/java/org/ldaptive/LdapEntry.java new file mode 100644 index 0000000..c7083af --- /dev/null +++ b/core/src/main/java/org/ldaptive/LdapEntry.java
@@ -0,0 +1,344 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * Simple bean representing an ldap entry. Contains a DN and ldap attributes. + * + * @author Middleware Services + */ +public class LdapEntry extends AbstractLdapBean +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 331; + + /** serial version uid. */ + private static final long serialVersionUID = 7819007625501406463L; + + /** Distinguished name for this entry. */ + private String entryDn; + + /** Attributes contained in this bean. */ + private final Map<String, LdapAttribute> entryAttributes; + + + /** Default constructor. */ + public LdapEntry() + { + this(SortBehavior.getDefaultSortBehavior()); + } + + + /** + * Creates a new ldap entry. + * + * @param sb sort behavior + */ + public LdapEntry(final SortBehavior sb) + { + super(sb); + if (SortBehavior.UNORDERED == sb) { + entryAttributes = new HashMap<>(); + } else if (SortBehavior.ORDERED == sb) { + entryAttributes = new LinkedHashMap<>(); + } else if (SortBehavior.SORTED == sb) { + entryAttributes = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + } else { + throw new IllegalArgumentException("Unknown sort behavior: " + sb); + } + } + + + /** + * Creates a new ldap entry. + * + * @param dn dn for this entry + */ + public LdapEntry(final String dn) + { + this(); + setDn(dn); + } + + + /** + * Creates a new ldap entry. + * + * @param dn dn for this entry + * @param attr ldap attribute for this entry + */ + public LdapEntry(final String dn, final LdapAttribute... attr) + { + this(); + setDn(dn); + for (LdapAttribute a : attr) { + addAttribute(a); + } + } + + + /** + * Creates a new ldap entry. + * + * @param dn dn for this entry + * @param attrs collection of attributes to add + */ + public LdapEntry(final String dn, final Collection<LdapAttribute> attrs) + { + this(); + setDn(dn); + addAttributes(attrs); + } + + + /** + * Returns the DN. + * + * @return entry DN + */ + public String getDn() + { + return entryDn; + } + + + /** + * Sets the DN. + * + * @param dn dn to set + */ + public void setDn(final String dn) + { + entryDn = dn; + } + + + /** + * Returns a collection of ldap attribute. + * + * @return collection of ldap attribute + */ + public Collection<LdapAttribute> getAttributes() + { + return entryAttributes.values(); + } + + + /** + * Returns a single attribute of this attributes. If multiple attributes exist the first attribute returned by the + * underlying iterator is used. If no attributes exist null is returned. + * + * @return single attribute + */ + public LdapAttribute getAttribute() + { + if (entryAttributes.isEmpty()) { + return null; + } + return entryAttributes.values().iterator().next(); + } + + + /** + * Returns the attribute with the supplied name. + * + * @param name of the attribute to return + * + * @return ldap attribute + */ + public LdapAttribute getAttribute(final String name) + { + if (name != null) { + return entryAttributes.get(name.toLowerCase()); + } + return null; + } + + + /** + * Returns the attribute names in this entry. + * + * @return string array of attribute names + */ + public String[] getAttributeNames() + { + final String[] names = new String[entryAttributes.size()]; + int i = 0; + for (LdapAttribute la : entryAttributes.values()) { + names[i++] = la.getName(); + } + return names; + } + + + /** + * Adds an attribute to this ldap attributes. + * + * @param attr attribute to add + */ + public void addAttribute(final LdapAttribute... attr) + { + for (LdapAttribute a : attr) { + entryAttributes.put(a.getName().toLowerCase(), a); + } + } + + + /** + * Adds attribute(s) to this ldap attributes. + * + * @param attrs collection of attributes to add + */ + public void addAttributes(final Collection<LdapAttribute> attrs) + { + attrs.forEach(this::addAttribute); + } + + + /** + * Removes an attribute from this ldap attributes. + * + * @param attr attribute to remove + */ + public void removeAttribute(final LdapAttribute... attr) + { + for (LdapAttribute a : attr) { + entryAttributes.remove(a.getName().toLowerCase()); + } + } + + + /** + * Removes the attribute of the supplied name from this ldap attributes. + * + * @param name of attribute to remove + */ + public void removeAttribute(final String name) + { + entryAttributes.remove(name.toLowerCase()); + } + + + /** + * Removes the attribute(s) from this ldap attributes. + * + * @param attrs collection of ldap attributes to remove + */ + public void removeAttributes(final Collection<LdapAttribute> attrs) + { + attrs.forEach(this::removeAttribute); + } + + + /** + * Changes the name of an attribute in this entry. The old attribute is removed from this entry, the name is changed + * with {@link LdapAttribute#setName(String)}, and the attribute is added back to this entry. If oldName does not + * exist, this method does nothing. + * + * @param oldName attribute name to change from + * @param newName attribute name to change to + */ + public void renameAttribute(final String oldName, final String newName) + { + final LdapAttribute la = getAttribute(oldName); + if (la != null) { + removeAttribute(oldName); + la.setName(newName); + addAttribute(la); + } + } + + + /** + * Returns the number of attributes in this ldap attributes. + * + * @return number of attributes in this ldap attributes + */ + public int size() + { + return entryAttributes.size(); + } + + + /** Removes all the attributes in this ldap attributes. */ + public void clear() + { + entryAttributes.clear(); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o != null && getClass() == o.getClass()) { + final LdapEntry v = (LdapEntry) o; + return LdapUtils.areEqual( + entryDn != null ? entryDn.toLowerCase() : null, + v.entryDn != null ? v.entryDn.toLowerCase() : null) && + LdapUtils.areEqual(entryAttributes, v.entryAttributes); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + entryDn != null ? entryDn.toLowerCase() : null, + entryAttributes.values()); + } + + + @Override + public String toString() + { + return String.format("[dn=%s%s]", entryDn, entryAttributes.values()); + } + + + /** + * Returns the list of attribute modifications needed to change the supplied target entry into the supplied source + * entry. + * + * @param source ldap entry containing new data + * @param target ldap entry containing existing data + * + * @return attribute modifications needed to change target into source or an empty array + */ + public static AttributeModification[] computeModifications(final LdapEntry source, final LdapEntry target) + { + final List<AttributeModification> mods = new ArrayList<>(); + for (LdapAttribute sourceAttr : source.getAttributes()) { + final LdapAttribute targetAttr = target.getAttribute(sourceAttr.getName()); + if (targetAttr == null) { + final AttributeModification mod = new AttributeModification(AttributeModificationType.ADD, sourceAttr); + mods.add(mod); + } else if (!targetAttr.equals(sourceAttr)) { + final AttributeModification mod = new AttributeModification(AttributeModificationType.REPLACE, sourceAttr); + mods.add(mod); + } + } + for (LdapAttribute targetAttr : target.getAttributes()) { + final LdapAttribute sourceAttr = source.getAttribute(targetAttr.getName()); + if (sourceAttr == null) { + final AttributeModification mod = new AttributeModification(AttributeModificationType.REMOVE, targetAttr); + mods.add(mod); + } + } + return mods.toArray(new AttributeModification[mods.size()]); + } +}
diff --git a/core/src/main/java/org/ldaptive/LdapException.java b/core/src/main/java/org/ldaptive/LdapException.java new file mode 100644 index 0000000..a95c460 --- /dev/null +++ b/core/src/main/java/org/ldaptive/LdapException.java
@@ -0,0 +1,492 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; +import org.ldaptive.control.ResponseControl; + +/** + * Base exception for all ldap related exceptions. Provider specific exception can be found using {@link #getCause()}. + * + * @author Middleware Services + */ +public class LdapException extends Exception implements ResponseMessage +{ + + /** serialVersionUID. */ + private static final long serialVersionUID = -1283840230801970620L; + + /** ldap result code. */ + private final ResultCode resultCode; + + /** response matched DN. */ + private final String matchedDn; + + /** response controls. */ + private final ResponseControl[] responseControls; + + /** referral URLs. */ + private final String[] referralURLs; + + /** Message ID. */ + private final int messageId; + + + /** + * Creates a new ldap exception. + * + * @param msg describing this exception + */ + public LdapException(final String msg) + { + super(msg); + resultCode = null; + matchedDn = null; + responseControls = null; + referralURLs = null; + messageId = -1; + } + + + /** + * Creates a new ldap exception. + * + * @param msg describing this exception + * @param code result code + */ + public LdapException(final String msg, final ResultCode code) + { + super(msg); + resultCode = code; + matchedDn = null; + responseControls = null; + referralURLs = null; + messageId = -1; + } + + + /** + * Creates a new ldap exception. + * + * @param msg describing this exception + * @param code result code + * @param dn matched dn + */ + public LdapException(final String msg, final ResultCode code, final String dn) + { + super(msg); + resultCode = code; + matchedDn = dn; + responseControls = null; + referralURLs = null; + messageId = -1; + } + + + /** + * Creates a new ldap exception. + * + * @param msg describing this exception + * @param code result code + * @param dn matched dn + * @param c response controls + */ + public LdapException(final String msg, final ResultCode code, final String dn, final ResponseControl[] c) + { + super(msg); + resultCode = code; + matchedDn = dn; + responseControls = c; + referralURLs = null; + messageId = -1; + } + + + /** + * Creates a new ldap exception. + * + * @param msg describing this exception + * @param code result code + * @param dn matched dn + * @param c response controls + * @param urls referral urls + */ + public LdapException( + final String msg, + final ResultCode code, + final String dn, + final ResponseControl[] c, + final String[] urls) + { + super(msg); + resultCode = code; + matchedDn = dn; + responseControls = c; + referralURLs = urls; + messageId = -1; + } + + + /** + * Creates a new ldap exception. + * + * @param msg describing this exception + * @param code result code + * @param dn matched dn + * @param c response controls + * @param urls referral urls + * @param id message id + */ + public LdapException( + final String msg, + final ResultCode code, + final String dn, + final ResponseControl[] c, + final String[] urls, + final int id) + { + super(msg); + resultCode = code; + matchedDn = dn; + responseControls = c; + referralURLs = urls; + messageId = id; + } + + + /** + * Creates a new ldap exception. + * + * @param e provider specific exception + */ + public LdapException(final Exception e) + { + super(e); + resultCode = null; + matchedDn = null; + responseControls = null; + referralURLs = null; + messageId = -1; + } + + + /** + * Creates a new ldap exception. + * + * @param e provider specific exception + * @param code result code + */ + public LdapException(final Exception e, final ResultCode code) + { + super(e); + resultCode = code; + matchedDn = null; + responseControls = null; + referralURLs = null; + messageId = -1; + } + + + /** + * Creates a new ldap exception. + * + * @param e provider specific exception + * @param code result code + * @param dn matched dn + */ + public LdapException(final Exception e, final ResultCode code, final String dn) + { + super(e); + resultCode = code; + matchedDn = dn; + responseControls = null; + referralURLs = null; + messageId = -1; + } + + + /** + * Creates a new ldap exception. + * + * @param e provider specific exception + * @param code result code + * @param dn matched dn + * @param c response controls + */ + public LdapException(final Exception e, final ResultCode code, final String dn, final ResponseControl[] c) + { + super(e); + resultCode = code; + matchedDn = dn; + responseControls = c; + referralURLs = null; + messageId = -1; + } + + + /** + * Creates a new ldap exception. + * + * @param e provider specific exception + * @param code result code + * @param dn matched dn + * @param c response controls + * @param urls referral urls + */ + public LdapException( + final Exception e, + final ResultCode code, + final String dn, + final ResponseControl[] c, + final String[] urls) + { + super(e); + resultCode = code; + matchedDn = dn; + responseControls = c; + referralURLs = urls; + messageId = -1; + } + + + /** + * Creates a new ldap exception. + * + * @param e provider specific exception + * @param code result code + * @param dn matched dn + * @param c response controls + * @param urls referral urls + * @param id message id + */ + public LdapException( + final Exception e, + final ResultCode code, + final String dn, + final ResponseControl[] c, + final String[] urls, + final int id) + { + super(e); + resultCode = code; + matchedDn = dn; + responseControls = c; + referralURLs = urls; + messageId = id; + } + + + /** + * Creates a new ldap exception. + * + * @param msg describing this exception + * @param e provider specific exception + */ + public LdapException(final String msg, final Exception e) + { + super(msg, e); + resultCode = null; + matchedDn = null; + responseControls = null; + referralURLs = null; + messageId = -1; + } + + + /** + * Creates a new ldap exception. + * + * @param msg describing this exception + * @param e provider specific exception + * @param code result code + */ + public LdapException(final String msg, final Exception e, final ResultCode code) + { + super(msg, e); + resultCode = code; + matchedDn = null; + responseControls = null; + referralURLs = null; + messageId = -1; + } + + + /** + * Creates a new ldap exception. + * + * @param msg describing this exception + * @param e provider specific exception + * @param code result code + * @param dn matched dn + */ + public LdapException(final String msg, final Exception e, final ResultCode code, final String dn) + { + super(msg, e); + resultCode = code; + matchedDn = dn; + responseControls = null; + referralURLs = null; + messageId = -1; + } + + + /** + * Creates a new ldap exception. + * + * @param msg describing this exception + * @param e provider specific exception + * @param code result code + * @param dn matched dn + * @param c response controls + */ + public LdapException( + final String msg, + final Exception e, + final ResultCode code, + final String dn, + final ResponseControl[] c) + { + super(msg, e); + resultCode = code; + matchedDn = dn; + responseControls = c; + referralURLs = null; + messageId = -1; + } + + + /** + * Creates a new ldap exception. + * + * @param msg describing this exception + * @param e provider specific exception + * @param code result code + * @param dn matched dn + * @param c response controls + * @param urls referral urls + */ + public LdapException( + final String msg, + final Exception e, + final ResultCode code, + final String dn, + final ResponseControl[] c, + final String[] urls) + { + super(msg, e); + resultCode = code; + matchedDn = dn; + responseControls = c; + referralURLs = urls; + messageId = -1; + } + + + /** + * Creates a new ldap exception. + * + * @param msg describing this exception + * @param e provider specific exception + * @param code result code + * @param dn matched dn + * @param c response controls + * @param urls referral urls + * @param id message id + */ + public LdapException( + final String msg, + final Exception e, + final ResultCode code, + final String dn, + final ResponseControl[] c, + final String[] urls, + final int id) + { + super(msg, e); + resultCode = code; + matchedDn = dn; + responseControls = c; + referralURLs = urls; + messageId = id; + } + + + /** + * Returns the ldap result code associated with this exception. May be null if the provider did not set this value or + * could not determine this value. + * + * @return ldap result code + */ + public ResultCode getResultCode() + { + return resultCode; + } + + + /** + * Returns the matched DN produced by the ldap operation. + * + * @return matched DN + */ + public String getMatchedDn() + { + return matchedDn; + } + + + @Override + public ResponseControl[] getControls() + { + return responseControls; + } + + + @Override + public ResponseControl getControl(final String oid) + { + if (getControls() != null) { + for (ResponseControl c : getControls()) { + if (c.getOID().equals(oid)) { + return c; + } + } + } + return null; + } + + + /** + * Returns the referral URLs produced by the ldap operation. + * + * @return referral urls + */ + public String[] getReferralURLs() + { + return referralURLs; + } + + + @Override + public int getMessageId() + { + return messageId; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::resultCode=%s, matchedDn=%s, responseControls=%s, " + + "referralURLs=%s, messageId=%s, message=%s, providerException=%s]", + getClass().getName(), + hashCode(), + resultCode, + matchedDn, + Arrays.toString(responseControls), + Arrays.toString(referralURLs), + messageId, + getMessage(), + getCause()); + } +}
diff --git a/core/src/main/java/org/ldaptive/LdapURL.java b/core/src/main/java/org/ldaptive/LdapURL.java new file mode 100644 index 0000000..05fa0aa --- /dev/null +++ b/core/src/main/java/org/ldaptive/LdapURL.java
@@ -0,0 +1,513 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Utility class for parsing LDAP URLs. See RFC 4516. Supports a space delimited format for representing multiple URLs. + * Expects URLs of the form scheme://hostname:port/baseDn?attrs?scope?filter. This implementation does not support URL + * extensions. + * + * @author Middleware Services + */ +public class LdapURL +{ + + /** Do not split URL. */ + public static final String NO_DELIMITER = "NO-DELIMITER"; + + /** Default delimiter for ldap urls. */ + private static final String DEFAULT_DELIMITER = " "; + + /** Pattern to match LDAP URLs. */ + private static final Pattern URL_PATTERN = Pattern.compile( + "([lL][dD][aA][pP][sSiI]?)://([^:/]+)?" + + "(?::(\\d+))?" + + "(?:/(?:([^?]+))?" + + "(?:\\?([^?]*))?" + + "(?:\\?([^?]*))?" + + "(?:\\?(.*))?)?"); + + /** URL entries. */ + private final List<Entry> ldapEntries = new ArrayList<>(); + + + /** + * Creates a new ldap url. + * + * @param url space delimited list of ldap urls + */ + public LdapURL(final String url) + { + this(url, DEFAULT_DELIMITER); + } + + + /** + * Creates a new ldap url. + * + * @param url space delimited list of ldap urls + * @param delimiter to split url with + */ + public LdapURL(final String url, final String delimiter) + { + final String[] urls; + if (NO_DELIMITER.equals(delimiter)) { + urls = new String[] {url}; + } else { + urls = url.split(delimiter); + } + + for (String s : urls) { + ldapEntries.add(parseEntry(s)); + } + } + + + /** + * Matches the supplied url against a pattern and reads it's components. + * + * @param url to parse + * + * @return entry + */ + protected Entry parseEntry(final String url) + { + final Matcher m = URL_PATTERN.matcher(url); + if (!m.matches()) { + throw new IllegalArgumentException("Invalid LDAP URL: " + url); + } + + // CheckStyle:MagicNumber OFF + final String scheme = m.group(1).toLowerCase(); + String hostname = m.group(2); + if (hostname != null) { + // check for ipv6 address + if (hostname.startsWith("[") && hostname.endsWith("]")) { + hostname = hostname.substring(1, hostname.length() - 1).trim(); + } + } + + final int port = m.group(3) != null ? Integer.parseInt(m.group(3)) : -1; + final String baseDn = m.group(4) != null ? LdapUtils.percentDecode(m.group(4)) : null; + final String[] attributes = m.group(5) != null ? m.group(5).length() > 0 ? m.group(5).split(",") : null : null; + final String scope = m.group(6); + SearchScope searchScope = null; + if (scope != null && scope.length() > 0) { + if ("base".equalsIgnoreCase(scope)) { + searchScope = SearchScope.OBJECT; + } else if ("one".equalsIgnoreCase(scope)) { + searchScope = SearchScope.ONELEVEL; + } else if ("sub".equalsIgnoreCase(scope)) { + searchScope = SearchScope.SUBTREE; + } else { + throw new IllegalArgumentException("Invalid scope: " + scope); + } + } + + final SearchFilter filter = m.group(7) != null + ? m.group(7).length() > 0 ? new SearchFilter(LdapUtils.percentDecode(m.group(7))) : null : null; + + return new Entry(scheme, hostname, port, baseDn, attributes, searchScope, filter); + // CheckStyle:MagicNumber ON + } + + + /** + * Returns the first entry of this ldap url. + * + * @return first entry + */ + public Entry getEntry() + { + return ldapEntries.get(0); + } + + + /** + * Returns the last entry of this ldap url. + * + * @return last entry + */ + public Entry getLastEntry() + { + return ldapEntries.get(ldapEntries.size() - 1); + } + + + /** + * Returns a list of all the ldap url entries in this ldap url. + * + * @return ldap url entries + */ + public List<Entry> getEntries() + { + return Collections.unmodifiableList(ldapEntries); + } + + + /** + * Returns a list of all the URLs in this ldap url. + * + * @return ldap urls + */ + public String[] getUrls() + { + final String[] entries = new String[ldapEntries.size()]; + for (int i = 0; i < ldapEntries.size(); i++) { + entries[i] = ldapEntries.get(i).getUrl(); + } + return entries; + } + + + /** + * Returns a list of all the hostnames including their scheme and port in this ldap url. + * + * @return ldap url hostnames with scheme and port + */ + public String[] getHostnamesWithSchemeAndPort() + { + final String[] entries = new String[ldapEntries.size()]; + for (int i = 0; i < ldapEntries.size(); i++) { + entries[i] = ldapEntries.get(i).getHostnameWithSchemeAndPort(); + } + return entries; + } + + + /** + * Returns a list of all the hostnames in this ldap url. + * + * @return ldap url hostnames + */ + public String[] getHostnames() + { + final String[] entries = new String[ldapEntries.size()]; + for (int i = 0; i < ldapEntries.size(); i++) { + entries[i] = ldapEntries.get(i).getHostname(); + } + return entries; + } + + + /** + * Returns the number of entries in this ldap url. + * + * @return number of entries in this ldap url + */ + public int size() + { + return ldapEntries.size(); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::ldapEntries=%s]", getClass().getName(), hashCode(), ldapEntries); + } + + + /** Represents a single LDAP URL entry. */ + public static class Entry + { + + /** Default LDAP port, value is {@value}. */ + protected static final int DEFAULT_LDAP_PORT = 389; + + /** Default LDAPS port, value is {@value}. */ + protected static final int DEFAULT_LDAPS_PORT = 636; + + /** Default base DN, value is {@value}. */ + protected static final String DEFAULT_BASE_DN = ""; + + /** Default search filter value is '(objectClass=*)'. */ + protected static final SearchFilter DEFAULT_FILTER = new SearchFilter("(objectClass=*)"); + + /** Default scope, value is {@link SearchScope#OBJECT}. */ + protected static final SearchScope DEFAULT_SCOPE = SearchScope.OBJECT; + + /** Default return attributes, value is none. */ + protected static final String[] DEFAULT_ATTRIBUTES = ReturnAttributes.DEFAULT.value(); + + /** Scheme of the ldap url. */ + private final String urlScheme; + + /** Hostname of the ldap url. */ + private final String urlHostname; + + /** Port of the ldap url. */ + private final int urlPort; + + /** Base DN of the ldap url. */ + private final String urlBaseDn; + + /** Attributes of the ldap url. */ + private final String[] urlAttributes; + + /** Search scope of the ldap url. */ + private final SearchScope urlScope; + + /** Search filter of the ldap url. */ + private final SearchFilter urlFilter; + + + /** + * Creates a new entry. + * + * @param scheme entryScheme + * @param hostname entryHostname + * @param port entryPort + * @param baseDn base DN + * @param attributes attributes + * @param scope search scope + * @param filter search filter + */ + public Entry( + final String scheme, + final String hostname, + final int port, + final String baseDn, + final String[] attributes, + final SearchScope scope, + final SearchFilter filter) + { + if (scheme == null) { + throw new IllegalArgumentException("Scheme cannot be null"); + } + urlScheme = scheme; + urlHostname = hostname; + urlPort = port; + urlBaseDn = baseDn; + urlAttributes = attributes; + urlScope = scope; + urlFilter = filter; + } + + + /** + * Returns the entryScheme. + * + * @return entryScheme + */ + public String getScheme() + { + return urlScheme; + } + + + /** + * Returns the entryHostname. + * + * @return entryHostname + */ + public String getHostname() + { + return urlHostname; + } + + + /** + * Returns the entryPort. + * + * @return entryPort + */ + public int getPort() + { + if (urlPort == -1) { + return "ldaps".equals(urlScheme) ? DEFAULT_LDAPS_PORT : DEFAULT_LDAP_PORT; + } + return urlPort; + } + + + /** + * Returns whether a port was supplied in this entry. + * + * @return whether a port was supplied in this entry + */ + public boolean isDefaultPort() + { + return urlPort == -1; + } + + + /** + * Returns the base DN. + * + * @return baseDn + */ + public String getBaseDn() + { + return urlBaseDn == null ? DEFAULT_BASE_DN : urlBaseDn; + } + + + /** + * Returns whether a base DN was supplied in this entry. + * + * @return whether a base DN was supplied in this entry + */ + public boolean isDefaultBaseDn() + { + return urlBaseDn == null; + } + + + /** + * Returns the attributes. + * + * @return attributes + */ + public String[] getAttributes() + { + return urlAttributes == null ? DEFAULT_ATTRIBUTES : urlAttributes; + } + + + /** + * Returns whether attributes were supplied in this entry. + * + * @return whether a attributes were supplied in this entry + */ + public boolean isDefaultAttributes() + { + return urlAttributes == null; + } + + + /** + * Returns the scope. + * + * @return scope + */ + public SearchScope getScope() + { + return urlScope == null ? DEFAULT_SCOPE : urlScope; + } + + + /** + * Returns whether a scope was supplied in this entry. + * + * @return whether a scope was supplied in this entry + */ + public boolean isDefaultScope() + { + return urlScope == null; + } + + + /** + * Returns the filter. + * + * @return filter + */ + public SearchFilter getFilter() + { + return urlFilter == null ? DEFAULT_FILTER : urlFilter; + } + + + /** + * Returns whether a filter was supplied in this entry. + * + * @return whether a filter was supplied in this entry + */ + public boolean isDefaultFilter() + { + return urlFilter == null; + } + + + /** + * Returns the formatted URL as scheme://hostname:port/baseDn?attrs?scope?filter. + * + * @return url + */ + public String getUrl() + { + + final StringBuilder sb = new StringBuilder(urlScheme).append("://"); + final String hostname = getHostname(); + if (hostname != null) { + // ipv6 address + if (hostname.contains(":")) { + sb.append("[").append(hostname).append("]"); + } else { + sb.append(hostname); + } + } + sb.append(":").append(getPort()); + sb.append("/").append(LdapUtils.percentEncode(getBaseDn())); + sb.append("?"); + + final String[] attrs = getAttributes(); + for (int i = 0; i < attrs.length; i++) { + sb.append(attrs[i]); + if (i + 1 < attrs.length) { + sb.append(","); + } + } + sb.append("?"); + + final SearchScope scope = getScope(); + if (SearchScope.OBJECT == scope) { + sb.append("base"); + } else if (SearchScope.ONELEVEL == scope) { + sb.append("one"); + } else if (SearchScope.SUBTREE == scope) { + sb.append("sub"); + } + sb.append("?").append(LdapUtils.percentEncode(getFilter().format())); + return sb.toString(); + } + + + /** + * Returns the hostname:port. + * + * @return hostname:port + */ + public String getHostnameWithPort() + { + return String.format("%s:%s", getHostname(), getPort()); + } + + + /** + * Returns the scheme://hostname:port. + * + * @return scheme://hostname:port + */ + public String getHostnameWithSchemeAndPort() + { + return String.format("%s://%s:%s", getScheme(), getHostname(), getPort()); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::scheme=%s, hostname=%s, port=%s, baseDn=%s, " + + "attributes=%s, scope=%s, filter=%s]", + getClass().getName(), + hashCode(), + urlScheme, + urlHostname, + urlPort, + urlBaseDn, + Arrays.toString(urlAttributes), + urlScope, + urlFilter); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/LdapUtils.java b/core/src/main/java/org/ldaptive/LdapUtils.java new file mode 100644 index 0000000..6ae39f7 --- /dev/null +++ b/core/src/main/java/org/ldaptive/LdapUtils.java
@@ -0,0 +1,499 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collection; +import java.util.List; +import java.util.Queue; +import java.util.regex.Pattern; +import org.ldaptive.io.Hex; + +/** + * Provides utility methods for this package. + * + * @author Middleware Services + */ +public final class LdapUtils +{ + + /** Size of buffer in bytes to use when reading files. */ + private static final int READ_BUFFER_SIZE = 128; + + /** Prime number to assist in calculating hash codes. */ + private static final int HASH_CODE_PRIME = 113; + + /** Pattern to match ipv4 addresses. */ + private static final Pattern IPV4_PATTERN = Pattern.compile( + "^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)" + + "(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$"); + + /** Pattern to match ipv6 addresses. */ + private static final Pattern IPV6_STD_PATTERN = Pattern.compile("^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$"); + + /** Pattern to match ipv6 hex compressed addresses. */ + private static final Pattern IPV6_HEX_COMPRESSED_PATTERN = Pattern.compile( + "^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::" + + "((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)$"); + + /** Prefix used to indicate a classpath resource. */ + private static final String CLASSPATH_PREFIX = "classpath:"; + + /** Prefix used to indicate a file resource. */ + private static final String FILE_PREFIX = "file:"; + + + /** Default constructor. */ + private LdapUtils() {} + + + /** + * This will convert the supplied value to a base64 encoded string. Returns null if the supplied byte array is null. + * + * @param value to base64 encode + * + * @return base64 encoded value + */ + public static String base64Encode(final byte[] value) + { + return value != null ? new String(Base64.getEncoder().encode(value), StandardCharsets.UTF_8) : null; + } + + + /** + * This will convert the supplied value to a base64 encoded string. Returns null if the supplied string is null. + * + * @param value to base64 encode + * + * @return base64 encoded value + */ + public static String base64Encode(final String value) + { + return value != null ? base64Encode(value.getBytes(StandardCharsets.UTF_8)) : null; + } + + + /** + * This will convert the supplied value to a UTF-8 encoded string. Returns null if the supplied byte array is null. + * + * @param value to UTF-8 encode + * + * @return UTF-8 encoded value + */ + public static String utf8Encode(final byte[] value) + { + return value != null ? new String(value, StandardCharsets.UTF_8) : null; + } + + + /** + * This will convert the supplied value to a UTF-8 encoded byte array. Returns null if the supplied string is null. + * + * @param value to UTF-8 encode + * + * @return UTF-8 encoded value + */ + public static byte[] utf8Encode(final String value) + { + return value != null ? value.getBytes(StandardCharsets.UTF_8) : null; + } + + + /** + * This will convert the supplied value to a hex encoded string. Returns null if the supplied byte array is null. + * + * @param value to hex encode + * + * @return hex encoded value + */ + public static char[] hexEncode(final byte[] value) + { + return value != null ? Hex.encode(value) : null; + } + + + /** + * This will convert the supplied value to a hex encoded string. Returns null if the supplied char array is null. + * + * @param value to hex encode + * + * @return hex encoded value + */ + public static char[] hexEncode(final char... value) + { + return value != null ? hexEncode(utf8Encode(String.valueOf(value))) : null; + } + + + /** + * Implementation of percent encoding as described in RFC 3986 section 2.1. + * + * @param value to encode + * + * @return percent encoded value + */ + public static String percentEncode(final String value) + { + if (value == null) { + return null; + } + + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < value.length(); i++) { + final char ch = value.charAt(i); + // uppercase + if (ch >= 'A' && ch <= 'Z') { + sb.append(ch); + // lowercase + } else if (ch >= 'a' && ch <= 'z') { + sb.append(ch); + // digit + } else if (ch >= '0' && ch <= '9') { + sb.append(ch); + } else { + // unreserved and reserved + switch (ch) { + + case '-': + case '.': + case '_': + case '~': + case '!': + case '$': + case '&': + case '\'': + case '(': + case ')': + case '*': + case '+': + case ',': + case ';': + case '=': + sb.append(ch); + break; + + default: + sb.append("%"); + // CheckStyle:MagicNumber OFF + if (ch <= 0x7F) { + sb.append(hexEncode(new byte[] {(byte) (ch & 0x7F)})); + } else { + sb.append(hexEncode(utf8Encode(String.valueOf(ch)))); + } + // CheckStyle:MagicNumber ON + } + } + } + return sb.toString(); + } + + + /** + * This will decode the supplied value as a base64 encoded string to a byte[]. Returns null if the supplied string is + * null. + * + * @param value to base64 decode + * + * @return base64 decoded value + */ + public static byte[] base64Decode(final String value) + { + return value != null ? Base64.getDecoder().decode(value.getBytes()) : null; + } + + + /** + * This will decode the supplied value as a hex encoded string to a byte[]. Returns null if the supplied character + * array is null. + * + * @param value to hex decode + * + * @return hex decoded value + */ + public static byte[] hexDecode(final char[] value) + { + return value != null ? Hex.decode(value) : null; + } + + + /** + * Implementation of percent decoding as described in RFC 3986 section 2.1. + * + * @param value to decode + * + * @return percent decoded value + */ + public static String percentDecode(final String value) + { + if (value == null || !value.contains("%")) { + return value; + } + + final StringBuilder sb = new StringBuilder(); + int pos = 0; + while (pos < value.length()) { + final char c = value.charAt(pos++); + if (c == '%') { + final char[] hex = new char[] { + value.charAt(pos++), + value.charAt(pos++), + }; + sb.append(utf8Encode(hexDecode(hex))); + } else { + sb.append(c); + } + } + return sb.toString(); + } + + + /** + * Reads the data at the supplied URL and returns it as a byte array. + * + * @param url to read + * + * @return bytes read from the URL + * + * @throws IOException if an error occurs reading data + */ + public static byte[] readURL(final URL url) + throws IOException + { + return readInputStream(url.openStream()); + } + + + /** + * Reads the data in the supplied stream and returns it as a byte array. + * + * @param is stream to read + * + * @return bytes read from the stream + * + * @throws IOException if an error occurs reading data + */ + public static byte[] readInputStream(final InputStream is) + throws IOException + { + final ByteArrayOutputStream data = new ByteArrayOutputStream(); + try { + final byte[] buffer = new byte[READ_BUFFER_SIZE]; + int length; + while ((length = is.read(buffer)) != -1) { + data.write(buffer, 0, length); + } + } finally { + is.close(); + data.close(); + } + return data.toByteArray(); + } + + + /** + * Concatenates multiple arrays together. + * + * @param <T> type of array + * @param first array to concatenate. Cannot be null. + * @param rest of the arrays to concatenate. May be null. + * + * @return array containing the concatenation of all parameters + */ + @SuppressWarnings("unchecked") + public static <T> T[] concatArrays(final T[] first, final T[]... rest) + { + int totalLength = first.length; + for (T[] array : rest) { + if (array != null) { + totalLength += array.length; + } + } + + final T[] result = Arrays.copyOf(first, totalLength); + + int offset = first.length; + for (T[] array : rest) { + if (array != null) { + System.arraycopy(array, 0, result, offset, array.length); + offset += array.length; + } + } + return result; + } + + + /** + * Determines equality of the supplied objects. Array types are automatically detected. + * + * @param o1 to test equality of + * @param o2 to test equality of + * + * @return whether o1 equals o2 + */ + public static boolean areEqual(final Object o1, final Object o2) + { + if (o1 == o2) { + return true; + } + boolean areEqual; + if (o1 instanceof boolean[] && o2 instanceof boolean[]) { + areEqual = Arrays.equals((boolean[]) o1, (boolean[]) o2); + } else if (o1 instanceof byte[] && o2 instanceof byte[]) { + areEqual = Arrays.equals((byte[]) o1, (byte[]) o2); + } else if (o1 instanceof char[] && o2 instanceof char[]) { + areEqual = Arrays.equals((char[]) o1, (char[]) o2); + } else if (o1 instanceof double[] && o2 instanceof double[]) { + areEqual = Arrays.equals((double[]) o1, (double[]) o2); + } else if (o1 instanceof float[] && o2 instanceof float[]) { + areEqual = Arrays.equals((float[]) o1, (float[]) o2); + } else if (o1 instanceof int[] && o2 instanceof int[]) { + areEqual = Arrays.equals((int[]) o1, (int[]) o2); + } else if (o1 instanceof long[] && o2 instanceof long[]) { + areEqual = Arrays.equals((long[]) o1, (long[]) o2); + } else if (o1 instanceof short[] && o2 instanceof short[]) { + areEqual = Arrays.equals((short[]) o1, (short[]) o2); + } else if (o1 instanceof Object[] && o2 instanceof Object[]) { + areEqual = Arrays.deepEquals((Object[]) o1, (Object[]) o2); + } else { + areEqual = o1 != null && o1.equals(o2); + } + return areEqual; + } + + + /** + * Computes a hash code for the supplied objects using the supplied seed. If a Collection type is found it is iterated + * over. + * + * @param seed odd/prime number + * @param objects to calculate hashCode for + * + * @return hash code for the supplied objects + */ + public static int computeHashCode(final int seed, final Object... objects) + { + if (objects == null || objects.length == 0) { + return seed * HASH_CODE_PRIME; + } + + int hc = seed; + for (Object object : objects) { + hc = HASH_CODE_PRIME * hc; + if (object != null) { + if (object instanceof List<?> || object instanceof Queue<?>) { + int index = 1; + for (Object o : (Collection<?>) object) { + hc += computeHashCode(o) * index++; + } + } else if (object instanceof Collection<?>) { + for (Object o : (Collection<?>) object) { + hc += computeHashCode(o); + } + } else { + hc += computeHashCode(object); + } + } + } + return hc; + } + + + /** + * Computes a hash code for the supplied object. Checks for arrays of primitives and Objects then delegates to the + * {@link Arrays} class. Otherwise {@link Object#hashCode()} is invoked. + * + * @param object to calculate hash code for + * + * @return hash code + */ + private static int computeHashCode(final Object object) + { + int hc = 0; + if (object instanceof boolean[]) { + hc += Arrays.hashCode((boolean[]) object); + } else if (object instanceof byte[]) { + hc += Arrays.hashCode((byte[]) object); + } else if (object instanceof char[]) { + hc += Arrays.hashCode((char[]) object); + } else if (object instanceof double[]) { + hc += Arrays.hashCode((double[]) object); + } else if (object instanceof float[]) { + hc += Arrays.hashCode((float[]) object); + } else if (object instanceof int[]) { + hc += Arrays.hashCode((int[]) object); + } else if (object instanceof long[]) { + hc += Arrays.hashCode((long[]) object); + } else if (object instanceof short[]) { + hc += Arrays.hashCode((short[]) object); + } else if (object instanceof Object[]) { + hc += Arrays.hashCode((Object[]) object); + } else { + hc += object.hashCode(); + } + return hc; + } + + + /** + * Returns whether the supplied string represents an IP address. Matches both IPv4 and IPv6 addresses. + * + * @param s to match + * + * @return whether the supplied string represents an IP address + */ + public static boolean isIPAddress(final String s) + { + return + s != null && + (IPV4_PATTERN.matcher(s).matches() || IPV6_STD_PATTERN.matcher(s).matches() || + IPV6_HEX_COMPRESSED_PATTERN.matcher(s).matches()); + } + + + /** + * Returns whether the supplied string starts with {@link #CLASSPATH_PREFIX} or {@link #FILE_PREFIX}. + * + * @param s to inspect + * + * @return whether the supplied string represents a resource + */ + public static boolean isResource(final String s) + { + return s != null && (s.startsWith(CLASSPATH_PREFIX) || s.startsWith(FILE_PREFIX)); + } + + + /** + * Parses the supplied path and returns an input stream based on the prefix in the path. If a path is prefixed with + * the string "classpath:" it is interpreted as a classpath specification. If a path is prefixed with the string + * "file:" it is interpreted as a file path. + * + * @param path that designates a resource + * + * @return input stream to read the resource + * + * @throws IOException if the resource cannot be read + * @throws IllegalArgumentException if path is not prefixed with either 'classpath:' or 'file:' + */ + public static InputStream getResource(final String path) + throws IOException + { + InputStream is; + if (path.startsWith(CLASSPATH_PREFIX)) { + is = LdapUtils.class.getResourceAsStream(path.substring(CLASSPATH_PREFIX.length())); + } else if (path.startsWith(FILE_PREFIX)) { + is = new FileInputStream(new File(path.substring(FILE_PREFIX.length()))); + } else { + throw new IllegalArgumentException( + "path '" + path + "' must start with either " + CLASSPATH_PREFIX + " or " + FILE_PREFIX); + } + return is; + } +}
diff --git a/core/src/main/java/org/ldaptive/Message.java b/core/src/main/java/org/ldaptive/Message.java new file mode 100644 index 0000000..b365283 --- /dev/null +++ b/core/src/main/java/org/ldaptive/Message.java
@@ -0,0 +1,23 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.ldaptive.control.Control; + +/** + * Interface for ldap messages. + * + * @param <T> type of control + * + * @author Middleware Services + */ +public interface Message<T extends Control> +{ + + + /** + * Returns the controls for this message. + * + * @return controls + */ + T[] getControls(); +}
diff --git a/core/src/main/java/org/ldaptive/ModifyDnOperation.java b/core/src/main/java/org/ldaptive/ModifyDnOperation.java new file mode 100644 index 0000000..cffb411 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ModifyDnOperation.java
@@ -0,0 +1,30 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Executes an ldap modify dn operation. + * + * @author Middleware Services + */ +public class ModifyDnOperation extends AbstractOperation<ModifyDnRequest, Void> +{ + + + /** + * Creates a new modify dn operation. + * + * @param conn connection + */ + public ModifyDnOperation(final Connection conn) + { + super(conn); + } + + + @Override + protected Response<Void> invoke(final ModifyDnRequest request) + throws LdapException + { + return getConnection().getProviderConnection().modifyDn(request); + } +}
diff --git a/core/src/main/java/org/ldaptive/ModifyDnRequest.java b/core/src/main/java/org/ldaptive/ModifyDnRequest.java new file mode 100644 index 0000000..71f2499 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ModifyDnRequest.java
@@ -0,0 +1,123 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; + +/** + * Contains the data required to perform an ldap modify dn operation. + * + * @author Middleware Services + */ +public class ModifyDnRequest extends AbstractRequest +{ + + /** DN to modify. */ + private String oldModifyDn; + + /** New DN. */ + private String newModifyDn; + + /** Whether to delete the old RDN attribute. */ + private boolean deleteOldRDn = true; + + + /** Default constructor. */ + public ModifyDnRequest() {} + + + /** + * Creates a new modify dn request. + * + * @param oldDn to modify + * @param newDn to rename to + */ + public ModifyDnRequest(final String oldDn, final String newDn) + { + setDn(oldDn); + setNewDn(newDn); + } + + + /** + * Returns the DN to modify. + * + * @return DN + */ + public String getDn() + { + return oldModifyDn; + } + + + /** + * Sets the DN to modify. + * + * @param dn to modify + */ + public void setDn(final String dn) + { + oldModifyDn = dn; + } + + + /** + * Returns the new DN. + * + * @return DN + */ + public String getNewDn() + { + return newModifyDn; + } + + + /** + * Sets the new DN. + * + * @param dn to rename to + */ + public void setNewDn(final String dn) + { + newModifyDn = dn; + } + + + /** + * Returns whether to delete the old RDN attribute. + * + * @return whether to delete the old RDN attribute + */ + public boolean getDeleteOldRDn() + { + return deleteOldRDn; + } + + + /** + * Sets whether to delete the old RDN attribute. + * + * @param b whether to delete the old RDN attribute + */ + public void setDeleteOldRDn(final boolean b) + { + deleteOldRDn = b; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::oldModifyDn=%s, newModifyDn=%s, deleteOldRDn=%s, " + + "controls=%s, referralHandler=%s, intermediateResponseHandlers=%s]", + getClass().getName(), + hashCode(), + oldModifyDn, + newModifyDn, + deleteOldRDn, + Arrays.toString(getControls()), + getReferralHandler(), + Arrays.toString(getIntermediateResponseHandlers())); + } +}
diff --git a/core/src/main/java/org/ldaptive/ModifyOperation.java b/core/src/main/java/org/ldaptive/ModifyOperation.java new file mode 100644 index 0000000..27101e2 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ModifyOperation.java
@@ -0,0 +1,30 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Executes an ldap modify operation. + * + * @author Middleware Services + */ +public class ModifyOperation extends AbstractOperation<ModifyRequest, Void> +{ + + + /** + * Creates a new modify operation. + * + * @param conn connection + */ + public ModifyOperation(final Connection conn) + { + super(conn); + } + + + @Override + protected Response<Void> invoke(final ModifyRequest request) + throws LdapException + { + return getConnection().getProviderConnection().modify(request); + } +}
diff --git a/core/src/main/java/org/ldaptive/ModifyRequest.java b/core/src/main/java/org/ldaptive/ModifyRequest.java new file mode 100644 index 0000000..3d6fe3b --- /dev/null +++ b/core/src/main/java/org/ldaptive/ModifyRequest.java
@@ -0,0 +1,97 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; + +/** + * Contains the data required to perform an ldap modify operation. + * + * @author Middleware Services + */ +public class ModifyRequest extends AbstractRequest +{ + + /** DN to modify. */ + private String modifyDn; + + /** Attribute modifications. */ + private AttributeModification[] attrMods; + + + /** Default constructor. */ + public ModifyRequest() {} + + + /** + * Creates a new modify request. + * + * @param dn to modify + * @param mods attribute modifications + */ + public ModifyRequest(final String dn, final AttributeModification... mods) + { + setDn(dn); + setAttributeModifications(mods); + } + + + /** + * Returns the DN to modify. + * + * @return DN + */ + public String getDn() + { + return modifyDn; + } + + + /** + * Sets the DN to modify. + * + * @param dn to modify + */ + public void setDn(final String dn) + { + modifyDn = dn; + } + + + /** + * Returns the attribute modifications. + * + * @return attribute modifications + */ + public AttributeModification[] getAttributeModifications() + { + return attrMods; + } + + + /** + * Sets the attribute modifications. + * + * @param mods attribute modifications + */ + public void setAttributeModifications(final AttributeModification... mods) + { + attrMods = mods; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::modifyDn=%s, attrMods=%s, controls=%s, referralHandler=%s, " + + "intermediateResponseHandlers=%s]", + getClass().getName(), + hashCode(), + modifyDn, + Arrays.toString(attrMods), + Arrays.toString(getControls()), + getReferralHandler(), + Arrays.toString(getIntermediateResponseHandlers())); + } +}
diff --git a/core/src/main/java/org/ldaptive/Operation.java b/core/src/main/java/org/ldaptive/Operation.java new file mode 100644 index 0000000..9208153 --- /dev/null +++ b/core/src/main/java/org/ldaptive/Operation.java
@@ -0,0 +1,27 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Interface for ldap operations. + * + * @param <Q> type of ldap request + * @param <S> type of ldap response + * + * @author Middleware Services + */ +public interface Operation<Q extends Request, S> +{ + + + /** + * Execute this ldap operation. + * + * @param request containing the data required by this operation + * + * @return response for this operation + * + * @throws LdapException if the operation fails + */ + Response<S> execute(Q request) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/OperationException.java b/core/src/main/java/org/ldaptive/OperationException.java new file mode 100644 index 0000000..61ed04d --- /dev/null +++ b/core/src/main/java/org/ldaptive/OperationException.java
@@ -0,0 +1,237 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.ldaptive.control.ResponseControl; + +/** + * Exception thrown when an ldap operation attempt fails. + * + * @author Middleware Services + */ +public class OperationException extends LdapException +{ + + /** serialVersionUID. */ + private static final long serialVersionUID = 4995760197708755601L; + + + /** + * Creates a new operation exception. + * + * @param msg describing this exception + */ + public OperationException(final String msg) + { + super(msg); + } + + + /** + * Creates a new operation exception. + * + * @param msg describing this exception + * @param code result code + */ + public OperationException(final String msg, final ResultCode code) + { + super(msg, code); + } + + + /** + * Creates a new operation exception. + * + * @param msg describing this exception + * @param code result code + * @param dn matched dn + */ + public OperationException(final String msg, final ResultCode code, final String dn) + { + super(msg, code, dn); + } + + + /** + * Creates a new operation exception. + * + * @param msg describing this exception + * @param code result code + * @param dn matched dn + * @param c response controls + */ + public OperationException(final String msg, final ResultCode code, final String dn, final ResponseControl[] c) + { + super(msg, code, dn, c); + } + + + /** + * Creates a new operation exception. + * + * @param msg describing this exception + * @param code result code + * @param dn matched dn + * @param c response controls + * @param urls referral urls + */ + public OperationException( + final String msg, + final ResultCode code, + final String dn, + final ResponseControl[] c, + final String[] urls) + { + super(msg, code, dn, c, urls); + } + + + /** + * Creates a new operation exception. + * + * @param e provider specific exception + */ + public OperationException(final Exception e) + { + super(e); + } + + + /** + * Creates a new operation exception. + * + * @param e provider specific exception + * @param code result code + */ + public OperationException(final Exception e, final ResultCode code) + { + super(e, code); + } + + + /** + * Creates a new operation exception. + * + * @param e provider specific exception + * @param code result code + * @param dn matched dn + */ + public OperationException(final Exception e, final ResultCode code, final String dn) + { + super(e, code, dn); + } + + + /** + * Creates a new operation exception. + * + * @param e provider specific exception + * @param code result code + * @param dn matched dn + * @param c response controls + */ + public OperationException(final Exception e, final ResultCode code, final String dn, final ResponseControl[] c) + { + super(e, code, dn, c); + } + + + /** + * Creates a new operation exception. + * + * @param e provider specific exception + * @param code result code + * @param dn matched dn + * @param c response controls + * @param urls referral urls + */ + public OperationException( + final Exception e, + final ResultCode code, + final String dn, + final ResponseControl[] c, + final String[] urls) + { + super(e, code, dn, c, urls); + } + + + /** + * Creates a new operation exception. + * + * @param msg describing this exception + * @param e provider specific exception + */ + public OperationException(final String msg, final Exception e) + { + super(msg, e); + } + + + /** + * Creates a new operation exception. + * + * @param msg describing this exception + * @param e provider specific exception + * @param code result code + */ + public OperationException(final String msg, final Exception e, final ResultCode code) + { + super(msg, e, code); + } + + + /** + * Creates a new operation exception. + * + * @param msg describing this exception + * @param e provider specific exception + * @param code result code + * @param dn matched dn + */ + public OperationException(final String msg, final Exception e, final ResultCode code, final String dn) + { + super(msg, e, code, dn); + } + + + /** + * Creates a new operation exception. + * + * @param msg describing this exception + * @param e provider specific exception + * @param code result code + * @param dn matched dn + * @param c response controls + */ + public OperationException( + final String msg, + final Exception e, + final ResultCode code, + final String dn, + final ResponseControl[] c) + { + super(msg, e, code, dn, c); + } + + + /** + * Creates a new operation exception. + * + * @param msg describing this exception + * @param e provider specific exception + * @param code result code + * @param dn matched dn + * @param c response controls + * @param urls referral urls + */ + public OperationException( + final String msg, + final Exception e, + final ResultCode code, + final String dn, + final ResponseControl[] c, + final String[] urls) + { + super(msg, e, code, dn, c, urls); + } +}
diff --git a/core/src/main/java/org/ldaptive/RandomConnectionStrategy.java b/core/src/main/java/org/ldaptive/RandomConnectionStrategy.java new file mode 100644 index 0000000..f3b312f --- /dev/null +++ b/core/src/main/java/org/ldaptive/RandomConnectionStrategy.java
@@ -0,0 +1,36 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Connection strategy that randomizes the list of configured URLs. A random URL ordering will be created for each + * connection attempt. + * + * @author Middleware Services + */ +public class RandomConnectionStrategy implements ConnectionStrategy +{ + + + /** + * Return a list of URLs in random order. + * + * @param metadata which can be used to produce the URL list + * + * @return list of URLs to attempt connections to + */ + @Override + public String[] getLdapUrls(final ConnectionFactoryMetadata metadata) + { + if (metadata == null || metadata.getLdapUrl() == null) { + return null; + } + + final List<String> l = Arrays.asList(metadata.getLdapUrl().split(" ")); + Collections.shuffle(l); + return l.toArray(new String[l.size()]); + } +}
diff --git a/core/src/main/java/org/ldaptive/Request.java b/core/src/main/java/org/ldaptive/Request.java new file mode 100644 index 0000000..c20bd0e --- /dev/null +++ b/core/src/main/java/org/ldaptive/Request.java
@@ -0,0 +1,31 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.ldaptive.control.RequestControl; +import org.ldaptive.handler.IntermediateResponseHandler; +import org.ldaptive.referral.ReferralHandler; + +/** + * Marker interface for all ldap requests. + * + * @author Middleware Services + */ +public interface Request extends Message<RequestControl> +{ + + + /** + * Returns the referral handler. + * + * @return referral handler + */ + ReferralHandler getReferralHandler(); + + + /** + * Returns the intermediate response handlers. + * + * @return intermediate response handlers + */ + IntermediateResponseHandler[] getIntermediateResponseHandlers(); +}
diff --git a/core/src/main/java/org/ldaptive/Response.java b/core/src/main/java/org/ldaptive/Response.java new file mode 100644 index 0000000..8707970 --- /dev/null +++ b/core/src/main/java/org/ldaptive/Response.java
@@ -0,0 +1,187 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; +import org.ldaptive.control.ResponseControl; + +/** + * Wrapper class for all operation responses. + * + * @param <T> type of ldap result contained in this response + * + * @author Middleware Services + */ +public class Response<T> implements ResponseMessage +{ + + /** Operation response. */ + private final T result; + + /** Operation result code. */ + private final ResultCode resultCode; + + /** Response message. */ + private final String message; + + /** Response matched DN. */ + private final String matchedDn; + + /** Response controls. */ + private final ResponseControl[] responseControls; + + /** Referral URLs. */ + private final String[] referralURLs; + + /** Message ID. */ + private final int messageId; + + + /** + * Creates a new ldap response. + * + * @param t response type + * @param rc result code + */ + public Response(final T t, final ResultCode rc) + { + result = t; + resultCode = rc; + message = null; + matchedDn = null; + responseControls = null; + referralURLs = null; + messageId = -1; + } + + + /** + * Creates a new ldap response. + * + * @param t response type + * @param rc result code + * @param msg result message + * @param dn matched dn + * @param c response controls + * @param urls referral urls + * @param id message id + */ + public Response( + final T t, + final ResultCode rc, + final String msg, + final String dn, + final ResponseControl[] c, + final String[] urls, + final int id) + { + result = t; + resultCode = rc; + message = msg; + matchedDn = dn; + responseControls = c; + referralURLs = urls; + messageId = id; + } + + + /** + * Returns the result of the ldap operation. + * + * @return operation result + */ + public T getResult() + { + return result; + } + + + /** + * Returns the result code of the ldap operation. + * + * @return operation result code + */ + public ResultCode getResultCode() + { + return resultCode; + } + + + /** + * Returns any error or diagnostic message produced by the ldap operation. + * + * @return message + */ + public String getMessage() + { + return message; + } + + + /** + * Returns the matched DN produced by the ldap operation. + * + * @return matched DN + */ + public String getMatchedDn() + { + return matchedDn; + } + + + @Override + public ResponseControl[] getControls() + { + return responseControls; + } + + + @Override + public ResponseControl getControl(final String oid) + { + if (getControls() != null) { + for (ResponseControl c : getControls()) { + if (c.getOID().equals(oid)) { + return c; + } + } + } + return null; + } + + + /** + * Returns the referral URLs produced by the ldap operation. + * + * @return referral urls + */ + public String[] getReferralURLs() + { + return referralURLs; + } + + + @Override + public int getMessageId() + { + return messageId; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::result=%s, resultCode=%s, message=%s, matchedDn=%s, " + + "responseControls=%s, referralURLs=%s, messageId=%s]", + getClass().getName(), + hashCode(), + result, + resultCode, + message, + matchedDn, + Arrays.toString(responseControls), + Arrays.toString(referralURLs), + messageId); + } +}
diff --git a/core/src/main/java/org/ldaptive/ResponseMessage.java b/core/src/main/java/org/ldaptive/ResponseMessage.java new file mode 100644 index 0000000..9628044 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ResponseMessage.java
@@ -0,0 +1,31 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.ldaptive.control.ResponseControl; + +/** + * Interface for ldap response messages. + * + * @author Middleware Services + */ +public interface ResponseMessage extends Message<ResponseControl> +{ + + + /** + * Returns the first response control with the supplied OID for this response message. + * + * @param oid of the response control to return + * + * @return response control or null if control could not be found + */ + ResponseControl getControl(String oid); + + + /** + * Returns the message ID for this response message. + * + * @return message id + */ + int getMessageId(); +}
diff --git a/core/src/main/java/org/ldaptive/ResultCode.java b/core/src/main/java/org/ldaptive/ResultCode.java new file mode 100644 index 0000000..22c7957 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ResultCode.java
@@ -0,0 +1,266 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Enum to define ldap result codes. + * + * @author Middleware Services + */ +public enum ResultCode { + + /** success. */ + SUCCESS(0), + + /** operations error. */ + OPERATIONS_ERROR(1), + + /** protocol error. */ + PROTOCOL_ERROR(2), + + /** time limit exceeded. */ + TIME_LIMIT_EXCEEDED(3), + + /** size limit exceeded. */ + SIZE_LIMIT_EXCEEDED(4), + + /** compare false. */ + COMPARE_FALSE(5), + + /** compare true. */ + COMPARE_TRUE(6), + + /** authentication method not supported. */ + AUTH_METHOD_NOT_SUPPORTED(7), + + /** strong authentication required. */ + STRONG_AUTH_REQUIRED(8), + + /** partial results. */ + PARTIAL_RESULTS(9), + + /** referral. */ + REFERRAL(10), + + /** admin limit exceeded. */ + ADMIN_LIMIT_EXCEEDED(11), + + /** unavailable critical extension. */ + UNAVAILABLE_CRITICAL_EXTENSION(12), + + /** confidentiality required. */ + CONFIDENTIALITY_REQUIRED(13), + + /** sasl bind in progress. */ + SASL_BIND_IN_PROGRESS(14), + + /** no such attribute. */ + NO_SUCH_ATTRIBUTE(16), + + /** undefined attribute type. */ + UNDEFINED_ATTRIBUTE_TYPE(17), + + /** inappropriate matching. */ + INAPPROPRIATE_MATCHING(18), + + /** constraint violation. */ + CONSTRAINT_VIOLATION(19), + + /** attribute or value exists. */ + ATTRIBUTE_OR_VALUE_EXISTS(20), + + /** invalid attribute syntax. */ + INVALID_ATTRIBUTE_SYNTAX(21), + + /** no such object. */ + NO_SUCH_OBJECT(32), + + /** alias problem. */ + ALIAS_PROBLEM(33), + + /** invalid dn syntax. */ + INVALID_DN_SYNTAX(34), + + /** is leaf. */ + IS_LEAF(35), + + /** alias dereferencing problem. */ + ALIAS_DEREFERENCING_PROBLEM(36), + + /** inappropriate authentication. */ + INAPPROPRIATE_AUTHENTICATION(48), + + /** invalid credentials. */ + INVALID_CREDENTIALS(49), + + /** insufficient access rights. */ + INSUFFICIENT_ACCESS_RIGHTS(50), + + /** busy. */ + BUSY(51), + + /** unavailable. */ + UNAVAILABLE(52), + + /** unwilling to perform. */ + UNWILLING_TO_PERFORM(53), + + /** loop detect. */ + LOOP_DETECT(54), + + /** sort control missing, See draft-ietf-ldapext-ldapv3-vlv. */ + SORT_CONTROL_MISSING(60), + + /** offset range error, See draft-ietf-ldapext-ldapv3-vlv. */ + OFFSET_RANGE_ERROR(61), + + /** naming violation. */ + NAMING_VIOLATION(64), + + /** object class violation. */ + OBJECT_CLASS_VIOLATION(65), + + /** not allowed on nonleaf. */ + NOT_ALLOWED_ON_NONLEAF(66), + + /** not allowed on rdn. */ + NOT_ALLOWED_ON_RDN(67), + + /** entry already exists. */ + ENTRY_ALREADY_EXISTS(68), + + /** object class mods prohibited. */ + OBJECT_CLASS_MODS_PROHIBITED(69), + + /** affected multiple dsas. */ + AFFECTS_MULTIPLE_DSAS(71), + + /** virtual list view error, See draft-ietf-ldapext-ldapv3-vlv. */ + VIRTUAL_LIST_VIEW_ERROR(76), + + /** other. */ + OTHER(80), + + /** server down. */ + SERVER_DOWN(81), + + /** local error. */ + LOCAL_ERROR(82), + + /** encoding error. */ + ENCODING_ERROR(83), + + /** decoding error. */ + DECODING_ERROR(84), + + /** ldap timeout. */ + LDAP_TIMEOUT(85), + + /** auth unknown. */ + AUTH_UNKNOWN(86), + + /** filter error. */ + FILTER_ERROR(87), + + /** user cancelled. */ + USER_CANCELLED(88), + + /** param error. */ + PARAM_ERROR(89), + + /** no memory. */ + NO_MEMORY(90), + + /** connect error. */ + CONNECT_ERROR(91), + + /** ldap not supported. */ + LDAP_NOT_SUPPORTED(92), + + /** control not found. */ + CONTROL_NOT_FOUND(93), + + /** no results returned. */ + NO_RESULTS_RETURNED(94), + + /** more results to return. */ + MORE_RESULTS_TO_RETURN(95), + + /** client loop. */ + CLIENT_LOOP(96), + + /** referral limit exceeded. */ + REFERRAL_LIMIT_EXCEEDED(97), + + /** invalid response. */ + INVALID_RESPONSE(100), + + /** ambiguous response. */ + AMBIGUOUS_RESPONSE(101), + + /** tls not supported. */ + TLS_NOT_SUPPORTED(112), + + /** operation canceled, See RFC 3909. */ + CANCELED(118), + + /** no such operation, See RFC 3909. */ + NO_SUCH_OPERATION(119), + + /** too late, See RFC 3909. */ + TOO_LATE(120), + + /** cannot cancel, See RFC 3909. */ + CANNOT_CANCEL(121), + + /** assertion failed, See RFC 4528. */ + ASSERTION_FAILED(122), + + /** authorization denied, See RFC 4370. */ + AUTHORIZATION_DENIED(123), + + /** e-syncRefreshRequired, See RFC 4533. */ + E_SYNC_REFRESH_REQUIRED(4096); + + /** underlying error code. */ + private final int code; + + + /** + * Creates a new result code. + * + * @param i error code + */ + ResultCode(final int i) + { + code = i; + } + + + /** + * Returns the result code value. + * + * @return ldap result code + */ + public int value() + { + return code; + } + + + /** + * Returns the result code for the supplied integer constant. + * + * @param code to find result code for + * + * @return result code + */ + public static ResultCode valueOf(final int code) + { + for (ResultCode rc : ResultCode.values()) { + if (rc.value() == code) { + return rc; + } + } + return null; + } +}
diff --git a/core/src/main/java/org/ldaptive/ReturnAttributes.java b/core/src/main/java/org/ldaptive/ReturnAttributes.java new file mode 100644 index 0000000..b8abd59 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ReturnAttributes.java
@@ -0,0 +1,98 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; + +/** + * Enum to define constants specific to ldap return attributes. + * + * @author Middleware Services + */ +public enum ReturnAttributes { + + /** all user and operational attributes. */ + ALL(new String[] {"*", "+"}), + + /** all user attributes. */ + ALL_USER(new String[] {"*"}), + + /** all operational attributes. */ + ALL_OPERATIONAL(new String[] {"+"}), + + /** no attributes. */ + NONE(new String[] {"1.1"}), + + /** default, which is all user attributes. */ + DEFAULT(new String[] {}); + + /** underlying value. */ + private final String[] value; + + + /** + * Creates a new return attributes. + * + * @param s value + */ + ReturnAttributes(final String[] s) + { + value = s; + } + + + /** + * Returns the value(s). + * + * @return ldap return attribute + */ + public String[] value() + { + return value; + } + + + /** + * Returns whether the supplied attributes matches the value of this return attributes. + * + * @param attrs to compare + * + * @return whether attrs contains only this return attributes + */ + public boolean equalsAttributes(final String... attrs) + { + return Arrays.equals(value, attrs); + } + + + /** + * Combines the supplied attributes with the value of this return attributes. + * + * @param attrs to combine + * + * @return combined attributes + */ + public String[] add(final String... attrs) + { + return LdapUtils.concatArrays(value, attrs); + } + + + /** + * Parses the supplied return attributes and applies the following convention: + * + * <ul> + * <li>null == {@link ReturnAttributes#DEFAULT}</li> + * </ul> + * + * @param attrs to parse + * + * @return parsed attributes according to convention + */ + public static String[] parse(final String... attrs) + { + if (attrs == null) { + return ReturnAttributes.DEFAULT.value(); + } + return attrs; + } +}
diff --git a/core/src/main/java/org/ldaptive/RoundRobinConnectionStrategy.java b/core/src/main/java/org/ldaptive/RoundRobinConnectionStrategy.java new file mode 100644 index 0000000..572ce48 --- /dev/null +++ b/core/src/main/java/org/ldaptive/RoundRobinConnectionStrategy.java
@@ -0,0 +1,103 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Connection strategy that attempts each URL in the order they are configured. The next attempt uses the next URL in + * the list. The class orders the URLs by computing a modulus with the connection count. Since metadata is stored per + * connection, computing the URL based on connection count may not give the desired result when using a connection pool. + * Set {@link #useConnectionCount} to false if using this strategy with a connection pool. + * + * @author Middleware Services + */ +public class RoundRobinConnectionStrategy implements ConnectionStrategy +{ + + /** Internal method invocation counter. */ + private int invocationCount; + + /** + * Whether {@link #getLdapUrls(ConnectionFactoryMetadata)} should use the connectionCount parameter or the {@link + * #invocationCount}. + */ + private final boolean useConnectionCount; + + + /** Creates a new round robin connection strategy. */ + public RoundRobinConnectionStrategy() + { + this(true); + } + + + /** + * Creates a new round robin connection strategy. + * + * @param b whether {@link #getLdapUrls(ConnectionFactoryMetadata)} should use the connectionCount parameter + */ + public RoundRobinConnectionStrategy(final boolean b) + { + useConnectionCount = b; + } + + + /** + * Return a list of URLs that cycles the list order. The first entry is moved to the end of the list for each + * invocation. + * + * @param metadata which can be used to produce the URL list + * + * @return list of URLs to attempt connections to + */ + @Override + public String[] getLdapUrls(final ConnectionFactoryMetadata metadata) + { + if (metadata == null || metadata.getLdapUrl() == null) { + return null; + } + + final List<String> l = new ArrayList<>(Arrays.asList(metadata.getLdapUrl().split(" "))); + final int count = getCount(metadata.getConnectionCount()); + for (int i = 0; i < count % l.size(); i++) { + l.add(l.remove(0)); + } + return l.toArray(new String[l.size()]); + } + + + /** + * Returns the supplied connection count if {@link #useConnectionCount} is true. Otherwise returns {@link + * #invocationCount}. + * + * @param connectionCount as reported by the connection + * + * @return count used to reorder the URL list + */ + protected int getCount(final int connectionCount) + { + if (useConnectionCount) { + return connectionCount; + } + return returnAndIncrementInvocationCount(); + } + + + /** + * Increments the internal invocation count and returns the previous value. + * + * @return previous invocation count + */ + private int returnAndIncrementInvocationCount() + { + final int i = invocationCount; + invocationCount++; + // reset the count if it exceeds the size of an integer + if (invocationCount < 0) { + invocationCount = 0; + } + return i; + } +}
diff --git a/core/src/main/java/org/ldaptive/SearchEntry.java b/core/src/main/java/org/ldaptive/SearchEntry.java new file mode 100644 index 0000000..c235f70 --- /dev/null +++ b/core/src/main/java/org/ldaptive/SearchEntry.java
@@ -0,0 +1,123 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; +import org.ldaptive.control.ResponseControl; + +/** + * Simple bean representing a search entry. + * + * @author Middleware Services + */ +public class SearchEntry extends LdapEntry implements ResponseMessage +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 347; + + /** serial version uid. */ + private static final long serialVersionUID = 3016288847468612093L; + + /** response controls. */ + private final ResponseControl[] responseControls; + + /** message ID. */ + private final int messageId; + + + /** + * Creates a new search entry. + * + * @param id message id + * @param c response controls + */ + public SearchEntry(final int id, final ResponseControl[] c) + { + messageId = id; + responseControls = c; + } + + + /** + * Creates a new search entry. + * + * @param id message id + * @param c response controls + * @param sb sort behavior + */ + public SearchEntry(final int id, final ResponseControl[] c, final SortBehavior sb) + { + super(sb); + messageId = id; + responseControls = c; + } + + + @Override + public ResponseControl[] getControls() + { + return responseControls; + } + + + @Override + public ResponseControl getControl(final String oid) + { + if (getControls() != null) { + for (ResponseControl c : getControls()) { + if (c.getOID().equals(oid)) { + return c; + } + } + } + return null; + } + + + @Override + public int getMessageId() + { + return messageId; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (super.equals(o)) { + final SearchEntry v = (SearchEntry) o; + return LdapUtils.areEqual(messageId, v.messageId) && + LdapUtils.areEqual(responseControls, v.responseControls); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + getDn() != null ? getDn().toLowerCase() : null, + getAttributes(), + messageId, + responseControls); + } + + + @Override + public String toString() + { + return + String.format( + "[dn=%s%s, responseControls=%s, messageId=%s]", + getDn(), + getAttributes(), + Arrays.toString(responseControls), + messageId); + } +}
diff --git a/core/src/main/java/org/ldaptive/SearchExecutor.java b/core/src/main/java/org/ldaptive/SearchExecutor.java new file mode 100644 index 0000000..d37aa9a --- /dev/null +++ b/core/src/main/java/org/ldaptive/SearchExecutor.java
@@ -0,0 +1,233 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.ldaptive.cache.Cache; +import org.ldaptive.handler.OperationExceptionHandler; +import org.ldaptive.handler.OperationResponseHandler; +import org.ldaptive.handler.SearchEntryHandler; + +/** + * Helper class which encapsulates the try, finally idiom used to execute a {@link SearchOperation}. This is a + * convenience class for searching if you don't need to manage individual connections. In addition, this class provides + * a way to hold common search request properties constant while changing properties that tend to be more dynamic. + * + * @author Middleware Services + */ +public class SearchExecutor extends SearchRequest +{ + + /** Handler to handle search exceptions. */ + private OperationExceptionHandler<SearchRequest, SearchResult> searchExceptionHandler; + + /** Handlers to handle search responses. */ + private OperationResponseHandler<SearchRequest, SearchResult>[] searchResponseHandlers; + + /** Cache to use when performing searches. */ + private Cache<SearchRequest> searchCache; + + + /** + * Returns the search exception handler. + * + * @return search exception handler + */ + public OperationExceptionHandler<SearchRequest, SearchResult> getSearchExceptionHandler() + { + return searchExceptionHandler; + } + + + /** + * Sets the search exception handler. + * + * @param handler search exception handler + */ + public void setSearchExceptionHandler(final OperationExceptionHandler<SearchRequest, SearchResult> handler) + { + searchExceptionHandler = handler; + } + + + /** + * Returns the search response handlers. + * + * @return search response handlers + */ + public OperationResponseHandler<SearchRequest, SearchResult>[] getSearchResponseHandlers() + { + return searchResponseHandlers; + } + + + /** + * Sets the search response handlers. + * + * @param handlers search response handlers + */ + @SuppressWarnings("unchecked") + public void setSearchResponseHandlers(final OperationResponseHandler<SearchRequest, SearchResult>... handlers) + { + searchResponseHandlers = handlers; + } + + + /** + * Returns the search cache. + * + * @return cache + */ + public Cache<SearchRequest> getSearchCache() + { + return searchCache; + } + + + /** + * Sets the search cache. + * + * @param cache to set + */ + public void setSearchCache(final Cache<SearchRequest> cache) + { + searchCache = cache; + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * + * @return search result + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> search(final ConnectionFactory factory) + throws LdapException + { + return search(factory, null, null, (SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * @param filter to search with + * + * @return search result + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> search(final ConnectionFactory factory, final String filter) + throws LdapException + { + return search(factory, new SearchFilter(filter), null, (SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * @param filter to search with + * + * @return search result + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> search(final ConnectionFactory factory, final SearchFilter filter) + throws LdapException + { + return search(factory, filter, null, (SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * @param filter to search with + * @param attrs to return + * + * @return search result + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> search(final ConnectionFactory factory, final String filter, final String... attrs) + throws LdapException + { + return search(factory, new SearchFilter(filter), attrs, (SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * @param filter to search with + * @param attrs to return + * + * @return search result + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> search( + final ConnectionFactory factory, + final SearchFilter filter, + final String... attrs) + throws LdapException + { + return search(factory, filter, attrs, (SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * @param filter to search with + * @param attrs to return + * @param handlers entry handlers + * + * @return search result + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> search( + final ConnectionFactory factory, + final SearchFilter filter, + final String[] attrs, + final SearchEntryHandler... handlers) + throws LdapException + { + Response<SearchResult> response; + try (Connection conn = factory.getConnection()) { + conn.open(); + + final SearchOperation op = new SearchOperation(conn); + if (searchExceptionHandler != null) { + op.setOperationExceptionHandler(searchExceptionHandler); + } + if (searchResponseHandlers != null) { + op.setOperationResponseHandlers(searchResponseHandlers); + } + if (searchCache != null) { + op.setCache(searchCache); + } + + final SearchRequest sr = newSearchRequest(this); + if (filter != null) { + sr.setSearchFilter(filter); + } + if (attrs != null) { + sr.setReturnAttributes(attrs); + } + if (handlers != null) { + sr.setSearchEntryHandlers(handlers); + } + response = op.execute(sr); + } + return response; + } +}
diff --git a/core/src/main/java/org/ldaptive/SearchFilter.java b/core/src/main/java/org/ldaptive/SearchFilter.java new file mode 100644 index 0000000..737113d --- /dev/null +++ b/core/src/main/java/org/ldaptive/SearchFilter.java
@@ -0,0 +1,282 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Simple bean for an ldap search filter and it's parameters. + * + * @author Middleware Services + */ +public class SearchFilter +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 311; + + /** filter. */ + private String searchFilter; + + /** filter parameters. */ + private final Map<String, Object> parameters = new HashMap<>(); + + + /** Default constructor. */ + public SearchFilter() {} + + + /** + * Creates a new search filter with the supplied filter. + * + * @param filter to set + */ + public SearchFilter(final String filter) + { + setFilter(filter); + } + + + /** + * Creates a new search filter with the supplied filter and parameters. + * + * @param filter to set + * @param params to set + */ + public SearchFilter(final String filter, final Object[] params) + { + setFilter(filter); + setParameters(params); + } + + + /** + * Gets the filter. + * + * @return filter + */ + public String getFilter() + { + return searchFilter; + } + + + /** + * Sets the filter. + * + * @param filter to set + */ + public void setFilter(final String filter) + { + searchFilter = filter; + } + + + /** + * Gets the filter parameters. + * + * @return unmodifiable map of filter parameters + */ + public Map<String, Object> getParameters() + { + return Collections.unmodifiableMap(parameters); + } + + + /** + * Sets a positional filter parameter. + * + * @param position of the parameter in the filter + * @param value to set + */ + public void setParameter(final int position, final Object value) + { + parameters.put(Integer.toString(position), value); + } + + + /** + * Sets a named filter parameter. + * + * @param name of the parameter in the filter + * @param value to set + */ + public void setParameter(final String name, final Object value) + { + parameters.put(name, value); + } + + + /** + * Sets positional filter parameters. + * + * @param values to set + */ + public void setParameters(final Object[] values) + { + int i = 0; + for (Object o : values) { + parameters.put(Integer.toString(i++), o); + } + } + + + /** + * Returns this filter with it's parameters encoded and replaced. See {@link #encode(Object)}. + * + * @return formatted and encoded filter + */ + public String format() + { + String s = searchFilter; + if (!parameters.isEmpty()) { + for (Map.Entry<String, Object> e : parameters.entrySet()) { + final String encoded = encode(e.getValue()); + if (encoded != null) { + s = s.replace("{" + e.getKey() + "}", encoded); + } + } + } + return s; + } + + + /** + * Hex encodes the supplied byte array for use in a search filter. + * + * @param value to encode + * + * @return encoded value or null if supplied value is null + */ + public static String encodeValue(final byte[] value) + { + if (value == null) { + return null; + } + + final char[] c = LdapUtils.hexEncode(value); + final StringBuilder sb = new StringBuilder(c.length + c.length / 2); + for (int i = 0; i < c.length; i += 2) { + sb.append('\\').append(c[i]).append(c[i + 1]); + } + return sb.toString(); + } + + + /** + * Encodes the supplied attribute value for use in a search filter. See {@link #escape(String)}. + * + * @param value to encode + * + * @return encoded value or null if supplied value is null + */ + public static String encodeValue(final String value) + { + if (value == null) { + return null; + } + + return escape(value); + } + + + /** + * Hex encodes the supplied object if it is of type byte[], otherwise the string format of the object is escaped. See + * {@link #escape(String)}. + * + * @param obj to encode + * + * @return encoded object + */ + protected static String encode(final Object obj) + { + if (obj == null) { + return null; + } + + String str; + if (obj instanceof String) { + str = encodeValue((String) obj); + } else if (obj instanceof byte[]) { + str = encodeValue((byte[]) obj); + } else { + str = encodeValue(obj.toString()); + } + return str; + } + + + /** + * Escapes the supplied string per RFC 2254. + * + * @param s to escape + * + * @return escaped string + */ + private static String escape(final String s) + { + final int len = s.length(); + final StringBuilder sb = new StringBuilder(len); + char ch; + for (int i = 0; i < len; i++) { + ch = s.charAt(i); + switch (ch) { + + case '*': + sb.append("\\2a"); + break; + + case '(': + sb.append("\\28"); + break; + + case ')': + sb.append("\\29"); + break; + + case '\\': + sb.append("\\5c"); + break; + + case 0: + sb.append("\\00"); + break; + + default: + sb.append(ch); + } + } + return sb.toString(); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof SearchFilter) { + final SearchFilter v = (SearchFilter) o; + return LdapUtils.areEqual(searchFilter, v.searchFilter) && + LdapUtils.areEqual(parameters, v.parameters); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, searchFilter, parameters); + } + + + @Override + public String toString() + { + return + String.format("[%s@%d::filter=%s, parameters=%s]", getClass().getName(), hashCode(), searchFilter, parameters); + } +}
diff --git a/core/src/main/java/org/ldaptive/SearchOperation.java b/core/src/main/java/org/ldaptive/SearchOperation.java new file mode 100644 index 0000000..2e3e832 --- /dev/null +++ b/core/src/main/java/org/ldaptive/SearchOperation.java
@@ -0,0 +1,193 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.ldaptive.cache.Cache; +import org.ldaptive.handler.HandlerResult; +import org.ldaptive.intermediate.IntermediateResponse; +import org.ldaptive.provider.SearchItem; +import org.ldaptive.provider.SearchIterator; + +/** + * Executes an ldap search operation. + * + * @author Middleware Services + */ +public class SearchOperation extends AbstractOperation<SearchRequest, SearchResult> +{ + + /** Cache to use when performing searches. */ + private Cache<SearchRequest> cache; + + + /** + * Creates a new search operation. + * + * @param conn connection + */ + public SearchOperation(final Connection conn) + { + super(conn); + } + + + /** + * Creates a new search operation. + * + * @param conn connection + * @param c cache + */ + public SearchOperation(final Connection conn, final Cache<SearchRequest> c) + { + super(conn); + cache = c; + } + + + /** + * Returns the cache to check when performing search operations. When a cache is provided it will be populated as new + * searches are performed and used when a search request hits the cache. + * + * @return cache + */ + public Cache<SearchRequest> getCache() + { + return cache; + } + + + /** + * Sets the cache. + * + * @param c cache to set + */ + public void setCache(final Cache<SearchRequest> c) + { + cache = c; + } + + + @Override + protected Response<SearchResult> invoke(final SearchRequest request) + throws LdapException + { + Response<SearchResult> response; + if (cache != null) { + final SearchResult sr = cache.get(request); + if (sr == null) { + response = executeSearch(request); + cache.put(request, response.getResult()); + logger.debug("invoke stored result={} in cache", response.getResult()); + } else { + logger.debug("invoke found result={} in cache", sr); + response = new Response<>(sr, null); + } + } else { + response = executeSearch(request); + } + return response; + } + + + /** + * Performs the ldap search. + * + * @param request to invoke search with + * + * @return ldap response + * + * @throws LdapException if an error occurs + */ + protected Response<SearchResult> executeSearch(final SearchRequest request) + throws LdapException + { + final SearchIterator si = getConnection().getProviderConnection().search(request); + final SearchResult result = readResult(request, si); + final Response<Void> response = si.getResponse(); + return + new Response<>( + result, + response.getResultCode(), + response.getMessage(), + response.getMatchedDn(), + response.getControls(), + response.getReferralURLs(), + response.getMessageId()); + } + + + /** + * Invokes the provider search operation and iterates over the results. Invokes handlers as necessary for each result + * type. + * + * @param request used to create the search iterator + * @param si search iterator + * + * @return search result + * + * @throws LdapException if an error occurs + */ + protected SearchResult readResult(final SearchRequest request, final SearchIterator si) + throws LdapException + { + final SearchResult result = new SearchResult(request.getSortBehavior()); + try { + while (si.hasNext()) { + final SearchItem item = si.next(); + logger.trace("Received search item={}", item); + if (item.isSearchEntry()) { + final SearchEntry se = item.getSearchEntry(); + if (se != null) { + final HandlerResult<SearchEntry> hr = executeHandlers(request.getSearchEntryHandlers(), request, se); + if (hr.getResult() != null) { + result.addEntry(hr.getResult()); + } + if (hr.getAbort()) { + logger.debug("Aborting search on entry=%s", se); + break; + } + } + } else if (item.isSearchReference()) { + final SearchReference sr = item.getSearchReference(); + if (sr != null) { + final HandlerResult<SearchReference> hr = executeHandlers( + request.getSearchReferenceHandlers(), + request, + sr); + if (hr.getResult() != null) { + final SearchReference reference = hr.getResult(); + final Response<SearchResult> refResponse = reference.getReferenceResponse(); + if (refResponse != null) { + if (refResponse.getResultCode() == ResultCode.SUCCESS) { + result.addEntries(refResponse.getResult().getEntries()); + } else { + result.addReference(reference); + } + } else { + result.addReference(reference); + } + } + if (hr.getAbort()) { + logger.debug("Aborting search on reference=%s", sr); + break; + } + } + } else if (item.isIntermediateResponse()) { + final IntermediateResponse ir = item.getIntermediateResponse(); + if (ir != null) { + final HandlerResult<IntermediateResponse> hr = executeHandlers( + request.getIntermediateResponseHandlers(), + request, + ir); + if (hr.getAbort()) { + logger.debug("Aborting search on intermediate response=%s", ir); + break; + } + } + } + } + } finally { + si.close(); + } + return result; + } +}
diff --git a/core/src/main/java/org/ldaptive/SearchReference.java b/core/src/main/java/org/ldaptive/SearchReference.java new file mode 100644 index 0000000..752fe6b --- /dev/null +++ b/core/src/main/java/org/ldaptive/SearchReference.java
@@ -0,0 +1,144 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; +import java.util.Collection; +import org.ldaptive.control.ResponseControl; + +/** + * Simple bean representing a search reference. + * + * @author Middleware Services + */ +public class SearchReference implements ResponseMessage +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 349; + + /** referral urls. */ + private final String[] referralUrls; + + /** response controls. */ + private final ResponseControl[] responseControls; + + /** message ID. */ + private final int messageId; + + /** response from following the reference. */ + private Response<SearchResult> referenceResponse; + + + /** + * Creates a search reference. + * + * @param id message id + * @param c response controls + * @param url referral urls + */ + public SearchReference(final int id, final ResponseControl[] c, final String... url) + { + messageId = id; + responseControls = c; + referralUrls = url; + } + + + /** + * Creates a search reference. + * + * @param id message id + * @param c response controls + * @param urls referral urls + */ + public SearchReference(final int id, final ResponseControl[] c, final Collection<String> urls) + { + messageId = id; + responseControls = c; + referralUrls = urls.toArray(new String[urls.size()]); + } + + + /** + * Returns the referral urls for this search reference. + * + * @return referral urls + */ + public String[] getReferralUrls() + { + return referralUrls; + } + + + @Override + public ResponseControl[] getControls() + { + return responseControls; + } + + + @Override + public ResponseControl getControl(final String oid) + { + if (getControls() != null) { + for (ResponseControl c : getControls()) { + if (c.getOID().equals(oid)) { + return c; + } + } + } + return null; + } + + + @Override + public int getMessageId() + { + return messageId; + } + + + /** + * Returns the response from following the reference. + * + * @return reference response or null. + */ + public Response<SearchResult> getReferenceResponse() + { + return referenceResponse; + } + + + /** + * Sets the response from following the reference. + * + * @param response from following the reference + */ + public void setReferenceResponse(final Response<SearchResult> response) + { + referenceResponse = response; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, referralUrls, responseControls, messageId); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::referralUrls=%s, responseControls=%s, " + + "messageId=%s, referenceResponse=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(referralUrls), + Arrays.toString(responseControls), + messageId, + referenceResponse); + } +}
diff --git a/core/src/main/java/org/ldaptive/SearchRequest.java b/core/src/main/java/org/ldaptive/SearchRequest.java new file mode 100644 index 0000000..85581e8 --- /dev/null +++ b/core/src/main/java/org/ldaptive/SearchRequest.java
@@ -0,0 +1,554 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.time.Duration; +import java.util.Arrays; +import org.ldaptive.handler.SearchEntryHandler; +import org.ldaptive.handler.SearchReferenceHandler; + +/** + * Contains the data required to perform an ldap search operation. + * + * @author Middleware Services + */ +public class SearchRequest extends AbstractRequest +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 307; + + /** DN to search. */ + private String baseDn = ""; + + /** Search filter to execute. */ + private SearchFilter searchFilter; + + /** Attributes to return. */ + private String[] retAttrs = ReturnAttributes.DEFAULT.value(); + + /** Search scope. */ + private SearchScope searchScope = SearchScope.SUBTREE; + + /** Time search operation will block. */ + private Duration timeLimit = Duration.ZERO; + + /** Number of entries to return. */ + private long sizeLimit; + + /** How to handle aliases. */ + private DerefAliases derefAliases; + + /** Whether to return only attribute types. */ + private boolean typesOnly; + + /** Binary attribute names. */ + private String[] binaryAttrs; + + /** Sort behavior of results. */ + private SortBehavior sortBehavior = SortBehavior.getDefaultSortBehavior(); + + /** Ldap entry handlers. */ + private SearchEntryHandler[] entryHandlers; + + /** Search reference handlers. */ + private SearchReferenceHandler[] referenceHandlers; + + + /** Default constructor. */ + public SearchRequest() {} + + + /** + * Creates a new search request. + * + * @param dn to search + * @param filter search filter + */ + public SearchRequest(final String dn, final SearchFilter filter) + { + setBaseDn(dn); + setSearchFilter(filter); + } + + + /** + * Creates a new search request. + * + * @param dn to search + * @param filter search filter + * @param attrs to return + */ + public SearchRequest(final String dn, final SearchFilter filter, final String... attrs) + { + setBaseDn(dn); + setSearchFilter(filter); + setReturnAttributes(attrs); + } + + + /** + * Creates a new search request. + * + * @param dn to search + * @param filter search filter + */ + public SearchRequest(final String dn, final String filter) + { + setBaseDn(dn); + setSearchFilter(new SearchFilter(filter)); + } + + + /** + * Creates a new search request. + * + * @param dn to search + * @param filter search filter + * @param attrs to return + */ + public SearchRequest(final String dn, final String filter, final String... attrs) + { + setBaseDn(dn); + setSearchFilter(new SearchFilter(filter)); + setReturnAttributes(attrs); + } + + + /** + * Returns the base DN. + * + * @return base DN + */ + public String getBaseDn() + { + return baseDn; + } + + + /** + * Sets the base DN. + * + * @param dn base DN + */ + public void setBaseDn(final String dn) + { + baseDn = dn; + } + + + /** + * Returns the search filter. + * + * @return search filter + */ + public SearchFilter getSearchFilter() + { + return searchFilter; + } + + + /** + * Sets the search filter. + * + * @param filter search filter + */ + public void setSearchFilter(final SearchFilter filter) + { + searchFilter = filter; + } + + + /** + * Returns the search return attributes. + * + * @return search return attributes + */ + public String[] getReturnAttributes() + { + return retAttrs; + } + + + /** + * Sets the search return attributes. + * + * @param attrs search return attributes + */ + public void setReturnAttributes(final String... attrs) + { + retAttrs = ReturnAttributes.parse(attrs); + } + + + /** + * Gets the search scope. + * + * @return search scope + */ + public SearchScope getSearchScope() + { + return searchScope; + } + + + /** + * Sets the search scope. + * + * @param scope search scope + */ + public void setSearchScope(final SearchScope scope) + { + searchScope = scope; + } + + + /** + * Returns the time limit. + * + * @return time limit + */ + public Duration getTimeLimit() + { + return timeLimit; + } + + + /** + * Sets the time limit. + * + * @param limit time limit + */ + public void setTimeLimit(final Duration limit) + { + if (limit == null || limit.isNegative()) { + throw new IllegalArgumentException("Time limit cannot be null or negative"); + } + timeLimit = limit; + } + + + /** + * Returns the size limit. + * + * @return size limit + */ + public long getSizeLimit() + { + return sizeLimit; + } + + + /** + * Sets the size limit. + * + * @param limit size limit + */ + public void setSizeLimit(final long limit) + { + sizeLimit = limit; + } + + + /** + * Returns how to dereference aliases. + * + * @return how to dereference aliases + */ + public DerefAliases getDerefAliases() + { + return derefAliases; + } + + + /** + * Sets how to dereference aliases. + * + * @param da how to dereference aliases + */ + public void setDerefAliases(final DerefAliases da) + { + derefAliases = da; + } + + + /** + * Returns whether to return only attribute types. + * + * @return whether to return only attribute types + */ + public boolean getTypesOnly() + { + return typesOnly; + } + + + /** + * Sets whether to return only attribute types. + * + * @param b whether to return only attribute types + */ + public void setTypesOnly(final boolean b) + { + typesOnly = b; + } + + + /** + * Returns names of binary attributes. + * + * @return binary attribute names + */ + public String[] getBinaryAttributes() + { + return binaryAttrs; + } + + + /** + * Sets names of binary attributes. + * + * @param attrs binary attribute names + */ + public void setBinaryAttributes(final String... attrs) + { + binaryAttrs = attrs; + } + + + /** + * Returns the sort behavior. + * + * @return sort behavior + */ + public SortBehavior getSortBehavior() + { + return sortBehavior; + } + + + /** + * Sets the sort behavior. + * + * @param sb sort behavior + */ + public void setSortBehavior(final SortBehavior sb) + { + sortBehavior = sb; + } + + + /** + * Returns the search entry handlers. + * + * @return search entry handlers + */ + public SearchEntryHandler[] getSearchEntryHandlers() + { + return entryHandlers; + } + + + /** + * Sets the search entry handlers. + * + * @param handlers search entry handlers + */ + public void setSearchEntryHandlers(final SearchEntryHandler... handlers) + { + if (handlers != null) { + for (SearchEntryHandler handler : handlers) { + handler.initializeRequest(this); + } + } + entryHandlers = handlers; + } + + + /** + * Returns the search reference handlers. + * + * @return search reference handlers + */ + public SearchReferenceHandler[] getSearchReferenceHandlers() + { + return referenceHandlers; + } + + + /** + * Sets the search reference handlers. + * + * @param handlers search reference handlers + */ + public void setSearchReferenceHandlers(final SearchReferenceHandler... handlers) + { + if (handlers != null) { + for (SearchReferenceHandler handler : handlers) { + handler.initializeRequest(this); + } + } + referenceHandlers = handlers; + } + + + /** + * Returns a search request initialized for use with an object level search scope. + * + * @param dn of an ldap entry + * + * @return search request + */ + public static SearchRequest newObjectScopeSearchRequest(final String dn) + { + return newObjectScopeSearchRequest(dn, null); + } + + + /** + * Returns a search request initialized for use with an object level search scope. + * + * @param dn of an ldap entry + * @param attrs to return + * + * @return search request + */ + public static SearchRequest newObjectScopeSearchRequest(final String dn, final String[] attrs) + { + return newObjectScopeSearchRequest(dn, attrs, new SearchFilter("(objectClass=*)")); + } + + + /** + * Returns a search request initialized for use with an object level search scope. + * + * @param dn of an ldap entry + * @param attrs to return + * @param filter to execute on the ldap entry + * + * @return search request + */ + public static SearchRequest newObjectScopeSearchRequest( + final String dn, + final String[] attrs, + final SearchFilter filter) + { + final SearchRequest request = new SearchRequest(); + request.setBaseDn(dn); + request.setSearchFilter(filter); + request.setReturnAttributes(attrs); + request.setSearchScope(SearchScope.OBJECT); + return request; + } + + + /** + * Returns a search request initialized with the supplied request. Note that stateful ldap entry handlers could cause + * thread safety issues. + * + * @param request search request to read properties from + * + * @return search request + */ + protected static SearchRequest newSearchRequest(final SearchRequest request) + { + final SearchRequest sr = new SearchRequest(); + sr.setBaseDn(request.getBaseDn()); + sr.setBinaryAttributes(request.getBinaryAttributes()); + sr.setDerefAliases(request.getDerefAliases()); + sr.setSearchEntryHandlers(request.getSearchEntryHandlers()); + sr.setSearchReferenceHandlers(request.getSearchReferenceHandlers()); + sr.setReturnAttributes(request.getReturnAttributes()); + sr.setSearchFilter(request.getSearchFilter()); + sr.setSearchScope(request.getSearchScope()); + sr.setSizeLimit(request.getSizeLimit()); + sr.setSortBehavior(request.getSortBehavior()); + sr.setTimeLimit(request.getTimeLimit()); + sr.setTypesOnly(request.getTypesOnly()); + sr.setControls(request.getControls()); + sr.setReferralHandler(request.getReferralHandler()); + sr.setIntermediateResponseHandlers(request.getIntermediateResponseHandlers()); + return sr; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof SearchRequest) { + final SearchRequest v = (SearchRequest) o; + return LdapUtils.areEqual(baseDn, v.baseDn) && + LdapUtils.areEqual(binaryAttrs, v.binaryAttrs) && + LdapUtils.areEqual(derefAliases, v.derefAliases) && + LdapUtils.areEqual(entryHandlers, v.entryHandlers) && + LdapUtils.areEqual(referenceHandlers, v.referenceHandlers) && + LdapUtils.areEqual(retAttrs, v.retAttrs) && + LdapUtils.areEqual(searchFilter, v.searchFilter) && + LdapUtils.areEqual(searchScope, v.searchScope) && + LdapUtils.areEqual(sizeLimit, v.sizeLimit) && + LdapUtils.areEqual(sortBehavior, v.sortBehavior) && + LdapUtils.areEqual(timeLimit, v.timeLimit) && + LdapUtils.areEqual(typesOnly, v.typesOnly) && + LdapUtils.areEqual(getControls(), v.getControls()) && + LdapUtils.areEqual(getReferralHandler(), v.getReferralHandler()) && + LdapUtils.areEqual(getIntermediateResponseHandlers(), v.getIntermediateResponseHandlers()); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + baseDn, + binaryAttrs, + derefAliases, + entryHandlers, + referenceHandlers, + retAttrs, + searchFilter, + searchScope, + sizeLimit, + sortBehavior, + timeLimit, + typesOnly, + getControls(), + getReferralHandler(), + getIntermediateResponseHandlers()); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::baseDn=%s, searchFilter=%s, returnAttributes=%s, " + + "searchScope=%s, timeLimit=%s, sizeLimit=%s, derefAliases=%s, " + + "typesOnly=%s, binaryAttributes=%s, sortBehavior=%s, " + + "searchEntryHandlers=%s, searchReferenceHandlers=%s, controls=%s, " + + "referralHandler=%s, intermediateResponseHandlers=%s]", + getClass().getName(), + hashCode(), + baseDn, + searchFilter, + Arrays.toString(retAttrs), + searchScope, + timeLimit, + sizeLimit, + derefAliases, + typesOnly, + Arrays.toString(binaryAttrs), + sortBehavior, + Arrays.toString(entryHandlers), + Arrays.toString(referenceHandlers), + Arrays.toString(getControls()), + getReferralHandler(), + Arrays.toString(getIntermediateResponseHandlers())); + } +}
diff --git a/core/src/main/java/org/ldaptive/SearchResult.java b/core/src/main/java/org/ldaptive/SearchResult.java new file mode 100644 index 0000000..9dda7e0 --- /dev/null +++ b/core/src/main/java/org/ldaptive/SearchResult.java
@@ -0,0 +1,395 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.TreeMap; +import java.util.TreeSet; + +/** + * Simple bean representing an ldap search result. Contains a map of entry DN to ldap entry. + * + * @author Middleware Services + */ +public class SearchResult extends AbstractLdapBean +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 337; + + /** serial version uid. */ + private static final long serialVersionUID = -4686725717997623766L; + + /** Entries contained in this result. */ + private final Map<String, LdapEntry> resultEntries; + + /** References contained in this result. */ + private final Collection<SearchReference> searchReferences; + + + /** Default constructor. */ + public SearchResult() + { + this(SortBehavior.getDefaultSortBehavior()); + } + + + /** + * Creates a new search result. + * + * @param sb sort behavior of the results + */ + public SearchResult(final SortBehavior sb) + { + super(sb); + if (SortBehavior.UNORDERED == sb) { + resultEntries = new HashMap<>(); + searchReferences = new HashSet<>(); + } else if (SortBehavior.ORDERED == sb) { + resultEntries = new LinkedHashMap<>(); + searchReferences = new LinkedHashSet<>(); + } else if (SortBehavior.SORTED == sb) { + resultEntries = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + searchReferences = new TreeSet<>( + (ref1, ref2) -> { + return Arrays.toString(ref1.getReferralUrls()).compareTo(Arrays.toString(ref2.getReferralUrls())); + }); + } else { + throw new IllegalArgumentException("Unknown sort behavior: " + sb); + } + } + + + /** + * Creates a new search result. + * + * @param entry ldap entry + */ + public SearchResult(final LdapEntry... entry) + { + this(); + for (LdapEntry e : entry) { + addEntry(e); + } + } + + + /** + * Creates a new search result. + * + * @param entries collection of ldap entries + */ + public SearchResult(final Collection<LdapEntry> entries) + { + this(); + addEntries(entries); + } + + + /** + * Returns a collection of ldap entry. + * + * @return collection of ldap entry + */ + public Collection<LdapEntry> getEntries() + { + return resultEntries.values(); + } + + + /** + * Returns a single entry of this result. If multiple entries exist the first entry returned by the underlying + * iterator is used. If no entries exist null is returned. + * + * @return single entry + */ + public LdapEntry getEntry() + { + if (resultEntries.isEmpty()) { + return null; + } + return resultEntries.values().iterator().next(); + } + + + /** + * Returns the ldap in this result with the supplied DN. + * + * @param dn of the entry to return + * + * @return ldap entry + */ + public LdapEntry getEntry(final String dn) + { + return resultEntries.get(dn.toLowerCase()); + } + + + /** + * Returns the entry DNs in this result. + * + * @return string array of entry DNs + */ + public String[] getEntryDns() + { + return resultEntries.keySet().toArray(new String[resultEntries.keySet().size()]); + } + + + /** + * Adds an entry to this search result. + * + * @param entry entry to add + */ + public void addEntry(final LdapEntry... entry) + { + for (LdapEntry e : entry) { + resultEntries.put(e.getDn().toLowerCase(), e); + } + } + + + /** + * Adds entry(s) to this search result. + * + * @param entries collection of entries to add + */ + public void addEntries(final Collection<LdapEntry> entries) + { + entries.forEach(this::addEntry); + } + + + /** + * Removes an entry from this search result. + * + * @param entry entry to remove + */ + public void removeEntry(final LdapEntry... entry) + { + for (LdapEntry e : entry) { + resultEntries.remove(e.getDn().toLowerCase()); + } + } + + + /** + * Removes the entry with the supplied dn from this search result. + * + * @param dn of entry to remove + */ + public void removeEntry(final String dn) + { + resultEntries.remove(dn.toLowerCase()); + } + + + /** + * Removes the entry(s) from this search result. + * + * @param entries collection of ldap entries to remove + */ + public void removeEntries(final Collection<LdapEntry> entries) + { + entries.forEach(this::removeEntry); + } + + + /** + * Returns a collection of ldap entry. + * + * @return collection of ldap entry + */ + public Collection<SearchReference> getReferences() + { + return searchReferences; + } + + + /** + * Returns a single search reference of this result. If multiple references exist the first references returned by the + * underlying iterator is used. If no references exist null is returned. + * + * @return single search references + */ + public SearchReference getReference() + { + if (searchReferences.isEmpty()) { + return null; + } + return searchReferences.iterator().next(); + } + + + /** + * Adds a reference to this search result. + * + * @param reference reference to add + */ + public void addReference(final SearchReference... reference) + { + Collections.addAll(searchReferences, reference); + } + + + /** + * Adds references(s) to this search result. + * + * @param references collection of references to add + */ + public void addReferences(final Collection<SearchReference> references) + { + references.forEach(this::addReference); + } + + + /** + * Removes a reference from this search result. + * + * @param reference reference to remove + */ + public void removeReference(final SearchReference... reference) + { + for (SearchReference r : reference) { + searchReferences.remove(r); + } + } + + + /** + * Removes the references(s) from this search result. + * + * @param references collection of search references to remove + */ + public void removeReferences(final Collection<SearchReference> references) + { + references.forEach(this::removeReference); + } + + + /** + * Returns a portion of this result between the specified fromIndex, inclusive, and toIndex, exclusive. If fromIndex + * and toIndex are equal, the return result is empty. The result of this method is undefined for unordered results. + * + * @param fromIndex low endpoint of the search result (inclusive) + * @param toIndex high endpoint of the search result (exclusive) + * + * @return portion of this search result + * + * @throws IndexOutOfBoundsException for illegal index values + */ + public SearchResult subResult(final int fromIndex, final int toIndex) + { + if (fromIndex < 0 || toIndex > resultEntries.size() || fromIndex > toIndex) { + throw new IndexOutOfBoundsException("Illegal index value"); + } + + final SearchResult result = new SearchResult(getSortBehavior()); + if (resultEntries.isEmpty() || fromIndex == toIndex) { + return result; + } + + int i = 0; + for (Map.Entry<String, LdapEntry> e : resultEntries.entrySet()) { + if (i >= fromIndex && i < toIndex) { + result.addEntry(e.getValue()); + } + i++; + } + return result; + } + + + /** + * Returns the number of entries in this search result. + * + * @return number of entries in this search result + */ + public int size() + { + return resultEntries.size(); + } + + + /** Removes all the entries in this search result. */ + public void clear() + { + resultEntries.clear(); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof SearchResult) { + final SearchResult v = (SearchResult) o; + return LdapUtils.areEqual(resultEntries, v.resultEntries) && + LdapUtils.areEqual(searchReferences, v.searchReferences); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, resultEntries.values(), searchReferences); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::entries=%s, references=%s]", + getClass().getName(), + hashCode(), + resultEntries.values(), + searchReferences); + } + + + /** + * Merges the entries in the supplied result into a single entry. This method always returns a search result of size + * zero or one. + * + * @param result search result containing entries to merge + * + * @return search result containing a single merged entry + */ + public static SearchResult mergeEntries(final SearchResult result) + { + LdapEntry mergedEntry = null; + if (result != null) { + for (LdapEntry le : result.getEntries()) { + if (mergedEntry == null) { + mergedEntry = le; + } else { + for (LdapAttribute la : le.getAttributes()) { + final LdapAttribute oldAttr = mergedEntry.getAttribute(la.getName()); + if (oldAttr == null) { + mergedEntry.addAttribute(la); + } else { + if (oldAttr.isBinary()) { + oldAttr.addBinaryValues(la.getBinaryValues()); + } else { + oldAttr.addStringValues(la.getStringValues()); + } + } + } + } + } + } + return mergedEntry != null ? new SearchResult(mergedEntry) : new SearchResult(); + } +}
diff --git a/core/src/main/java/org/ldaptive/SearchScope.java b/core/src/main/java/org/ldaptive/SearchScope.java new file mode 100644 index 0000000..57d04c2 --- /dev/null +++ b/core/src/main/java/org/ldaptive/SearchScope.java
@@ -0,0 +1,19 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Enum to define the type of search scope. + * + * @author Middleware Services + */ +public enum SearchScope { + + /** object level search. */ + OBJECT, + + /** one level search. */ + ONELEVEL, + + /** subtree search. */ + SUBTREE +}
diff --git a/core/src/main/java/org/ldaptive/SortBehavior.java b/core/src/main/java/org/ldaptive/SortBehavior.java new file mode 100644 index 0000000..9052059 --- /dev/null +++ b/core/src/main/java/org/ldaptive/SortBehavior.java
@@ -0,0 +1,68 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Enum to define how ldap result, entries, and attribute data should be sorted. Default sort behavior can be controlled + * with the org.ldaptive.sortBehavior system property. This property must be the fully qualified name of a sort + * behavior. + * + * @author Middleware Services + */ +public enum SortBehavior { + + /** unordered results. */ + UNORDERED, + + /** ordered results. */ + ORDERED, + + /** sorted results. */ + SORTED; + + /** Sort behavior name. */ + public static final String SORT_BEHAVIOR = "org.ldaptive.sortBehavior"; + + /** Logger for this class. */ + private static final Logger LOGGER = LoggerFactory.getLogger(SortBehavior.class); + + /** Default sort behavior. */ + private static SortBehavior defaultSortBehavior; + + /** + * statically initialize the default sort behavior. + */ + static { + final String sb = System.getProperty(SORT_BEHAVIOR); + if (sb != null) { + try { + final SortBehavior sortBehavior; + if (sb.startsWith(SortBehavior.class.getName())) { + sortBehavior = SortBehavior.valueOf(sb.substring(SortBehavior.class.getName().length() + 1, sb.length())); + } else { + sortBehavior = SortBehavior.valueOf(sb); + } + LOGGER.info("Setting default sort behavior to {}", sortBehavior); + defaultSortBehavior = sortBehavior; + } catch (IllegalArgumentException e) { + LOGGER.error("Error instantiating {}", sb, e); + } + } + if (defaultSortBehavior == null) { + defaultSortBehavior = UNORDERED; + } + } + + + /** + * Returns the default sort behavior. + * + * @return default sort behavior + */ + public static SortBehavior getDefaultSortBehavior() + { + return defaultSortBehavior; + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/GlobalIdentifier.java b/core/src/main/java/org/ldaptive/ad/GlobalIdentifier.java new file mode 100644 index 0000000..93a70a0 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/GlobalIdentifier.java
@@ -0,0 +1,148 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad; + +import java.nio.ByteBuffer; +import java.util.StringTokenizer; +import org.ldaptive.LdapUtils; + +/** + * Class to represent an active directory GUID. Provides conversion from binary to string and vice versa. + * + * @author Middleware Services + */ +public final class GlobalIdentifier +{ + + + /** Default constructor. */ + private GlobalIdentifier() {} + + + /** + * Converts the supplied GUID to it's string format. + * + * @param guid to convert + * + * @return string format of the GUID + */ + public static String toString(final byte[] guid) + { + // CheckStyle:MagicNumber OFF + + // create a byte buffer for reading the guid + final ByteBuffer guidBuffer = ByteBuffer.wrap(guid); + + // string identifier + final StringBuilder sb = new StringBuilder("{"); + // encode the first 4 bytes, big endian + guidBuffer.limit(4); + sb.append(LdapUtils.hexEncode(getBytes(guidBuffer, true))); + + // encode the next 2 bytes, big endian + guidBuffer.limit(6); + sb.append("-").append(LdapUtils.hexEncode(getBytes(guidBuffer, true))); + + // encode the next 2 bytes, big endian + guidBuffer.limit(8); + sb.append("-").append(LdapUtils.hexEncode(getBytes(guidBuffer, true))); + + // encode the next 2 bytes, little endian + guidBuffer.limit(10); + sb.append("-").append(LdapUtils.hexEncode(getBytes(guidBuffer, false))); + + // encode the last 6 bytes, little endian + guidBuffer.limit(guidBuffer.capacity()); + sb.append("-").append(LdapUtils.hexEncode(getBytes(guidBuffer, false))); + sb.append("}"); + + return sb.toString(); + // CheckStyle:MagicNumber ON + } + + + /** + * Converts the supplied GUID to it's binary format. + * + * @param guid to convert + * + * @return binary format of the GUID + */ + public static byte[] toBytes(final String guid) + { + // CheckStyle:MagicNumber OFF + + // remove the enclosing brackets {...} + final StringTokenizer st = new StringTokenizer(guid.substring(1, guid.length() - 1), "-"); + // first token is 4 bytes, big endian + final String data1 = st.nextToken(); + // second token is 2 bytes, big endian + final String data2 = st.nextToken(); + // third token is 2 bytes, big endian + final String data3 = st.nextToken(); + // fourth token is 2 bytes, little endian + final String data4 = st.nextToken(); + // fifth token is 6 bytes, little endian + final String data5 = st.nextToken(); + + final ByteBuffer guidBuffer = ByteBuffer.allocate(16); + putBytes(guidBuffer, LdapUtils.hexDecode(data1.toCharArray()), true); + putBytes(guidBuffer, LdapUtils.hexDecode(data2.toCharArray()), true); + putBytes(guidBuffer, LdapUtils.hexDecode(data3.toCharArray()), true); + putBytes(guidBuffer, LdapUtils.hexDecode(data4.toCharArray()), false); + putBytes(guidBuffer, LdapUtils.hexDecode(data5.toCharArray()), false); + + return guidBuffer.array(); + // CheckStyle:MagicNumber ON + } + + + /** + * Reads bytes from the supplied byte buffer. The byte buffer limit must be set appropriately by the caller. + * + * @param buffer to read bytes from + * @param bigEndian whether to return the bytes as big endian + * + * @return long value + */ + private static byte[] getBytes(final ByteBuffer buffer, final boolean bigEndian) + { + // CheckStyle:MagicNumber OFF + final byte[] bytes = new byte[buffer.limit() - buffer.position()]; + if (bigEndian) { + int offset = bytes.length - 1; + while (buffer.hasRemaining()) { + bytes[offset--] = (byte) (buffer.get() & 0xFF); + } + } else { + int offset = 0; + while (buffer.hasRemaining()) { + bytes[offset++] = (byte) (buffer.get() & 0xFF); + } + } + return bytes; + // CheckStyle:MagicNumber ON + } + + + /** + * Writes a long into the supplied byte buffer. The byte buffer limit must be set appropriately by the caller. + * + * @param buffer to write long to + * @param bytes to write + * @param bigEndian whether to write the bytes as big endian + */ + private static void putBytes(final ByteBuffer buffer, final byte[] bytes, final boolean bigEndian) + { + // CheckStyle:MagicNumber OFF + if (bigEndian) { + for (int i = bytes.length - 1; i >= 0; i--) { + buffer.put((byte) (bytes[i] & 0xFF)); + } + } else { + for (byte b : bytes) { + buffer.put((byte) (b & 0xFF)); + } + } + // CheckStyle:MagicNumber ON + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/SecurityIdentifier.java b/core/src/main/java/org/ldaptive/ad/SecurityIdentifier.java new file mode 100644 index 0000000..e3ca75a --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/SecurityIdentifier.java
@@ -0,0 +1,177 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +/** + * Class to represent an active directory SID. Provides conversion from binary to string and vice versa. + * + * @author Middleware Services + */ +public final class SecurityIdentifier +{ + + + /** Default constructor. */ + private SecurityIdentifier() {} + + + /** + * Converts the supplied SID to it's string format. + * + * @param sid to convert + * + * @return string format of the SID + */ + public static String toString(final byte[] sid) + { + // CheckStyle:MagicNumber OFF + + // format of SID: S-R-X-Y1-Y2...-Yn + // S: static 'S', indicating string + // R: revision + // X: authority + // Yn: sub-authority + + // create a byte buffer for reading the sid + final ByteBuffer sidBuffer = ByteBuffer.wrap(sid); + + // string identifier + final StringBuilder sb = new StringBuilder("S"); + + // byte[0] is the revision + sb.append("-").append(sidBuffer.get() & 0xFF); + + // byte[1] is the count of sub-authorities + final int countSubAuth = sidBuffer.get() & 0xFF; + + // byte[2] - byte[7] is the authority (48 bits) + sidBuffer.limit(8); + sb.append("-").append(getLong(sidBuffer, true)); + + // byte[8] - ? is the sub-authorities, + // (32 bits per authority, little endian) + for (int i = 0; i < countSubAuth; i++) { + // values are unsigned, so get 4 bytes as a long + sidBuffer.limit(sidBuffer.position() + 4); + sb.append("-").append(getLong(sidBuffer, false)); + } + + return sb.toString(); + // CheckStyle:MagicNumber ON + } + + + /** + * Converts the supplied SID to it's binary format. + * + * @param sid to convert + * + * @return binary format of the SID + */ + public static byte[] toBytes(final String sid) + { + // CheckStyle:MagicNumber OFF + + // format of SID: S-R-X-Y1-Y2...-Yn + // S: static 'S', indicating string + // R: revision + // X: authority + // Yn: sub-authority + + final StringTokenizer st = new StringTokenizer(sid, "-"); + // first token is the 'S' + st.nextToken(); + + // second token is the revision + final int revision = Integer.valueOf(st.nextToken()); + // third token is the authority + final long authority = Long.valueOf(st.nextToken()); + // remaining token are the sub authorities + final List<String> subAuthorities = new ArrayList<>(); + while (st.hasMoreTokens()) { + subAuthorities.add(st.nextToken()); + } + + // revision is 1 byte + // sub-authorities count is 1 byte + // authority is 6 bytes + // 4 bytes for each sub-authority + final int size = 8 + (4 * subAuthorities.size()); + final ByteBuffer sidBuffer = ByteBuffer.allocate(size); + sidBuffer.put((byte) (revision & 0xFF)); + sidBuffer.put((byte) (subAuthorities.size() & 0xFF)); + sidBuffer.limit(8); + putLong(sidBuffer, authority, true); + for (String subAuthority : subAuthorities) { + sidBuffer.limit(sidBuffer.position() + 4); + putLong(sidBuffer, Long.valueOf(subAuthority), false); + } + + return sidBuffer.array(); + // CheckStyle:MagicNumber ON + } + + + /** + * Reads a long from the supplied byte buffer. The byte buffer limit must be set appropriately by the caller. + * + * @param buffer to read long from + * @param bigEndian whether to read the bytes as big endian + * + * @return long value + */ + private static long getLong(final ByteBuffer buffer, final boolean bigEndian) + { + // CheckStyle:MagicNumber OFF + long value = buffer.get() & 0xFF; + if (bigEndian) { + // shift the value to the right, or with the next byte + while (buffer.hasRemaining()) { + value <<= Byte.SIZE; + value |= buffer.get() & 0xFF; + } + } else { + // shift the next byte to the right, or with the value + int offset = Byte.SIZE; + while (buffer.hasRemaining()) { + value |= (buffer.get() & 0xFF) << offset; + offset += Byte.SIZE; + } + } + return value & 0xFFFFFFFFL; + // CheckStyle:MagicNumber ON + } + + + /** + * Writes a long into the supplied byte buffer. The byte buffer limit must be set appropriately by the caller. + * + * @param buffer to write long to + * @param value to write + * @param bigEndian whether to write the bytes as big endian + */ + private static void putLong(final ByteBuffer buffer, final long value, final boolean bigEndian) + { + // CheckStyle:MagicNumber OFF + if (bigEndian) { + int offset = Byte.SIZE * (buffer.limit() - buffer.position() - 1); + while (buffer.hasRemaining()) { + // get the high bits and decrement down + buffer.put((byte) ((value >> offset) & 0xFF)); + offset -= Byte.SIZE; + } + } else { + int offset = 0; + while (buffer.hasRemaining()) { + // get the low bits and increment up + buffer.put((byte) ((value >> offset) & 0xFF)); + offset += Byte.SIZE; + } + } + // CheckStyle:MagicNumber ON + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/UnicodePwdAttribute.java b/core/src/main/java/org/ldaptive/ad/UnicodePwdAttribute.java new file mode 100644 index 0000000..42c3dac --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/UnicodePwdAttribute.java
@@ -0,0 +1,71 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad; + +import java.util.Collection; +import org.ldaptive.LdapAttribute; +import org.ldaptive.SortBehavior; +import org.ldaptive.ad.io.UnicodePwdValueTranscoder; + +/** + * Helper class for the active directory unicodePwd attribute. Configures a binary attribute of that name and allows + * setting of the attribute value using a string. See {@link UnicodePwdValueTranscoder}. + * + * @author Middleware Services + */ +public class UnicodePwdAttribute extends LdapAttribute +{ + + /** serial version uid. */ + private static final long serialVersionUID = -6140237711183070669L; + + /** name of this attribute. */ + private static final String ATTR_NAME = "unicodePwd"; + + /** transcoder used when adding string values. */ + private static final UnicodePwdValueTranscoder TRANSCODER = new UnicodePwdValueTranscoder(); + + + /** Default constructor. */ + public UnicodePwdAttribute() + { + super(SortBehavior.UNORDERED, true); + setName(ATTR_NAME); + } + + + /** + * Creates a new unicode pwd attribute. + * + * @param values of this attribute + */ + public UnicodePwdAttribute(final String... values) + { + this(); + addStringValue(values); + } + + + @Override + public Collection<String> getStringValues() + { + return getValues(TRANSCODER); + } + + + @Override + public void addStringValue(final String... value) + { + for (String s : value) { + addValue(TRANSCODER, value); + } + } + + + @Override + public void removeStringValue(final String... value) + { + for (String s : value) { + removeBinaryValue(TRANSCODER.encodeBinaryValue(s)); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/control/DirSyncControl.java b/core/src/main/java/org/ldaptive/ad/control/DirSyncControl.java new file mode 100644 index 0000000..1c6e7f2 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/control/DirSyncControl.java
@@ -0,0 +1,429 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import java.math.BigInteger; +import java.nio.ByteBuffer; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.AbstractParseHandler; +import org.ldaptive.asn1.ConstructedDEREncoder; +import org.ldaptive.asn1.DERParser; +import org.ldaptive.asn1.DERPath; +import org.ldaptive.asn1.IntegerType; +import org.ldaptive.asn1.OctetStringType; +import org.ldaptive.asn1.UniversalDERTag; +import org.ldaptive.control.AbstractControl; +import org.ldaptive.control.RequestControl; +import org.ldaptive.control.ResponseControl; + +/** + * Request/response control for active directory synchronization. Control is defined as: + * + * <pre> + dirSyncValue ::= SEQUENCE { + flags INTEGER, + maxAttributeCount INTEGER, + cookie OCTET STRING + } + * </pre> + * + * <p>See http://msdn.microsoft.com/en-us/library/cc223347.aspx</p> + * + * @author Middleware Services + */ +public class DirSyncControl extends AbstractControl implements RequestControl, ResponseControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.841"; + + /** hash value seed. */ + private static final int HASH_CODE_SEED = 907; + + /** Empty byte array used for null cookies. */ + private static final byte[] EMPTY_COOKIE = new byte[0]; + + /** Types of flags. */ + public enum Flag { + + /** object security. */ + OBJECT_SECURITY(1L), + + /** ancestors first order. */ + ANCESTORS_FIRST_ORDER(2048L), + + /** public data only. */ + PUBLIC_DATA_ONLY(8192L), + + /** incremental values. */ + INCREMENTAL_VALUES(2147483648L); + + /** underlying value. */ + private final long value; + + + /** + * Creates a new flag. + * + * @param l value + */ + Flag(final long l) + { + value = l; + } + + + /** + * Returns the value. + * + * @return enum value + */ + public long value() + { + return value; + } + + + /** + * Returns the flag for the supplied integer constant. + * + * @param l to find flag for + * + * @return flag + */ + public static Flag valueOf(final long l) + { + for (Flag f : Flag.values()) { + if (f.value() == l) { + return f; + } + } + return null; + } + } + + /** flags. */ + private long flags; + + /** maximum attribute count. */ + private int maxAttributeCount; + + /** server generated cookie. */ + private byte[] cookie; + + + /** Default constructor. */ + public DirSyncControl() + { + super(OID); + } + + + /** + * Creates a new dir sync control. + * + * @param critical whether this control is critical + */ + public DirSyncControl(final boolean critical) + { + this(null, null, critical); + } + + + /** + * Creates a new dir sync control. + * + * @param f request flags + */ + public DirSyncControl(final Flag[] f) + { + this(f, false); + } + + + /** + * Creates a new dir sync control. + * + * @param f request flags + * @param critical whether this control is critical + */ + public DirSyncControl(final Flag[] f, final boolean critical) + { + this(f, null, critical); + } + + + /** + * Creates a new dir sync control. + * + * @param f request flags + * @param count maximum attribute count + */ + public DirSyncControl(final Flag[] f, final int count) + { + this(f, null, count, false); + } + + + /** + * Creates a new dir sync control. + * + * @param f request flags + * @param count maximum attribute count + * @param critical whether this control is critical + */ + public DirSyncControl(final Flag[] f, final int count, final boolean critical) + { + this(f, null, count, critical); + } + + + /** + * Creates a new dir sync control. + * + * @param f request flags + * @param value dir sync cookie + * @param critical whether this control is critical + */ + public DirSyncControl(final Flag[] f, final byte[] value, final boolean critical) + { + this(f, value, 0, critical); + } + + + /** + * Creates a new dir sync control. + * + * @param f request flags + * @param value dir sync cookie + * @param count maximum attribute count + * @param critical whether this control is critical + */ + public DirSyncControl(final Flag[] f, final byte[] value, final int count, final boolean critical) + { + super(OID, critical); + if (f != null) { + long l = 0; + for (Flag flag : f) { + if (flag != null) { + l += flag.value(); + } + } + setFlags(l); + } + setCookie(value); + setMaxAttributeCount(count); + } + + + /** + * Returns the flags value. + * + * @return flags value + */ + public long getFlags() + { + return flags; + } + + + /** + * Sets the flags. + * + * @param l flags value + */ + public void setFlags(final long l) + { + flags = l; + } + + + /** + * Returns the maximum attribute count. + * + * @return maximum attribute count + */ + public int getMaxAttributeCount() + { + return maxAttributeCount; + } + + + /** + * Sets the maximum attribute count. + * + * @param count maximum attribute count + */ + public void setMaxAttributeCount(final int count) + { + maxAttributeCount = count; + } + + + /** + * Returns the sync request cookie. + * + * @return sync request cookie + */ + public byte[] getCookie() + { + return cookie; + } + + + /** + * Sets the sync request cookie. + * + * @param value sync request cookie + */ + public void setCookie(final byte[] value) + { + cookie = value; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof DirSyncControl && super.equals(o)) { + final DirSyncControl v = (DirSyncControl) o; + return LdapUtils.areEqual(flags, v.flags) && + LdapUtils.areEqual(maxAttributeCount, v.maxAttributeCount) && + LdapUtils.areEqual(cookie, v.cookie); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality(), flags, maxAttributeCount, cookie); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, flags=%s, maxAttributeCount=%s, cookie=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + flags, + maxAttributeCount, + LdapUtils.base64Encode(cookie)); + } + + + @Override + public byte[] encode() + { + final ConstructedDEREncoder se = new ConstructedDEREncoder( + UniversalDERTag.SEQ, + new IntegerType(BigInteger.valueOf(getFlags())), + new IntegerType(getMaxAttributeCount()), + new OctetStringType(getCookie() != null ? getCookie() : EMPTY_COOKIE)); + return se.encode(); + } + + + @Override + public void decode(final byte[] berValue) + { + logger.trace("decoding control: {}", LdapUtils.base64Encode(berValue)); + + final DERParser parser = new DERParser(); + parser.registerHandler(FlagHandler.PATH, new FlagHandler(this)); + parser.registerHandler(MaxAttrCountHandler.PATH, new MaxAttrCountHandler(this)); + parser.registerHandler(CookieHandler.PATH, new CookieHandler(this)); + parser.parse(ByteBuffer.wrap(berValue)); + } + + + /** Parse handler implementation for the flag. */ + private static class FlagHandler extends AbstractParseHandler<DirSyncControl> + { + + /** DER path to flag. */ + public static final DERPath PATH = new DERPath("/SEQ/INT[0]"); + + + /** + * Creates a new flag handler. + * + * @param control to configure + */ + FlagHandler(final DirSyncControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setFlags(IntegerType.decode(encoded).longValue()); + } + } + + + /** Parse handler implementation for the maxAttributeCount. */ + private static class MaxAttrCountHandler extends AbstractParseHandler<DirSyncControl> + { + + /** DER path to cookie value. */ + public static final DERPath PATH = new DERPath("/SEQ/INT[1]"); + + + /** + * Creates a new max attr handler handler. + * + * @param control to configure + */ + MaxAttrCountHandler(final DirSyncControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setMaxAttributeCount(IntegerType.decode(encoded).intValue()); + } + } + + + /** Parse handler implementation for the cookie. */ + private static class CookieHandler extends AbstractParseHandler<DirSyncControl> + { + + /** DER path to cookie value. */ + public static final DERPath PATH = new DERPath("/SEQ/OCTSTR"); + + + /** + * Creates a new cookie handler. + * + * @param control to configure + */ + CookieHandler(final DirSyncControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + final byte[] cookie = OctetStringType.readBuffer(encoded); + if (cookie != null && cookie.length > 0) { + getObject().setCookie(cookie); + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/control/ExtendedDnControl.java b/core/src/main/java/org/ldaptive/ad/control/ExtendedDnControl.java new file mode 100644 index 0000000..92f9cf1 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/control/ExtendedDnControl.java
@@ -0,0 +1,138 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.ConstructedDEREncoder; +import org.ldaptive.asn1.IntegerType; +import org.ldaptive.asn1.UniversalDERTag; +import org.ldaptive.control.AbstractControl; +import org.ldaptive.control.RequestControl; + +/** + * Request control for active directory servers to use an extended form of an object distinguished name. Control is + * defined as: + * + * <pre> + extendedDnValue ::= SEQUENCE { + flag INTEGER + } + * </pre> + * + * <p>See http://msdn.microsoft.com/en-us/library/cc223349.aspx</p> + * + * @author Middleware Services + */ +public class ExtendedDnControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.529"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 919; + + /** Types of flags. */ + public enum Flag { + + /** hexadecimal format. */ + HEXADECIMAL, + + /** standard format. */ + STANDARD + } + + /** flag. */ + private Flag flag = Flag.STANDARD; + + + /** Default constructor. */ + public ExtendedDnControl() + { + super(OID); + } + + + /** + * Creates a new extended dn control. + * + * @param f flag + */ + public ExtendedDnControl(final Flag f) + { + super(OID); + setFlag(f); + } + + + /** + * Creates a new extended dn control. + * + * @param f flag + * @param critical whether this control is critical + */ + public ExtendedDnControl(final Flag f, final boolean critical) + { + super(OID, critical); + setFlag(f); + } + + + /** + * Returns the flag. + * + * @return flag + */ + public Flag getFlag() + { + return flag; + } + + + /** + * Sets the flag. + * + * @param f flag + */ + public void setFlag(final Flag f) + { + flag = f; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof ExtendedDnControl && super.equals(o)) { + final ExtendedDnControl v = (ExtendedDnControl) o; + return LdapUtils.areEqual(flag, v.flag); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality(), flag); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::criticality=%s, flag=%s]", getClass().getName(), hashCode(), getCriticality(), flag); + } + + + @Override + public byte[] encode() + { + final ConstructedDEREncoder se = new ConstructedDEREncoder( + UniversalDERTag.SEQ, + new IntegerType(getFlag().ordinal())); + return se.encode(); + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/control/ForceUpdateControl.java b/core/src/main/java/org/ldaptive/ad/control/ForceUpdateControl.java new file mode 100644 index 0000000..7d95485 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/control/ForceUpdateControl.java
@@ -0,0 +1,71 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.ldaptive.control.AbstractControl; +import org.ldaptive.control.RequestControl; + +/** + * Request control for active directory servers to perform an update even if the data is already the same. See + * http://msdn.microsoft.com/en-us/library/cc223344.aspx + * + * @author Middleware Services + */ +public class ForceUpdateControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.1974"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 971; + + + /** Default constructor. */ + public ForceUpdateControl() + { + super(OID); + } + + + /** + * Creates a new force update control. + * + * @param critical whether this control is critical + */ + public ForceUpdateControl(final boolean critical) + { + super(OID, critical); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + return o instanceof ForceUpdateControl && super.equals(o); + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality()); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::criticality=%s]", getClass().getName(), hashCode(), getCriticality()); + } + + + @Override + public byte[] encode() + { + return null; + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/control/GetStatsControl.java b/core/src/main/java/org/ldaptive/ad/control/GetStatsControl.java new file mode 100644 index 0000000..4fba6c0 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/control/GetStatsControl.java
@@ -0,0 +1,219 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.AbstractParseHandler; +import org.ldaptive.asn1.DERParser; +import org.ldaptive.asn1.IntegerType; +import org.ldaptive.asn1.OctetStringType; +import org.ldaptive.control.AbstractControl; +import org.ldaptive.control.RequestControl; +import org.ldaptive.control.ResponseControl; + +/** + * Request/response control for active directory servers to return statistics along with search results. This + * implementation supports the format for Windows Server 2008, Windows Server 2008 R2, and Windows Server 2012 DCs. The + * response control is defined as: + * + * <pre> + SEQUENCE { + threadCountTag INTEGER + threadCount INTEGER + callTimeTag INTEGER + callTime INTEGER + entriesReturnedTag INTEGER + entriesReturned INTEGER + entriesVisitedTag INTEGER + entriesVisited INTEGER + filterTag INTEGER + filter OCTET STRING + indexTag INTEGER + index OCTET STRING + pagesReferencedTag INTEGER + pagesReferenced INTEGER + pagesReadTag INTEGER + pagesRead INTEGER + pagesPrereadTag INTEGER + pagesPreread INTEGER + pagesDirtiedTag INTEGER + pagesDirtied INTEGER + pagesRedirtiedTag INTEGER + pagesRedirtied INTEGER + logRecordCountTag INTEGER + logRecordCount INTEGER + logRecordBytesTag INTEGER + logRecordBytes INTEGER + } + * </pre> + * + * <p>See http://msdn.microsoft.com/en-us/library/cc223350.aspx</p> + * + * @author Middleware Services + */ +public class GetStatsControl extends AbstractControl implements RequestControl, ResponseControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.970"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 929; + + /** statistics. */ + private final Map<String, Object> statistics = new HashMap<>(); + + + /** Default constructor. */ + public GetStatsControl() + { + super(OID); + } + + + /** + * Creates a new get stats control. + * + * @param critical whether this control is critical + */ + public GetStatsControl(final boolean critical) + { + super(OID, critical); + } + + + /** + * Returns the statistics. + * + * @return statistics + */ + public Map<String, Object> getStatistics() + { + return statistics; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof GetStatsControl && super.equals(o)) { + final GetStatsControl v = (GetStatsControl) o; + return LdapUtils.areEqual(statistics, v.statistics); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality(), statistics); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, statistics=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + statistics); + } + + + @Override + public byte[] encode() + { + return null; + } + + + @Override + public void decode(final byte[] berValue) + { + logger.trace("decoding control: {}", LdapUtils.base64Encode(berValue)); + + final DERParser parser = new DERParser(); + parser.registerHandler("/SEQ/INT[1]", new IntegerHandler(this, "threadCount")); + parser.registerHandler("/SEQ/INT[3]", new IntegerHandler(this, "callTime")); + parser.registerHandler("/SEQ/INT[5]", new IntegerHandler(this, "entriesReturned")); + parser.registerHandler("/SEQ/INT[7]", new IntegerHandler(this, "entriesVisited")); + parser.registerHandler("/SEQ/OCTSTR[9]", new StringHandler(this, "filter")); + parser.registerHandler("/SEQ/OCTSTR[11]", new StringHandler(this, "index")); + parser.registerHandler("/SEQ/INT[13]", new IntegerHandler(this, "pagesReferenced")); + parser.registerHandler("/SEQ/INT[15]", new IntegerHandler(this, "pagesRead")); + parser.registerHandler("/SEQ/INT[17]", new IntegerHandler(this, "pagesPreread")); + parser.registerHandler("/SEQ/INT[19]", new IntegerHandler(this, "pagesDirtied")); + parser.registerHandler("/SEQ/INT[21]", new IntegerHandler(this, "pagesRedirtied")); + parser.registerHandler("/SEQ/INT[23]", new IntegerHandler(this, "logRecordCount")); + parser.registerHandler("/SEQ/INT[25]", new IntegerHandler(this, "logRecordBytes")); + parser.parse(ByteBuffer.wrap(berValue)); + } + + + /** Parse handler implementation for integer stats. */ + private static class IntegerHandler extends AbstractParseHandler<GetStatsControl> + { + + /** name of this statistic. */ + private final String statName; + + + /** + * Creates a new integer handler. + * + * @param control to configure + * @param name of the statistic + */ + IntegerHandler(final GetStatsControl control, final String name) + { + super(control); + statName = name; + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().getStatistics().put(statName, IntegerType.decode(encoded).intValue()); + } + } + + + /** Parse handler implementation for string stats. */ + private static class StringHandler extends AbstractParseHandler<GetStatsControl> + { + + /** name of this statistic. */ + private final String statName; + + + /** + * Creates a new string handler. + * + * @param control to configure + * @param name of the statistic + */ + StringHandler(final GetStatsControl control, final String name) + { + super(control); + statName = name; + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + // strings are terminated with 0x00(null), use trim to remove + getObject().getStatistics().put(statName, OctetStringType.decode(encoded).trim()); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/control/LazyCommitControl.java b/core/src/main/java/org/ldaptive/ad/control/LazyCommitControl.java new file mode 100644 index 0000000..eb8a662 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/control/LazyCommitControl.java
@@ -0,0 +1,70 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.ldaptive.control.AbstractControl; +import org.ldaptive.control.RequestControl; + +/** + * Request control for active directory domain controllers to sacrifice durability guarantees on updates to improve + * performance. See http://msdn.microsoft.com/en-us/library/cc223351.aspx + * + * @author Middleware Services + */ +public class LazyCommitControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.619"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 937; + + + /** Default constructor. */ + public LazyCommitControl() + { + super(OID); + } + + + /** + * Creates a new lazy commit control. + * + * @param critical whether this control is critical + */ + public LazyCommitControl(final boolean critical) + { + super(OID, critical); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + return o instanceof LazyCommitControl && super.equals(o); + } + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality()); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::criticality=%s]", getClass().getName(), hashCode(), getCriticality()); + } + + + @Override + public byte[] encode() + { + return null; + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/control/NotificationControl.java b/core/src/main/java/org/ldaptive/ad/control/NotificationControl.java new file mode 100644 index 0000000..84c2938 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/control/NotificationControl.java
@@ -0,0 +1,71 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.ldaptive.control.AbstractControl; +import org.ldaptive.control.RequestControl; + +/** + * Request control for active directory servers to send asynchronous notifications to the client when a change is made. + * See http://msdn.microsoft.com/en-us/library/cc223353.aspx + * + * @author Middleware Services + */ +public class NotificationControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.528"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 947; + + + /** Default constructor. */ + public NotificationControl() + { + super(OID); + } + + + /** + * Creates a new notification control. + * + * @param critical whether this control is critical + */ + public NotificationControl(final boolean critical) + { + super(OID, critical); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + return o instanceof NotificationControl && super.equals(o); + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality()); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::criticality=%s]", getClass().getName(), hashCode(), getCriticality()); + } + + + @Override + public byte[] encode() + { + return null; + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/control/PermissiveModifyControl.java b/core/src/main/java/org/ldaptive/ad/control/PermissiveModifyControl.java new file mode 100644 index 0000000..3fff0db --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/control/PermissiveModifyControl.java
@@ -0,0 +1,71 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.ldaptive.control.AbstractControl; +import org.ldaptive.control.RequestControl; + +/** + * Request control for active directory servers to return success on add/modify/delete operations that would normally + * return an error. See http://msdn.microsoft.com/en-us/library/cc223352.aspx + * + * @author Middleware Services + */ +public class PermissiveModifyControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.1413"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 941; + + + /** Default constructor. */ + public PermissiveModifyControl() + { + super(OID); + } + + + /** + * Creates a new permissive modify control. + * + * @param critical whether this control is critical + */ + public PermissiveModifyControl(final boolean critical) + { + super(OID, critical); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + return o instanceof PermissiveModifyControl && super.equals(o); + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality()); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::criticality=%s]", getClass().getName(), hashCode(), getCriticality()); + } + + + @Override + public byte[] encode() + { + return null; + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/control/RangeRetrievalNoerrControl.java b/core/src/main/java/org/ldaptive/ad/control/RangeRetrievalNoerrControl.java new file mode 100644 index 0000000..852a111 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/control/RangeRetrievalNoerrControl.java
@@ -0,0 +1,71 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.ldaptive.control.AbstractControl; +import org.ldaptive.control.RequestControl; + +/** + * Request control for active directory servers to avoid error response with range retrieval. See + * http://msdn.microsoft.com/en-us/library/cc223345.aspx + * + * @author Middleware Services + */ +public class RangeRetrievalNoerrControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.1948"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 983; + + + /** Default constructor. */ + public RangeRetrievalNoerrControl() + { + super(OID); + } + + + /** + * Creates a new notification control. + * + * @param critical whether this control is critical + */ + public RangeRetrievalNoerrControl(final boolean critical) + { + super(OID, critical); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + return o instanceof RangeRetrievalNoerrControl && super.equals(o); + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality()); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::criticality=%s]", getClass().getName(), hashCode(), getCriticality()); + } + + + @Override + public byte[] encode() + { + return null; + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/control/SearchOptionsControl.java b/core/src/main/java/org/ldaptive/ad/control/SearchOptionsControl.java new file mode 100644 index 0000000..b2ad4e2 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/control/SearchOptionsControl.java
@@ -0,0 +1,137 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.ConstructedDEREncoder; +import org.ldaptive.asn1.IntegerType; +import org.ldaptive.asn1.UniversalDERTag; +import org.ldaptive.control.AbstractControl; +import org.ldaptive.control.RequestControl; + +/** + * Request control for active directory servers to control various search behaviors. Control is defined as: + * + * <pre> + searchOptionsValue ::= SEQUENCE { + flag INTEGER + } + * </pre> + * + * <p>See http://msdn.microsoft.com/en-us/library/cc223324.aspx</p> + * + * @author Middleware Services + */ +public class SearchOptionsControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.1340"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 953; + + /** Types of flags. */ + public enum Flag { + + /** SERVER_SEARCH_FLAG_DOMAIN_SCOPE . */ + DOMAIN_SCOPE, + + /** SERVER_SEARCH_FLAG_PHANTOM_ROOT . */ + PHANTOM_ROOT + } + + /** flag. */ + private Flag flag = Flag.DOMAIN_SCOPE; + + + /** Default constructor. */ + public SearchOptionsControl() + { + super(OID); + } + + + /** + * Creates a new search options control. + * + * @param f flag + */ + public SearchOptionsControl(final Flag f) + { + super(OID); + setFlag(f); + } + + + /** + * Creates a new search options control. + * + * @param f flag + * @param critical whether this control is critical + */ + public SearchOptionsControl(final Flag f, final boolean critical) + { + super(OID, critical); + setFlag(f); + } + + + /** + * Returns the flag. + * + * @return flag + */ + public Flag getFlag() + { + return flag; + } + + + /** + * Sets the flag. + * + * @param f flag + */ + public void setFlag(final Flag f) + { + flag = f; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof SearchOptionsControl && super.equals(o)) { + final SearchOptionsControl v = (SearchOptionsControl) o; + return LdapUtils.areEqual(flag, v.flag); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality(), flag); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::criticality=%s, flag=%s]", getClass().getName(), hashCode(), getCriticality(), flag); + } + + + @Override + public byte[] encode() + { + final ConstructedDEREncoder se = new ConstructedDEREncoder( + UniversalDERTag.SEQ, + new IntegerType(getFlag().ordinal())); + return se.encode(); + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/control/ShowDeactivatedLinkControl.java b/core/src/main/java/org/ldaptive/ad/control/ShowDeactivatedLinkControl.java new file mode 100644 index 0000000..b8a136f --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/control/ShowDeactivatedLinkControl.java
@@ -0,0 +1,71 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.ldaptive.control.AbstractControl; +import org.ldaptive.control.RequestControl; + +/** + * Request control for active directory servers in include link attributes that refer to deleted-objects in a search + * operation. See http://msdn.microsoft.com/en-us/library/dd302781.aspx + * + * @author Middleware Services + */ +public class ShowDeactivatedLinkControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.2065"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 967; + + + /** Default constructor. */ + public ShowDeactivatedLinkControl() + { + super(OID); + } + + + /** + * Creates a new show deactivated link control. + * + * @param critical whether this control is critical + */ + public ShowDeactivatedLinkControl(final boolean critical) + { + super(OID, critical); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + return o instanceof ShowDeactivatedLinkControl && super.equals(o); + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality()); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::criticality=%s]", getClass().getName(), hashCode(), getCriticality()); + } + + + @Override + public byte[] encode() + { + return null; + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/control/ShowDeletedControl.java b/core/src/main/java/org/ldaptive/ad/control/ShowDeletedControl.java new file mode 100644 index 0000000..a2de2cc --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/control/ShowDeletedControl.java
@@ -0,0 +1,71 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.ldaptive.control.AbstractControl; +import org.ldaptive.control.RequestControl; + +/** + * Request control for active directory servers to include deleted objects that match a search filter. See + * http://msdn.microsoft.com/en-us/library/cc223326.aspx + * + * @author Middleware Services + */ +public class ShowDeletedControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.417"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 911; + + + /** Default constructor. */ + public ShowDeletedControl() + { + super(OID); + } + + + /** + * Creates a new show deleted control. + * + * @param critical whether this control is critical + */ + public ShowDeletedControl(final boolean critical) + { + super(OID, critical); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + return o instanceof ShowDeletedControl && super.equals(o); + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality()); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::criticality=%s]", getClass().getName(), hashCode(), getCriticality()); + } + + + @Override + public byte[] encode() + { + return null; + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/control/ShowRecycledControl.java b/core/src/main/java/org/ldaptive/ad/control/ShowRecycledControl.java new file mode 100644 index 0000000..dd9a8ac --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/control/ShowRecycledControl.java
@@ -0,0 +1,71 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.ldaptive.control.AbstractControl; +import org.ldaptive.control.RequestControl; + +/** + * Request control for active directory servers to include tombstones, deleted-objects, and recycled-objects that match + * a search filter. See http://msdn.microsoft.com/en-us/library/dd304621.aspx + * + * @author Middleware Services + */ +public class ShowRecycledControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.2064"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 971; + + + /** Default constructor. */ + public ShowRecycledControl() + { + super(OID); + } + + + /** + * Creates a new show recycled control. + * + * @param critical whether this control is critical + */ + public ShowRecycledControl(final boolean critical) + { + super(OID, critical); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + return o instanceof ShowRecycledControl && super.equals(o); + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality()); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::criticality=%s]", getClass().getName(), hashCode(), getCriticality()); + } + + + @Override + public byte[] encode() + { + return null; + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/control/VerifyNameControl.java b/core/src/main/java/org/ldaptive/ad/control/VerifyNameControl.java new file mode 100644 index 0000000..116da3c --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/control/VerifyNameControl.java
@@ -0,0 +1,137 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.ConstructedDEREncoder; +import org.ldaptive.asn1.IntegerType; +import org.ldaptive.asn1.OctetStringType; +import org.ldaptive.asn1.UniversalDERTag; +import org.ldaptive.control.AbstractControl; +import org.ldaptive.control.RequestControl; + +/** + * Request control for active directory servers to use an extended form of an object distinguished name. Control is + * defined as: + * + * <pre> + verifyNameValue ::= SEQUENCE { + Flags INTEGER + ServerName OCTET STRING + } + * </pre> + * + * <p>See http://msdn.microsoft.com/en-us/library/cc223328.aspx</p> + * + * @author Middleware Services + */ +public class VerifyNameControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.1338"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 977; + + /** Global catalog server to contact. */ + private String serverName; + + + /** Default constructor. */ + public VerifyNameControl() + { + super(OID); + } + + + /** + * Creates a new verify name control. + * + * @param name server name + */ + public VerifyNameControl(final String name) + { + super(OID); + setServerName(name); + } + + + /** + * Creates a new verify name control. + * + * @param name server name + * @param critical whether this control is critical + */ + public VerifyNameControl(final String name, final boolean critical) + { + super(OID, critical); + setServerName(name); + } + + + /** + * Returns the server name. + * + * @return server name + */ + public String getServerName() + { + return serverName; + } + + + /** + * Sets the server name. + * + * @param name server name + */ + public void setServerName(final String name) + { + serverName = name; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof VerifyNameControl && super.equals(o)) { + final VerifyNameControl v = (VerifyNameControl) o; + return LdapUtils.areEqual(serverName, v.serverName); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality(), serverName); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, serverName=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + serverName); + } + + + @Override + public byte[] encode() + { + final ConstructedDEREncoder se = new ConstructedDEREncoder( + UniversalDERTag.SEQ, + new IntegerType(0), + new OctetStringType(serverName)); + return se.encode(); + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/control/util/DirSyncClient.java b/core/src/main/java/org/ldaptive/ad/control/util/DirSyncClient.java new file mode 100644 index 0000000..c7b8367 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/control/util/DirSyncClient.java
@@ -0,0 +1,319 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control.util; + +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Response; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.ad.control.DirSyncControl; +import org.ldaptive.ad.control.ExtendedDnControl; +import org.ldaptive.ad.control.ShowDeletedControl; +import org.ldaptive.control.RequestControl; +import org.ldaptive.control.util.CookieManager; +import org.ldaptive.control.util.DefaultCookieManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Client that simplifies using the active directory dir sync control. + * + * @author Middleware Services + */ +public class DirSyncClient +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Connection to invoke the search operation on. */ + private final Connection connection; + + /** DirSync flags. */ + private final DirSyncControl.Flag[] dirSyncFlags; + + /** Maximum attribute count. */ + private final int maxAttributeCount; + + /** ExtendedDn flags. */ + private ExtendedDnControl.Flag extendedDnFlag = ExtendedDnControl.Flag.STANDARD; + + + /** + * Creates a new dir sync client. + * + * @param conn to execute the search operation on + */ + public DirSyncClient(final Connection conn) + { + this(conn, null, 0); + } + + + /** + * Creates a new dir sync client. + * + * @param conn to execute the search operation on + * @param dsFlags to set on the dir sync control + */ + public DirSyncClient(final Connection conn, final DirSyncControl.Flag[] dsFlags) + { + this(conn, dsFlags, 0); + } + + + /** + * Creates a new dir sync client. + * + * @param conn to execute the search operation on + * @param dsFlags to set on the dir sync control + * @param count max attribute count + */ + public DirSyncClient(final Connection conn, final DirSyncControl.Flag[] dsFlags, final int count) + { + connection = conn; + dirSyncFlags = dsFlags; + maxAttributeCount = count; + } + + + /** + * Returns the flag that is used on the extended dn control. + * + * @return extended dn control flag + */ + public ExtendedDnControl.Flag getExtendedDnFlag() + { + return extendedDnFlag; + } + + + /** + * Sets the flag to use on the extended dn control. + * + * @param flag to set on the extended dn control + */ + public void setExtendedDnFlag(final ExtendedDnControl.Flag flag) + { + extendedDnFlag = flag; + } + + + /** + * Performs a search operation with the {@link DirSyncControl}. The supplied request is modified in the following way: + * + * <ul> + * <li>{@link SearchRequest#setControls( org.ldaptive.control.RequestControl...)} is invoked with {@link + * DirSyncControl}, {@link ShowDeletedControl}, and {@link ExtendedDnControl}</li> + * </ul> + * + * @param request search request to execute + * + * @return search operation response + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> execute(final SearchRequest request) + throws LdapException + { + return execute(request, new DefaultCookieManager()); + } + + + /** + * Performs a search operation with the {@link DirSyncControl}. The supplied request is modified in the following way: + * + * <ul> + * <li>{@link SearchRequest#setControls( org.ldaptive.control.RequestControl...)} is invoked with {@link + * DirSyncControl}, {@link ShowDeletedControl}, and {@link ExtendedDnControl}</li> + * </ul> + * + * <p>The cookie is extracted from the supplied response and replayed in the request.</p> + * + * @param request search request to execute + * @param response of a previous dir sync operation + * + * @return search operation response + * + * @throws IllegalArgumentException if the response does not contain a dir sync cookie + * @throws LdapException if the search fails + */ + public Response<SearchResult> execute(final SearchRequest request, final Response<SearchResult> response) + throws LdapException + { + final byte[] cookie = getDirSyncCookie(response); + if (cookie == null) { + throw new IllegalArgumentException("Response does not contain a dir sync cookie"); + } + + return execute(request, new DefaultCookieManager(cookie)); + } + + + /** + * Performs a search operation with the {@link DirSyncControl}. The supplied request is modified in the following way: + * + * <ul> + * <li>{@link SearchRequest#setControls( org.ldaptive.control.RequestControl...)} is invoked with {@link + * DirSyncControl}, {@link ShowDeletedControl}, and {@link ExtendedDnControl}</li> + * </ul> + * + * <p>The cookie used in the request is read from the cookie manager and written to the cookie manager after a + * successful search, if the response contains a cookie.</p> + * + * @param request search request to execute + * @param manager for reading and writing cookies + * + * @return search operation response + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> execute(final SearchRequest request, final CookieManager manager) + throws LdapException + { + final SearchOperation search = new SearchOperation(connection); + request.setControls(createRequestControls(manager.readCookie())); + + final Response<SearchResult> response = search.execute(request); + final byte[] cookie = getDirSyncCookie(response); + if (cookie != null) { + manager.writeCookie(cookie); + } + return response; + } + + + /** + * Returns whether {@link #execute(SearchRequest, Response)} can be invoked again. + * + * @param response of a previous paged results operation + * + * @return whether more dir sync results can be retrieved from the server + */ + public boolean hasMore(final Response<SearchResult> response) + { + return getDirSyncFlags(response) != 0; + } + + + /** + * Invokes {@link #execute(SearchRequest, CookieManager)} with a {@link DefaultCookieManager}. + * + * @param request search request to execute + * + * @return search operation response of the last dir sync operation + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> executeToCompletion(final SearchRequest request) + throws LdapException + { + return executeToCompletion(request, new DefaultCookieManager()); + } + + + /** + * Performs a search operation with the {@link DirSyncControl}. The supplied request is modified in the following way: + * + * <ul> + * <li>{@link SearchRequest#setControls( org.ldaptive.control.RequestControl...)} is invoked with {@link + * DirSyncControl}, {@link ShowDeletedControl}, and {@link ExtendedDnControl}</li> + * </ul> + * + * <p>This method will continue to execute search operations until all dir sync search results have been retrieved + * from the server. The returned response contains the response data of the last dir sync operation plus the entries + * and references returned by all previous search operations.</p> + * + * <p>The cookie used for each request is read from the cookie manager and written to the cookie manager after a + * successful search, if the response contains a cookie.</p> + * + * @param request search request to execute + * @param manager for reading and writing cookies + * + * @return search operation response of the last dir sync operation + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> executeToCompletion(final SearchRequest request, final CookieManager manager) + throws LdapException + { + Response<SearchResult> response = null; + final SearchResult result = new SearchResult(); + final SearchOperation search = new SearchOperation(connection); + byte[] cookie = manager.readCookie(); + long flags; + do { + if (response != null && response.getResult() != null) { + result.addEntries(response.getResult().getEntries()); + result.addReferences(response.getResult().getReferences()); + } + request.setControls(createRequestControls(cookie)); + response = search.execute(request); + flags = getDirSyncFlags(response); + cookie = getDirSyncCookie(response); + if (cookie != null) { + manager.writeCookie(cookie); + } + } while (flags != 0); + response.getResult().addEntries(result.getEntries()); + response.getResult().addReferences(result.getReferences()); + return response; + } + + + /** + * Returns the dir sync flags in the supplied response or -1 if no flags exists. + * + * @param response of a previous dir sync operation + * + * @return dir sync flags or -1 + */ + protected long getDirSyncFlags(final Response<SearchResult> response) + { + long flags = -1; + final DirSyncControl ctl = (DirSyncControl) response.getControl(DirSyncControl.OID); + if (ctl != null) { + flags = ctl.getFlags(); + } + return flags; + } + + + /** + * Returns the dir sync cookie in the supplied response or null if no cookie exists. + * + * @param response of a previous dir sync operation + * + * @return dir sync cookie or null + */ + protected byte[] getDirSyncCookie(final Response<SearchResult> response) + { + byte[] cookie = null; + final DirSyncControl ctl = (DirSyncControl) response.getControl(DirSyncControl.OID); + if (ctl != null) { + if (ctl.getCookie() != null && ctl.getCookie().length > 0) { + cookie = ctl.getCookie(); + } + } + return cookie; + } + + + /** + * Returns the list of request controls configured for this client. + * + * @param cookie to add to the dir sync control or null + * + * @return search request controls + */ + private RequestControl[] createRequestControls(final byte[] cookie) + { + return + new RequestControl[] { + new DirSyncControl(dirSyncFlags, cookie, maxAttributeCount, true), + new ExtendedDnControl(extendedDnFlag), + new ShowDeletedControl(), + }; + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/control/util/NotificationClient.java b/core/src/main/java/org/ldaptive/ad/control/util/NotificationClient.java new file mode 100644 index 0000000..ad1e2c8 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/control/util/NotificationClient.java
@@ -0,0 +1,373 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control.util; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.ad.control.NotificationControl; +import org.ldaptive.ad.handler.ObjectGuidHandler; +import org.ldaptive.ad.handler.ObjectSidHandler; +import org.ldaptive.async.AbandonOperation; +import org.ldaptive.async.AsyncRequest; +import org.ldaptive.async.AsyncSearchOperation; +import org.ldaptive.async.handler.AsyncRequestHandler; +import org.ldaptive.handler.HandlerResult; +import org.ldaptive.handler.OperationResponseHandler; +import org.ldaptive.handler.SearchEntryHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Client that simplifies using the notification control. + * + * @author Middleware Services + */ +public class NotificationClient +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Connection to invoke the search operation on. */ + private final Connection connection; + + + /** + * Creates a new notification client. + * + * @param conn to execute the search operation on + */ + public NotificationClient(final Connection conn) + { + connection = conn; + } + + + /** + * Invokes {@link #execute(SearchRequest, int)} with a capacity of {@link Integer#MAX_VALUE}. + * + * @param request search request to execute + * + * @return blocking queue to wait for search entries + * + * @throws LdapException if the search fails + */ + public BlockingQueue<NotificationItem> execute(final SearchRequest request) + throws LdapException + { + return execute(request, Integer.MAX_VALUE); + } + + + /** + * Performs a search operation with the {@link NotificationControl}. The supplied request is modified in the following + * way: + * + * <ul> + * <li>{@link SearchRequest#setControls( org.ldaptive.control.RequestControl...)} is invoked with {@link + * NotificationControl}</li> + * <li>{@link SearchRequest#setSearchEntryHandlers(SearchEntryHandler...)} is invoked with a custom handler that + * places notification data in a blocking queue. The {@link ObjectGuidHandler} and {@link ObjectSidHandler} + * handlers are included as well.</li> + * <li>{@link AsyncSearchOperation#setExceptionHandler(org.ldaptive.async.handler.ExceptionHandler)} is invoked with + * a custom handler that places the exception in a blocking queue.</li> + * </ul> + * + * <p>The search request object should not be reused for any other search operations.</p> + * + * @param request search request to execute + * @param capacity of the returned blocking queue + * + * @return blocking queue to wait for search entries + * + * @throws LdapException if the search fails + */ + @SuppressWarnings("unchecked") + public BlockingQueue<NotificationItem> execute(final SearchRequest request, final int capacity) + throws LdapException + { + final BlockingQueue<NotificationItem> queue = new LinkedBlockingQueue<>(capacity); + + final AsyncSearchOperation search = new AsyncSearchOperation(connection); + search.setOperationResponseHandlers( + new OperationResponseHandler<SearchRequest, SearchResult>() { + @Override + public HandlerResult<Response<SearchResult>> handle( + final Connection conn, + final SearchRequest request, + final Response<SearchResult> response) + throws LdapException + { + try { + logger.debug("received {}", response); + search.shutdown(); + + queue.put(new NotificationItem(response)); + } catch (Exception e) { + logger.warn("Unable to enqueue response {}", response); + } + return new HandlerResult<>(response); + } + }); + search.setAsyncRequestHandlers( + new AsyncRequestHandler() { + @Override + public HandlerResult<AsyncRequest> handle( + final Connection conn, + final Request request, + final AsyncRequest asyncRequest) + throws LdapException + { + try { + logger.debug("received {}", asyncRequest); + queue.put(new NotificationItem(asyncRequest)); + } catch (Exception e) { + logger.warn("Unable to enqueue async request {}", asyncRequest); + } + return new HandlerResult<>(null); + } + }); + search.setExceptionHandler( + (conn, request1, exception) -> { + try { + logger.debug("received exception:", exception); + search.shutdown(); + queue.put(new NotificationItem(exception)); + } catch (Exception e) { + logger.warn("Unable to enqueue exception:", exception); + } + return new HandlerResult<>(null); + }); + + request.setControls(new NotificationControl()); + request.setSearchEntryHandlers( + new ObjectGuidHandler(), + new ObjectSidHandler(), + new SearchEntryHandler() { + @Override + public HandlerResult<SearchEntry> handle( + final Connection conn, + final SearchRequest request, + final SearchEntry entry) + throws LdapException + { + try { + logger.debug("received {}", entry); + queue.put(new NotificationItem(entry)); + } catch (Exception e) { + logger.warn("Unable to enqueue entry {}", entry); + } + return new HandlerResult<>(null); + } + + @Override + public void initializeRequest(final SearchRequest request) {} + }); + + search.execute(request); + return queue; + } + + + /** + * Invokes an abandon operation on the supplied ldap message id. Convenience method supplied to abandon async search + * operations. + * + * @param messageId of the operation to abandon + * + * @throws LdapException if the abandon operation fails + */ + public void abandon(final int messageId) + throws LdapException + { + final AbandonOperation abandon = new AbandonOperation(connection); + abandon.execute(messageId); + } + + + /** Contains data returned when using the notification control. */ + public static class NotificationItem + { + + /** Async request from the search operation. */ + private final AsyncRequest asyncRequest; + + /** Entry contained in this notification item. */ + private final SearchEntry searchEntry; + + /** Response contained in this notification item. */ + private final Response searchResponse; + + /** Exception thrown by the search operation. */ + private final Exception searchException; + + + /** + * Creates a new notification item. + * + * @param request that represents this item + */ + public NotificationItem(final AsyncRequest request) + { + asyncRequest = request; + searchEntry = null; + searchResponse = null; + searchException = null; + } + + + /** + * Creates a new notification item. + * + * @param entry that represents this item + */ + public NotificationItem(final SearchEntry entry) + { + asyncRequest = null; + searchEntry = entry; + searchResponse = null; + searchException = null; + } + + + /** + * Creates a new notification item. + * + * @param response that represents this item + */ + public NotificationItem(final Response response) + { + asyncRequest = null; + searchEntry = null; + searchResponse = response; + searchException = null; + } + + + /** + * Creates a new notification item. + * + * @param exception that represents this item + */ + public NotificationItem(final Exception exception) + { + asyncRequest = null; + searchEntry = null; + searchResponse = null; + searchException = exception; + } + + + /** + * Returns whether this item represents an async request. + * + * @return whether this item represents an async request + */ + public boolean isAsyncRequest() + { + return asyncRequest != null; + } + + + /** + * Returns the async request contained in this item or null if this item does not contain an async request. + * + * @return async request + */ + public AsyncRequest getAsyncRequest() + { + return asyncRequest; + } + + + /** + * Returns whether this item represents a search entry. + * + * @return whether this item represents a search entry + */ + public boolean isEntry() + { + return searchEntry != null; + } + + + /** + * Returns the search entry contained in this item or null if this item does not contain a search entry. + * + * @return search entry + */ + public SearchEntry getEntry() + { + return searchEntry; + } + + + /** + * Returns whether this item represents a response. + * + * @return whether this item represents a response + */ + public boolean isResponse() + { + return searchResponse != null; + } + + + /** + * Returns the response contained in this item or null if this item does not contain a response. + * + * @return response + */ + public Response getResponse() + { + return searchResponse; + } + + + /** + * Returns whether this item represents an exception. + * + * @return whether this item represents an exception + */ + public boolean isException() + { + return searchException != null; + } + + + /** + * Returns the exception contained in this item or null if this item does not contain an exception. + * + * @return exception + */ + public Exception getException() + { + return searchException; + } + + + @Override + public String toString() + { + String s; + if (isAsyncRequest()) { + s = String.format("[%s@%d::asyncRequest=%s]", getClass().getName(), hashCode(), asyncRequest); + } else if (isEntry()) { + s = String.format("[%s@%d::searchEntry=%s]", getClass().getName(), hashCode(), searchEntry); + } else if (isResponse()) { + s = String.format("[%s@%d::searchResponse=%s]", getClass().getName(), hashCode(), searchResponse); + } else if (isException()) { + s = String.format("[%s@%d::searchException=%s]", getClass().getName(), hashCode(), searchException); + } else { + s = String.format("[%s@%d]", getClass().getName(), hashCode()); + } + return s; + } + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/extended/FastBindOperation.java b/core/src/main/java/org/ldaptive/ad/extended/FastBindOperation.java new file mode 100644 index 0000000..0278dca --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/extended/FastBindOperation.java
@@ -0,0 +1,55 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.extended; + +import org.ldaptive.AbstractOperation; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionInitializer; +import org.ldaptive.LdapException; +import org.ldaptive.Response; + +/** + * Executes an active directory fast bind operation. See + * http://msdn.microsoft.com/en-us/library/cc223503(v=prot.20).aspx. + * + * @author Middleware Services + */ +public class FastBindOperation extends AbstractOperation<FastBindRequest, Void> +{ + + + /** + * Creates a new fast bind operation. + * + * @param conn connection + */ + public FastBindOperation(final Connection conn) + { + super(conn); + } + + + @Override + protected Response<Void> invoke(final FastBindRequest request) + throws LdapException + { + @SuppressWarnings("unchecked") + final Response<Void> response = (Response<Void>) getConnection().getProviderConnection().extendedOperation(request); + return response; + } + + + /** Connection initializer that executes the {@link FastBindOperation}. */ + public static class FastBindConnectionInitializer implements ConnectionInitializer + { + + + @Override + public Response<Void> initialize(final Connection c) + throws LdapException + { + final FastBindOperation op = new FastBindOperation(c); + op.setOperationExceptionHandler(null); + return op.execute(new FastBindRequest()); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/extended/FastBindRequest.java b/core/src/main/java/org/ldaptive/ad/extended/FastBindRequest.java new file mode 100644 index 0000000..6e3dbbb --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/extended/FastBindRequest.java
@@ -0,0 +1,47 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.extended; + +import java.util.Arrays; +import org.ldaptive.AbstractRequest; +import org.ldaptive.extended.ExtendedRequest; + +/** + * Contains the data required to perform a fast bind operation. + * + * @author Middleware Services + */ +public class FastBindRequest extends AbstractRequest implements ExtendedRequest +{ + + /** OID of this extended request. */ + public static final String OID = "1.2.840.113556.1.4.1781"; + + + @Override + public byte[] encode() + { + return null; + } + + + @Override + public String getOID() + { + return OID; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::controls=%s, referralHandler=%s, " + + "intermediateResponseHandlers=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(getControls()), + getReferralHandler(), + Arrays.toString(getIntermediateResponseHandlers())); + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/extended/FastBindResponse.java b/core/src/main/java/org/ldaptive/ad/extended/FastBindResponse.java new file mode 100644 index 0000000..2d0dbce --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/extended/FastBindResponse.java
@@ -0,0 +1,31 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.extended; + +import org.ldaptive.extended.AbstractExtendedResponse; + +/** + * Contains the response from a fast bind operation. + * + * @author Middleware Services + */ +public class FastBindResponse extends AbstractExtendedResponse<Void> +{ + + + @Override + public String getOID() + { + return null; + } + + + @Override + public void decode(final byte[] encoded) {} + + + @Override + public String toString() + { + return String.format("[%s@%d]", getClass().getName(), hashCode()); + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/handler/AbstractBinaryAttributeHandler.java b/core/src/main/java/org/ldaptive/ad/handler/AbstractBinaryAttributeHandler.java new file mode 100644 index 0000000..892f9f7 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/handler/AbstractBinaryAttributeHandler.java
@@ -0,0 +1,125 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.handler; + +import org.ldaptive.Connection; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapException; +import org.ldaptive.LdapUtils; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchRequest; +import org.ldaptive.handler.AbstractSearchEntryHandler; + +/** + * Base class for entry handlers that convert a binary attribute to it's string form. + * + * @author Middleware Services + */ +public abstract class AbstractBinaryAttributeHandler extends AbstractSearchEntryHandler +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1847; + + /** attribute name. */ + private String attributeName; + + + /** + * Returns the attribute name to convert from binary to string. + * + * @return attribute name + */ + public String getAttributeName() + { + return attributeName; + } + + + /** + * Sets the attribute name to convert from binary to string. + * + * @param name of the attribute + */ + public void setAttributeName(final String name) + { + attributeName = name; + } + + + @Override + protected void handleAttributes(final Connection conn, final SearchRequest request, final SearchEntry entry) + throws LdapException + { + for (LdapAttribute la : entry.getAttributes()) { + if (attributeName.equalsIgnoreCase(la.getName())) { + if (la.isBinary()) { + final LdapAttribute newAttr = new LdapAttribute(la.getSortBehavior()); + newAttr.setName(la.getName()); + for (byte[] b : la.getBinaryValues()) { + newAttr.addStringValue(convertValue(b)); + } + entry.addAttribute(newAttr); + logger.debug("Processed attribute {}", newAttr); + handleAttribute(conn, request, newAttr); + } else { + logger.warn("Attribute {} must be set as a binary attribute", attributeName); + handleAttribute(conn, request, la); + } + } else { + handleAttribute(conn, request, la); + } + } + } + + + /** + * Converts the supplied binary value to it's string form. + * + * @param value to convert + * + * @return string form of the value + */ + protected abstract String convertValue(final byte[] value); + + + @Override + public void initializeRequest(final SearchRequest request) + { + boolean isAttrSet = false; + final String[] binaryAttrs = request.getBinaryAttributes(); + if (binaryAttrs != null) { + for (String attr : binaryAttrs) { + if (attributeName.equalsIgnoreCase(attr)) { + isAttrSet = true; + break; + } + } + if (!isAttrSet) { + request.setBinaryAttributes(LdapUtils.concatArrays(binaryAttrs, new String[] {attributeName})); + } + } else { + request.setBinaryAttributes(attributeName); + } + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof AbstractBinaryAttributeHandler) { + final AbstractBinaryAttributeHandler v = (AbstractBinaryAttributeHandler) o; + return LdapUtils.areEqual(attributeName, v.attributeName); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, attributeName); + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/handler/ObjectGuidHandler.java b/core/src/main/java/org/ldaptive/ad/handler/ObjectGuidHandler.java new file mode 100644 index 0000000..15682ca --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/handler/ObjectGuidHandler.java
@@ -0,0 +1,52 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.handler; + +import org.ldaptive.LdapUtils; +import org.ldaptive.ad.GlobalIdentifier; + +/** + * Processes an objectGuid attribute by converting it from binary to it's string form. + * + * @author Middleware Services + */ +public class ObjectGuidHandler extends AbstractBinaryAttributeHandler +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1823; + + /** objectGuid attribute name. */ + private static final String ATTRIBUTE_NAME = "objectGUID"; + + + /** Creates a new object guid handler. */ + public ObjectGuidHandler() + { + setAttributeName(ATTRIBUTE_NAME); + } + + + /** + * Creates a new object guid handler. + * + * @param attrName name of the attribute which is encoded as an objectGUID + */ + public ObjectGuidHandler(final String attrName) + { + setAttributeName(attrName); + } + + + @Override + protected String convertValue(final byte[] value) + { + return GlobalIdentifier.toString(value); + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getAttributeName()); + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/handler/ObjectSidHandler.java b/core/src/main/java/org/ldaptive/ad/handler/ObjectSidHandler.java new file mode 100644 index 0000000..e88655d --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/handler/ObjectSidHandler.java
@@ -0,0 +1,53 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.handler; + +import org.ldaptive.LdapUtils; +import org.ldaptive.ad.SecurityIdentifier; + +/** + * Processes an objectSid attribute by converting it from binary to it's string form. See + * http://msdn.microsoft.com/en-us/library/windows/desktop/ ms679024(v=vs.85).aspx. + * + * @author Middleware Services + */ +public class ObjectSidHandler extends AbstractBinaryAttributeHandler +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1801; + + /** objectSid attribute name. */ + private static final String ATTRIBUTE_NAME = "objectSid"; + + + /** Creates a new object sid handler. */ + public ObjectSidHandler() + { + setAttributeName(ATTRIBUTE_NAME); + } + + + /** + * Creates a new object sid handler. + * + * @param attrName name of the attribute which is encoded as an objectSid + */ + public ObjectSidHandler(final String attrName) + { + setAttributeName(attrName); + } + + + @Override + protected String convertValue(final byte[] value) + { + return SecurityIdentifier.toString(value); + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getAttributeName()); + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/handler/PrimaryGroupIdHandler.java b/core/src/main/java/org/ldaptive/ad/handler/PrimaryGroupIdHandler.java new file mode 100644 index 0000000..b16bdc4 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/handler/PrimaryGroupIdHandler.java
@@ -0,0 +1,148 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.handler; + +import org.ldaptive.Connection; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapException; +import org.ldaptive.LdapUtils; +import org.ldaptive.ReturnAttributes; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.ad.SecurityIdentifier; +import org.ldaptive.handler.AbstractSearchEntryHandler; + +/** + * Constructs the primary group SID and then searches for that group and puts it's DN in the 'memberOf' attribute of the + * original search entry. This handler requires that entries contain both the 'objectSid' and 'primaryGroupID' + * attributes. If those attributes are not found this handler is a no-op. This handler should be used in conjunction + * with the {@link ObjectSidHandler} to ensure the 'objectSid' attribute is in the proper form. See + * http://support2.microsoft.com/kb/297951 + * + * @author Middleware Services + */ +public class PrimaryGroupIdHandler extends AbstractSearchEntryHandler +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1831; + + /** search filter used to find the primary group. */ + private String groupFilter = "(&(objectClass=group)(objectSid={0}))"; + + /** base DN used for searching for the primary group. */ + private String baseDn; + + + /** + * Returns the search filter used to find the primary group. + * + * @return group search filter + */ + public String getGroupFilter() + { + return groupFilter; + } + + + /** + * Sets the search filter used to find the primary group. + * + * @param filter search filter + */ + public void setGroupFilter(final String filter) + { + groupFilter = filter; + } + + + /** + * Returns the base DN to search for the primary group. If this is not set the base DN from the original search is + * used. + * + * @return base DN to search for the primary group + */ + public String getBaseDn() + { + return baseDn; + } + + + /** + * Sets the base DN to search for the primary group. If this is not set the base DN from the original search is used. + * + * @param dn base DN + */ + public void setBaseDn(final String dn) + { + baseDn = dn; + } + + + @Override + protected void handleAttributes(final Connection conn, final SearchRequest request, final SearchEntry entry) + throws LdapException + { + final LdapAttribute objectSid = entry.getAttribute("objectSid"); + final LdapAttribute primaryGroupId = entry.getAttribute("primaryGroupID"); + + logger.debug("found objectSid {} and primaryGroupID {}", objectSid, primaryGroupId); + if (objectSid != null && primaryGroupId != null) { + String sid; + if (objectSid.isBinary()) { + sid = SecurityIdentifier.toString(objectSid.getBinaryValue()); + } else { + sid = objectSid.getStringValue(); + } + + final String groupSid = sid.substring(0, sid.lastIndexOf('-') + 1) + primaryGroupId.getStringValue(); + logger.debug( + "created primary group SID {} from object SID {} and primaryGroupID {}", + groupSid, + sid, + primaryGroupId.getStringValue()); + + final SearchRequest sr = new SearchRequest(); + sr.setBaseDn(baseDn != null ? baseDn : request.getBaseDn()); + sr.setReturnAttributes(ReturnAttributes.NONE.value()); + sr.setSearchFilter(new SearchFilter(groupFilter, new Object[] {groupSid})); + + final SearchOperation search = new SearchOperation(conn); + final SearchResult result = search.execute(sr).getResult(); + if (result.size() == 0) { + logger.debug("could not find primary group for SID {}", groupSid); + } else { + LdapAttribute memberOf = entry.getAttribute("memberOf"); + if (memberOf == null) { + memberOf = new LdapAttribute("memberOf"); + entry.addAttribute(memberOf); + } + memberOf.addStringValue(result.getEntry().getDn()); + } + } + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof PrimaryGroupIdHandler) { + final PrimaryGroupIdHandler v = (PrimaryGroupIdHandler) o; + return LdapUtils.areEqual(groupFilter, v.groupFilter) && + LdapUtils.areEqual(baseDn, v.baseDn); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, groupFilter, baseDn); + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/handler/RangeEntryHandler.java b/core/src/main/java/org/ldaptive/ad/handler/RangeEntryHandler.java new file mode 100644 index 0000000..47f0b6c --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/handler/RangeEntryHandler.java
@@ -0,0 +1,129 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.handler; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.ldaptive.Connection; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapException; +import org.ldaptive.LdapUtils; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.handler.AbstractSearchEntryHandler; + +/** + * Rewrites attributes returned from Active Directory to include all values by performing additional searches. This + * behavior is based on the expired RFC "Incremental Retrieval of Multi-valued Properties" + * http://www.ietf.org/proceedings/53/I-D/draft-kashi-incremental-00.txt. + * + * <p>For example, when the membership of a group exceeds 1500, requests for the member attribute will likely return an + * attribute with name "member;Range=0-1499" and 1500 values. For a group with just over 3000 members, subsequent + * searches will request "member;Range=1500-2999" and then "member;Range=3000-4499". When the returned attribute is of + * the form "member;Range=3000-*", all values have been retrieved.</p> + * + * @author Middleware Services + * @author Tom Zeller + */ +public class RangeEntryHandler extends AbstractSearchEntryHandler +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 839; + + /** The character indicating that the end of the range has been reached. */ + private static final String END_OF_RANGE = "*"; + + /** The format used to calculate attribute IDs for subsequent searches. */ + private static final String RANGE_FORMAT = "%1$s;Range=%2$s-%3$s"; + + /** The expression matching the range attribute ID "<id>range=<X>-<Y>". */ + private static final String RANGE_PATTERN_STRING = "^(.*?);Range=([\\d\\*]+)-([\\d\\*]+)"; + + /** The pattern matching the range attribute ID. */ + private static final Pattern RANGE_PATTERN = Pattern.compile(RANGE_PATTERN_STRING, Pattern.CASE_INSENSITIVE); + + + @Override + protected void handleAttributes(final Connection conn, final SearchRequest request, final SearchEntry entry) + throws LdapException + { + final Map<LdapAttribute, Matcher> matchingAttrs = new HashMap<>(); + for (LdapAttribute la : entry.getAttributes()) { + // Match attribute ID against the pattern + final Matcher matcher = RANGE_PATTERN.matcher(la.getName()); + + // If the attribute ID matches the pattern + if (matcher.find()) { + matchingAttrs.put(la, matcher); + } + } + + for (Map.Entry<LdapAttribute, Matcher> mEntry : matchingAttrs.entrySet()) { + final LdapAttribute la = mEntry.getKey(); + final Matcher matcher = mEntry.getValue(); + final String msg = String.format("attribute '%s' entry '%s'", la.getName(), entry.getDn()); + + // Determine the attribute name without the range syntax + final String attrTypeName = matcher.group(1); + logger.debug("Found Range option {}", msg); + if (attrTypeName == null || attrTypeName.isEmpty()) { + logger.error("Unable to determine the attribute type name for {}", msg); + throw new IllegalArgumentException("Unable to determine the attribute type name for " + msg); + } + + // Create or update the attribute whose ID has the range syntax removed + LdapAttribute newAttr = entry.getAttribute(attrTypeName); + if (newAttr == null) { + newAttr = new LdapAttribute(la.getSortBehavior(), la.isBinary()); + newAttr.setName(attrTypeName); + entry.addAttribute(newAttr); + } + + // Copy values + if (la.isBinary()) { + newAttr.addBinaryValues(la.getBinaryValues()); + } else { + newAttr.addStringValues(la.getStringValues()); + } + + // Remove original attribute with range syntax from returned attributes + entry.removeAttribute(la); + + // If the attribute ID ends with * we're done, otherwise increment + if (!la.getName().endsWith(END_OF_RANGE)) { + + // Determine next attribute ID + // CheckStyle:MagicNumber OFF + final int start = Integer.parseInt(matcher.group(2)); + final int end = Integer.parseInt(matcher.group(3)); + // CheckStyle:MagicNumber ON + final int diff = end - start; + final String nextAttrID = String.format(RANGE_FORMAT, attrTypeName, end + 1, end + diff + 1); + + // Search for next increment of values + logger.debug("Searching for '{}' to increment {}", nextAttrID, msg); + + final SearchOperation search = new SearchOperation(conn); + final SearchRequest sr = SearchRequest.newObjectScopeSearchRequest(entry.getDn(), new String[] {nextAttrID}); + final SearchResult result = search.execute(sr).getResult(); + + // Add all attributes to the search result + entry.addAttributes(result.getEntry().getAttributes()); + + // Iterate + handleAttributes(conn, request, entry); + } + } + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, (Object[]) null); + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/io/DeltaTimeValueTranscoder.java b/core/src/main/java/org/ldaptive/ad/io/DeltaTimeValueTranscoder.java new file mode 100644 index 0000000..f96f6b8 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/io/DeltaTimeValueTranscoder.java
@@ -0,0 +1,37 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.io; + +import org.ldaptive.io.AbstractStringValueTranscoder; + +/** + * Decodes and encodes an active directory delta time value for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class DeltaTimeValueTranscoder extends AbstractStringValueTranscoder<Long> +{ + + /** Delta time uses 100-nanosecond intervals. For conversion purposes this is 1x10^6 / 100. */ + private static final long ONE_HUNDRED_NANOSECOND_INTERVAL = 10000L; + + + @Override + public Long decodeStringValue(final String value) + { + return -Long.parseLong(value) / ONE_HUNDRED_NANOSECOND_INTERVAL; + } + + + @Override + public String encodeStringValue(final Long value) + { + return String.valueOf(-value * ONE_HUNDRED_NANOSECOND_INTERVAL); + } + + + @Override + public Class<Long> getType() + { + return Long.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/io/FileTimeValueTranscoder.java b/core/src/main/java/org/ldaptive/ad/io/FileTimeValueTranscoder.java new file mode 100644 index 0000000..6d3ecc3 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/io/FileTimeValueTranscoder.java
@@ -0,0 +1,44 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.io; + +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import org.ldaptive.io.AbstractStringValueTranscoder; + +/** + * Decodes and encodes an active directory file time value for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class FileTimeValueTranscoder extends AbstractStringValueTranscoder<ZonedDateTime> +{ + + /** Number of milliseconds between standard Unix era (1/1/1970) and filetime start (1/1/1601). */ + private static final long ERA_OFFSET = 11644473600000L; + + /** File time uses 100-nanosecond intervals. For conversion purposes this is 1x10^6 / 100. */ + private static final long ONE_HUNDRED_NANOSECOND_INTERVAL = 10000L; + + + @Override + public ZonedDateTime decodeStringValue(final String value) + { + final Instant i = Instant.ofEpochMilli(Long.parseLong(value) / ONE_HUNDRED_NANOSECOND_INTERVAL - ERA_OFFSET); + return ZonedDateTime.ofInstant(i, ZoneId.of("Z")); + } + + + @Override + public String encodeStringValue(final ZonedDateTime value) + { + return String.valueOf((value.toInstant().toEpochMilli() + ERA_OFFSET) * ONE_HUNDRED_NANOSECOND_INTERVAL); + } + + + @Override + public Class<ZonedDateTime> getType() + { + return ZonedDateTime.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/io/UnicodePwdValueTranscoder.java b/core/src/main/java/org/ldaptive/ad/io/UnicodePwdValueTranscoder.java new file mode 100644 index 0000000..56a98de --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/io/UnicodePwdValueTranscoder.java
@@ -0,0 +1,44 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.io; + +import java.nio.charset.StandardCharsets; +import org.ldaptive.io.AbstractBinaryValueTranscoder; + +/** + * Decodes and encodes an active directory unicodePwd value for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class UnicodePwdValueTranscoder extends AbstractBinaryValueTranscoder<String> +{ + + + @Override + public String decodeBinaryValue(final byte[] value) + { + final String pwd = new String(value, StandardCharsets.UTF_16LE); + if (pwd.length() < 2) { + throw new IllegalArgumentException("unicodePwd must be at least 2 characters long"); + } + return pwd.substring(1, pwd.length() - 1); + } + + + @Override + public byte[] encodeBinaryValue(final String value) + { + if (value == null) { + throw new IllegalArgumentException("Cannot encode null value"); + } + + final String pwd = String.format("\"%s\"", value); + return pwd.getBytes(StandardCharsets.UTF_16LE); + } + + + @Override + public Class<String> getType() + { + return String.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/ad/schema/SchemaFactory.java b/core/src/main/java/org/ldaptive/ad/schema/SchemaFactory.java new file mode 100644 index 0000000..ad45805 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ad/schema/SchemaFactory.java
@@ -0,0 +1,251 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.schema; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.Response; +import org.ldaptive.ReturnAttributes; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.control.util.PagedResultsClient; +import org.ldaptive.io.LdifReader; +import org.ldaptive.schema.AttributeType; +import org.ldaptive.schema.ObjectClass; +import org.ldaptive.schema.ObjectClassType; +import org.ldaptive.schema.Schema; + +/** + * Factory to create {@link Schema} from an active directory schema search result. Active Directory does not adhere to + * RFC 4512 to represent it's schema. Each schema element is represented with a separate LDAP entry. The factory parses + * and sets the object classes and attribute types for the schema. The other properties on the schema object are not + * available. + * + * @author Middleware Services + */ +public final class SchemaFactory +{ + + + /** Default constructor. */ + private SchemaFactory() {} + + + /** + * Creates a new schema. The input stream should contain the LDIF for the schema search results. + * + * @param is containing the schema ldif + * + * @return schema + * + * @throws IOException if an error occurs reading the input stream + */ + public static Schema createSchema(final InputStream is) + throws IOException + { + final LdifReader reader = new LdifReader(new InputStreamReader(is)); + return createSchema(reader.read()); + } + + + /** + * Creates a new schema. The entryDn is searched to obtain the schema. + * + * @param factory to obtain an LDAP connection from + * @param entryDn the schema entries + * + * @return schema + * + * @throws LdapException if the search fails + */ + public static Schema createSchema(final ConnectionFactory factory, final String entryDn) + throws LdapException + { + return createSchema(getSearchResult(factory, entryDn, "(objectClass=*)", ReturnAttributes.ALL.value())); + } + + + /** + * Creates a new schema. The schema result should contain entries with the 'attributeSchema' and 'classSchema' + * objectClasses. + * + * @param schemaResult containing the schema entries + * + * @return schema + */ + public static Schema createSchema(final SearchResult schemaResult) + { + final Set<AttributeType> attributeTypes = new HashSet<>(); + final Set<ObjectClass> objectClasses = new HashSet<>(); + for (LdapEntry entry : schemaResult.getEntries()) { + final LdapAttribute la = entry.getAttribute("objectClass"); + if (la != null && la.getStringValues().contains("attributeSchema")) { + attributeTypes.add(createAttributeType(entry)); + } + if (la != null && la.getStringValues().contains("classSchema")) { + objectClasses.add(createObjectClass(entry)); + } + } + + final Schema schema = new Schema(); + schema.setAttributeTypes(attributeTypes); + schema.setObjectClasses(objectClasses); + return schema; + } + + + /** + * Searches for the supplied dn and returns its ldap entry. This methods uses the paged results search control as + * schema entries typically number beyond the server search size limit. + * + * @param factory to obtain an LDAP connection from + * @param dn to search for + * @param filter to search with + * @param retAttrs attributes to return + * + * @return ldap entry + * + * @throws LdapException if the search fails + */ + protected static SearchResult getSearchResult( + final ConnectionFactory factory, + final String dn, + final String filter, + final String[] retAttrs) + throws LdapException + { + try (Connection conn = factory.getConnection()) { + conn.open(); + + final PagedResultsClient client = new PagedResultsClient(conn, 100); + final SearchRequest request = new SearchRequest(dn, filter, retAttrs); + final Response<SearchResult> response = client.executeToCompletion(request); + return response.getResult(); + } + } + + + /** + * Creates an attribute type from the supplied ldap entry. The entry must contain an objectClass of 'attributeSchema'. + * This method only populates the OID, names, description, syntax, and single valued properties of the attribute type. + * + * @param entry containing an attribute schema + * + * @return attribute type + */ + protected static AttributeType createAttributeType(final LdapEntry entry) + { + final LdapAttribute la = entry.getAttribute("objectClass"); + if (la == null || !la.getStringValues().contains("attributeSchema")) { + throw new IllegalArgumentException("Entry is not an attribute schema"); + } + return + new AttributeType( + getAttributeValue(entry, "attributeID"), + getAttributeValues(entry, "lDAPDisplayName", "adminDisplayName", "name"), + getAttributeValue(entry, "adminDescription"), + false, + null, + null, + null, + null, + getAttributeValue(entry, "attributeSyntax"), + Boolean.valueOf(getAttributeValue(entry, "isSingleValued")), + false, + false, + null, + null); + } + + + /** + * Creates an object class from the supplied ldap entry. The entry must contain an objectClass of 'classSchema'. This + * method only populates the OID, names, description, superior classes, object class type, required attributes, and + * optional attributes of the object class. + * + * @param entry containing a class schema + * + * @return object class + */ + protected static ObjectClass createObjectClass(final LdapEntry entry) + { + final LdapAttribute la = entry.getAttribute("objectClass"); + if (la == null || !la.getStringValues().contains("classSchema")) { + throw new IllegalArgumentException("Entry is not an object class"); + } + + ObjectClassType ocType = null; + final String ocCategory = getAttributeValue(entry, "objectClassCategory"); + if (ocCategory != null) { + for (ObjectClassType type : ObjectClassType.values()) { + if (type.ordinal() == Integer.parseInt(ocCategory)) { + ocType = type; + break; + } + } + } + return + new ObjectClass( + getAttributeValue(entry, "governsID"), + getAttributeValues(entry, "lDAPDisplayName", "adminDisplayName", "name"), + getAttributeValue(entry, "adminDescription"), + false, + getAttributeValues(entry, "possSuperiors", "systemPossSuperiors"), + ocType, + getAttributeValues(entry, "mustContain", "systemMustContain"), + getAttributeValues(entry, "mayContain", "systemMayContain"), + null); + } + + + /** + * Returns a single value for the first attribute name found in the supplied entry. + * + * @param entry containing the attributes + * @param names to search for in the entry + * + * @return single attribute value + */ + private static String getAttributeValue(final LdapEntry entry, final String... names) + { + String value = null; + for (String name : names) { + final LdapAttribute la = entry.getAttribute(name); + if (la != null) { + value = la.getStringValue(); + break; + } + } + return value; + } + + + /** + * Returns the values for the first attribute name found in the supplied entry. + * + * @param entry containing the attributes + * @param names to search for in the entry + * + * @return attribute values + */ + private static String[] getAttributeValues(final LdapEntry entry, final String... names) + { + Collection<String> values = null; + for (String name : names) { + final LdapAttribute la = entry.getAttribute(name); + if (la != null) { + values = la.getStringValues(); + break; + } + } + return values != null ? values.toArray(new String[values.size()]) : null; + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/AbstractDERTag.java b/core/src/main/java/org/ldaptive/asn1/AbstractDERTag.java new file mode 100644 index 0000000..29352da --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/AbstractDERTag.java
@@ -0,0 +1,58 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +/** + * Abstract base class for custom DER tag types. + * + * @author Middleware Services + */ +public abstract class AbstractDERTag implements DERTag +{ + + /** Tag number. */ + private final int tagNo; + + /** Flag indicating whether value is primitive or constructed. */ + private final boolean constructed; + + + /** + * Creates a new tag with given tag number. + * + * @param number Tag number. + * @param isConstructed True for constructed tag, false otherwise. + */ + public AbstractDERTag(final int number, final boolean isConstructed) + { + tagNo = number; + constructed = isConstructed; + } + + + @Override + public int getTagNo() + { + return tagNo; + } + + + @Override + public boolean isConstructed() + { + return constructed; + } + + + @Override + public int getTagByte() + { + return constructed ? tagNo | ASN_CONSTRUCTED : tagNo; + } + + + @Override + public String toString() + { + return String.format("%s(%s)", name(), tagNo); + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/AbstractDERType.java b/core/src/main/java/org/ldaptive/asn1/AbstractDERType.java new file mode 100644 index 0000000..286bb54 --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/AbstractDERType.java
@@ -0,0 +1,89 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.nio.ByteBuffer; + +/** + * Provides functionality common to DER types implementations. + * + * @author Middleware Services + */ +public abstract class AbstractDERType +{ + + /** Length of short form integers. */ + private static final int SHORT_FORM_INT_LENGTH = 127; + + /** Constructed tag. */ + private final int derTag; + + + /** + * Creates a new abstract der type. + * + * @param tag to encode for this type + */ + public AbstractDERType(final DERTag tag) + { + derTag = tag.getTagByte(); + } + + + /** + * DER encode the supplied items with the tag associated with this type. If the length is greater than 127 bytes the + * long form is always expressed using 4 bytes. + * + * @param items to encode + * + * @return DER encoded items + */ + protected byte[] encode(final byte[]... items) + { + int itemLength = 0; + for (byte[] b : items) { + itemLength += b.length; + } + + byte[] lengthBytes; + if (itemLength <= SHORT_FORM_INT_LENGTH) { + lengthBytes = new byte[] {(byte) itemLength}; + } else { + // use 4 bytes for all long form integers + // CheckStyle:MagicNumber OFF + lengthBytes = new byte[] { + (byte) 0x84, + (byte) (itemLength >>> 24), + (byte) (itemLength >>> 16), + (byte) (itemLength >>> 8), + (byte) itemLength, + }; + // CheckStyle:MagicNumber ON + } + + // add 1 for the type tag, 1 or 5 for the length + final ByteBuffer encodedItem = ByteBuffer.allocate(itemLength + 1 + lengthBytes.length); + encodedItem.put((byte) derTag); + for (byte b : lengthBytes) { + encodedItem.put(b); + } + for (byte[] b : items) { + encodedItem.put(b); + } + return encodedItem.array(); + } + + + /** + * Returns a byte array containing the bytes from {@link ByteBuffer#limit()} to {@link ByteBuffer#position()}. + * + * @param encoded to read bytes from + * + * @return bytes + */ + public static byte[] readBuffer(final ByteBuffer encoded) + { + final byte[] bytes = new byte[encoded.limit() - encoded.position()]; + encoded.get(bytes); + return bytes; + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/AbstractParseHandler.java b/core/src/main/java/org/ldaptive/asn1/AbstractParseHandler.java new file mode 100644 index 0000000..a7bcbdc --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/AbstractParseHandler.java
@@ -0,0 +1,38 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +/** + * Parse handler for managing and initializing an object. + * + * @param <T> type of object initialized by this handler + * + * @author Middleware Services + */ +public abstract class AbstractParseHandler<T> implements ParseHandler +{ + + /** Object to initialize. */ + private final T object; + + + /** + * Creates a new abstract parse handler. + * + * @param t object to initialize + */ + public AbstractParseHandler(final T t) + { + object = t; + } + + + /** + * Returns the object. + * + * @return object + */ + public T getObject() + { + return object; + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/ApplicationDERTag.java b/core/src/main/java/org/ldaptive/asn1/ApplicationDERTag.java new file mode 100644 index 0000000..38a0085 --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/ApplicationDERTag.java
@@ -0,0 +1,50 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +/** + * Generic application-specific tag. + * + * @author Middleware Services + */ +public class ApplicationDERTag extends AbstractDERTag +{ + + /** Generic tag name "APP" for a application-specific type. */ + public static final String TAG_NAME = "APP"; + + /** Application class is 01b in first two high-order bits. */ + public static final int TAG_CLASS = 0x40; + + + /** + * Creates a new application-specific tag with given tag number. + * + * @param number Tag number. + * @param isConstructed True for constructed tag, false otherwise. + */ + public ApplicationDERTag(final int number, final boolean isConstructed) + { + super(number, isConstructed); + } + + + @Override + public int getTagByte() + { + return super.getTagByte() | TAG_CLASS; + } + + + @Override + public String name() + { + return String.format("%s(%s)", TAG_NAME, getTagNo()); + } + + + @Override + public String toString() + { + return name(); + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/AttributeValueAssertion.java b/core/src/main/java/org/ldaptive/asn1/AttributeValueAssertion.java new file mode 100644 index 0000000..946c576 --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/AttributeValueAssertion.java
@@ -0,0 +1,231 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import org.ldaptive.LdapUtils; + +/** + * An OID representing the type of attribute and its value. + * + * @author Middleware Services + */ +public class AttributeValueAssertion extends AbstractDERType implements DEREncoder +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 613; + + /** OID of the attribute. */ + private final String attributeOid; + + /** Tag and value of the attribute. */ + private final Value attributeValue; + + + /** + * Creates a new attribute value assertion. + * + * @param oid describing the attribute value + * @param value of the attribute + */ + public AttributeValueAssertion(final String oid, final Value value) + { + super(value.getTag()); + attributeOid = oid; + attributeValue = value; + } + + + /** + * Returns the OID. + * + * @return oid + */ + public String getOid() + { + return attributeOid; + } + + + /** + * Returns the tag and value of the attribute. + * + * @return attribute value + */ + public Value getValue() + { + return attributeValue; + } + + + @Override + public byte[] encode() + { + final ConstructedDEREncoder se = new ConstructedDEREncoder( + UniversalDERTag.SEQ, + () -> { + final OidType type = new OidType(attributeOid); + return type.encode(); + }, + () -> AttributeValueAssertion.this.encode(attributeValue.getBytes())); + + return se.encode(); + } + + + /** + * Converts bytes in the buffer to attribute value assertions by reading from the current position to the limit. + * + * @param encoded buffer containing DER-encoded data where the buffer is positioned at the tag of the oid and the + * limit is set beyond the last byte of attribute value data. + * + * @return decoded bytes as attribute value assertions + */ + public static AttributeValueAssertion[] decode(final ByteBuffer encoded) + { + final List<AttributeValueAssertion> assertions = new ArrayList<>(); + final DERParser parser = new DERParser(); + parser.registerHandler( + "/SEQ", + (parser1, encoded1) -> { + if (UniversalDERTag.OID.getTagNo() != parser1.readTag(encoded1).getTagNo()) { + throw new IllegalArgumentException("Expected OID tag"); + } + + final int seqLimit = encoded1.limit(); + final int oidLength = parser1.readLength(encoded1); + encoded1.limit(encoded1.position() + oidLength); + + final String oid = OidType.decode(encoded1); + encoded1.limit(seqLimit); + + final DERTag tag = parser1.readTag(encoded1); + parser1.readLength(encoded1); + assertions.add(new AttributeValueAssertion(oid, new Value(tag, readBuffer(encoded1)))); + }); + parser.parse(encoded); + return assertions.toArray(new AttributeValueAssertion[assertions.size()]); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof AttributeValueAssertion) { + final AttributeValueAssertion v = (AttributeValueAssertion) o; + return LdapUtils.areEqual(attributeOid, v.attributeOid) && + LdapUtils.areEqual(attributeValue, v.attributeValue); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, attributeOid, attributeValue); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::attributeOid=%s, attributeValue=%s]", + getClass().getName(), + hashCode(), + attributeOid, + attributeValue); + } + + + /** Class to represent the tag and value. */ + public static class Value + { + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 617; + + /** attribute value tag. */ + private final DERTag attributeValueTag; + + /** attribute value bytes. */ + private final byte[] attributeValueBytes; + + + /** + * Creates a new value. + * + * @param tag type of the attribute value + * @param bytes of the attribute + */ + public Value(final DERTag tag, final byte[] bytes) + { + attributeValueTag = tag; + attributeValueBytes = bytes; + } + + + /** + * Returns the attribute value tag. + * + * @return attribute value tag + */ + public DERTag getTag() + { + return attributeValueTag; + } + + + /** + * Returns the attribute value bytes. + * + * @return attribute value bytes + */ + public byte[] getBytes() + { + return attributeValueBytes; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof Value) { + final Value v = (Value) o; + return LdapUtils.areEqual(attributeValueTag, v.attributeValueTag) && + LdapUtils.areEqual(attributeValueBytes, v.attributeValueBytes); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, attributeValueTag, attributeValueBytes); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::attributeValueTag=%s, attributeValueBytes=%s]", + getClass().getName(), + hashCode(), + attributeValueTag, + LdapUtils.utf8Encode(attributeValueBytes)); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/BooleanType.java b/core/src/main/java/org/ldaptive/asn1/BooleanType.java new file mode 100644 index 0000000..69642a7 --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/BooleanType.java
@@ -0,0 +1,96 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.nio.ByteBuffer; + +/** + * Converts booleans to and from their DER encoded format. + * + * @author Middleware Services + */ +public class BooleanType extends AbstractDERType implements DEREncoder +{ + + /** Boolean true byte representation. */ + private static final byte TRUE_BYTE = (byte) 0xff; + + /** Boolean false byte representation. */ + private static final byte FALSE_BYTE = (byte) 0x00; + + /** Boolean to encode. */ + private final byte[] derItem; + + + /** + * Creates a new boolean type. + * + * @param item to DER encode + */ + public BooleanType(final boolean item) + { + super(UniversalDERTag.BOOL); + derItem = toBytes(item); + } + + + /** + * Creates a new boolean type. + * + * @param tag der tag associated with this type + * @param item to DER encode + * + * @throws IllegalArgumentException if the der tag is constructed + */ + public BooleanType(final DERTag tag, final boolean item) + { + super(tag); + if (tag.isConstructed()) { + throw new IllegalArgumentException("DER tag must not be constructed"); + } + derItem = toBytes(item); + } + + + @Override + public byte[] encode() + { + return encode(derItem); + } + + + /** + * Converts bytes in the buffer to a boolean by reading from the current position to the limit. + * + * @param encoded buffer containing DER-encoded data where the buffer is positioned at the start of boolean bytes + * and the limit is set beyond the last byte of integer data. + * + * @return decoded bytes as a boolean. + */ + public static boolean decode(final ByteBuffer encoded) + { + final byte[] bytes = readBuffer(encoded); + if (bytes.length > 1) { + throw new IllegalArgumentException("Boolean cannot be longer than 1 byte"); + } + if (bytes[0] == TRUE_BYTE) { + return true; + } else if (bytes[0] == FALSE_BYTE) { + return false; + } else { + throw new IllegalArgumentException("Invalid boolean value: " + (int) bytes[0]); + } + } + + + /** + * Converts the supplied boolean to a byte array. + * + * @param b to convert + * + * @return byte array + */ + public static byte[] toBytes(final boolean b) + { + return new byte[] {b ? TRUE_BYTE : FALSE_BYTE}; + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/ConstructedDEREncoder.java b/core/src/main/java/org/ldaptive/asn1/ConstructedDEREncoder.java new file mode 100644 index 0000000..a49972f --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/ConstructedDEREncoder.java
@@ -0,0 +1,55 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * Encodes constructed types to their DER format. + * + * @author Middleware Services + */ +public class ConstructedDEREncoder extends AbstractDERType implements DEREncoder +{ + + /** Encoders in this sequence. */ + private final DEREncoder[] derEncoders; + + + /** + * Creates a new sequence encoder. + * + * @param tag der tag associated with this type + * @param encoders to encode in this sequence + */ + public ConstructedDEREncoder(final DERTag tag, final DEREncoder... encoders) + { + super(tag); + if (!tag.isConstructed()) { + throw new IllegalArgumentException("DER tag must be constructed"); + } + if (encoders == null || encoders.length == 0) { + throw new IllegalArgumentException("Encoders cannot be null or empty"); + } + derEncoders = encoders; + } + + + @Override + public byte[] encode() + { + final ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + try { + try { + for (DEREncoder encoder : derEncoders) { + bytes.write(encoder.encode()); + } + } finally { + bytes.close(); + } + } catch (IOException e) { + throw new IllegalStateException("Encode failed", e); + } + return encode(bytes.toByteArray()); + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/ContextDERTag.java b/core/src/main/java/org/ldaptive/asn1/ContextDERTag.java new file mode 100644 index 0000000..c75c66a --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/ContextDERTag.java
@@ -0,0 +1,43 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +/** + * Generic context-specific tag. + * + * @author Middleware Services + */ +public class ContextDERTag extends AbstractDERTag +{ + + /** Generic tag name "CTX" for a context-specific type. */ + public static final String TAG_NAME = "CTX"; + + /** Context-specific class is 10b in first two high-order bits. */ + public static final int TAG_CLASS = 0x80; + + + /** + * Creates a new context-specific tag with given tag number. + * + * @param number Tag number. + * @param isConstructed True for constructed tag, false otherwise. + */ + public ContextDERTag(final int number, final boolean isConstructed) + { + super(number, isConstructed); + } + + + @Override + public int getTagByte() + { + return super.getTagByte() | TAG_CLASS; + } + + + @Override + public String name() + { + return String.format("%s(%s)", TAG_NAME, getTagNo()); + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/ContextType.java b/core/src/main/java/org/ldaptive/asn1/ContextType.java new file mode 100644 index 0000000..248c728 --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/ContextType.java
@@ -0,0 +1,72 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.math.BigInteger; + +/** + * Converts context types to their DER encoded format. + * + * @author Middleware Services + */ +public class ContextType extends AbstractDERType implements DEREncoder +{ + + /** Data to encode. */ + private final byte[] derItem; + + + /** + * Creates a new context type. + * + * @param index of this item in the context + * @param item to encode + */ + public ContextType(final int index, final byte[] item) + { + super(new ContextDERTag(index, false)); + derItem = item; + } + + + /** + * Creates a new context type. + * + * @param index of this item in the context + * @param item to encode + */ + public ContextType(final int index, final String item) + { + this(index, OctetStringType.toBytes(item)); + } + + + /** + * Creates a new context type. + * + * @param index of this item in the context + * @param item to encode + */ + public ContextType(final int index, final boolean item) + { + this(index, BooleanType.toBytes(item)); + } + + + /** + * Creates a new context type. + * + * @param index of this item in the context + * @param item to encode + */ + public ContextType(final int index, final BigInteger item) + { + this(index, IntegerType.toBytes(item)); + } + + + @Override + public byte[] encode() + { + return encode(derItem); + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/CustomDERTag.java b/core/src/main/java/org/ldaptive/asn1/CustomDERTag.java new file mode 100644 index 0000000..3d7dbd8 --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/CustomDERTag.java
@@ -0,0 +1,43 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +/** + * Describes the tag of an application-specific, context-specific, or private DER type where the tag name may be + * specified for clarity in application code. + * + * @author Middleware Services + */ +public class CustomDERTag extends AbstractDERTag +{ + + /** Tag name. */ + private final String tagName; + + + /** + * Creates a new custom DER tag. + * + * @param number of the tag + * @param name of the tag + * @param isConstructed whether this tag is primitive or constructed + */ + public CustomDERTag(final int number, final String name, final boolean isConstructed) + { + super(number, isConstructed); + tagName = name; + } + + + @Override + public String name() + { + return tagName; + } + + + @Override + public String toString() + { + return String.format("%s(%s)", name(), getTagNo()); + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/DEREncoder.java b/core/src/main/java/org/ldaptive/asn1/DEREncoder.java new file mode 100644 index 0000000..24eef7a --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/DEREncoder.java
@@ -0,0 +1,19 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +/** + * Interface for encoding DER objects. + * + * @author Middleware Services + */ +public interface DEREncoder +{ + + + /** + * Encode this object into it's DER type. + * + * @return DER encoded object + */ + byte[] encode(); +}
diff --git a/core/src/main/java/org/ldaptive/asn1/DERParser.java b/core/src/main/java/org/ldaptive/asn1/DERParser.java new file mode 100644 index 0000000..c22500a --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/DERParser.java
@@ -0,0 +1,237 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.nio.ByteBuffer; +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Queue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class provides a SAX-like parsing facility for DER-encoded data where elements of interest in the parse tree may + * be registered to handlers via the {@link #registerHandler} methods. {@link DERPath} strings are used to map handlers + * to elements of interest. + * + * @author Middleware Services + * @see DERPath + */ +public class DERParser +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Handlers for DER paths. */ + private final Map<DERPath, ParseHandler> handlerMap = new HashMap<>(); + + /** Permutations of the current path. */ + private final Queue<DERPath> permutations = new ArrayDeque<>(); + + + /** + * See {@link #registerHandler(DERPath, ParseHandler)}. + * + * @param path to register + * @param handler to associate with the path + */ + public void registerHandler(final String path, final ParseHandler handler) + { + registerHandler(new DERPath(path), handler); + } + + + /** + * Registers the supplied handler to fire when the supplied path is encountered. + * + * @param path to register + * @param handler to associate with the path + */ + public void registerHandler(final DERPath path, final ParseHandler handler) + { + handlerMap.put(path, handler); + } + + + /** + * Parse a DER-encoded data structure by calling registered handlers when points of interest are encountered in the + * parse tree. + * + * @param encoded DER-encoded bytes. + */ + public void parse(final ByteBuffer encoded) + { + parseTags(encoded); + } + + + /** + * Reads a DER tag from a single byte at the current position of the given buffer. The buffer position is naturally + * advanced one byte in this operation. + * + * @param encoded Buffer containing DER-encoded bytes positioned at tag. + * + * @return Tag or null if no universal tag or application-specific tag is known that matches the byte read in. + */ + public DERTag readTag(final ByteBuffer encoded) + { + if (encoded.position() >= encoded.limit()) { + return null; + } + + DERTag tag; + final byte b = encoded.get(); + // CheckStyle:MagicNumber OFF + final int tagNo = b & 0x1F; + final boolean constructed = (b & 0x20) == 0x20; + // Read class from first two high-order bits + switch (b & 0xC0) { + + case UniversalDERTag.TAG_CLASS: + tag = UniversalDERTag.fromTagNo(tagNo); + break; + + case ApplicationDERTag.TAG_CLASS: + tag = new ApplicationDERTag(tagNo, constructed); + break; + + case ContextDERTag.TAG_CLASS: + tag = new ContextDERTag(tagNo, constructed); + break; + + default: + // Private class (class 11b) + throw new IllegalArgumentException("Private classes not supported."); + } + // CheckStyle:MagicNumber ON + return tag; + } + + + /** + * Reads the length of a DER-encoded value from the given byte buffer. The buffer is expected to be positioned at the + * byte immediately following the tag byte, which is where the length byte(s) begin(s). Invocation of this method has + * two generally beneficial side effects: + * + * <ol> + * <li>Buffer is positioned at <em>start</em> of value bytes.</li> + * <li>Buffer limit is set to the <em>end</em> of value bytes.</li> + * </ol> + * + * @param encoded buffer containing DER-encoded bytes positioned at start of length byte(s). + * + * @return number of bytes occupied by tag value. + */ + public int readLength(final ByteBuffer encoded) + { + int length = 0; + final byte b = encoded.get(); + // CheckStyle:MagicNumber OFF + if ((b & 0x80) == 0x80) { + final int len = b & 0x7F; + if (len > 0) { + encoded.limit(encoded.position() + len); + length = IntegerType.decodeUnsigned(encoded).intValue(); + encoded.limit(encoded.capacity()); + } + } else { + length = b; + } + return length; + // CheckStyle:MagicNumber ON + } + + + /** + * Reads the supplied DER encoded bytes and invokes handlers as configured paths are encountered. + * + * @param encoded to parse + */ + private void parseTags(final ByteBuffer encoded) + { + int index = 0; + while (encoded.position() < encoded.limit()) { + final DERTag tag = readTag(encoded); + if (tag != null) { + addTag(tag, index++); + parseTag(tag, encoded); + removeTag(); + } + } + } + + + /** + * Invokes the parse handler for the current path and advances to the next position in the encoded bytes. + * + * @param tag to inspect for internal tags + * @param encoded to parse + */ + private void parseTag(final DERTag tag, final ByteBuffer encoded) + { + final int end = readLength(encoded) + encoded.position(); + final int start = encoded.position(); + + // Invoke handlers for all permutations of current path + ParseHandler handler; + for (DERPath p : permutations) { + handler = handlerMap.get(p); + if (handler != null) { + encoded.position(start).limit(end); + handler.handle(this, encoded); + } + } + + if (tag.isConstructed()) { + parseTags(encoded); + } + encoded.position(end).limit(encoded.capacity()); + } + + + /** + * Add the given tag at the specified index to all permutations of the current parser path and increases the number of + * permutations as necessary to satisfy the following relation: + * + * <pre>size = 2^n</pre> + * + * <p>where n is the path length.</p> + * + * @param tag to add to path. + * @param index of tag relative to parent. + */ + private void addTag(final DERTag tag, final int index) + { + if (permutations.isEmpty()) { + permutations.add(new DERPath().pushNode(tag.name())); + permutations.add(new DERPath().pushNode(tag.name(), index)); + } else { + final Collection<DERPath> generation = new ArrayDeque<>(permutations.size()); + for (DERPath p : permutations) { + generation.add(new DERPath(p).pushNode(tag.name())); + p.pushNode(tag.name(), index); + } + permutations.addAll(generation); + } + } + + + /** + * Removes the tag at the leaf position of all permutations of the current parser path, and reduces the number of + * permutations as necessary to satisfy the following relation: + * + * <pre>size = 2^n</pre> + * + * <p>where n is the path length.</p> + */ + private void removeTag() + { + final int half = permutations.size() / 2; + while (permutations.size() > half) { + permutations.remove(); + } + permutations.forEach(DERPath::popNode); + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/DERPath.java b/core/src/main/java/org/ldaptive/asn1/DERPath.java new file mode 100644 index 0000000..5601834 --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/DERPath.java
@@ -0,0 +1,371 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.ldaptive.LdapUtils; + +/** + * Describes paths to individual elements of an encoded DER object that may be addressed during parsing to associate a + * parsed element with a handler to handle that element. Consider the following production rule for a complex type that + * may be DER encoded: + * + * <pre> + + BankAccountSet ::= SET OF { + account BankAccount + } + + BankAccount ::= SEQUENCE OF { + accountNumber OCTET STRING, + accountName OCTET STRING, + accountType AccountType, + balance REAL + } + + AccountType ::= ENUM { + checking (0), + savings (1) + } + + * </pre> + * + * <p>Given an instance of BankAccountSet with two elements, the path to the balance of each bank account in the set is + * given by the following expression:</p> + * + * <pre>/SET/SEQ/REAL</pre> + * + * <p>Individual child elements can be accessed by explicitly mentioning the index of the item relative to its parent. + * For example, the second bank account in the set can be accessed as follows:</p> + * + * <pre>/SET/SEQ[1]</pre> + * + * <p>Node names in DER paths are constrained to the following:</p> + * + * <ul> + * <li>{@link UniversalDERTag} tag names</li> + * <li>{@link ApplicationDERTag#TAG_NAME}</li> + * <li>{@link ContextDERTag#TAG_NAME}</li> + * </ul> + * + * @author Middleware Services + * @see DERParser + */ +public class DERPath +{ + + /** Separates nodes in a path specification. */ + public static final String PATH_SEPARATOR = "/"; + + /** General pattern for DER path nodes. */ + private static final Pattern NODE_PATTERN; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 601; + + + /** + * Class initializer. + */ + static { + final StringBuilder validNames = new StringBuilder(); + validNames.append(ApplicationDERTag.TAG_NAME).append("\\(\\d+\\)|"); + validNames.append(ContextDERTag.TAG_NAME).append("\\(\\d+\\)|"); + for (UniversalDERTag tag : UniversalDERTag.values()) { + validNames.append('|').append(tag.name()); + } + NODE_PATTERN = Pattern.compile(String.format("(%s)(\\[(\\d+)\\])?", validNames.toString())); + } + + /** Describes the path as a FIFO set of nodes. */ + private final Deque<Node> nodeStack = new ArrayDeque<>(); + + + /** Creates an empty path specification. */ + public DERPath() + { + this(PATH_SEPARATOR); + } + + + /** + * Copy constructor. + * + * @param path to read nodes from + */ + public DERPath(final DERPath path) + { + nodeStack.addAll(path.nodeStack); + } + + + /** + * Creates a path specification from its string representation. + * + * @param pathSpec string representation of a path, e.g. /SEQ[1]/CHOICE. + */ + public DERPath(final String pathSpec) + { + final String[] nodes = pathSpec.split(PATH_SEPARATOR); + for (String node : nodes) { + if ("".equals(node)) { + continue; + } + // Normalize node names to upper case + nodeStack.add(toNode(node.toUpperCase())); + } + } + + + /** + * Appends a node to the path. + * + * @param name of the path element to add + * + * @return This instance with new node appended. + */ + public DERPath pushNode(final String name) + { + nodeStack.addLast(new Node(name)); + return this; + } + + + /** + * Appends a node to the path with the given child index. + * + * @param name of the path element to add + * @param index child index + * + * @return This instance with new node appended. + */ + public DERPath pushNode(final String name, final int index) + { + nodeStack.addLast(new Node(name, index)); + return this; + } + + + /** + * Examines the last node in the path without removing it. + * + * @return last node in the path or null if no nodes remain + */ + public String peekNode() + { + return nodeStack.peek().toString(); + } + + + /** + * Removes the last node in the path. + * + * @return last node in the path or null if no more nodes remain. + */ + public String popNode() + { + if (nodeStack.isEmpty()) { + return null; + } + return nodeStack.removeLast().toString(); + } + + + /** + * Gets the number of nodes in the path. + * + * @return node count. + */ + public int getSize() + { + return nodeStack.size(); + } + + + /** + * Determines whether the path contains any nodes. + * + * @return True if path contains 0 nodes, false otherwise. + */ + public boolean isEmpty() + { + return nodeStack.isEmpty(); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof DERPath) { + final DERPath v = (DERPath) o; + return LdapUtils.areEqual(nodeStack.toArray(), v.nodeStack.toArray()); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, nodeStack); + } + + + @Override + public String toString() + { + final StringBuilder sb = new StringBuilder(nodeStack.size() * 10); + for (Node node : nodeStack) { + sb.append(PATH_SEPARATOR); + node.toString(sb); + } + return sb.toString(); + } + + + /** + * Converts a string representation of a node into a {@link Node} object. + * + * @param node String representation of node. + * + * @return Node corresponding to given string representation. + * + * @throws IllegalArgumentException for an invalid node name. + */ + static Node toNode(final String node) + { + final Matcher matcher = NODE_PATTERN.matcher(node); + if (!matcher.matches()) { + throw new IllegalArgumentException("Invalid node: " + node); + } + + final String name = matcher.group(1); + final String index = matcher.group(3); + if (index != null) { + return new Node(name, Integer.parseInt(index)); + } + return new Node(name); + } + + + /** + * DER path node encapsulates the path name and its location among other children that share a common parent. + * + * @author Middleware Services + */ + static class Node + { + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 607; + + /** Name of this node. */ + private final String name; + + /** Index of this node. */ + private final int childIndex; + + + /** + * Creates a new node with an indeterminate index. + * + * @param n name of this node + */ + Node(final String n) + { + name = n; + childIndex = -1; + } + + + /** + * Creates a new node with the given index. + * + * @param n name of this node + * @param i child index location of this node in the path + */ + Node(final String n, final int i) + { + if (i < 0) { + throw new IllegalArgumentException("Child index cannot be negative."); + } + name = n; + childIndex = i; + } + + + /** + * Returns the name. + * + * @return name + */ + public String getName() + { + return name; + } + + + /** + * Returns the child index. + * + * @return child index + */ + public int getChildIndex() + { + return childIndex; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof Node) { + final Node v = (Node) o; + return LdapUtils.areEqual(name, v.name) && + LdapUtils.areEqual(childIndex, v.childIndex); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, name, childIndex); + } + + + @Override + public String toString() + { + // CheckStyle:MagicNumber OFF + final StringBuilder sb = new StringBuilder(name.length() + 4); + // CheckStyle:MagicNumber ON + toString(sb); + return sb.toString(); + } + + + /** + * Appends the string representation of this instance to the given string builder. + * + * @param builder Builder to hold string representation of this instance. + */ + public void toString(final StringBuilder builder) + { + builder.append(name); + if (childIndex < 0) { + return; + } + builder.append('[').append(childIndex).append(']'); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/DERTag.java b/core/src/main/java/org/ldaptive/asn1/DERTag.java new file mode 100644 index 0000000..e0829c3 --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/DERTag.java
@@ -0,0 +1,46 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +/** + * Describes the tag of a DER-encoded type. + * + * @author Middleware Services + */ +public interface DERTag +{ + + /** Constructed tags should have the 6th bit set. */ + int ASN_CONSTRUCTED = 0x20; + + + /** + * Gets the decimal value of the tag. + * + * @return decimal tag number. + */ + int getTagNo(); + + + /** + * Gets the name of the tag. + * + * @return tag name. + */ + String name(); + + + /** + * Determines whether the tag is constructed or primitive. + * + * @return true if constructed, false if primitive. + */ + boolean isConstructed(); + + + /** + * Gets the value of this tag for encoding. + * + * @return byte value of this tag + */ + int getTagByte(); +}
diff --git a/core/src/main/java/org/ldaptive/asn1/DN.java b/core/src/main/java/org/ldaptive/asn1/DN.java new file mode 100644 index 0000000..a22319e --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/DN.java
@@ -0,0 +1,114 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import org.ldaptive.LdapUtils; + +/** + * A sequence of RDN values. + * + * @author Middleware Services + */ +public class DN implements DEREncoder +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 631; + + /** RDNs in this RDN sequence. */ + private final RDN[] rdns; + + + /** + * Creates a new DN. + * + * @param names RDNs in this sequence + */ + public DN(final Collection<RDN> names) + { + rdns = names.toArray(new RDN[names.size()]); + } + + + /** + * Creates a new DN. + * + * @param names RDNs in this sequence + */ + public DN(final RDN... names) + { + rdns = names; + } + + + /** + * Returns the RDNs in this DN. + * + * @return RDNs + */ + public RDN[] getRDNs() + { + return rdns; + } + + + @Override + public byte[] encode() + { + final List<DEREncoder> typeEncoders = new ArrayList<>(); + for (final RDN rdn : rdns) { + typeEncoders.add(rdn::encode); + } + + final ConstructedDEREncoder se = new ConstructedDEREncoder( + UniversalDERTag.SEQ, + typeEncoders.toArray(new DEREncoder[typeEncoders.size()])); + return se.encode(); + } + + + /** + * Converts bytes in the buffer to a DN by reading from the current position to the limit. + * + * @param encoded buffer containing DER-encoded data where the buffer is positioned at the tag of the DN and the + * limit is set beyond the last byte of DN data. + * + * @return decoded bytes as a DN + */ + public static DN decode(final ByteBuffer encoded) + { + return new DN(RDN.decode(encoded)); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof DN) { + final DN v = (DN) o; + return LdapUtils.areEqual(rdns, v.rdns); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, (Object) rdns); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::rdns=%s]", getClass().getName(), hashCode(), Arrays.toString(rdns)); + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/IntegerType.java b/core/src/main/java/org/ldaptive/asn1/IntegerType.java new file mode 100644 index 0000000..c839c51 --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/IntegerType.java
@@ -0,0 +1,127 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.math.BigInteger; +import java.nio.ByteBuffer; + +/** + * Converts arbitrary-precision integers to and from their DER encoded format. + * + * @author Middleware Services + */ +public class IntegerType extends AbstractDERType implements DEREncoder +{ + + /** Integer to encode. */ + private final byte[] derItem; + + + /** + * Creates a new integer type. + * + * @param item to DER encode + */ + public IntegerType(final BigInteger item) + { + super(UniversalDERTag.INT); + derItem = item.toByteArray(); + } + + + /** + * Creates a new integer type. + * + * @param item to DER encode + */ + public IntegerType(final int item) + { + super(UniversalDERTag.INT); + derItem = BigInteger.valueOf(item).toByteArray(); + } + + + /** + * Creates a new integer type. + * + * @param tag der tag associated with this type + * @param item to DER encode + * + * @throws IllegalArgumentException if the der tag is constructed + */ + public IntegerType(final DERTag tag, final BigInteger item) + { + super(tag); + if (tag.isConstructed()) { + throw new IllegalArgumentException("DER tag must not be constructed"); + } + derItem = item.toByteArray(); + } + + + /** + * Creates a new integer type. + * + * @param tag der tag associated with this type + * @param item to DER encode + * + * @throws IllegalArgumentException if the der tag is constructed + */ + public IntegerType(final DERTag tag, final int item) + { + super(tag); + if (tag.isConstructed()) { + throw new IllegalArgumentException("DER tag must not be constructed"); + } + derItem = BigInteger.valueOf(item).toByteArray(); + } + + + @Override + public byte[] encode() + { + return encode(derItem); + } + + + /** + * Converts bytes in the buffer to an integer by reading from the current position to the limit, which assumes the + * bytes of the integer are in big-endian order. + * + * @param encoded buffer containing DER-encoded data where the buffer is positioned at the start of integer bytes + * and the limit is set beyond the last byte of integer data. + * + * @return decoded bytes as an integer of arbitrary size. + */ + public static BigInteger decode(final ByteBuffer encoded) + { + return new BigInteger(readBuffer(encoded)); + } + + + /** + * Converts bytes in the buffer to an unsigned integer by reading from the current position to the limit, which + * assumes the bytes of the integer are in big-endian order. + * + * @param encoded buffer containing DER-encoded data where the buffer is positioned at the start of integer bytes + * and the limit is set beyond the last byte of integer data. + * + * @return decoded bytes as an unsigned integer of arbitrary size. + */ + public static BigInteger decodeUnsigned(final ByteBuffer encoded) + { + return new BigInteger(1, readBuffer(encoded)); + } + + + /** + * Converts the supplied big integer to a byte array. + * + * @param i to convert + * + * @return byte array + */ + public static byte[] toBytes(final BigInteger i) + { + return i.toByteArray(); + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/OctetStringType.java b/core/src/main/java/org/ldaptive/asn1/OctetStringType.java new file mode 100644 index 0000000..d207055 --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/OctetStringType.java
@@ -0,0 +1,107 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; + +/** + * Converts strings to and from their DER encoded format. + * + * @author Middleware Services + */ +public class OctetStringType extends AbstractDERType implements DEREncoder +{ + + /** String to encode. */ + private final byte[] derItem; + + + /** + * Creates a new octet string type. + * + * @param item to DER encode + */ + public OctetStringType(final String item) + { + this(item.getBytes(StandardCharsets.UTF_8)); + } + + + /** + * Creates a new octet string type. + * + * @param item to DER encode + */ + public OctetStringType(final byte[] item) + { + super(UniversalDERTag.OCTSTR); + derItem = item; + } + + + /** + * Creates a new octet string type. + * + * @param tag der tag associated with this type + * @param item to DER encode + * + * @throws IllegalArgumentException if the der tag is constructed + */ + public OctetStringType(final DERTag tag, final String item) + { + this(tag, item.getBytes(StandardCharsets.UTF_8)); + } + + + /** + * Creates a new octet string type. + * + * @param tag der tag associated with this type + * @param item to DER encode + * + * @throws IllegalArgumentException if the der tag is constructed + */ + public OctetStringType(final DERTag tag, final byte[] item) + { + super(tag); + if (tag.isConstructed()) { + throw new IllegalArgumentException("DER tag must not be constructed"); + } + derItem = item; + } + + + @Override + public byte[] encode() + { + return encode(derItem); + } + + + /** + * Converts bytes in the buffer to a string by reading from the current position to the limit, which assumes the bytes + * of the string are in big-endian order. + * + * @param encoded buffer containing DER-encoded data where the buffer is positioned at the start of string bytes and + * the limit is set beyond the last byte of string data. + * + * @return decoded bytes as an string + */ + public static String decode(final ByteBuffer encoded) + { + return new String(readBuffer(encoded), StandardCharsets.UTF_8); + } + + + /** + * Converts the supplied string to a byte array using the UTF-8 encoding. + * + * @param s to convert + * + * @return byte array + */ + public static byte[] toBytes(final String s) + { + return s.getBytes(StandardCharsets.UTF_8); + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/OidType.java b/core/src/main/java/org/ldaptive/asn1/OidType.java new file mode 100644 index 0000000..b27de9c --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/OidType.java
@@ -0,0 +1,278 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.StringTokenizer; + +/** + * Converts object identifiers to and from their DER encoded format. + * + * @author Middleware Services + */ +public class OidType extends AbstractDERType implements DEREncoder +{ + + /** Integer to encode. */ + private final byte[] derItem; + + + /** + * Creates a new oid type. + * + * @param item to DER encode + */ + public OidType(final String item) + { + super(UniversalDERTag.OID); + derItem = toBytes(parse(item)); + } + + + /** + * Creates a new oid type. + * + * @param item to DER encode + */ + public OidType(final int[] item) + { + super(UniversalDERTag.OID); + derItem = toBytes(item); + } + + + /** + * Creates a new oid type. + * + * @param tag der tag associated with this type + * @param item to DER encode + * + * @throws IllegalArgumentException if the der tag is constructed + */ + public OidType(final DERTag tag, final String item) + { + super(tag); + if (tag.isConstructed()) { + throw new IllegalArgumentException("DER tag must not be constructed"); + } + derItem = toBytes(parse(item)); + } + + + /** + * Creates a new oid type. + * + * @param tag der tag associated with this type + * @param item to DER encode + * + * @throws IllegalArgumentException if the der tag is constructed + */ + public OidType(final DERTag tag, final int[] item) + { + super(tag); + if (tag.isConstructed()) { + throw new IllegalArgumentException("DER tag must not be constructed"); + } + derItem = toBytes(item); + } + + + @Override + public byte[] encode() + { + return encode(derItem); + } + + + /** + * Converts bytes in the buffer to an OID by reading from the current position to the limit, which assumes the bytes + * of the integer are in big-endian order. + * + * @param encoded buffer containing DER-encoded data where the buffer is positioned at the start of OID bytes and + * the limit is set beyond the last byte of OID data. + * + * @return decoded bytes as an OID. + */ + public static String decode(final ByteBuffer encoded) + { + final ByteBuffer buffer = ByteBuffer.wrap(readBuffer(encoded)); + final StringBuilder sb = new StringBuilder(); + final int firstId = buffer.get(); + // CheckStyle:MagicNumber OFF + if (firstId < 40) { + sb.append("0").append(".").append(firstId).append("."); + } else if (firstId < 80) { + sb.append("1").append(".").append(firstId - 40).append("."); + } else { + sb.append("2").append(".").append(firstId - 80).append("."); + } + // CheckStyle:MagicNumber ON + while (buffer.hasRemaining()) { + sb.append(readInt(buffer)).append("."); + } + sb.setLength(sb.length() - 1); + return sb.toString(); + } + + + /** + * Converts the supplied list of oid components to a byte array. + * + * @param oid to convert + * + * @return byte array + * + * @throws IllegalArgumentException if the oid is not valid. See {@link #isValid(int[])} + */ + public static byte[] toBytes(final int[] oid) + { + isValid(oid); + + final ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + try { + try { + // CheckStyle:MagicNumber OFF + if (oid[0] < 2) { + // should always fit into one byte, since oid[1] must be <= 38 + bytes.write((oid[0] * 40) + oid[1]); + } else { + bytes.write(toBytes((oid[0] * 40) + oid[1])); + } + for (int i = 2; i < oid.length; i++) { + bytes.write(toBytes(oid[i])); + } + // CheckStyle:MagicNumber ON + } finally { + bytes.close(); + } + } catch (IOException e) { + throw new IllegalStateException("Byte conversion failed", e); + } + return bytes.toByteArray(); + } + + + /** + * Checks whether the supplied oid is valid. Oids must meet the following criteria: + * + * <ul> + * <li>must not be null and must have at least 2 elements</li> + * <li>components must not be negative</li> + * <li>first component must be 0, 1, or 2</li> + * <li>if first component 0 or 1, second component must be <= 38</li> + * </ul> + * + * @param oid to check + * + * @throws IllegalArgumentException if the oid is not valid. + */ + protected static void isValid(final int[] oid) + { + // CheckStyle:MagicNumber OFF + if (oid == null || oid.length < 2) { + throw new IllegalArgumentException("OIDs must have at least two components"); + } + if (oid[0] < 0 || oid[0] > 2) { + throw new IllegalArgumentException("The first OID must be 0, 1, or 2"); + } + if (oid[0] < 2 && oid[1] > 39) { + throw new IllegalArgumentException("The second OID must be less than or equal to 38"); + } + for (int i : oid) { + if (i < 0) { + throw new IllegalArgumentException("OIDs cannot be negative"); + } + } + // CheckStyle:MagicNumber ON + } + + + /** + * Converts the supplied oid component to a byte array. The length of the byte array is the minimal size needed to + * contain the oid component. + * + * @param component to convert to bytes + * + * @return oid bytes + */ + protected static byte[] toBytes(final int component) + { + // CheckStyle:MagicNumber OFF + final byte[] buffer = new byte[4]; + int size = 0; + int val = component; + while (val != 0) { + if (size > 0) { + buffer[size++] = (byte) ((val & 0x7F) | 0x80); + } else { + buffer[size++] = (byte) (val & 0x7F); + } + val >>>= 7; + } + + final byte[] bytes = new byte[size]; + for (int i = 0; i < bytes.length; i++) { + bytes[i] = buffer[--size]; + } + return bytes; + // CheckStyle:MagicNumber ON + } + + + /** + * Reads the necessary encoded bytes from the supplied buffer to create an integer. + * + * @param buffer to read + * + * @return OID component integer + */ + protected static int readInt(final ByteBuffer buffer) + { + // CheckStyle:MagicNumber OFF + int val = 0; + for (int i = 0; i < 4; i++) { + final byte b = buffer.get(); + if (i == 0 && b == 0x80) { + throw new IllegalArgumentException("Component starts with 0x80"); + } + val <<= 7; + val |= b & 0x7F; + if ((b & 0x80) == 0) { + return val; + } + } + // CheckStyle:MagicNumber ON + throw new IllegalArgumentException("Integer greater than 4 bytes in size"); + } + + + /** + * Converts the supplied oid into an array on integers. + * + * @param oid to parse + * + * @return array of oid components + * + * @throws IllegalArgumentException if the oid is not valid. See {@link #isValid(int[])} + */ + public static int[] parse(final String oid) + { + if (oid == null) { + throw new IllegalArgumentException("OID cannot be null"); + } + + final StringTokenizer st = new StringTokenizer(oid, "."); + final int[] oids = new int[st.countTokens()]; + int i = 0; + while (st.hasMoreTokens()) { + try { + oids[i++] = Integer.parseInt(st.nextToken()); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(e); + } + } + isValid(oids); + return oids; + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/ParseHandler.java b/core/src/main/java/org/ldaptive/asn1/ParseHandler.java new file mode 100644 index 0000000..29c1055 --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/ParseHandler.java
@@ -0,0 +1,22 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.nio.ByteBuffer; + +/** + * Provides a hook in the DER parser for handling specific paths as they are encountered. + * + * @author Middleware Services + */ +public interface ParseHandler +{ + + + /** + * Invoked when a DER path is encountered that belongs to this parse handler. + * + * @param parser that invoked this handler + * @param encoded to handle + */ + void handle(DERParser parser, ByteBuffer encoded); +}
diff --git a/core/src/main/java/org/ldaptive/asn1/RDN.java b/core/src/main/java/org/ldaptive/asn1/RDN.java new file mode 100644 index 0000000..aab9b89 --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/RDN.java
@@ -0,0 +1,206 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import org.ldaptive.LdapUtils; +import org.ldaptive.io.ValueTranscoder; + +/** + * A set of attribute value assertions. + * + * @author Middleware Services + */ +public class RDN implements DEREncoder +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 619; + + /** Attribute value assertions in this RDN. */ + private final AttributeValueAssertion[] attributeValueAssertions; + + + /** + * Creates a new RDN. + * + * @param assertions in this RDN + */ + public RDN(final Collection<AttributeValueAssertion> assertions) + { + attributeValueAssertions = assertions.toArray(new AttributeValueAssertion[assertions.size()]); + } + + + /** + * Creates a new RDN. + * + * @param assertions in this RDN + */ + public RDN(final AttributeValueAssertion... assertions) + { + attributeValueAssertions = assertions; + } + + + /** + * Returns the attribute value assertions in this RDN. + * + * @return attribute value assertions + */ + public AttributeValueAssertion[] getAttributeValueAssertions() + { + return attributeValueAssertions; + } + + + /** + * Returns the attribute values for the supplied oid. + * + * @param oid to match + * + * @return attribute values + */ + public AttributeValueAssertion.Value[] getAttributeValues(final String oid) + { + final List<AttributeValueAssertion.Value> values = new ArrayList<>(); + for (AttributeValueAssertion type : attributeValueAssertions) { + if (type.getOid().equals(oid)) { + values.add(type.getValue()); + } + } + return values.toArray(new AttributeValueAssertion.Value[values.size()]); + } + + + /** + * Returns a single attribute value for the supplied oid. See {@link #getAttributeValues(String)}. + * + * @param oid to match + * + * @return attribute value + */ + public AttributeValueAssertion.Value getAttributeValue(final String oid) + { + final AttributeValueAssertion.Value[] values = getAttributeValues(oid); + if (values == null || values.length == 0) { + return null; + } + return values[0]; + } + + + /** + * Returns the attribute values decoded by the supplied transcoder. + * + * @param <T> type of value + * @param oid to match + * @param transcoder to decode the binary value + * + * @return decoded attribute values + */ + @SuppressWarnings("unchecked") + public <T> T[] getAttributeValues(final String oid, final ValueTranscoder<T> transcoder) + { + final List<T> values = new ArrayList<>(); + for (AttributeValueAssertion type : attributeValueAssertions) { + if (type.getOid().equals(oid)) { + values.add(transcoder.decodeBinaryValue(type.getValue().getBytes())); + } + } + return (T[]) values.toArray(); + } + + + /** + * Returns a single attribute value for the supplied oid. See {@link #getAttributeValues(String, ValueTranscoder)}. + * + * @param <T> type of value + * @param oid to match + * @param transcoder to decode the binary value + * + * @return decoded attribute value + */ + public <T> T getAttributeValue(final String oid, final ValueTranscoder<T> transcoder) + { + final T[] values = getAttributeValues(oid, transcoder); + if (values == null || values.length == 0) { + return null; + } + return values[0]; + } + + + @Override + public byte[] encode() + { + final List<DEREncoder> typeEncoders = new ArrayList<>(); + for (final AttributeValueAssertion types : attributeValueAssertions) { + typeEncoders.add(types::encode); + } + + final ConstructedDEREncoder se = new ConstructedDEREncoder( + UniversalDERTag.SET, + typeEncoders.toArray(new DEREncoder[typeEncoders.size()])); + return se.encode(); + } + + + /** + * Converts bytes in the buffer to RDNs by reading from the current position to the limit. + * + * @param encoded buffer containing DER-encoded data where the buffer is positioned at the tag of the RDN and the + * limit is set beyond the last byte of the RDN. + * + * @return decoded bytes as RDNs + */ + public static RDN[] decode(final ByteBuffer encoded) + { + final List<RDN> rdns = new ArrayList<>(); + final DERParser parser = new DERParser(); + parser.registerHandler( + "/SEQ/SET", + (parser1, encoded1) -> { + rdns.add(new RDN(AttributeValueAssertion.decode(encoded1.slice()))); + encoded1.position(encoded1.limit()); + }); + parser.parse(encoded); + return rdns.toArray(new RDN[rdns.size()]); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof RDN) { + final RDN v = (RDN) o; + return LdapUtils.areEqual(attributeValueAssertions, v.attributeValueAssertions); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, (Object) attributeValueAssertions); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::attributeValueAssertions=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(attributeValueAssertions)); + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/UniversalDERTag.java b/core/src/main/java/org/ldaptive/asn1/UniversalDERTag.java new file mode 100644 index 0000000..482e728 --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/UniversalDERTag.java
@@ -0,0 +1,200 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.util.HashMap; +import java.util.Map; + +/** + * Enumeration with common BER/DER universal tag types. + * + * @author Middleware Services + */ +public enum UniversalDERTag implements DERTag { + + /** BOOLEAN type. */ + BOOL(1, false), + + /** INTEGER type. */ + INT(2, false), + + /** BITSTRING type. */ + BITSTR(3, false), + + /** OCTETSTRING type. */ + OCTSTR(4, false), + + /** NULL type. */ + NULL(5, false), + + /** OBJECT IDENTIFIER type. */ + OID(6, false), + + /** ObjectDescriptor type. */ + ODESC(7, false), + + /** EXTERNAL type. */ + EXT(8, false), + + /** REAL type. */ + REAL(9, false), + + /** ENUMERATED type. */ + ENUM(10, false), + + /** EMBEDDED PDV type. */ + EMBPDV(11, false), + + /** UTF8String type. */ + UTF8STR(12, false), + + /** RELATIVE-OID type. */ + ROID(13, false), + + /** SEQUENCE type. */ + SEQ(16, true), + + /** SET type. */ + SET(17, true), + + /** NumericString type. */ + NUMSTR(18, false), + + /** PrintableString type. */ + PRINTSTR(19, false), + + /** T61String type. */ + T61STR(20, false), + + /** VideotexString type. */ + VTEXSTR(21, false), + + /** IA5String type. */ + IA5STR(22, false), + + /** UTCTime type. */ + UTCTIME(23, false), + + /** GeneralizedTime type. */ + GENTIME(24, false), + + /** GraphicString type. */ + GRAPHICSTR(25, false), + + /** ISO646String type. */ + ISO646STR(26, false), + + /** GeneralString type. */ + GENSTR(27, false), + + /** UniversalString type. */ + UNISTR(28, false), + + /** CharacterString type. */ + CHARSTR(29, false), + + /** BMPString type. */ + BMPSTR(30, false); + + /** Universal tag class is 00b in first two high-order bytes. */ + public static final int TAG_CLASS = 0; + + /** Maps tag numbers to tags. */ + private static final Map<Integer, UniversalDERTag> TAGNO_MAP = new HashMap<>(); + + /** Maps tag names to tags. */ + private static final Map<String, UniversalDERTag> TAGNAME_MAP = new HashMap<>(); + + + /** + * Initializes tag mapping. + */ + static { + for (UniversalDERTag tag : UniversalDERTag.values()) { + TAGNO_MAP.put(tag.getTagNo(), tag); + TAGNAME_MAP.put(tag.name(), tag); + } + } + + /** Tag number. */ + private final int tagNo; + + /** Flag indicating whether value is primitive or constructed. */ + private final boolean constructed; + + + /** + * Creates a new universal DER tag. + * + * @param number of the tag + * @param isConstructed whether this tag is primitive or constructed + */ + UniversalDERTag(final int number, final boolean isConstructed) + { + tagNo = number; + constructed = isConstructed; + } + + + /** + * Gets the decimal value of the tag. + * + * @return decimal tag number. + */ + @Override + public int getTagNo() + { + return tagNo; + } + + + /** + * Determines whether the tag is constructed or primitive. + * + * @return true if constructed, false if primitive. + */ + @Override + public boolean isConstructed() + { + return constructed; + } + + + @Override + public int getTagByte() + { + return constructed ? tagNo | ASN_CONSTRUCTED : tagNo; + } + + + /** + * Looks up a universal tag from a tag number. + * + * @param number tag number. + * + * @return tag object corresponding to given number. + * + * @throws IllegalArgumentException if tag is unknown + */ + public static UniversalDERTag fromTagNo(final int number) + { + final UniversalDERTag derTag = TAGNO_MAP.get(number); + if (derTag == null) { + throw new IllegalArgumentException("Unknown tag number: " + number); + } + return derTag; + } + + + /** + * Looks up a universal tag from a tag name. This method differs from {@link #valueOf(String)} in that it does not + * throw for unknown names. + * + * @param name tag name. + * + * @return tag object corresponding to given name or null if no tag of the given name is found. + */ + public static UniversalDERTag fromTagName(final String name) + { + return TAGNAME_MAP.get(name); + } +}
diff --git a/core/src/main/java/org/ldaptive/asn1/UuidType.java b/core/src/main/java/org/ldaptive/asn1/UuidType.java new file mode 100644 index 0000000..11b0ddb --- /dev/null +++ b/core/src/main/java/org/ldaptive/asn1/UuidType.java
@@ -0,0 +1,90 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.nio.ByteBuffer; +import java.util.UUID; + +/** + * Converts UUIDs to and from their DER encoded format. See RFC 4122. + * + * @author Middleware Services + */ +public class UuidType extends AbstractDERType implements DEREncoder +{ + + /** Number of bytes in a uuid. */ + private static final int UUID_LENGTH = 16; + + /** UUID to encode. */ + private final byte[] derItem; + + + /** + * Creates a new uuid type. + * + * @param item to DER encode + */ + public UuidType(final UUID item) + { + super(UniversalDERTag.OCTSTR); + derItem = toBytes(item); + } + + + /** + * Creates a new uuid type. + * + * @param tag der tag associated with this type + * @param item to DER encode + * + * @throws IllegalArgumentException if the der tag is constructed + */ + public UuidType(final DERTag tag, final UUID item) + { + super(tag); + if (tag.isConstructed()) { + throw new IllegalArgumentException("DER tag must not be constructed"); + } + derItem = toBytes(item); + } + + + @Override + public byte[] encode() + { + return encode(derItem); + } + + + /** + * Converts bytes in the buffer to a uuid by reading from the current position to the limit. + * + * @param encoded buffer containing DER-encoded data where the buffer is positioned at the start of uuid bytes and + * the limit is set beyond the last byte of uuid data. + * + * @return decoded bytes as a uuid. + */ + public static UUID decode(final ByteBuffer encoded) + { + final ByteBuffer buffer = ByteBuffer.wrap(readBuffer(encoded)); + final long mostSig = buffer.getLong(); + final long leastSig = buffer.getLong(); + return new UUID(mostSig, leastSig); + } + + + /** + * Converts the supplied uuid to a byte array. + * + * @param uuid to convert + * + * @return byte array + */ + public static byte[] toBytes(final UUID uuid) + { + final ByteBuffer buffer = ByteBuffer.wrap(new byte[UUID_LENGTH]); + buffer.putLong(uuid.getMostSignificantBits()); + buffer.putLong(uuid.getLeastSignificantBits()); + return buffer.array(); + } +}
diff --git a/core/src/main/java/org/ldaptive/async/AbandonOperation.java b/core/src/main/java/org/ldaptive/async/AbandonOperation.java new file mode 100644 index 0000000..c6ec522 --- /dev/null +++ b/core/src/main/java/org/ldaptive/async/AbandonOperation.java
@@ -0,0 +1,69 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.async; + +import java.util.Arrays; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.control.RequestControl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Executes an ldap abandon operation. + * + * @author Middleware Services + */ +public class AbandonOperation +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Connection to perform operation. */ + private final Connection connection; + + + /** + * Creates a new abandon operation. + * + * @param conn connection + */ + public AbandonOperation(final Connection conn) + { + connection = conn; + } + + + /** + * Execute this ldap operation. + * + * @param messageId of the operation to abandon + * + * @throws LdapException if the operation fails + */ + public void execute(final int messageId) + throws LdapException + { + execute(messageId, null); + } + + + /** + * Execute this ldap operation. + * + * @param messageId of the operation to abandon + * @param controls request controls + * + * @throws LdapException if the operation fails + */ + public void execute(final int messageId, final RequestControl[] controls) + throws LdapException + { + logger.debug( + "execute abandon for messageId={}, controls={} with connection={}", + messageId, + Arrays.toString(controls), + connection); + connection.getProviderConnection().abandon(messageId, controls); + } +}
diff --git a/core/src/main/java/org/ldaptive/async/AbstractAsyncOperation.java b/core/src/main/java/org/ldaptive/async/AbstractAsyncOperation.java new file mode 100644 index 0000000..88f3e53 --- /dev/null +++ b/core/src/main/java/org/ldaptive/async/AbstractAsyncOperation.java
@@ -0,0 +1,81 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.async; + +import org.ldaptive.AbstractOperation; +import org.ldaptive.Connection; +import org.ldaptive.Request; +import org.ldaptive.async.handler.AsyncRequestHandler; +import org.ldaptive.async.handler.ExceptionHandler; + +/** + * Base class for asynchronous ldap operations. + * + * @param <Q> type of ldap request + * @param <S> type of ldap response + * + * @author Middleware Services + */ +public abstract class AbstractAsyncOperation<Q extends Request, S> extends AbstractOperation<Q, S> +{ + + /** Handlers to handle async requests. */ + private AsyncRequestHandler[] asyncRequestHandlers; + + /** Handler to handle exceptions. */ + private ExceptionHandler exceptionHandler; + + + /** + * Creates a new abstract async operation. + * + * @param conn to use for this operation + */ + public AbstractAsyncOperation(final Connection conn) + { + super(conn); + } + + + /** + * Returns the async request handlers. + * + * @return async request handlers + */ + public AsyncRequestHandler[] getAsyncRequestHandlers() + { + return asyncRequestHandlers; + } + + + /** + * Sets the async request handlers. + * + * @param handlers async request handlers + */ + public void setAsyncRequestHandlers(final AsyncRequestHandler... handlers) + { + asyncRequestHandlers = handlers; + } + + + /** + * Returns the exception handler. + * + * @return exception handler + */ + public ExceptionHandler getExceptionHandler() + { + return exceptionHandler; + } + + + /** + * Sets the exception handler. + * + * @param handler exception handler + */ + public void setExceptionHandler(final ExceptionHandler handler) + { + exceptionHandler = handler; + } +}
diff --git a/core/src/main/java/org/ldaptive/async/AsyncRequest.java b/core/src/main/java/org/ldaptive/async/AsyncRequest.java new file mode 100644 index 0000000..2a11180 --- /dev/null +++ b/core/src/main/java/org/ldaptive/async/AsyncRequest.java
@@ -0,0 +1,42 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.async; + +import org.ldaptive.LdapException; +import org.ldaptive.control.RequestControl; + +/** + * Interface for asynchronous operation requests. + * + * @author Middleware Services + */ +public interface AsyncRequest +{ + + + /** + * Message ID associated with the operation. + * + * @return message id + */ + int getMessageId(); + + + /** + * Abandon the operation. + * + * @throws LdapException if the operation fails + */ + void abandon() + throws LdapException; + + + /** + * Abandon the operation. + * + * @param controls request controls + * + * @throws LdapException if the operation fails + */ + void abandon(RequestControl[] controls) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/async/AsyncSearchOperation.java b/core/src/main/java/org/ldaptive/async/AsyncSearchOperation.java new file mode 100644 index 0000000..3ae1cc4 --- /dev/null +++ b/core/src/main/java/org/ldaptive/async/AsyncSearchOperation.java
@@ -0,0 +1,327 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.async; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.Semaphore; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Response; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchReference; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.async.handler.ExceptionHandler; +import org.ldaptive.handler.HandlerResult; +import org.ldaptive.intermediate.IntermediateResponse; +import org.ldaptive.provider.SearchItem; +import org.ldaptive.provider.SearchListener; + +/** + * Executes an asynchronous ldap search operation. + * + * @author Middleware Services + */ +public class AsyncSearchOperation extends AbstractAsyncOperation<SearchRequest, SearchResult> +{ + + /** Cached thread executor to submit async operations to. */ + private final ExecutorService executorService = Executors.newCachedThreadPool(); + + /** Whether the listener should spawn a new thread to process each result. */ + private boolean useMultiThreadedListener; + + + /** + * Creates a new async search operation. + * + * @param conn connection + */ + public AsyncSearchOperation(final Connection conn) + { + super(conn); + } + + + /** + * Returns whether the listener should spawn a new thread to process each result. + * + * @return whether the listener is multi-threaded + */ + public boolean getUseMultiThreadedListener() + { + return useMultiThreadedListener; + } + + + /** + * Sets whether the listener should spawn a new thread to process each result. + * + * @param b make the listener multi-threaded + */ + public void setUseMultiThreadedListener(final boolean b) + { + useMultiThreadedListener = b; + } + + + @Override + public FutureResponse<SearchResult> execute(final SearchRequest request) + throws LdapException + { + final Future<Response<SearchResult>> future = executorService.submit( + () -> { + final ExceptionHandler handler = getExceptionHandler(); + try { + return AsyncSearchOperation.super.execute(request); + } catch (LdapException | RuntimeException e) { + if (handler != null) { + handler.handle(getConnection(), request, e); + } + throw e; + } + }); + return new FutureResponse<>(future); + } + + + @Override + protected Response<SearchResult> invoke(final SearchRequest request) + throws LdapException + { + final AsyncSearchListener listener = new AsyncSearchListener(request); + getConnection().getProviderConnection().searchAsync(request, listener); + try { + return listener.getResponse(); + } catch (InterruptedException e) { + throw new LdapException("Asynchronous search interrupted", e); + } + } + + + /** Invokes {@link ExecutorService#shutdown()} on the underlying executor service. */ + public void shutdown() + { + executorService.shutdown(); + } + + + @Override + protected void finalize() + throws Throwable + { + try { + shutdown(); + } finally { + super.finalize(); + } + } + + + /** Async search listener used to build a search result and invoke search request handlers. */ + protected class AsyncSearchListener implements SearchListener + { + + /** Containing request handlers. */ + private final SearchRequest searchRequest; + + /** To build as results arrive. */ + private final SearchResult searchResult; + + /** Wait for the response to arrive. */ + private final Semaphore responseLock = new Semaphore(0); + + /** To return when a response is received or the operation is aborted. */ + private Response<SearchResult> searchResponse; + + /** Thrown by the async search operation. */ + private LdapException searchException; + + + /** + * Creates a new async search listener. + * + * @param request ldap search request + */ + public AsyncSearchListener(final SearchRequest request) + { + searchRequest = request; + searchResult = new SearchResult(searchRequest.getSortBehavior()); + } + + + @Override + public void asyncRequestReceived(final AsyncRequest request) + { + logger.trace("received async request={}", request); + if (useMultiThreadedListener) { + executorService.submit( + () -> { + try { + processAsyncRequest(request); + } catch (LdapException e) { + logger.warn("Handler exception ignored", e); + } + return null; + }); + } else { + try { + processAsyncRequest(request); + } catch (LdapException e) { + logger.warn("Handler exception ignored", e); + } + } + } + + + @Override + public void searchItemReceived(final SearchItem item) + { + logger.trace("received search item={}", item); + if (useMultiThreadedListener) { + executorService.submit( + () -> { + try { + processSearchItem(item); + } catch (LdapException e) { + logger.warn("Handler exception ignored", e); + } + return null; + }); + } else { + try { + processSearchItem(item); + } catch (LdapException e) { + logger.warn("Handler exception ignored", e); + } + } + } + + + @Override + public void responseReceived(final Response<Void> response) + { + searchResponse = new Response<>( + searchResult, + response.getResultCode(), + response.getMessage(), + response.getMatchedDn(), + response.getControls(), + response.getReferralURLs(), + response.getMessageId()); + responseLock.release(); + } + + + /** + * Returns the response data associated with this search, blocking until a response is available. + * + * @return response data + * + * @throws InterruptedException if this thread is interrupted before a response is received + * @throws LdapException if the async search encountered an error + */ + public Response<SearchResult> getResponse() + throws InterruptedException, LdapException + { + responseLock.acquire(); + if (searchException != null) { + throw searchException; + } + return searchResponse; + } + + + @Override + public void exceptionReceived(final Exception exception) + { + logger.trace("received exception={}", exception); + if (exception instanceof LdapException) { + searchException = (LdapException) exception; + } else { + searchException = new LdapException(exception); + } + responseLock.release(); + } + + + /** + * Invokes the handlers for the supplied async request. Calls {@link #responseReceived(Response)} if a handler + * aborts the operation. + * + * @param request to handle + * + * @throws LdapException if a handler throws + */ + protected void processAsyncRequest(final AsyncRequest request) + throws LdapException + { + logger.trace("processing async request={}", request); + + final HandlerResult<AsyncRequest> hr = executeHandlers(getAsyncRequestHandlers(), searchRequest, request); + if (hr.getAbort()) { + logger.debug("Aborting search on async request=%s", request); + responseReceived(new Response<>(null, null)); + } + } + + + /** + * Invokes the handlers for the supplied search item. Calls {@link #responseReceived(Response)} if a handler aborts + * the operation. + * + * @param item to handle + * + * @throws LdapException if a handler throws + */ + protected void processSearchItem(final SearchItem item) + throws LdapException + { + logger.trace("processing search item={}", item); + if (item.isSearchEntry()) { + final SearchEntry se = item.getSearchEntry(); + if (se != null) { + final HandlerResult<SearchEntry> hr = executeHandlers( + searchRequest.getSearchEntryHandlers(), + searchRequest, + se); + if (hr.getResult() != null) { + searchResult.addEntry(hr.getResult()); + } + if (hr.getAbort()) { + logger.debug("Aborting search on entry=%s", se); + responseReceived(new Response<>(null, null)); + } + } + } else if (item.isSearchReference()) { + final SearchReference sr = item.getSearchReference(); + if (sr != null) { + final HandlerResult<SearchReference> hr = executeHandlers( + searchRequest.getSearchReferenceHandlers(), + searchRequest, + sr); + if (hr.getResult() != null) { + searchResult.addReference(hr.getResult()); + } + if (hr.getAbort()) { + logger.debug("Aborting search on reference=%s", sr); + responseReceived(new Response<>(null, null)); + } + } + } else if (item.isIntermediateResponse()) { + final IntermediateResponse ir = item.getIntermediateResponse(); + if (ir != null) { + final HandlerResult<IntermediateResponse> hr = executeHandlers( + searchRequest.getIntermediateResponseHandlers(), + searchRequest, + ir); + if (hr.getAbort()) { + logger.debug("Aborting search on intermediate response=%s", ir); + responseReceived(new Response<>(null, null)); + } + } + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/async/FutureResponse.java b/core/src/main/java/org/ldaptive/async/FutureResponse.java new file mode 100644 index 0000000..dc33c85 --- /dev/null +++ b/core/src/main/java/org/ldaptive/async/FutureResponse.java
@@ -0,0 +1,109 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.async; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.control.ResponseControl; + +/** + * Response that blocks on each property until it is available. + * + * @param <T> type of ldap result contained in this response + * + * @author Middleware Services + */ +public class FutureResponse<T> extends Response<T> +{ + + /** Future that will contain the response. */ + private final Future<Response<T>> future; + + + /** + * Creates a new future ldap response. + * + * @param f future response + */ + public FutureResponse(final Future<Response<T>> f) + { + super(null, null); + future = f; + } + + + /** + * Invokes {@link Future#get()}, waiting until the response is returned. + * + * @return response from the future + * + * @throws IllegalStateException if the future is interrupted or throws an execution exception + */ + protected Response<T> getResponse() + { + try { + return future.get(); + } catch (InterruptedException e) { + throw new IllegalStateException("Future interrupted", e); + } catch (ExecutionException e) { + throw new IllegalStateException("Future execution error", e); + } + } + + + @Override + public T getResult() + { + return getResponse().getResult(); + } + + + @Override + public ResultCode getResultCode() + { + return getResponse().getResultCode(); + } + + + @Override + public String getMessage() + { + return getResponse().getMessage(); + } + + + @Override + public String getMatchedDn() + { + return getResponse().getMatchedDn(); + } + + + @Override + public ResponseControl[] getControls() + { + return getResponse().getControls(); + } + + + @Override + public String[] getReferralURLs() + { + return getResponse().getReferralURLs(); + } + + + @Override + public int getMessageId() + { + return getResponse().getMessageId(); + } + + + @Override + public String toString() + { + return getResponse().toString(); + } +}
diff --git a/core/src/main/java/org/ldaptive/async/handler/AsyncRequestHandler.java b/core/src/main/java/org/ldaptive/async/handler/AsyncRequestHandler.java new file mode 100644 index 0000000..271c7e8 --- /dev/null +++ b/core/src/main/java/org/ldaptive/async/handler/AsyncRequestHandler.java
@@ -0,0 +1,23 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.async.handler; + +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Request; +import org.ldaptive.async.AsyncRequest; +import org.ldaptive.handler.Handler; +import org.ldaptive.handler.HandlerResult; + +/** + * Provides post search handling of an ldap async request. + * + * @author Middleware Services + */ +public interface AsyncRequestHandler extends Handler<Request, AsyncRequest> +{ + + + @Override + HandlerResult<AsyncRequest> handle(Connection conn, Request request, AsyncRequest asyncRequest) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/async/handler/ExceptionHandler.java b/core/src/main/java/org/ldaptive/async/handler/ExceptionHandler.java new file mode 100644 index 0000000..1f025c6 --- /dev/null +++ b/core/src/main/java/org/ldaptive/async/handler/ExceptionHandler.java
@@ -0,0 +1,20 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.async.handler; + +import org.ldaptive.Connection; +import org.ldaptive.Request; +import org.ldaptive.handler.Handler; +import org.ldaptive.handler.HandlerResult; + +/** + * Provides post search handling of an exception thrown by an async operation. + * + * @author Middleware Services + */ +public interface ExceptionHandler extends Handler<Request, Exception> +{ + + + @Override + HandlerResult<Exception> handle(Connection conn, Request request, Exception exception); +}
diff --git a/core/src/main/java/org/ldaptive/auth/AbstractAuthenticationHandler.java b/core/src/main/java/org/ldaptive/auth/AbstractAuthenticationHandler.java new file mode 100644 index 0000000..915435a --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AbstractAuthenticationHandler.java
@@ -0,0 +1,120 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.LdapUtils; +import org.ldaptive.control.RequestControl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base class for an LDAP authentication implementations. + * + * @author Middleware Services + */ +public abstract class AbstractAuthenticationHandler implements AuthenticationHandler +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** controls used by this handler. */ + private RequestControl[] authenticationControls; + + + /** + * Returns the controls for this authentication handler. + * + * @return controls + */ + public RequestControl[] getAuthenticationControls() + { + return authenticationControls; + } + + + /** + * Sets the controls for this authentication handler. + * + * @param c controls to set + */ + public void setAuthenticationControls(final RequestControl... c) + { + authenticationControls = c; + } + + + @Override + public AuthenticationHandlerResponse authenticate(final AuthenticationCriteria ac) + throws LdapException + { + logger.debug("authenticate criteria={}", ac); + + AuthenticationHandlerResponse response = null; + final Connection conn = getConnection(); + boolean closeConn = false; + try { + response = authenticateInternal(conn, ac); + } catch (LdapException | RuntimeException e) { + closeConn = true; + throw e; + } finally { + if (closeConn) { + conn.close(); + } + } + logger.debug("authenticate response={} for criteria={}", response, ac); + return response; + } + + + /** + * Returns a connection that the authentication operation should be performed on. + * + * @return connection + * + * @throws LdapException if an error occurs provisioning the connection + */ + protected abstract Connection getConnection() + throws LdapException; + + + /** + * Authenticate on the supplied connection using the supplied criteria. + * + * @param c to authenticate on + * @param criteria criteria to authenticate with + * + * @return authentication handler response + * + * @throws LdapException if the authentication fails + */ + protected abstract AuthenticationHandlerResponse authenticateInternal( + final Connection c, + final AuthenticationCriteria criteria) + throws LdapException; + + + /** + * Combines request controls in the {@link AuthenticationRequest} with {@link #authenticationControls}. + * + * @param criteria containing request controls + * + * @return combined request controls or null + */ + protected RequestControl[] processRequestControls(final AuthenticationCriteria criteria) + { + RequestControl[] ctls; + if (criteria.getAuthenticationRequest().getControls() != null) { + if (getAuthenticationControls() != null) { + ctls = LdapUtils.concatArrays(criteria.getAuthenticationRequest().getControls(), getAuthenticationControls()); + } else { + ctls = criteria.getAuthenticationRequest().getControls(); + } + } else { + ctls = getAuthenticationControls(); + } + return ctls; + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/AbstractBindAuthenticationHandler.java b/core/src/main/java/org/ldaptive/auth/AbstractBindAuthenticationHandler.java new file mode 100644 index 0000000..11fb2d7 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AbstractBindAuthenticationHandler.java
@@ -0,0 +1,38 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import org.ldaptive.sasl.SaslConfig; + +/** + * Provides implementation common to bind authentication handlers. + * + * @author Middleware Services + */ +public abstract class AbstractBindAuthenticationHandler extends AbstractAuthenticationHandler +{ + + /** sasl configuration used by this handler. */ + private SaslConfig authenticationSaslConfig; + + + /** + * Returns the sasl config for this authentication handler. + * + * @return sasl config + */ + public SaslConfig getAuthenticationSaslConfig() + { + return authenticationSaslConfig; + } + + + /** + * Sets the sasl config for this authentication handler. + * + * @param config sasl config + */ + public void setAuthenticationSaslConfig(final SaslConfig config) + { + authenticationSaslConfig = config; + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/AbstractCompareAuthenticationHandler.java b/core/src/main/java/org/ldaptive/auth/AbstractCompareAuthenticationHandler.java new file mode 100644 index 0000000..f4699f0 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AbstractCompareAuthenticationHandler.java
@@ -0,0 +1,208 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import org.ldaptive.CompareOperation; +import org.ldaptive.CompareRequest; +import org.ldaptive.Connection; +import org.ldaptive.Credential; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapException; +import org.ldaptive.LdapUtils; +import org.ldaptive.Response; + +/** + * Provides implementation common to compare authentication handlers. + * + * @author Middleware Services + */ +public abstract class AbstractCompareAuthenticationHandler extends AbstractAuthenticationHandler +{ + + /** Default password scheme. Value is {@value}. */ + protected static final String DEFAULT_SCHEME = "SHA:SHA"; + + /** Default password attribute. Value is {@value}. */ + protected static final String DEFAULT_ATTRIBUTE = "userPassword"; + + /** Password scheme. */ + private Scheme passwordScheme = new Scheme(DEFAULT_SCHEME); + + /** Password attribute. */ + private String passwordAttribute = DEFAULT_ATTRIBUTE; + + + /** + * Returns the password scheme. + * + * @return password scheme + */ + public String getPasswordScheme() + { + return passwordScheme.toString(); + } + + + /** + * Sets the password scheme. + * + * @param s password scheme + */ + public void setPasswordScheme(final String s) + { + passwordScheme = new Scheme(s); + } + + + /** + * Returns the password attribute. + * + * @return password attribute + */ + public String getPasswordAttribute() + { + return passwordAttribute; + } + + + /** + * Sets the password attribute. Must equal a readable attribute in LDAP scheme. + * + * @param s password attribute + */ + public void setPasswordAttribute(final String s) + { + passwordAttribute = s; + } + + + @Override + protected AuthenticationHandlerResponse authenticateInternal( + final Connection c, + final AuthenticationCriteria criteria) + throws LdapException + { + final byte[] hash = digestCredential(criteria.getCredential(), passwordScheme.getAlgorithm()); + final LdapAttribute la = new LdapAttribute( + passwordAttribute, + String.format("{%s}%s", passwordScheme.getLabel(), LdapUtils.base64Encode(hash)).getBytes()); + final CompareOperation compare = new CompareOperation(c); + final CompareRequest request = new CompareRequest(criteria.getDn(), la); + request.setControls(processRequestControls(criteria)); + + final Response<Boolean> compareResponse = compare.execute(request); + return + new AuthenticationHandlerResponse( + compareResponse.getResult(), + compareResponse.getResultCode(), + c, + compareResponse.getMessage(), + compareResponse.getControls(), + compareResponse.getMessageId()); + } + + + /** + * Digests the supplied credential using the supplied algorithm. + * + * @param credential to digest + * @param algorithm type of digest to use + * + * @return digested credential + * + * @throws LdapException if the supplied algorithm cannot be found + */ + protected byte[] digestCredential(final Credential credential, final String algorithm) + throws LdapException + { + try { + final MessageDigest md = MessageDigest.getInstance(algorithm); + md.update(credential.getBytes()); + return md.digest(); + } catch (NoSuchAlgorithmException e) { + throw new LdapException(e); + } + } + + + /** + * Returns a connection that the compare operation should be performed on. + * + * @return connection + * + * @throws LdapException if an error occurs provisioning the connection + */ + @Override + protected abstract Connection getConnection() + throws LdapException; + + + /** + * Represents a password scheme used for attribute comparison. + */ + public static class Scheme + { + + /** Label of the scheme. */ + private final String label; + + /** Algorithm used by this scheme. */ + private final String algorithm; + + + /** + * Creates a new scheme. + * + * @param labelAndAlgorithm colon delimited label:algorithm + */ + public Scheme(final String labelAndAlgorithm) + { + final String[] s = labelAndAlgorithm.split(":", 2); + label = s[0]; + algorithm = s.length == 2 ? s[1] : s[0]; + } + + + /** + * Creates a new scheme. + * + * @param l label + * @param a algorithm + */ + public Scheme(final String l, final String a) + { + label = l; + algorithm = a; + } + + + /** + * Returns the scheme label. + * + * @return label + */ + public String getLabel() + { + return label; + } + + + /** + * Returns the scheme algorithm. + * + * @return algorithm + */ + public String getAlgorithm() + { + return algorithm; + } + + + @Override + public String toString() + { + return String.format("%s:%s", label, algorithm); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/AbstractSearchDnResolver.java b/core/src/main/java/org/ldaptive/auth/AbstractSearchDnResolver.java new file mode 100644 index 0000000..6d3c04c --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AbstractSearchDnResolver.java
@@ -0,0 +1,358 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import java.util.Iterator; +import org.ldaptive.Connection; +import org.ldaptive.DerefAliases; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.ReturnAttributes; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.SearchScope; +import org.ldaptive.referral.ReferralHandler; + +/** + * Base implementation for search dn resolvers. + * + * @author Middleware Services + */ +public abstract class AbstractSearchDnResolver extends AbstractSearchOperationFactory implements DnResolver +{ + + /** DN to search. */ + private String baseDn = ""; + + /** Filter for searching for the user. */ + private String userFilter; + + /** Filter parameters for searching for the user. */ + private Object[] userFilterParameters; + + /** Whether to throw an exception if multiple DNs are found. */ + private boolean allowMultipleDns; + + /** Whether to use a subtree search when resolving DNs. */ + private boolean subtreeSearch; + + /** How to handle aliases. */ + private DerefAliases derefAliases; + + /** Referral handler. */ + private ReferralHandler referralHandler; + + + /** + * Returns the base DN. + * + * @return base DN + */ + public String getBaseDn() + { + return baseDn; + } + + + /** + * Sets the base DN. + * + * @param dn base DN + */ + public void setBaseDn(final String dn) + { + logger.trace("setting baseDn: {}", dn); + baseDn = dn; + } + + + /** + * Returns the filter used to search for the user. + * + * @return filter for searching + */ + public String getUserFilter() + { + return userFilter; + } + + + /** + * Sets the filter used to search for the user. + * + * @param filter for searching + */ + public void setUserFilter(final String filter) + { + logger.trace("setting userFilter: {}", filter); + userFilter = filter; + } + + + /** + * Returns the filter parameters used to search for the user. + * + * @return filter parameters + */ + public Object[] getUserFilterParameters() + { + return userFilterParameters; + } + + + /** + * Sets the filter parameters used to search for the user. + * + * @param filterParams filter parameters + */ + public void setUserFilterParameters(final Object[] filterParams) + { + logger.trace("setting userFilterParameters: {}", Arrays.toString(filterParams)); + userFilterParameters = filterParams; + } + + + /** + * Returns whether DN resolution should fail if multiple DNs are found. + * + * @return whether an exception will be thrown if multiple DNs are found + */ + public boolean getAllowMultipleDns() + { + return allowMultipleDns; + } + + + /** + * Sets whether DN resolution should fail if multiple DNs are found. If false an exception will be thrown if {@link + * #resolve(User)} finds more than one DN matching it's filter. Otherwise the first DN found is returned. + * + * @param b whether multiple DNs are allowed + */ + public void setAllowMultipleDns(final boolean b) + { + logger.trace("setting allowMultipleDns: {}", b); + allowMultipleDns = b; + } + + + /** + * Returns whether subtree searching will be used. + * + * @return whether the DN will be searched for over the entire base + */ + public boolean getSubtreeSearch() + { + return subtreeSearch; + } + + + /** + * Sets whether subtree searching will be used. If true, the DN used for authenticating will be searched for over the + * entire {@link #getBaseDn()}. Otherwise the DN will be searched for in the {@link #getBaseDn()} context. + * + * @param b whether the DN will be searched for over the entire base + */ + public void setSubtreeSearch(final boolean b) + { + logger.trace("setting subtreeSearch: {}", b); + subtreeSearch = b; + } + + + /** + * Returns how to dereference aliases. + * + * @return how to dereference aliases + */ + public DerefAliases getDerefAliases() + { + return derefAliases; + } + + + /** + * Sets how to dereference aliases. + * + * @param da how to dereference aliases + */ + public void setDerefAliases(final DerefAliases da) + { + logger.trace("setting derefAliases: {}", da); + derefAliases = da; + } + + + /** + * Returns the referral handler. + * + * @return referral handler + */ + public ReferralHandler getReferralHandler() + { + return referralHandler; + } + + + /** + * Sets the referral handler. + * + * @param handler referral handler + */ + public void setReferralHandler(final ReferralHandler handler) + { + logger.trace("setting referralHandler: {}", handler); + referralHandler = handler; + } + + + /** + * Attempts to find the DN for the supplied user. {@link #createSearchFilter(User)} ()} is used to create the search + * filter. If more than one entry matches the search, the result is controlled by {@link + * #setAllowMultipleDns(boolean)}. + * + * @param user to find DN for + * + * @return user DN + * + * @throws LdapException if the entry resolution fails + */ + @Override + public String resolve(final User user) + throws LdapException + { + logger.debug("resolve user={}", user); + + String dn = null; + if (user != null) { + // create the search filter + final SearchFilter filter = createSearchFilter(user); + + if (filter != null && filter.getFilter() != null) { + final SearchResult result = performLdapSearch(filter); + final Iterator<LdapEntry> answer = result.getEntries().iterator(); + + // return first match, otherwise user doesn't exist + if (answer != null && answer.hasNext()) { + dn = resolveDn(answer.next()); + if (answer.hasNext()) { + logger.debug("multiple results found for user={} using filter={}", user, filter); + if (!allowMultipleDns) { + throw new LdapException("Found more than (1) DN for: " + user); + } + } + } else { + logger.info("search for user={} failed using filter={}", user, filter); + } + } else { + logger.error("DN search filter not found, no search performed"); + } + } else { + logger.warn("DN resolution cannot occur, user is null"); + } + logger.debug("resolved dn={} for user={}", dn, user); + return dn; + } + + + /** + * Returns the DN for the supplied ldap entry. + * + * @param entry to retrieve the DN from + * + * @return dn + */ + protected String resolveDn(final LdapEntry entry) + { + return entry.getDn(); + } + + + /** + * Returns a search filter using {@link #userFilter} and {@link #userFilterParameters}. The user parameter is injected + * as a named parameter of 'user'. + * + * @param user to resolve DN + * + * @return search filter + */ + protected SearchFilter createSearchFilter(final User user) + { + final SearchFilter filter = new SearchFilter(); + if (user != null && user.getIdentifier() != null && !"".equals(user.getIdentifier())) { + if (userFilter != null) { + logger.debug("searching for DN using userFilter"); + filter.setFilter(userFilter); + if (userFilterParameters != null) { + filter.setParameters(userFilterParameters); + } + // assign user as a named parameter + filter.setParameter("user", user.getIdentifier()); + // assign context as a named parameter + filter.setParameter("context", user.getContext()); + } else { + logger.error("Invalid userFilter, cannot be null or empty."); + } + } else { + logger.warn("Search filter cannot be created, user input was empty or null"); + } + return filter; + } + + + /** + * Returns a search request for searching for a single entry in an LDAP, returning no attributes. + * + * @param filter to execute + * + * @return search request + */ + protected SearchRequest createSearchRequest(final SearchFilter filter) + { + final SearchRequest request = new SearchRequest(); + request.setBaseDn(baseDn); + request.setSearchFilter(filter); + request.setReturnAttributes(ReturnAttributes.NONE.value()); + if (subtreeSearch) { + request.setSearchScope(SearchScope.SUBTREE); + } else { + request.setSearchScope(SearchScope.ONELEVEL); + } + request.setDerefAliases(derefAliases); + request.setReferralHandler(referralHandler); + return request; + } + + + /** + * Executes the ldap search operation with the supplied filter. + * + * @param filter to execute + * + * @return ldap search result + * + * @throws LdapException if an error occurs + */ + protected SearchResult performLdapSearch(final SearchFilter filter) + throws LdapException + { + final SearchRequest request = createSearchRequest(filter); + try (Connection conn = getConnection()) { + final SearchOperation op = createSearchOperation(conn); + return op.execute(request).getResult(); + } + } + + + /** + * Retrieve a connection that is ready for use. + * + * @return connection + * + * @throws LdapException if an error occurs opening the connection + */ + protected abstract Connection getConnection() + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/auth/AbstractSearchEntryResolver.java b/core/src/main/java/org/ldaptive/auth/AbstractSearchEntryResolver.java new file mode 100644 index 0000000..60f59a0 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AbstractSearchEntryResolver.java
@@ -0,0 +1,337 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import java.util.Iterator; +import org.ldaptive.DerefAliases; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.SearchScope; +import org.ldaptive.handler.SearchEntryHandler; +import org.ldaptive.referral.ReferralHandler; + +/** + * Base implementation for search entry resolvers. Uses an object level search on the {@link + * AuthenticationCriteria#getDn()} if no {@link #userFilter} is configured. If a {@link #userFilter} is configured, then + * a search is executed using that filter. + * + * @author Middleware Services + */ +public abstract class AbstractSearchEntryResolver extends AbstractSearchOperationFactory implements EntryResolver +{ + + /** DN to search. */ + private String baseDn = ""; + + /** Filter for searching for the user. */ + private String userFilter; + + /** Filter parameters for searching for the user. */ + private Object[] userFilterParameters; + + /** Whether to throw an exception if multiple entries are found. */ + private boolean allowMultipleEntries; + + /** Whether to use a subtree search when resolving DNs. */ + private boolean subtreeSearch; + + /** How to handle aliases. */ + private DerefAliases derefAliases; + + /** Referral handler. */ + private ReferralHandler referralHandler; + + /** Ldap entry handlers. */ + private SearchEntryHandler[] entryHandlers; + + + /** + * Returns the base DN. + * + * @return base DN + */ + public String getBaseDn() + { + return baseDn; + } + + + /** + * Sets the base DN. + * + * @param dn base DN + */ + public void setBaseDn(final String dn) + { + logger.trace("setting baseDn: {}", dn); + baseDn = dn; + } + + + /** + * Returns the filter used to search for the user. + * + * @return filter for searching + */ + public String getUserFilter() + { + return userFilter; + } + + + /** + * Sets the filter used to search for the user. + * + * @param filter for searching + */ + public void setUserFilter(final String filter) + { + logger.trace("setting userFilter: {}", filter); + userFilter = filter; + } + + + /** + * Returns the filter parameters used to search for the user. + * + * @return filter parameters + */ + public Object[] getUserFilterParameters() + { + return userFilterParameters; + } + + + /** + * Sets the filter parameters used to search for the user. + * + * @param filterParams filter parameters + */ + public void setUserFilterParameters(final Object[] filterParams) + { + logger.trace("setting userFilterParameters: {}", Arrays.toString(filterParams)); + userFilterParameters = filterParams; + } + + + /** + * Returns whether entry resolution should fail if multiple entries are found. + * + * @return whether an exception will be thrown if multiple entries are found + */ + public boolean getAllowMultipleEntries() + { + return allowMultipleEntries; + } + + + /** + * Sets whether entry resolution should fail if multiple entries are found. If false an exception will be thrown if + * {@link #resolve(AuthenticationCriteria, AuthenticationHandlerResponse)} finds more than one entry matching it's + * filter. Otherwise the first entry found is returned. + * + * @param b whether multiple entries are allowed + */ + public void setAllowMultipleEntries(final boolean b) + { + logger.trace("setting allowMultipleEntries: {}", b); + allowMultipleEntries = b; + } + + + /** + * Returns whether subtree searching will be used. + * + * @return whether the entry will be searched for over the entire base + */ + public boolean getSubtreeSearch() + { + return subtreeSearch; + } + + + /** + * Sets whether subtree searching will be used. If true, the entry will be searched for over the entire {@link + * #getBaseDn()}. Otherwise the entry will be searched for in the {@link #getBaseDn()} context. + * + * @param b whether the entry will be searched for over the entire base + */ + public void setSubtreeSearch(final boolean b) + { + logger.trace("setting subtreeSearch: {}", b); + subtreeSearch = b; + } + + + /** + * Returns how to dereference aliases. + * + * @return how to dereference aliases + */ + public DerefAliases getDerefAliases() + { + return derefAliases; + } + + + /** + * Sets how to dereference aliases. + * + * @param da how to dereference aliases + */ + public void setDerefAliases(final DerefAliases da) + { + logger.trace("setting derefAliases: {}", da); + derefAliases = da; + } + + + /** + * Returns the referral handler. + * + * @return referral handler + */ + public ReferralHandler getReferralHandler() + { + return referralHandler; + } + + + /** + * Sets the referral handler. + * + * @param handler referral handler + */ + public void setReferralHandler(final ReferralHandler handler) + { + logger.trace("setting referralHandler: {}", handler); + referralHandler = handler; + } + + + /** + * Returns the search entry handlers. + * + * @return search entry handlers + */ + public SearchEntryHandler[] getSearchEntryHandlers() + { + return entryHandlers; + } + + + /** + * Sets the search entry handlers. + * + * @param handlers search entry handlers + */ + public void setSearchEntryHandlers(final SearchEntryHandler... handlers) + { + entryHandlers = handlers; + } + + + /** + * Executes an ldap search with the supplied authentication criteria. + * + * @param criteria authentication criteria associated with the user + * @param response response from the authentication event + * + * @return search result + * + * @throws LdapException if an error occurs attempting the search + */ + protected abstract SearchResult performLdapSearch( + final AuthenticationCriteria criteria, + final AuthenticationHandlerResponse response) + throws LdapException; + + + /** + * Returns a search filter using {@link #userFilter} and {@link #userFilterParameters}. {@link + * User#getIdentifier()} is injected with a named parameter of 'user', {@link User#getContext()} is injected with a + * named parameter of 'context', and {@link AuthenticationCriteria#getDn()} is injected with a named parameter of + * 'dn'. + * + * @param ac authentication criteria + * + * @return search filter + */ + protected SearchFilter createSearchFilter(final AuthenticationCriteria ac) + { + final SearchFilter filter = new SearchFilter(); + if (userFilter != null) { + logger.debug("searching for entry using userFilter"); + filter.setFilter(userFilter); + if (userFilterParameters != null) { + filter.setParameters(userFilterParameters); + } + // assign named parameters + filter.setParameter("user", ac.getAuthenticationRequest().getUser().getIdentifier()); + filter.setParameter("context", ac.getAuthenticationRequest().getUser().getContext()); + filter.setParameter("dn", ac.getDn()); + } else { + logger.error("Invalid userFilter, cannot be null or empty."); + } + return filter; + } + + + /** + * Returns a search request for the supplied authentication criteria. If no {@link #userFilter} is defined then an + * object level search on the authentication criteria DN is returned. Otherwise the {@link #userFilter}, {@link + * #baseDn} and {@link #subtreeSearch} are used to create the search request. + * + * @param ac authentication criteria containing a DN + * + * @return search request + */ + protected SearchRequest createSearchRequest(final AuthenticationCriteria ac) + { + SearchRequest request; + if (userFilter != null) { + request = new SearchRequest(baseDn, createSearchFilter(ac)); + request.setReturnAttributes(ac.getAuthenticationRequest().getReturnAttributes()); + if (subtreeSearch) { + request.setSearchScope(SearchScope.SUBTREE); + } else { + request.setSearchScope(SearchScope.ONELEVEL); + } + } else { + request = SearchRequest.newObjectScopeSearchRequest( + ac.getDn(), + ac.getAuthenticationRequest().getReturnAttributes()); + } + request.setDerefAliases(derefAliases); + request.setReferralHandler(referralHandler); + request.setSearchEntryHandlers(entryHandlers); + return request; + } + + + @Override + public LdapEntry resolve(final AuthenticationCriteria criteria, final AuthenticationHandlerResponse response) + throws LdapException + { + logger.debug("resolve criteria={}", criteria); + + final SearchResult result = performLdapSearch(criteria, response); + logger.debug("resolved result={} for criteria={}", result, criteria); + + LdapEntry entry = null; + final Iterator<LdapEntry> answer = result.getEntries().iterator(); + if (answer != null && answer.hasNext()) { + entry = answer.next(); + if (answer.hasNext()) { + logger.debug("multiple results found for user={}", criteria.getDn()); + if (!allowMultipleEntries) { + throw new LdapException("Found more than (1) entry for: " + criteria.getDn()); + } + } + } + return entry; + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/AbstractSearchOperationFactory.java b/core/src/main/java/org/ldaptive/auth/AbstractSearchOperationFactory.java new file mode 100644 index 0000000..d6180cd --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AbstractSearchOperationFactory.java
@@ -0,0 +1,123 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import org.ldaptive.Connection; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.cache.Cache; +import org.ldaptive.handler.OperationExceptionHandler; +import org.ldaptive.handler.OperationResponseHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base class for authentication related classes that perform searches. + * + * @author Middleware Services + */ +public abstract class AbstractSearchOperationFactory +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Handler to handle search exceptions. */ + private OperationExceptionHandler<SearchRequest, SearchResult> searchExceptionHandler; + + /** Handlers to handle search responses. */ + private OperationResponseHandler<SearchRequest, SearchResult>[] searchResponseHandlers; + + /** Cache to use when performing searches. */ + private Cache<SearchRequest> searchCache; + + + /** + * Returns the search exception handler. + * + * @return search exception handler + */ + public OperationExceptionHandler<SearchRequest, SearchResult> getSearchExceptionHandler() + { + return searchExceptionHandler; + } + + + /** + * Sets the search exception handler. + * + * @param handler search exception handler + */ + public void setSearchExceptionHandler(final OperationExceptionHandler<SearchRequest, SearchResult> handler) + { + searchExceptionHandler = handler; + } + + + /** + * Returns the search response handlers. + * + * @return search response handlers + */ + public OperationResponseHandler<SearchRequest, SearchResult>[] getSearchResponseHandlers() + { + return searchResponseHandlers; + } + + + /** + * Sets the search response handlers. + * + * @param handlers search response handlers + */ + @SuppressWarnings("unchecked") + public void setSearchResponseHandlers(final OperationResponseHandler<SearchRequest, SearchResult>... handlers) + { + searchResponseHandlers = handlers; + } + + + /** + * Returns the search cache. + * + * @return cache + */ + public Cache<SearchRequest> getSearchCache() + { + return searchCache; + } + + + /** + * Sets the search cache. + * + * @param cache to set + */ + public void setSearchCache(final Cache<SearchRequest> cache) + { + searchCache = cache; + } + + + /** + * Creates a new search operation configured with the properties on this factory. + * + * @param conn to pass to the search operation + * + * @return search operation + */ + protected SearchOperation createSearchOperation(final Connection conn) + { + final SearchOperation op = new SearchOperation(conn); + if (searchExceptionHandler != null) { + op.setOperationExceptionHandler(searchExceptionHandler); + } + if (searchResponseHandlers != null) { + op.setOperationResponseHandlers(searchResponseHandlers); + } + if (searchCache != null) { + op.setCache(searchCache); + } + return op; + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/AccountState.java b/core/src/main/java/org/ldaptive/auth/AccountState.java new file mode 100644 index 0000000..0286634 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AccountState.java
@@ -0,0 +1,208 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.time.ZonedDateTime; +import java.util.Arrays; +import javax.security.auth.login.LoginException; + +/** + * Represents the state of an LDAP account based on account policies for that LDAP. Note that only warning(s) or + * error(s) may be set, not both. + * + * @author Middleware Services + */ +public class AccountState +{ + + /** account warning. */ + private final AccountState.Warning[] accountWarnings; + + /** account error. */ + private final AccountState.Error[] accountErrors; + + + /** + * Creates a new account state. + * + * @param warnings associated with the account + */ + public AccountState(final AccountState.Warning... warnings) + { + accountWarnings = warnings; + accountErrors = null; + } + + + /** + * Creates a new account state. + * + * @param errors associated with the account + */ + public AccountState(final AccountState.Error... errors) + { + accountWarnings = null; + accountErrors = errors; + } + + + /** + * Returns the account state warnings. + * + * @return account state warnings + */ + public AccountState.Warning[] getWarnings() + { + return accountWarnings; + } + + + /** + * Returns the first account state warning or null if no warnings exist. + * + * @return first account state warning + */ + public AccountState.Warning getWarning() + { + return accountWarnings != null && accountWarnings.length > 0 ? accountWarnings[0] : null; + } + + + /** + * Returns the account state errors. + * + * @return account state errors + */ + public AccountState.Error[] getErrors() + { + return accountErrors; + } + + + /** + * Returns the first account state error or null if no errors exist. + * + * @return first account state error + */ + public AccountState.Error getError() + { + return accountErrors != null && accountErrors.length > 0 ? accountErrors[0] : null; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::accountWarnings=%s, accountErrors=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(accountWarnings), + Arrays.toString(accountErrors)); + } + + + /** Contains error information for an account state. */ + public interface Error + { + + + /** + * Returns the error code. + * + * @return error code + */ + int getCode(); + + + /** + * Returns the error message. + * + * @return error message + */ + String getMessage(); + + + /** + * Throws the LoginException that best maps to this error. + * + * @throws LoginException for this account state error + */ + void throwSecurityException() + throws LoginException; + } + + + /** Contains warning information for an account state. */ + public interface Warning + { + + + /** + * Returns the expiration. + * + * @return expiration + */ + ZonedDateTime getExpiration(); + + + /** + * Returns the number of logins remaining until the account locks. + * + * @return number of logins remaining + */ + int getLoginsRemaining(); + } + + + /** Default warning implementation. */ + public static class DefaultWarning implements Warning + { + + /** expiration. */ + private final ZonedDateTime expiration; + + /** number of logins remaining before the account locks. */ + private final int loginsRemaining; + + + /** + * Creates a new warning. + * + * @param exp date of expiration + * @param remaining number of logins + */ + public DefaultWarning(final ZonedDateTime exp, final int remaining) + { + expiration = exp; + loginsRemaining = remaining; + } + + + @Override + public ZonedDateTime getExpiration() + { + return expiration; + } + + + @Override + public int getLoginsRemaining() + { + return loginsRemaining; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::expiration=%s, loginsRemaining=%s]", + getClass().getName(), + hashCode(), + expiration, + loginsRemaining); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/AddControlAuthenticationRequestHandler.java b/core/src/main/java/org/ldaptive/auth/AddControlAuthenticationRequestHandler.java new file mode 100644 index 0000000..dfa7a90 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AddControlAuthenticationRequestHandler.java
@@ -0,0 +1,69 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import org.ldaptive.LdapException; +import org.ldaptive.LdapUtils; +import org.ldaptive.control.RequestControl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Authentication request handler that adds {@link RequestControl}s to the {@link AuthenticationRequest}. + * + * @author Middleware Services + */ +public class AddControlAuthenticationRequestHandler implements AuthenticationRequestHandler +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Factory that produces request controls. */ + private final ControlFactory controlFactory; + + + /** + * Creates a new add control authentication request handler. + * + * @param factory to produce request controls + */ + public AddControlAuthenticationRequestHandler(final ControlFactory factory) + { + controlFactory = factory; + } + + + @Override + public void handle(final String dn, final AuthenticationRequest request) + throws LdapException + { + final RequestControl[] ctls = controlFactory.getControls(dn, request.getUser()); + logger.trace("{} produced controls {}", controlFactory, Arrays.toString(ctls)); + if (ctls != null && ctls.length > 0) { + if (request.getControls() != null && request.getControls().length > 0) { + request.setControls(LdapUtils.concatArrays(request.getControls(), ctls)); + } else { + request.setControls(ctls); + } + } + } + + + /** Factory that produces {@link RequestControl}s. */ + public interface ControlFactory + { + + + /** + * Creates a new array of request controls. Implementations must treat the supplied parameters as unauthenticated + * data. Authentication has not been performed when this factory is invoked. + * + * @param dn distinguished name of the unauthenticated user + * @param user id of the unauthenticated user + * + * @return request controls + */ + RequestControl[] getControls(String dn, User user); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/AggregateDnResolver.java b/core/src/main/java/org/ldaptive/auth/AggregateDnResolver.java new file mode 100644 index 0000000..be0ecbf --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AggregateDnResolver.java
@@ -0,0 +1,403 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletionService; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Looks up a user's DN using multiple DN resolvers. Each DN resolver is invoked on a separate thread. If multiple DNs + * are allowed then the first one retrieved is returned. + * + * @author Middleware Services + */ +public class AggregateDnResolver implements DnResolver +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** To submit operations to. */ + private final ExecutorService service; + + /** Labeled DN resolvers. */ + private Map<String, DnResolver> dnResolvers; + + /** Whether to throw an exception if multiple DNs are found. */ + private boolean allowMultipleDns; + + + /** Default constructor. */ + public AggregateDnResolver() + { + service = Executors.newCachedThreadPool(); + } + + + /** + * Creates a new aggregate dn resolver. + * + * @param resolvers dn resolvers + */ + public AggregateDnResolver(final Map<String, DnResolver> resolvers) + { + this(resolvers, Executors.newCachedThreadPool()); + } + + + /** + * Creates a new aggregate dn resolver. + * + * @param resolvers dn resolvers + * @param es executor service for invoking DN resolvers + */ + public AggregateDnResolver(final Map<String, DnResolver> resolvers, final ExecutorService es) + { + setDnResolvers(resolvers); + service = es; + } + + + /** + * Returns the DN resolvers to aggregate over. + * + * @return map of label to dn resolver + */ + public Map<String, DnResolver> getDnResolvers() + { + return Collections.unmodifiableMap(dnResolvers); + } + + + /** + * Sets the DN resolvers to aggregate over. + * + * @param resolvers to set + */ + public void setDnResolvers(final Map<String, DnResolver> resolvers) + { + logger.trace("setting dnResolvers: {}", resolvers); + dnResolvers = resolvers; + } + + + /** + * Returns whether DN resolution should fail if multiple DNs are found. + * + * @return whether an exception will be thrown if multiple DNs are found + */ + public boolean getAllowMultipleDns() + { + return allowMultipleDns; + } + + + /** + * Sets whether DN resolution should fail if multiple DNs are found If false an exception will be thrown if {@link + * #resolve(User)} finds that more than one DN resolver returns a DN. Otherwise the first DN found is returned. + * + * @param b whether multiple DNs are allowed + */ + public void setAllowMultipleDns(final boolean b) + { + logger.trace("setting allowMultipleDns: {}", b); + allowMultipleDns = b; + } + + + /** + * Creates an aggregate entry resolver using the labels from the DN resolver and the supplied entry resolver. + * + * @param resolver used for every label + * + * @return aggregate entry resolver + */ + public EntryResolver createEntryResolver(final org.ldaptive.auth.EntryResolver resolver) + { + final Map<String, org.ldaptive.auth.EntryResolver> resolvers = new HashMap<>(dnResolvers.size()); + for (String label : dnResolvers.keySet()) { + resolvers.put(label, resolver); + } + return new EntryResolver(resolvers); + } + + + @Override + public String resolve(final User user) + throws LdapException + { + final CompletionService<String> cs = new ExecutorCompletionService<>(service); + final List<String> results = new ArrayList<>(dnResolvers.size()); + for (final Map.Entry<String, DnResolver> entry : dnResolvers.entrySet()) { + cs.submit( + () -> { + final String dn = entry.getValue().resolve(user); + logger.debug("DN resolver {} resolved dn {} for user {}", entry.getValue(), dn, user); + if (dn != null && !dn.isEmpty()) { + return String.format("%s:%s", entry.getKey(), dn); + } + return null; + }); + logger.debug("submitted DN resolver {}", entry.getValue()); + } + for (int i = 1; i <= dnResolvers.size(); i++) { + try { + logger.trace("waiting on DN resolver {} of {}", i, dnResolvers.size()); + final String dn = cs.take().get(); + if (dn != null) { + results.add(dn); + } + } catch (ExecutionException e) { + if (e.getCause() instanceof LdapException) { + throw (LdapException) e.getCause(); + } else if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } else { + logger.warn("ExecutionException thrown, ignoring", e); + } + } catch (InterruptedException e) { + logger.warn("InterruptedException thrown, ignoring", e); + } + } + if (results.size() > 1 && !allowMultipleDns) { + throw new LdapException("Found more than (1) DN for: " + user); + } + logger.debug("resolved aggregate DN {}", results); + return results.isEmpty() ? null : results.get(0); + } + + + /** Invokes {@link ExecutorService#shutdown()} on the underlying executor service. */ + public void shutdown() + { + service.shutdown(); + } + + + @Override + protected void finalize() + throws Throwable + { + try { + shutdown(); + } finally { + super.finalize(); + } + } + + + /** + * Used in conjunction with an {@link AggregateDnResolver} to authenticate the resolved DN. In particular, the + * resolved DN is expected to be of the form: label:DN where the label indicates the authentication handler to use. + * This class only invokes one authentication handler that matches the label found on the DN. + */ + public static class AuthenticationHandler implements org.ldaptive.auth.AuthenticationHandler + { + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Labeled authentication handlers. */ + private Map<String, org.ldaptive.auth.AuthenticationHandler> authenticationHandlers; + + + /** Default constructor. */ + public AuthenticationHandler() {} + + + /** + * Creates a new aggregate authentication handler. + * + * @param handlers authentication handlers + */ + public AuthenticationHandler(final Map<String, org.ldaptive.auth.AuthenticationHandler> handlers) + { + setAuthenticationHandlers(handlers); + } + + + /** + * Returns the authentication handlers to aggregate over. + * + * @return map of label to authentication handler + */ + public Map<String, org.ldaptive.auth.AuthenticationHandler> getAuthenticationHandlers() + { + return Collections.unmodifiableMap(authenticationHandlers); + } + + + /** + * Sets the authentication handlers to aggregate over. + * + * @param handlers to set + */ + public void setAuthenticationHandlers(final Map<String, org.ldaptive.auth.AuthenticationHandler> handlers) + { + logger.trace("setting authenticationHandlers: {}", handlers); + authenticationHandlers = handlers; + } + + + @Override + public AuthenticationHandlerResponse authenticate(final AuthenticationCriteria criteria) + throws LdapException + { + final String[] labeledDn = criteria.getDn().split(":", 2); + final org.ldaptive.auth.AuthenticationHandler ah = authenticationHandlers.get(labeledDn[0]); + if (ah == null) { + throw new LdapException("Could not find authentication handler for label: " + labeledDn[0]); + } + return ah.authenticate(new AuthenticationCriteria(labeledDn[1], criteria.getAuthenticationRequest())); + } + } + + + /** + * Used in conjunction with an {@link AggregateDnResolver} to resolve an entry. In particular, the resolved DN is + * expected to be of the form: label:DN where the label indicates the entry resolver to use. This class only invokes + * one entry resolver that matches the label found on the DN. + */ + public static class EntryResolver implements org.ldaptive.auth.EntryResolver + { + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Labeled entry resolvers. */ + private Map<String, org.ldaptive.auth.EntryResolver> entryResolvers; + + + /** Default constructor. */ + public EntryResolver() {} + + + /** + * Creates a new aggregate entry resolver. + * + * @param resolvers entry resolvers + */ + public EntryResolver(final Map<String, org.ldaptive.auth.EntryResolver> resolvers) + { + setEntryResolvers(resolvers); + } + + + /** + * Returns the entry resolvers to aggregate over. + * + * @return map of label to entry resolver + */ + public Map<String, org.ldaptive.auth.EntryResolver> getEntryResolvers() + { + return Collections.unmodifiableMap(entryResolvers); + } + + + /** + * Sets the entry resolvers to aggregate over. + * + * @param resolvers to set + */ + public void setEntryResolvers(final Map<String, org.ldaptive.auth.EntryResolver> resolvers) + { + logger.trace("setting entryResolvers: {}", resolvers); + entryResolvers = resolvers; + } + + + @Override + public LdapEntry resolve(final AuthenticationCriteria criteria, final AuthenticationHandlerResponse response) + throws LdapException + { + final String[] labeledDn = criteria.getDn().split(":", 2); + final org.ldaptive.auth.EntryResolver er = entryResolvers.get(labeledDn[0]); + if (er == null) { + throw new LdapException("Could not find entry resolver for label: " + labeledDn[0]); + } + return er.resolve(new AuthenticationCriteria(labeledDn[1], criteria.getAuthenticationRequest()), response); + } + } + + + /** + * Used in conjunction with an {@link AggregateDnResolver} to execute a list of response handlers. In particular, the + * resolved DN is expected to be of the form: label:DN where the label indicates the response handler to use. This + * class only invokes the response handlers that matches the label found on the DN. + */ + public static class AuthenticationResponseHandler implements org.ldaptive.auth.AuthenticationResponseHandler + { + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Labeled entry resolvers. */ + private Map<String, org.ldaptive.auth.AuthenticationResponseHandler[]> responseHandlers; + + + /** Default constructor. */ + public AuthenticationResponseHandler() {} + + + /** + * Creates a new aggregate authentication response handler. + * + * @param handlers authentication response handlers + */ + public AuthenticationResponseHandler(final Map<String, org.ldaptive.auth.AuthenticationResponseHandler[]> handlers) + { + setAuthenticationResponseHandlers(handlers); + } + + + /** + * Returns the response handlers to aggregate over. + * + * @return map of label to response handlers + */ + public Map<String, org.ldaptive.auth.AuthenticationResponseHandler[]> getAuthenticationResponseHandlers() + { + return Collections.unmodifiableMap(responseHandlers); + } + + + /** + * Sets the response handlers to aggregate over. + * + * @param handlers to set + */ + public void setAuthenticationResponseHandlers( + final Map<String, org.ldaptive.auth.AuthenticationResponseHandler[]> handlers) + { + logger.trace("setting authenticationResponseHandlers: {}", handlers); + responseHandlers = handlers; + } + + + @Override + public void handle(final AuthenticationResponse response) throws LdapException + { + final String[] labeledDn = response.getResolvedDn().split(":", 2); + final org.ldaptive.auth.AuthenticationResponseHandler[] handlers = responseHandlers.get(labeledDn[0]); + if (handlers == null) { + throw new LdapException("Could not find response handlers for label: " + labeledDn[0]); + } + if (handlers.length > 0) { + for (org.ldaptive.auth.AuthenticationResponseHandler ah : handlers) { + ah.handle(response); + } + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/AuthenticationCriteria.java b/core/src/main/java/org/ldaptive/auth/AuthenticationCriteria.java new file mode 100644 index 0000000..156776a --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AuthenticationCriteria.java
@@ -0,0 +1,115 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import org.ldaptive.Credential; + +/** + * Contains the properties used to perform authentication. + * + * @author Middleware Services + */ +public class AuthenticationCriteria +{ + + /** dn. */ + private String authenticationDn; + + /** authentication request. */ + private AuthenticationRequest authenticationRequest; + + + /** Default constructor. */ + public AuthenticationCriteria() {} + + + /** + * Creates a new authentication criteria. + * + * @param dn to authenticate + */ + public AuthenticationCriteria(final String dn) + { + authenticationDn = dn; + } + + + /** + * Creates a new authentication criteria. + * + * @param dn to authenticate + * @param request that initiated the authentication + */ + public AuthenticationCriteria(final String dn, final AuthenticationRequest request) + { + authenticationDn = dn; + authenticationRequest = request; + } + + + /** + * Returns the dn. + * + * @return dn to authenticate + */ + public String getDn() + { + return authenticationDn; + } + + + /** + * Sets the dn. + * + * @param dn to set dn + */ + public void setDn(final String dn) + { + authenticationDn = dn; + } + + + /** + * Returns the credential. + * + * @return credential to authenticate dn + */ + public Credential getCredential() + { + return authenticationRequest.getCredential(); + } + + + /** + * Returns the authentication request. + * + * @return authentication request + */ + public AuthenticationRequest getAuthenticationRequest() + { + return authenticationRequest; + } + + + /** + * Sets the authentication request. + * + * @param request to set authentication request + */ + public void setAuthenticationRequest(final AuthenticationRequest request) + { + authenticationRequest = request; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::dn=%s, authenticationRequest=%s]", + getClass().getName(), + hashCode(), + authenticationDn, + authenticationRequest); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/AuthenticationHandler.java b/core/src/main/java/org/ldaptive/auth/AuthenticationHandler.java new file mode 100644 index 0000000..c0658e7 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AuthenticationHandler.java
@@ -0,0 +1,26 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import org.ldaptive.LdapException; + +/** + * Provides an interface for LDAP authentication implementations. + * + * @author Middleware Services + */ +public interface AuthenticationHandler +{ + + + /** + * Perform an ldap authentication. + * + * @param criteria to perform the authentication with + * + * @return authentication handler response + * + * @throws LdapException if ldap operation fails + */ + AuthenticationHandlerResponse authenticate(AuthenticationCriteria criteria) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/auth/AuthenticationHandlerResponse.java b/core/src/main/java/org/ldaptive/auth/AuthenticationHandlerResponse.java new file mode 100644 index 0000000..e190224 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AuthenticationHandlerResponse.java
@@ -0,0 +1,104 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import org.ldaptive.Connection; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.control.ResponseControl; + +/** + * Response object for authentication handlers. + * + * @author Middleware Services + */ +public class AuthenticationHandlerResponse extends Response<Boolean> +{ + + /** Connection that authentication occurred on. */ + private final Connection connection; + + + /** + * Creates a new authentication response. + * + * @param success authentication result + * @param rc result code from the underlying ldap operation + * @param conn connection the authentication occurred on + */ + public AuthenticationHandlerResponse(final boolean success, final ResultCode rc, final Connection conn) + { + super(success, rc); + connection = conn; + } + + + /** + * Creates a new authentication response. + * + * @param success authentication result + * @param rc result code from the underlying ldap operation + * @param conn connection the authentication occurred on + * @param msg authentication message + */ + public AuthenticationHandlerResponse( + final boolean success, + final ResultCode rc, + final Connection conn, + final String msg) + { + super(success, rc, msg, null, null, null, -1); + connection = conn; + } + + + /** + * Creates a new ldap response. + * + * @param success authentication result + * @param rc result code from the underlying ldap operation + * @param conn connection the authentication occurred on + * @param msg authentication message + * @param controls response controls from the underlying ldap operation + * @param msgId message id from the underlying ldap operation + */ + public AuthenticationHandlerResponse( + final boolean success, + final ResultCode rc, + final Connection conn, + final String msg, + final ResponseControl[] controls, + final int msgId) + { + super(success, rc, msg, null, controls, null, msgId); + connection = conn; + } + + + /** + * Returns the connection that the ldap operation occurred on. + * + * @return connection + */ + public Connection getConnection() + { + return connection; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::connection=%s, result=%s, resultCode=%s, message=%s, " + + "controls=%s]", + getClass().getName(), + hashCode(), + connection, + getResult(), + getResultCode(), + getMessage(), + Arrays.toString(getControls())); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/AuthenticationRequest.java b/core/src/main/java/org/ldaptive/auth/AuthenticationRequest.java new file mode 100644 index 0000000..5217153 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AuthenticationRequest.java
@@ -0,0 +1,208 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import org.ldaptive.Credential; +import org.ldaptive.ReturnAttributes; +import org.ldaptive.control.RequestControl; + +/** + * Contains the data required to perform an ldap authentication. + * + * @author Middleware Services + */ +public class AuthenticationRequest +{ + + /** User. */ + private User user; + + /** User credential. */ + private Credential credential; + + /** User attributes to return. */ + private String[] returnAttributes = ReturnAttributes.NONE.value(); + + /** Request controls. */ + private RequestControl[] controls; + + + /** Default constructor. */ + public AuthenticationRequest() {} + + + /** + * Creates a new authentication request. + * + * @param id that identifies the user + * @param c credential to authenticate the user + */ + public AuthenticationRequest(final String id, final Credential c) + { + setUser(new User(id)); + setCredential(c); + } + + + /** + * Creates a new authentication request. + * + * @param id that identifies the user + * @param c credential to authenticate the user + * @param attrs attributes to return + */ + public AuthenticationRequest(final String id, final Credential c, final String... attrs) + { + setUser(new User(id)); + setCredential(c); + setReturnAttributes(attrs); + } + + + /** + * Creates a new authentication request. + * + * @param u that identifies the user + * @param c credential to authenticate the user + */ + public AuthenticationRequest(final User u, final Credential c) + { + setUser(u); + setCredential(c); + } + + + /** + * Creates a new authentication request. + * + * @param u that identifies the user + * @param c credential to authenticate the user + * @param attrs attributes to return + */ + public AuthenticationRequest(final User u, final Credential c, final String... attrs) + { + setUser(u); + setCredential(c); + setReturnAttributes(attrs); + } + + + /** + * Returns the user. + * + * @return user identifier + */ + public User getUser() + { + return user; + } + + + /** + * Sets the user. + * + * @param u user + */ + public void setUser(final User u) + { + user = u; + } + + + /** + * Returns the credential. + * + * @return user credential + */ + public Credential getCredential() + { + return credential; + } + + + /** + * Sets the credential. + * + * @param c user credential + */ + public void setCredential(final Credential c) + { + credential = c; + } + + + /** + * Returns the return attributes. + * + * @return attributes to return + */ + public String[] getReturnAttributes() + { + return returnAttributes; + } + + + /** + * Sets the return attributes. + * + * @param attrs return attributes + */ + public void setReturnAttributes(final String... attrs) + { + returnAttributes = ReturnAttributes.parse(attrs); + } + + + /** + * Returns the controls. + * + * @return controls + */ + public RequestControl[] getControls() + { + return controls; + } + + + /** + * Sets the controls. + * + * @param c controls to set + */ + public void setControls(final RequestControl... c) + { + controls = c; + } + + + /** + * Returns an authentication request initialized with the supplied request. + * + * @param request authentication request to read properties from + * + * @return authentication request + */ + public static AuthenticationRequest newAuthenticationRequest(final AuthenticationRequest request) + { + final AuthenticationRequest r = new AuthenticationRequest(); + r.setUser(request.getUser()); + r.setCredential(request.getCredential()); + r.setReturnAttributes(request.getReturnAttributes()); + r.setControls(request.getControls()); + return r; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::user=%s, returnAttributes=%s, controls=%s]", + getClass().getName(), + hashCode(), + user, + Arrays.toString(returnAttributes), + Arrays.toString(controls)); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/AuthenticationRequestHandler.java b/core/src/main/java/org/ldaptive/auth/AuthenticationRequestHandler.java new file mode 100644 index 0000000..d33b5f7 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AuthenticationRequestHandler.java
@@ -0,0 +1,25 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import org.ldaptive.LdapException; + +/** + * Provides pre authentication handling of authentication requests. + * + * @author Middleware Services + */ +public interface AuthenticationRequestHandler +{ + + + /** + * Handle the request for an ldap authentication. + * + * @param dn distinguished name resolved for this request + * @param request for this authentication event + * + * @throws LdapException if an error occurs handling an authentication request + */ + void handle(String dn, AuthenticationRequest request) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/auth/AuthenticationResponse.java b/core/src/main/java/org/ldaptive/auth/AuthenticationResponse.java new file mode 100644 index 0000000..86fa7f6 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AuthenticationResponse.java
@@ -0,0 +1,175 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import org.ldaptive.LdapEntry; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.control.ResponseControl; + +/** + * Response object for authenticator. + * + * @author Middleware Services + */ +public class AuthenticationResponse extends Response<Boolean> +{ + + /** Result of the authentication operation. */ + private final AuthenticationResultCode authenticationResultCode; + + /** Resolved DN. */ + private final String resolvedDn; + + /** Ldap entry of authenticated user. */ + private final LdapEntry ldapEntry; + + /** Account state. */ + private AccountState accountState; + + + /** + * Creates a new authentication response. + * + * @param authRc authentication result code + * @param rc result code from the underlying ldap operation + * @param dn produced by the DN resolver + * @param entry of the authenticated user + */ + public AuthenticationResponse( + final AuthenticationResultCode authRc, + final ResultCode rc, + final String dn, + final LdapEntry entry) + { + super(AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS == authRc, rc); + authenticationResultCode = authRc; + resolvedDn = dn; + ldapEntry = entry; + } + + + /** + * Creates a new authentication response. + * + * @param authRc authentication result code + * @param rc result code from the underlying ldap operation + * @param dn produced by the DN resolver + * @param entry of the authenticated user + * @param msg authentication message + */ + public AuthenticationResponse( + final AuthenticationResultCode authRc, + final ResultCode rc, + final String dn, + final LdapEntry entry, + final String msg) + { + super(AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS == authRc, rc, msg, null, null, null, -1); + authenticationResultCode = authRc; + resolvedDn = dn; + ldapEntry = entry; + } + + + /** + * Creates a new authentication response. + * + * @param authRc authentication result code + * @param rc result code from the underlying ldap operation + * @param dn produced by the DN resolver + * @param entry of the authenticated user + * @param msg authentication message + * @param controls response controls from the underlying ldap operation + * @param msgId message id from the underlying ldap operation + */ + public AuthenticationResponse( + final AuthenticationResultCode authRc, + final ResultCode rc, + final String dn, + final LdapEntry entry, + final String msg, + final ResponseControl[] controls, + final int msgId) + { + super(AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS == authRc, rc, msg, null, controls, null, msgId); + authenticationResultCode = authRc; + resolvedDn = dn; + ldapEntry = entry; + } + + + /** + * Returns the result code associated with the authentication operation. + * + * @return authentication result code + */ + public AuthenticationResultCode getAuthenticationResultCode() + { + return authenticationResultCode; + } + + + /** + * Returns the DN that was resolved in order to perform authentication. + * + * @return resolved dn + */ + public String getResolvedDn() + { + return resolvedDn; + } + + + /** + * Returns the ldap entry of the authenticated user. + * + * @return ldap entry + */ + public LdapEntry getLdapEntry() + { + return ldapEntry; + } + + + /** + * Returns the account state associated with the authenticated user. + * + * @return account state + */ + public AccountState getAccountState() + { + return accountState; + } + + + /** + * Sets the account state for the authenticated user. + * + * @param state for this user + */ + public void setAccountState(final AccountState state) + { + accountState = state; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::authenticationResultCode=%s, resolvedDn=%s, ldapEntry=%s, accountState=%s, result=%s, " + + "resultCode=%s, message=%s, controls=%s]", + getClass().getName(), + hashCode(), + authenticationResultCode, + resolvedDn, + ldapEntry, + accountState, + getResult(), + getResultCode(), + getMessage(), + Arrays.toString(getControls())); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/AuthenticationResponseHandler.java b/core/src/main/java/org/ldaptive/auth/AuthenticationResponseHandler.java new file mode 100644 index 0000000..f75724f --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AuthenticationResponseHandler.java
@@ -0,0 +1,24 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import org.ldaptive.LdapException; + +/** + * Provides post authentication handling of authentication responses. + * + * @author Middleware Services + */ +public interface AuthenticationResponseHandler +{ + + + /** + * Handle the response from an ldap authentication. + * + * @param response produced from an authentication + * + * @throws LdapException if an error occurs handling an authentication response + */ + void handle(AuthenticationResponse response) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/auth/AuthenticationResultCode.java b/core/src/main/java/org/ldaptive/auth/AuthenticationResultCode.java new file mode 100644 index 0000000..b58ad68 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AuthenticationResultCode.java
@@ -0,0 +1,22 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +/** + * Enum to define authentication results. + * + * @author Middleware Services + */ +public enum AuthenticationResultCode { + + /** The configured authentication handler produced a result of true. */ + AUTHENTICATION_HANDLER_SUCCESS, + + /** The configured authentication handler produced a result of false. */ + AUTHENTICATION_HANDLER_FAILURE, + + /** The supplied credential was empty or null. */ + INVALID_CREDENTIAL, + + /** The configured DN resolver produced an empty or null value. */ + DN_RESOLUTION_FAILURE +}
diff --git a/core/src/main/java/org/ldaptive/auth/Authenticator.java b/core/src/main/java/org/ldaptive/auth/Authenticator.java new file mode 100644 index 0000000..cc97b46 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/Authenticator.java
@@ -0,0 +1,466 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import org.ldaptive.Credential; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.LdapUtils; +import org.ldaptive.ReturnAttributes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides functionality to authenticate users against an ldap directory. + * + * @author Middleware Services + */ +public class Authenticator +{ + + /** NoOp entry resolver. */ + private static final EntryResolver NOOP_RESOLVER = new NoOpEntryResolver(); + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** For finding user DNs. */ + private DnResolver dnResolver; + + /** Handler to handle authentication. */ + private AuthenticationHandler authenticationHandler; + + /** For finding user entries. */ + private EntryResolver entryResolver; + + /** User attributes to return. Concatenated to {@link AuthenticationRequest#getReturnAttributes()}. */ + private String[] returnAttributes; + + /** Handlers to handle authentication requests. */ + private AuthenticationRequestHandler[] authenticationRequestHandlers; + + /** Handlers to handle authentication responses. */ + private AuthenticationResponseHandler[] authenticationResponseHandlers; + + /** Whether to execute the entry resolver on authentication failure. */ + private boolean resolveEntryOnFailure; + + + /** Default constructor. */ + public Authenticator() {} + + + /** + * Creates a new authenticator. + * + * @param resolver dn resolver + * @param handler authentication handler + */ + public Authenticator(final DnResolver resolver, final AuthenticationHandler handler) + { + setDnResolver(resolver); + setAuthenticationHandler(handler); + } + + + /** + * Returns the DN resolver. + * + * @return DN resolver + */ + public DnResolver getDnResolver() + { + return dnResolver; + } + + + /** + * Sets the DN resolver. + * + * @param resolver for finding DNs + */ + public void setDnResolver(final DnResolver resolver) + { + dnResolver = resolver; + } + + + /** + * Returns the authentication handler. + * + * @return authentication handler + */ + public AuthenticationHandler getAuthenticationHandler() + { + return authenticationHandler; + } + + + /** + * Sets the authentication handler. + * + * @param handler for performing authentication + */ + public void setAuthenticationHandler(final AuthenticationHandler handler) + { + authenticationHandler = handler; + } + + + /** + * Returns the entry resolver. + * + * @return entry resolver + */ + public EntryResolver getEntryResolver() + { + return entryResolver; + } + + + /** + * Sets the entry resolver. + * + * @param resolver for finding entries + */ + public void setEntryResolver(final EntryResolver resolver) + { + entryResolver = resolver; + } + + + /** + * Returns whether to execute the entry resolver on authentication failure. + * + * @return whether to execute the entry resolver on authentication failure + */ + public boolean getResolveEntryOnFailure() + { + return resolveEntryOnFailure; + } + + + /** + * Sets whether to execute the entry resolver on authentication failure. + * + * @param b whether to execute the entry resolver + */ + public void setResolveEntryOnFailure(final boolean b) + { + resolveEntryOnFailure = b; + } + + + /** + * Returns the return attributes. + * + * @return attributes to return + */ + public String[] getReturnAttributes() + { + return returnAttributes; + } + + + /** + * Sets the return attributes. + * + * @param attrs return attributes + */ + public void setReturnAttributes(final String... attrs) + { + returnAttributes = attrs; + } + + + /** + * Returns the authentication request handlers. + * + * @return authentication request handlers + */ + public AuthenticationRequestHandler[] getAuthenticationRequestHandlers() + { + return authenticationRequestHandlers; + } + + + /** + * Sets the authentication request handlers. + * + * @param handlers authentication request handlers + */ + public void setAuthenticationRequestHandlers(final AuthenticationRequestHandler... handlers) + { + authenticationRequestHandlers = handlers; + } + + + /** + * Returns the authentication response handlers. + * + * @return authentication response handlers + */ + public AuthenticationResponseHandler[] getAuthenticationResponseHandlers() + { + return authenticationResponseHandlers; + } + + + /** + * Sets the authentication response handlers. + * + * @param handlers authentication response handlers + */ + public void setAuthenticationResponseHandlers(final AuthenticationResponseHandler... handlers) + { + authenticationResponseHandlers = handlers; + } + + + /** + * This will attempt to find the DN for the supplied user. {@link DnResolver#resolve(User)} is invoked to perform this + * operation. + * + * @param user to find DN for + * + * @return user DN + * + * @throws LdapException if an LDAP error occurs during resolution + */ + public String resolveDn(final User user) + throws LdapException + { + return dnResolver.resolve(user); + } + + + /** + * Authenticate the user in the supplied request. + * + * @param request authentication request + * + * @return response containing the ldap entry of the user authenticated + * + * @throws LdapException if an LDAP error occurs + */ + public AuthenticationResponse authenticate(final AuthenticationRequest request) + throws LdapException + { + return authenticate(resolveDn(request.getUser()), request); + } + + + /** + * Validates input and performs authentication using an {@link AuthenticationHandler}. Executes any configured {@link + * AuthenticationResponseHandler}. + * + * @param dn to authenticate as + * @param request containing authentication parameters + * + * @return ldap entry for the supplied DN + * + * @throws LdapException if an LDAP error occurs + */ + protected AuthenticationResponse authenticate(final String dn, final AuthenticationRequest request) + throws LdapException + { + logger.debug("authenticate dn={} with request={}", dn, request); + + final AuthenticationResponse invalidInput = validateInput(dn, request); + if (invalidInput != null) { + return invalidInput; + } + + LdapEntry entry = null; + + final AuthenticationRequest processedRequest = processRequest(dn, request); + AuthenticationHandlerResponse response = null; + try { + final AuthenticationCriteria ac = new AuthenticationCriteria(dn, processedRequest); + + // attempt to authenticate as this dn + response = getAuthenticationHandler().authenticate(ac); + // resolve the entry + entry = resolveEntry(ac, response); + } finally { + if (response != null && response.getConnection() != null) { + response.getConnection().close(); + } + } + + logger.info("Authentication {} for dn: {}", response.getResult() ? "succeeded" : "failed", dn); + + final AuthenticationResponse authResponse = new AuthenticationResponse( + response.getResult() ? AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS + : AuthenticationResultCode.AUTHENTICATION_HANDLER_FAILURE, + response.getResultCode(), + dn, + entry, + response.getMessage(), + response.getControls(), + response.getMessageId()); + + // execute authentication response handlers + if (getAuthenticationResponseHandlers() != null && getAuthenticationResponseHandlers().length > 0) { + for (AuthenticationResponseHandler ah : getAuthenticationResponseHandlers()) { + ah.handle(authResponse); + } + } + + logger.debug("authenticate response={} for dn={} with request={}", response, dn, processedRequest); + return authResponse; + } + + + /** + * Validates the authentication request and resolved DN. Returns an authentication response if validation failed. + * + * @param dn to validate + * @param request to validate + * + * @return authentication response if validation failed, otherwise null + */ + protected AuthenticationResponse validateInput(final String dn, final AuthenticationRequest request) + { + AuthenticationResponse response = null; + final Credential credential = request.getCredential(); + if (credential == null || credential.getBytes() == null) { + response = new AuthenticationResponse( + AuthenticationResultCode.INVALID_CREDENTIAL, + null, + dn, + null, + "Credential cannot be null", + null, + -1); + } else if (credential.getBytes().length == 0) { + response = new AuthenticationResponse( + AuthenticationResultCode.INVALID_CREDENTIAL, + null, + dn, + null, + "Credential cannot be empty", + null, + -1); + } else if (dn == null) { + response = new AuthenticationResponse( + AuthenticationResultCode.DN_RESOLUTION_FAILURE, + null, + dn, + null, + "DN cannot be null", + null, + -1); + } else if (dn.isEmpty()) { + response = new AuthenticationResponse( + AuthenticationResultCode.DN_RESOLUTION_FAILURE, + null, + dn, + null, + "DN cannot be empty", + null, + -1); + } + return response; + } + + + /** + * Creates a new authentication request applying any applicable configuration on this authenticator. Returns the + * supplied request if no configuration is applied. + * + * @param dn to process + * @param request to process + * + * @return authentication request + * + * @throws LdapException if an error occurs with a request handler + */ + protected AuthenticationRequest processRequest(final String dn, final AuthenticationRequest request) + throws LdapException + { + if (returnAttributes == null && + (getAuthenticationRequestHandlers() == null || getAuthenticationRequestHandlers().length == 0)) { + return request; + } + + final AuthenticationRequest newRequest = AuthenticationRequest.newAuthenticationRequest(request); + if (returnAttributes != null) { + if (newRequest.getReturnAttributes() == null || + ReturnAttributes.NONE.equalsAttributes(newRequest.getReturnAttributes())) { + newRequest.setReturnAttributes(returnAttributes); + } else { + newRequest.setReturnAttributes(LdapUtils.concatArrays(newRequest.getReturnAttributes(), returnAttributes)); + } + } + + // execute authentication request handlers + if (getAuthenticationRequestHandlers() != null && getAuthenticationRequestHandlers().length > 0) { + for (AuthenticationRequestHandler ah : getAuthenticationRequestHandlers()) { + ah.handle(dn, newRequest); + } + } + return newRequest; + } + + + /** + * Attempts to find the ldap entry for the supplied DN. If an entry resolver has been configured it is used. A {@link + * SearchEntryResolver} is used if return attributes have been requested. If none of these criteria is met, a {@link + * NoOpDnResolver} is used. + * + * @param criteria needed by the entry resolver + * @param response from the authentication handler + * + * @return ldap entry + * + * @throws LdapException if an error occurs resolving the entry + */ + protected LdapEntry resolveEntry(final AuthenticationCriteria criteria, final AuthenticationHandlerResponse response) + throws LdapException + { + LdapEntry entry = null; + EntryResolver er; + if (resolveEntryOnFailure || response.getResult()) { + if (entryResolver != null) { + er = entryResolver; + } else if (!ReturnAttributes.NONE.equalsAttributes(criteria.getAuthenticationRequest().getReturnAttributes())) { + if (dnResolver instanceof AggregateDnResolver) { + er = ((AggregateDnResolver) dnResolver).createEntryResolver(new SearchEntryResolver()); + } else { + er = new SearchEntryResolver(); + } + } else { + er = NOOP_RESOLVER; + } + try { + entry = er.resolve(criteria, response); + logger.trace("resolved entry={} with resolver={}", entry, er); + } catch (LdapException e) { + logger.debug("entry resolution failed for resolver={}", er, e); + } + } + if (entry == null) { + entry = NOOP_RESOLVER.resolve(criteria, response); + logger.trace("resolved entry={} with resolver={}", entry, NOOP_RESOLVER); + } + return entry; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::dnResolver=%s, authenticationHandler=%s, entryResolver=%s, returnAttributes=%s, " + + "authenticationResponseHandlers=%s]", + getClass().getName(), + hashCode(), + getDnResolver(), + getAuthenticationHandler(), + getEntryResolver(), + Arrays.toString(getReturnAttributes()), + Arrays.toString(getAuthenticationResponseHandlers())); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/AuthorizationIdentityEntryResolver.java b/core/src/main/java/org/ldaptive/auth/AuthorizationIdentityEntryResolver.java new file mode 100644 index 0000000..77f8b90 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/AuthorizationIdentityEntryResolver.java
@@ -0,0 +1,60 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import org.ldaptive.LdapException; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.control.AuthorizationIdentityResponseControl; + +/** + * Reads the authorization identity response control, then performs an object level search on the result. Useful when + * users authenticate with some mapped identifier, like DIGEST-MD5. This resolver must be used with an {@link + * AuthenticationHandler} that is configured to send the {@link + * org.ldaptive.control.AuthorizationIdentityRequestControl}. + * + * @author Middleware Services + */ +public class AuthorizationIdentityEntryResolver extends AbstractSearchEntryResolver +{ + + + @Override + protected SearchResult performLdapSearch( + final AuthenticationCriteria criteria, + final AuthenticationHandlerResponse response) + throws LdapException + { + final AuthorizationIdentityResponseControl ctrl = (AuthorizationIdentityResponseControl) response.getControl( + AuthorizationIdentityResponseControl.OID); + if (ctrl == null) { + throw new IllegalStateException("Authorization Identity Response Control not found"); + } + logger.debug("found authorization identity response control {}", ctrl); + + final String authzId = ctrl.getAuthorizationId(); + final String dn = authzId.split(":", 2)[1].trim(); + final SearchOperation search = createSearchOperation(response.getConnection()); + return search.execute(createSearchRequest(criteria, dn)).getResult(); + } + + + /** + * Returns a search request for an object level search for the supplied DN. + * + * @param ac authentication criteria containing return attributes + * @param dn from the who am i operation + * + * @return search request + */ + protected SearchRequest createSearchRequest(final AuthenticationCriteria ac, final String dn) + { + final SearchRequest request = SearchRequest.newObjectScopeSearchRequest( + dn, + ac.getAuthenticationRequest().getReturnAttributes()); + request.setDerefAliases(getDerefAliases()); + request.setReferralHandler(getReferralHandler()); + request.setSearchEntryHandlers(getSearchEntryHandlers()); + return request; + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/BindAuthenticationHandler.java b/core/src/main/java/org/ldaptive/auth/BindAuthenticationHandler.java new file mode 100644 index 0000000..5b02d90 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/BindAuthenticationHandler.java
@@ -0,0 +1,110 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import org.ldaptive.BindRequest; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.ConnectionFactoryManager; +import org.ldaptive.LdapException; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; + +/** + * Provides an LDAP authentication implementation that leverages the LDAP bind operation. + * + * @author Middleware Services + */ +public class BindAuthenticationHandler extends AbstractBindAuthenticationHandler implements ConnectionFactoryManager +{ + + /** Connection factory. */ + private ConnectionFactory factory; + + + /** Default constructor. */ + public BindAuthenticationHandler() {} + + + /** + * Creates a new bind authentication handler. + * + * @param cf connection factory + */ + public BindAuthenticationHandler(final ConnectionFactory cf) + { + setConnectionFactory(cf); + } + + + @Override + public ConnectionFactory getConnectionFactory() + { + return factory; + } + + + @Override + public void setConnectionFactory(final ConnectionFactory cf) + { + factory = cf; + } + + + @Override + protected Connection getConnection() + throws LdapException + { + return factory.getConnection(); + } + + + @Override + protected AuthenticationHandlerResponse authenticateInternal( + final Connection c, + final AuthenticationCriteria criteria) + throws LdapException + { + AuthenticationHandlerResponse response; + final BindRequest request = new BindRequest(criteria.getDn(), criteria.getCredential()); + request.setSaslConfig(getAuthenticationSaslConfig()); + request.setControls(processRequestControls(criteria)); + try { + final Response<Void> connResponse = c.open(request); + response = new AuthenticationHandlerResponse( + ResultCode.SUCCESS == connResponse.getResultCode(), + connResponse.getResultCode(), + c, + connResponse.getMessage(), + connResponse.getControls(), + connResponse.getMessageId()); + } catch (LdapException e) { + if (e.getResultCode() != null) { + response = new AuthenticationHandlerResponse( + false, + e.getResultCode(), + c, + e.getMessage(), + e.getControls(), + e.getMessageId()); + } else { + throw e; + } + } + return response; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::factory=%s, saslConfig=%s, controls=%s]", + getClass().getName(), + hashCode(), + factory, + getAuthenticationSaslConfig(), + Arrays.toString(getAuthenticationControls())); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/CompareAuthenticationHandler.java b/core/src/main/java/org/ldaptive/auth/CompareAuthenticationHandler.java new file mode 100644 index 0000000..05d458a --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/CompareAuthenticationHandler.java
@@ -0,0 +1,76 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.ConnectionFactoryManager; +import org.ldaptive.LdapException; + +/** + * Provides an LDAP authentication implementation that leverages a compare operation against the userPassword attribute. + * The default password scheme used is 'SHA'. + * + * @author Middleware Services + */ +public class CompareAuthenticationHandler extends AbstractCompareAuthenticationHandler + implements ConnectionFactoryManager +{ + + /** Connection factory. */ + private ConnectionFactory factory; + + + /** Default constructor. */ + public CompareAuthenticationHandler() {} + + + /** + * Creates a new compare authentication handler. + * + * @param cf connection factory + */ + public CompareAuthenticationHandler(final ConnectionFactory cf) + { + setConnectionFactory(cf); + } + + + @Override + public ConnectionFactory getConnectionFactory() + { + return factory; + } + + + @Override + public void setConnectionFactory(final ConnectionFactory cf) + { + factory = cf; + } + + + @Override + protected Connection getConnection() + throws LdapException + { + final Connection conn = factory.getConnection(); + conn.open(); + return conn; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::factory=%s, passwordAttribute=%s, passwordScheme=%s, controls=%s]", + getClass().getName(), + hashCode(), + factory, + getPasswordAttribute(), + getPasswordScheme(), + Arrays.toString(getAuthenticationControls())); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/DnResolver.java b/core/src/main/java/org/ldaptive/auth/DnResolver.java new file mode 100644 index 0000000..76dda1f --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/DnResolver.java
@@ -0,0 +1,26 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import org.ldaptive.LdapException; + +/** + * Provides an interface for finding LDAP DNs with a user identifier. + * + * @author Middleware Services + */ +public interface DnResolver +{ + + + /** + * Attempts to find the LDAP DN for the supplied user. + * + * @param user to find DN for + * + * @return user DN + * + * @throws LdapException if an LDAP error occurs + */ + String resolve(User user) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/auth/EntryResolver.java b/core/src/main/java/org/ldaptive/auth/EntryResolver.java new file mode 100644 index 0000000..52819c5 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/EntryResolver.java
@@ -0,0 +1,29 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; + +/** + * Provides an interface for finding a user's ldap entry after a successful authentication. + * + * @author Middleware Services + */ +public interface EntryResolver +{ + + + /** + * Attempts to find the LDAP entry for the supplied authentication criteria and authentication handler response. The + * connection available in the response should <b>not</b> be closed in this method. + * + * @param criteria authentication criteria used to perform the authentication + * @param response produced by the authentication handler + * + * @return ldap entry + * + * @throws LdapException if an LDAP error occurs + */ + LdapEntry resolve(AuthenticationCriteria criteria, AuthenticationHandlerResponse response) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/auth/FormatDnResolver.java b/core/src/main/java/org/ldaptive/auth/FormatDnResolver.java new file mode 100644 index 0000000..af7a209 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/FormatDnResolver.java
@@ -0,0 +1,169 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Returns a DN by applying a formatter. See {@link java.util.Formatter}. + * + * @author Middleware Services + */ +public class FormatDnResolver implements DnResolver +{ + + /** log for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** format of DN. */ + private String formatString; + + /** format arguments. */ + private Object[] formatArgs; + + /** whether to escape the user input. */ + private boolean escapeUser = true; + + + /** Default constructor. */ + public FormatDnResolver() {} + + + /** + * Creates a new format DN resolver. + * + * @param format formatter string + */ + public FormatDnResolver(final String format) + { + setFormat(format); + } + + + /** + * Creates a new format DN resolver with the supplied format and arguments. + * + * @param format to set formatter string + * @param args to set formatter arguments + */ + public FormatDnResolver(final String format, final Object[] args) + { + setFormat(format); + setFormatArgs(args); + } + + + /** + * Returns the formatter string used to return the entry DN. + * + * @return user field + */ + public String getFormat() + { + return formatString; + } + + + /** + * Sets the formatter string used to return the entry DN. + * + * @param format formatter string + */ + public void setFormat(final String format) + { + formatString = format; + } + + + /** + * Returns the format arguments. + * + * @return format args + */ + public Object[] getFormatArgs() + { + return formatArgs; + } + + + /** + * Sets the format arguments. + * + * @param args to set format arguments + */ + public void setFormatArgs(final Object[] args) + { + formatArgs = args; + } + + + /** + * Returns whether the user input will be escaped. See {@link LdapAttribute#escapeValue(String)}. + * + * @return whether the user input will be escaped. + */ + public boolean getEscapeUser() + { + return escapeUser; + } + + + /** + * Sets whether the user input will be escaped. See {@link LdapAttribute#escapeValue(String)}. + * + * @param b whether the user input will be escaped. + */ + public void setEscapeUser(final boolean b) + { + escapeUser = b; + } + + + /** + * Returns a DN for the supplied user by applying it to a format string. + * + * @param user to format dn for + * + * @return user DN + * + * @throws LdapException never + */ + @Override + public String resolve(final User user) + throws LdapException + { + String dn = null; + if (user != null && user.getIdentifier() != null && !"".equals(user.getIdentifier())) { + final String escapedUser = escapeUser ? LdapAttribute.escapeValue(user.getIdentifier()) : user.getIdentifier(); + logger.debug("Formatting DN for {} with {}", escapedUser, formatString); + if (formatArgs != null && formatArgs.length > 0) { + final Object[] args = new Object[formatArgs.length + 1]; + args[0] = escapedUser; + System.arraycopy(formatArgs, 0, args, 1, formatArgs.length); + dn = String.format(formatString, args); + } else { + dn = String.format(formatString, escapedUser); + } + } else { + logger.debug("User input was empty or null"); + } + return dn; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::formatString=%s, formatArgs=%s, escapeUser=%s]", + getClass().getName(), + hashCode(), + formatString, + Arrays.toString(formatArgs), + escapeUser); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/NoOpDnResolver.java b/core/src/main/java/org/ldaptive/auth/NoOpDnResolver.java new file mode 100644 index 0000000..f0286a6 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/NoOpDnResolver.java
@@ -0,0 +1,37 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import org.ldaptive.LdapException; + +/** + * Returns a DN that is the user identifier. + * + * @author Middleware Services + */ +public class NoOpDnResolver implements DnResolver +{ + + + /** + * Returns the user as the DN. + * + * @param user to set as DN + * + * @return user as DN + * + * @throws LdapException never + */ + @Override + public String resolve(final User user) + throws LdapException + { + return user != null ? user.getIdentifier() : null; + } + + + @Override + public String toString() + { + return String.format("[%s@%d]", getClass().getName(), hashCode()); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/NoOpEntryResolver.java b/core/src/main/java/org/ldaptive/auth/NoOpEntryResolver.java new file mode 100644 index 0000000..b22a679 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/NoOpEntryResolver.java
@@ -0,0 +1,29 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; + +/** + * Returns an LDAP entry that contains only the DN that was supplied to it. + * + * @author Middleware Services + */ +public class NoOpEntryResolver implements EntryResolver +{ + + + @Override + public LdapEntry resolve(final AuthenticationCriteria criteria, final AuthenticationHandlerResponse response) + throws LdapException + { + return new LdapEntry(criteria.getDn()); + } + + + @Override + public String toString() + { + return String.format("[%s@%d]", getClass().getName(), hashCode()); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/PooledBindAuthenticationHandler.java b/core/src/main/java/org/ldaptive/auth/PooledBindAuthenticationHandler.java new file mode 100644 index 0000000..ffad47c --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/PooledBindAuthenticationHandler.java
@@ -0,0 +1,115 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import org.ldaptive.BindOperation; +import org.ldaptive.BindRequest; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.pool.PooledConnectionFactoryManager; + +/** + * Provides an LDAP authentication implementation that leverages a pool of LDAP connections to perform the LDAP bind + * operation. + * + * @author Middleware Services + */ +public class PooledBindAuthenticationHandler extends AbstractBindAuthenticationHandler + implements PooledConnectionFactoryManager +{ + + /** Connection factory. */ + private PooledConnectionFactory factory; + + + /** Default constructor. */ + public PooledBindAuthenticationHandler() {} + + + /** + * Creates a new pooled bind authentication handler. + * + * @param cf connection factory + */ + public PooledBindAuthenticationHandler(final PooledConnectionFactory cf) + { + setConnectionFactory(cf); + } + + + @Override + public PooledConnectionFactory getConnectionFactory() + { + return factory; + } + + + @Override + public void setConnectionFactory(final PooledConnectionFactory cf) + { + factory = cf; + } + + + @Override + protected Connection getConnection() + throws LdapException + { + return factory.getConnection(); + } + + + @Override + protected AuthenticationHandlerResponse authenticateInternal( + final Connection c, + final AuthenticationCriteria criteria) + throws LdapException + { + AuthenticationHandlerResponse response; + final BindRequest request = new BindRequest(criteria.getDn(), criteria.getCredential()); + request.setSaslConfig(getAuthenticationSaslConfig()); + request.setControls(processRequestControls(criteria)); + + final BindOperation op = new BindOperation(c); + try { + final Response<Void> bindResponse = op.execute(request); + response = new AuthenticationHandlerResponse( + ResultCode.SUCCESS == bindResponse.getResultCode(), + bindResponse.getResultCode(), + c, + bindResponse.getMessage(), + bindResponse.getControls(), + bindResponse.getMessageId()); + } catch (LdapException e) { + if (e.getResultCode() != null) { + response = new AuthenticationHandlerResponse( + false, + e.getResultCode(), + c, + e.getMessage(), + e.getControls(), + e.getMessageId()); + } else { + throw e; + } + } + return response; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::factory=%s, saslConfig=%s, controls=%s]", + getClass().getName(), + hashCode(), + factory, + getAuthenticationSaslConfig(), + Arrays.toString(getAuthenticationControls())); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/PooledCompareAuthenticationHandler.java b/core/src/main/java/org/ldaptive/auth/PooledCompareAuthenticationHandler.java new file mode 100644 index 0000000..1169687 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/PooledCompareAuthenticationHandler.java
@@ -0,0 +1,74 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.pool.PooledConnectionFactoryManager; + +/** + * Provides an LDAP authentication implementation that leverages a pool of ldap connections to perform the compare + * operation against the userPassword attribute. The default password scheme used is 'SHA'. + * + * @author Middleware Services + */ +public class PooledCompareAuthenticationHandler extends AbstractCompareAuthenticationHandler + implements PooledConnectionFactoryManager +{ + + /** Connection factory. */ + private PooledConnectionFactory factory; + + + /** Default constructor. */ + public PooledCompareAuthenticationHandler() {} + + + /** + * Creates a new pooled compare authentication handler. + * + * @param cf connection factory + */ + public PooledCompareAuthenticationHandler(final PooledConnectionFactory cf) + { + setConnectionFactory(cf); + } + + + @Override + public PooledConnectionFactory getConnectionFactory() + { + return factory; + } + + + @Override + public void setConnectionFactory(final PooledConnectionFactory cf) + { + factory = cf; + } + + + @Override + protected Connection getConnection() + throws LdapException + { + return factory.getConnection(); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::factory=%s, passwordAttribute=%s, passwordScheme=%s, controls=%s]", + getClass().getName(), + hashCode(), + factory, + getPasswordAttribute(), + getPasswordScheme(), + Arrays.toString(getAuthenticationControls())); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/PooledSearchDnResolver.java b/core/src/main/java/org/ldaptive/auth/PooledSearchDnResolver.java new file mode 100644 index 0000000..e701b15 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/PooledSearchDnResolver.java
@@ -0,0 +1,78 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.pool.PooledConnectionFactoryManager; + +/** + * Looks up a user's DN using a pool of connections. + * + * @author Middleware Services + */ +public class PooledSearchDnResolver extends AbstractSearchDnResolver implements PooledConnectionFactoryManager +{ + + /** Connection factory. */ + private PooledConnectionFactory factory; + + + /** Default constructor. */ + public PooledSearchDnResolver() {} + + + /** + * Creates a new pooled search dn resolver. + * + * @param cf connection factory + */ + public PooledSearchDnResolver(final PooledConnectionFactory cf) + { + setConnectionFactory(cf); + } + + + @Override + public PooledConnectionFactory getConnectionFactory() + { + return factory; + } + + + @Override + public void setConnectionFactory(final PooledConnectionFactory cf) + { + factory = cf; + } + + + @Override + protected Connection getConnection() + throws LdapException + { + return factory.getConnection(); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::factory=%s, baseDn=%s, userFilter=%s, " + + "userFilterParameters=%s, allowMultipleDns=%s, subtreeSearch=%s, " + + "derefAliases=%s, referralHandler=%s]", + getClass().getName(), + hashCode(), + factory, + getBaseDn(), + getUserFilter(), + Arrays.toString(getUserFilterParameters()), + getAllowMultipleDns(), + getSubtreeSearch(), + getDerefAliases(), + getReferralHandler()); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/PooledSearchEntryResolver.java b/core/src/main/java/org/ldaptive/auth/PooledSearchEntryResolver.java new file mode 100644 index 0000000..a553563 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/PooledSearchEntryResolver.java
@@ -0,0 +1,88 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchResult; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.pool.PooledConnectionFactoryManager; + +/** + * Looks up the LDAP entry associated with a user using a pool of LDAP connections. Resolution will not occur using the + * connection that the user attempted to bind on. + * + * @author Middleware Services + */ +public class PooledSearchEntryResolver extends AbstractSearchEntryResolver implements PooledConnectionFactoryManager +{ + + /** Connection factory. */ + private PooledConnectionFactory factory; + + + /** Default constructor. */ + public PooledSearchEntryResolver() {} + + + /** + * Creates a new pooled search entry resolver. + * + * @param cf connection factory + */ + public PooledSearchEntryResolver(final PooledConnectionFactory cf) + { + setConnectionFactory(cf); + } + + + @Override + public PooledConnectionFactory getConnectionFactory() + { + return factory; + } + + + @Override + public void setConnectionFactory(final PooledConnectionFactory cf) + { + factory = cf; + } + + + @Override + protected SearchResult performLdapSearch( + final AuthenticationCriteria criteria, + final AuthenticationHandlerResponse response) + throws LdapException + { + try (Connection pooledConn = factory.getConnection()) { + final SearchOperation op = createSearchOperation(pooledConn); + return op.execute(createSearchRequest(criteria)).getResult(); + } + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::factory=%s, baseDn=%s, userFilter=%s, " + + "userFilterParameters=%s, allowMultipleEntries=%s, " + + "subtreeSearch=%s, derefAliases=%s, referralHandler=%s, " + + "searchEntryHandlers=%s]", + getClass().getName(), + hashCode(), + factory, + getBaseDn(), + getUserFilter(), + Arrays.toString(getUserFilterParameters()), + getAllowMultipleEntries(), + getSubtreeSearch(), + getDerefAliases(), + getReferralHandler(), + Arrays.toString(getSearchEntryHandlers())); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/SearchDnResolver.java b/core/src/main/java/org/ldaptive/auth/SearchDnResolver.java new file mode 100644 index 0000000..24b085b --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/SearchDnResolver.java
@@ -0,0 +1,80 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.ConnectionFactoryManager; +import org.ldaptive.LdapException; + +/** + * Looks up a user's DN using an LDAP search. + * + * @author Middleware Services + */ +public class SearchDnResolver extends AbstractSearchDnResolver implements ConnectionFactoryManager +{ + + /** Connection factory. */ + private ConnectionFactory factory; + + + /** Default constructor. */ + public SearchDnResolver() {} + + + /** + * Creates a new search dn resolver. + * + * @param cf connection factory + */ + public SearchDnResolver(final ConnectionFactory cf) + { + setConnectionFactory(cf); + } + + + @Override + public ConnectionFactory getConnectionFactory() + { + return factory; + } + + + @Override + public void setConnectionFactory(final ConnectionFactory cf) + { + factory = cf; + } + + + @Override + protected Connection getConnection() + throws LdapException + { + final Connection conn = factory.getConnection(); + conn.open(); + return conn; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::factory=%s, baseDn=%s, userFilter=%s, " + + "userFilterParameters=%s, allowMultipleDns=%s, subtreeSearch=%s, " + + "derefAliases=%s, referralHandler=%s]", + getClass().getName(), + hashCode(), + factory, + getBaseDn(), + getUserFilter(), + Arrays.toString(getUserFilterParameters()), + getAllowMultipleDns(), + getSubtreeSearch(), + getDerefAliases(), + getReferralHandler()); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/SearchEntryResolver.java b/core/src/main/java/org/ldaptive/auth/SearchEntryResolver.java new file mode 100644 index 0000000..bd795fb --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/SearchEntryResolver.java
@@ -0,0 +1,96 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.Arrays; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.ConnectionFactoryManager; +import org.ldaptive.LdapException; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchResult; + +/** + * Looks up the LDAP entry associated with a user. If a connection factory is configured it will be used to perform the + * search for user. The connection will be opened and closed for each resolution. If no connection factory is configured + * the search will occur using the connection that the bind was attempted on. + * + * @author Middleware Services + */ +public class SearchEntryResolver extends AbstractSearchEntryResolver implements ConnectionFactoryManager +{ + + /** Connection factory. */ + private ConnectionFactory factory; + + + /** Default constructor. */ + public SearchEntryResolver() {} + + + /** + * Creates a new search entry resolver. + * + * @param cf connection factory + */ + public SearchEntryResolver(final ConnectionFactory cf) + { + setConnectionFactory(cf); + } + + + @Override + public ConnectionFactory getConnectionFactory() + { + return factory; + } + + + @Override + public void setConnectionFactory(final ConnectionFactory cf) + { + factory = cf; + } + + + @Override + public SearchResult performLdapSearch( + final AuthenticationCriteria criteria, + final AuthenticationHandlerResponse response) + throws LdapException + { + if (factory == null) { + final SearchOperation op = createSearchOperation(response.getConnection()); + return op.execute(createSearchRequest(criteria)).getResult(); + } else { + try (Connection factoryConn = factory.getConnection()) { + factoryConn.open(); + + final SearchOperation op = createSearchOperation(factoryConn); + return op.execute(createSearchRequest(criteria)).getResult(); + } + } + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::factory=%s, baseDn=%s, userFilter=%s, " + + "userFilterParameters=%s, allowMultipleEntries=%s, " + + "subtreeSearch=%s, derefAliases=%s, referralHandler=%s, " + + "searchEntryHandlers=%s]", + getClass().getName(), + hashCode(), + factory, + getBaseDn(), + getUserFilter(), + Arrays.toString(getUserFilterParameters()), + getAllowMultipleEntries(), + getSubtreeSearch(), + getDerefAliases(), + getReferralHandler(), + Arrays.toString(getSearchEntryHandlers())); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/User.java b/core/src/main/java/org/ldaptive/auth/User.java new file mode 100644 index 0000000..6f13308 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/User.java
@@ -0,0 +1,70 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +/** + * Encapsulates the data needed to perform authentication for a user. + * + * @author Middleware Services + */ +public class User +{ + + /** User identifier. */ + private final String identifier; + + /** User context. */ + private final Object context; + + + /** + * Creates a new user. + * + * @param id user identifier + */ + public User(final String id) + { + this(id, null); + } + + + /** + * Creates a new user. + * + * @param id user identifier + * @param ctx user context + */ + public User(final String id, final Object ctx) + { + identifier = id; + context = ctx; + } + + + /** + * Returns the user identifier. + * + * @return user identifier + */ + public String getIdentifier() + { + return identifier; + } + + + /** + * Returns the user context. + * + * @return user context + */ + public Object getContext() + { + return context; + } + + + @Override + public String toString() + { + return String.format("[%s@%d::identifier=%s, context=%s]", getClass().getName(), hashCode(), identifier, context); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/WhoAmIEntryResolver.java b/core/src/main/java/org/ldaptive/auth/WhoAmIEntryResolver.java new file mode 100644 index 0000000..e9e8e6c --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/WhoAmIEntryResolver.java
@@ -0,0 +1,61 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import org.ldaptive.LdapException; +import org.ldaptive.Response; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.extended.WhoAmIOperation; +import org.ldaptive.extended.WhoAmIRequest; + +/** + * Executes the {@link WhoAmIOperation} on the authenticated connection, then performs an object level search on the + * result. Useful when users authenticate with some mapped identifier, like DIGEST-MD5. + * + * @author Middleware Services + */ +public class WhoAmIEntryResolver extends AbstractSearchEntryResolver +{ + + + @Override + protected SearchResult performLdapSearch( + final AuthenticationCriteria criteria, + final AuthenticationHandlerResponse response) + throws LdapException + { + final WhoAmIOperation whoami = new WhoAmIOperation(response.getConnection()); + final Response<String> res = whoami.execute(new WhoAmIRequest()); + logger.debug("whoami operation returned {}", res); + + final String authzId = res.getResult(); + if (authzId == null || !authzId.contains(":")) { + throw new IllegalStateException("WhoAmI operation returned illegal authorization ID: '" + authzId + "'"); + } + + final String dn = authzId.split(":", 2)[1].trim(); + final SearchOperation search = createSearchOperation(response.getConnection()); + return search.execute(createSearchRequest(criteria, dn)).getResult(); + } + + + /** + * Returns a search request for an object level search for the supplied DN. + * + * @param ac authentication criteria containing return attributes + * @param dn from the who am i operation + * + * @return search request + */ + protected SearchRequest createSearchRequest(final AuthenticationCriteria ac, final String dn) + { + final SearchRequest request = SearchRequest.newObjectScopeSearchRequest( + dn, + ac.getAuthenticationRequest().getReturnAttributes()); + request.setDerefAliases(getDerefAliases()); + request.setReferralHandler(getReferralHandler()); + request.setSearchEntryHandlers(getSearchEntryHandlers()); + return request; + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/ext/ActiveDirectoryAccountState.java b/core/src/main/java/org/ldaptive/auth/ext/ActiveDirectoryAccountState.java new file mode 100644 index 0000000..4434af4 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/ext/ActiveDirectoryAccountState.java
@@ -0,0 +1,215 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth.ext; + +import java.time.ZonedDateTime; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.security.auth.login.AccountException; +import javax.security.auth.login.AccountExpiredException; +import javax.security.auth.login.AccountLockedException; +import javax.security.auth.login.AccountNotFoundException; +import javax.security.auth.login.CredentialExpiredException; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginException; +import org.ldaptive.auth.AccountState; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Represents the state of an Active Directory account. Note that the warning returned by this implementation always + * returns -1 for logins remaining. + * + * @author Middleware Services + */ +public class ActiveDirectoryAccountState extends AccountState +{ + + + /** + * Enum to define active directory errors. See http://ldapwiki.willeke.com/wiki/ + * Common%20Active%20Directory%20Bind%20Errors + */ + public enum Error implements AccountState.Error { + + /** no such user. 0x525. */ + NO_SUCH_USER(1317), + + /** logon failure. 0x52e. */ + LOGON_FAILURE(1326), + + /** invalid logon hours. 0x530. */ + INVALID_LOGON_HOURS(1328), + + /** invalid workstation. 0x531. */ + INVALID_WORKSTATION(1329), + + /** password expired. 0x532. */ + PASSWORD_EXPIRED(1330), + + /** account disabled. 0x533. */ + ACCOUNT_DISABLED(1331), + + /** account expired. 0x701. */ + ACCOUNT_EXPIRED(1793), + + /** password must change. 0x773. */ + PASSWORD_MUST_CHANGE(1907), + + /** account locked out. 0x775. */ + ACCOUNT_LOCKED_OUT(1909); + + /** hex radix for hex to decimal conversion. */ + private static final int HEX_RADIX = 16; + + /** pattern to find hex code in active directory messages. */ + private static final Pattern PATTERN = Pattern.compile("data (\\w+)"); + + /** underlying error code. */ + private final int code; + + + /** + * Creates a new active directory error. + * + * @param i error code + */ + Error(final int i) + { + code = i; + } + + + @Override + public int getCode() + { + return code; + } + + + @Override + public String getMessage() + { + return name(); + } + + + @Override + public void throwSecurityException() + throws LoginException + { + switch (this) { + + case NO_SUCH_USER: + throw new AccountNotFoundException(name()); + + case LOGON_FAILURE: + throw new FailedLoginException(name()); + + case INVALID_LOGON_HOURS: + throw new AccountLockedException(name()); + + case INVALID_WORKSTATION: + throw new AccountException(name()); + + case PASSWORD_EXPIRED: + throw new CredentialExpiredException(name()); + + case ACCOUNT_DISABLED: + throw new AccountLockedException(name()); + + case ACCOUNT_EXPIRED: + throw new AccountExpiredException(name()); + + case PASSWORD_MUST_CHANGE: + throw new CredentialExpiredException(name()); + + case ACCOUNT_LOCKED_OUT: + throw new AccountLockedException(name()); + + default: + throw new IllegalStateException("Unknown active directory error: " + this); + } + } + + + /** + * Returns the error for the supplied integer constant. + * + * @param code to find error for + * + * @return error + */ + public static Error valueOf(final int code) + { + for (Error e : Error.values()) { + if (e.getCode() == code) { + return e; + } + } + return null; + } + + + /** + * Parses the supplied error messages and returns the corresponding error enum. Attempts to find {@link #PATTERN} + * and parses the first group match as a hexadecimal integer. + * + * @param message to parse + * + * @return active directory error + */ + public static Error parse(final String message) + { + if (message != null) { + final Matcher matcher = PATTERN.matcher(message); + if (matcher.find()) { + try { + return Error.valueOf(Integer.parseInt(matcher.group(1).toUpperCase(), HEX_RADIX)); + } catch (NumberFormatException e) { + final Logger l = LoggerFactory.getLogger(Error.class); + l.warn("Error parsing active directory error", e); + } + } + } + return null; + } + } + + /** active directory specific enum. */ + private final Error adError; + + + /** + * Creates a new active directory account state. + * + * @param exp account expiration + */ + public ActiveDirectoryAccountState(final ZonedDateTime exp) + { + super(new AccountState.DefaultWarning(exp, -1)); + adError = null; + } + + + /** + * Creates a new active directory account state. + * + * @param error containing authentication failure details + */ + public ActiveDirectoryAccountState(final ActiveDirectoryAccountState.Error error) + { + super(error); + adError = error; + } + + + /** + * Returns the active directory error for this account state. + * + * @return active directory error + */ + public ActiveDirectoryAccountState.Error getActiveDirectoryError() + { + return adError; + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/ext/ActiveDirectoryAuthenticationResponseHandler.java b/core/src/main/java/org/ldaptive/auth/ext/ActiveDirectoryAuthenticationResponseHandler.java new file mode 100644 index 0000000..d80ad9e --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/ext/ActiveDirectoryAuthenticationResponseHandler.java
@@ -0,0 +1,156 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth.ext; + +import java.time.Period; +import java.time.ZonedDateTime; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.ad.io.FileTimeValueTranscoder; +import org.ldaptive.auth.AuthenticationResponse; +import org.ldaptive.auth.AuthenticationResponseHandler; + +/** + * Attempts to parse the authentication response message and set the account state using data associated with active + * directory. If this handler is assigned a {@link #expirationPeriod}, then the {@link org.ldaptive.auth.Authenticator} + * should be configured to return the 'pwdLastSet' attribute so it can be consumed by this handler. This will cause the + * handler to emit a warning for the pwdLastSet value plus the expiration amount. The scope of that warning can be + * further narrowed by providing a {@link #warningPeriod}. By default if the msDS-UserPasswordExpiryTimeComputed + * attribute is found, expirationPeriod is ignored. + * + * @author Middleware Services + */ +public class ActiveDirectoryAuthenticationResponseHandler implements AuthenticationResponseHandler +{ + + /** Attributes needed to enforce password policy. */ + public static final String[] ATTRIBUTES = new String[] {"msDS-UserPasswordExpiryTimeComputed", "pwdLastSet", }; + + /** Amount of time since a password was set until it will expire. Used if msDS-UserPasswordExpiryTimeComputed cannot + * be read. */ + private Period expirationPeriod; + + /** Amount of time before expiration to produce a warning. */ + private Period warningPeriod; + + + /** Default constructor. */ + public ActiveDirectoryAuthenticationResponseHandler() {} + + + /** + * Creates a new active directory authentication response handler. + * + * @param warning length of time before expiration that should produce a warning + */ + public ActiveDirectoryAuthenticationResponseHandler(final Period warning) + { + setWarningPeriod(warning); + } + + + /** + * Creates a new active directory authentication response handler. + * + * @param expiration length of time that a password is valid + * @param warning length of time before expiration that should produce a warning + */ + public ActiveDirectoryAuthenticationResponseHandler(final Period expiration, final Period warning) + { + setExpirationPeriod(expiration); + setWarningPeriod(warning); + } + + + @Override + public void handle(final AuthenticationResponse response) + { + if (response.getResult()) { + final LdapEntry entry = response.getLdapEntry(); + final LdapAttribute expTime = entry.getAttribute("msDS-UserPasswordExpiryTimeComputed"); + final LdapAttribute pwdLastSet = entry.getAttribute("pwdLastSet"); + + ZonedDateTime exp = null; + // ignore expTime if account is set to never expire + if (expTime != null && !"9223372036854775807".equals(expTime.getStringValue())) { + exp = expTime.getValue(new FileTimeValueTranscoder()); + } else if (expirationPeriod != null && pwdLastSet != null) { + exp = pwdLastSet.getValue(new FileTimeValueTranscoder()).plus(expirationPeriod); + } + + if (exp != null) { + if (warningPeriod != null) { + final ZonedDateTime warn = exp.minus(warningPeriod); + if (ZonedDateTime.now().isAfter(warn)) { + response.setAccountState(new ActiveDirectoryAccountState(exp)); + } + } else { + response.setAccountState(new ActiveDirectoryAccountState(exp)); + } + } + } else { + if (response.getMessage() != null) { + final ActiveDirectoryAccountState.Error adError = ActiveDirectoryAccountState.Error.parse( + response.getMessage()); + if (adError != null) { + response.setAccountState(new ActiveDirectoryAccountState(adError)); + } + } + } + } + + + /** + * Returns the amount of time since a password was set until it will expire. + * + * @return expiration period + */ + public Period getExpirationPeriod() + { + return expirationPeriod; + } + + + /** + * Sets amount of time since a password was set until it will expire. + * + * @param period expiration period + */ + public void setExpirationPeriod(final Period period) + { + expirationPeriod = period; + } + + + /** + * Returns the amount of time before expiration to produce a warning. + * + * @return warning period + */ + public Period getWarningPeriod() + { + return warningPeriod; + } + + + /** + * Sets the amount of time before expiration to produce a warning. + * + * @param period warning period + */ + public void setWarningPeriod(final Period period) + { + warningPeriod = period; + } + + + @Override + public String toString() + { + return String.format( + "[%s@%d::expirationPeriod=%s, warningPeriod=%s]", + getClass().getName(), + hashCode(), + expirationPeriod, + warningPeriod); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/ext/EDirectoryAccountState.java b/core/src/main/java/org/ldaptive/auth/ext/EDirectoryAccountState.java new file mode 100644 index 0000000..3b9e088 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/ext/EDirectoryAccountState.java
@@ -0,0 +1,198 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth.ext; + +import java.time.ZonedDateTime; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.security.auth.login.AccountExpiredException; +import javax.security.auth.login.AccountLockedException; +import javax.security.auth.login.CredentialExpiredException; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginException; +import org.ldaptive.auth.AccountState; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Represents the state of an eDirectory account. + * + * @author Middleware Services + */ +public class EDirectoryAccountState extends AccountState +{ + + + /** + * Enum to define edirectory errors. See http://support.novell.com/docs/Tids/Solutions/10067240.html and + * http://www.novell.com/documentation/nwec/nwec_enu/nwec_nds_error_codes.html + */ + public enum Error implements AccountState.Error { + + /** failed authentication. */ + FAILED_AUTHENTICATION(-669), + + /** password expired. binds still succeed. */ + PASSWORD_EXPIRED(-223), + + /** bad password. */ + BAD_PASSWORD(-222), + + /** account expired. */ + ACCOUNT_EXPIRED(-220), + + /** maximum logins exceeded. */ + MAXIMUM_LOGINS_EXCEEDED(-217), + + /** login time limited. */ + LOGIN_TIME_LIMITED(-218), + + /** login lockout. */ + LOGIN_LOCKOUT(-197); + + /** pattern to find decimal code in edirectory messages. */ + private static final Pattern PATTERN = Pattern.compile("NDS error: (.+) \\((-\\d+)\\)"); + + /** underlying error code. */ + private final int code; + + + /** + * Creates a new edirectory error. + * + * @param i error code + */ + Error(final int i) + { + code = i; + } + + + @Override + public int getCode() + { + return code; + } + + + @Override + public String getMessage() + { + return name(); + } + + + @Override + public void throwSecurityException() + throws LoginException + { + switch (this) { + + case FAILED_AUTHENTICATION: + throw new FailedLoginException(name()); + + case PASSWORD_EXPIRED: + throw new CredentialExpiredException(name()); + + case BAD_PASSWORD: + throw new FailedLoginException(name()); + + case ACCOUNT_EXPIRED: + throw new AccountExpiredException(name()); + + case MAXIMUM_LOGINS_EXCEEDED: + throw new AccountLockedException(name()); + + case LOGIN_TIME_LIMITED: + throw new AccountLockedException(name()); + + case LOGIN_LOCKOUT: + throw new AccountLockedException(name()); + + default: + throw new IllegalStateException("Unknown edirectory error: " + this); + } + } + + + /** + * Returns the error for the supplied integer constant. + * + * @param code to find error for + * + * @return error + */ + public static Error valueOf(final int code) + { + for (Error e : Error.values()) { + if (e.getCode() == code) { + return e; + } + } + return null; + } + + + /** + * Parses the supplied error messages and returns the corresponding error enum. Attempts to find {@link #PATTERN} + * and parses the second group match as a decimal integer. + * + * @param message to parse + * + * @return edirectory error + */ + public static Error parse(final String message) + { + if (message != null) { + final Matcher matcher = PATTERN.matcher(message); + if (matcher.find()) { + try { + return Error.valueOf(Integer.parseInt(matcher.group(2))); + } catch (NumberFormatException e) { + final Logger l = LoggerFactory.getLogger(Error.class); + l.warn("Error parsing edirectory error", e); + } + } + } + return null; + } + } + + /** edirectory specific enum. */ + private final Error edError; + + + /** + * Creates a new edirectory account state. + * + * @param exp account expiration + * @param remaining number of logins available + */ + public EDirectoryAccountState(final ZonedDateTime exp, final int remaining) + { + super(new AccountState.DefaultWarning(exp, remaining)); + edError = null; + } + + + /** + * Creates a new edirectory account state. + * + * @param error containing authentication failure details + */ + public EDirectoryAccountState(final EDirectoryAccountState.Error error) + { + super(error); + edError = error; + } + + + /** + * Returns the edirectory error for this account state. + * + * @return edirectory error + */ + public EDirectoryAccountState.Error getEDirectoryError() + { + return edError; + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/ext/EDirectoryAuthenticationResponseHandler.java b/core/src/main/java/org/ldaptive/auth/ext/EDirectoryAuthenticationResponseHandler.java new file mode 100644 index 0000000..8009ee1 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/ext/EDirectoryAuthenticationResponseHandler.java
@@ -0,0 +1,104 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth.ext; + +import java.time.Period; +import java.time.ZonedDateTime; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.auth.AuthenticationResponse; +import org.ldaptive.auth.AuthenticationResponseHandler; +import org.ldaptive.io.GeneralizedTimeValueTranscoder; + +/** + * Attempts to parse the authentication response and set the account state using data associated with eDirectory. The + * {@link org.ldaptive.auth.Authenticator} should be configured to return 'passwordExpirationTime' and + * 'loginGraceRemaining' attributes so they can be consumed by this handler. If this handler is assigned a {@link + * #warningPeriod}, this handler will only emit warnings during that window before password expiration. Otherwise, + * a warning is always emitted if passwordExpirationTime is set. + * + * @author Middleware Services + */ +public class EDirectoryAuthenticationResponseHandler implements AuthenticationResponseHandler +{ + + /** Attributes needed to enforce password policy. */ + public static final String[] ATTRIBUTES = new String[] {"passwordExpirationTime", "loginGraceRemaining", }; + + /** Amount of time before expiration to produce a warning. */ + private Period warningPeriod; + + + /** Default constructor. */ + public EDirectoryAuthenticationResponseHandler() {} + + + /** + * Creates a new edirectory authentication response handler. + * + * @param warning length of time before expiration that should produce a warning + */ + public EDirectoryAuthenticationResponseHandler(final Period warning) + { + setWarningPeriod(warning); + } + + + @Override + public void handle(final AuthenticationResponse response) + { + if (response.getMessage() != null) { + final EDirectoryAccountState.Error edError = EDirectoryAccountState.Error.parse(response.getMessage()); + if (edError != null) { + response.setAccountState(new EDirectoryAccountState(edError)); + } + } else if (response.getResult()) { + final LdapEntry entry = response.getLdapEntry(); + final LdapAttribute expTime = entry.getAttribute("passwordExpirationTime"); + final LdapAttribute loginRemaining = entry.getAttribute("loginGraceRemaining"); + final int loginRemainingValue = loginRemaining != null ? Integer.parseInt(loginRemaining.getStringValue()) : 0; + + if (expTime != null) { + final ZonedDateTime exp = expTime.getValue(new GeneralizedTimeValueTranscoder()); + if (warningPeriod != null) { + final ZonedDateTime warn = exp.minus(warningPeriod); + if (ZonedDateTime.now().isAfter(warn)) { + response.setAccountState(new EDirectoryAccountState(exp, loginRemainingValue)); + } + } else { + response.setAccountState(new EDirectoryAccountState(exp, loginRemainingValue)); + } + } else if (loginRemaining != null) { + response.setAccountState(new EDirectoryAccountState(null, loginRemainingValue)); + } + } + } + + + /** + * Returns the amount of time before expiration to produce a warning. + * + * @return warning period + */ + public Period getWarningPeriod() + { + return warningPeriod; + } + + + /** + * Sets the amount of time before expiration to produce a warning. + * + * @param period warning period + */ + public void setWarningPeriod(final Period period) + { + warningPeriod = period; + } + + + @Override + public String toString() + { + return String.format("[%s@%d::warningPeriod=%s]", getClass().getName(), hashCode(), warningPeriod); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/ext/FreeIPAAccountState.java b/core/src/main/java/org/ldaptive/auth/ext/FreeIPAAccountState.java new file mode 100644 index 0000000..98b5113 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/ext/FreeIPAAccountState.java
@@ -0,0 +1,221 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth.ext; + +import java.time.ZonedDateTime; +import javax.security.auth.login.AccountExpiredException; +import javax.security.auth.login.AccountLockedException; +import javax.security.auth.login.AccountNotFoundException; +import javax.security.auth.login.CredentialExpiredException; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginException; +import org.ldaptive.ResultCode; +import org.ldaptive.auth.AccountState; + +/** + * Represents the state of a FreeIPA account. + * + * @author tduehr + */ +public class FreeIPAAccountState extends AccountState +{ + + + /** + * Enum to define FreeIPA errors. + */ + public enum Error implements AccountState.Error { + + /** unknown state. */ + UNKNOWN(-1), + + /** failed authentication. */ + FAILED_AUTHENTICATION(1), + + /** password expired. */ + PASSWORD_EXPIRED(2), + + /** account expired. */ + ACCOUNT_EXPIRED(3), + + /** maximum logins exceeded. */ + MAXIMUM_LOGINS_EXCEEDED(4), + + /** login time limited. */ + LOGIN_TIME_LIMITED(5), + + /** login lockout. */ + LOGIN_LOCKOUT(6), + + /** account not found. */ + ACCOUNT_NOT_FOUND(7), + + /** credential not found. */ + CREDENTIAL_NOT_FOUND(8), + + /** account disabled. */ + ACCOUNT_DISABLED(9); + + /** underlying error code. */ + private final int code; + + + /** + * Creates a new freeipa error. + * + * @param i error code + */ + Error(final int i) + { + code = i; + } + + + @Override + public int getCode() + { + return code; + } + + + @Override + public String getMessage() + { + return name(); + } + + + @Override + public void throwSecurityException() + throws LoginException + { + switch (this) { + + case ACCOUNT_NOT_FOUND: + throw new AccountNotFoundException(name()); + + case FAILED_AUTHENTICATION: + throw new FailedLoginException(name()); + + case ACCOUNT_DISABLED: + throw new FailedLoginException(name()); + + case PASSWORD_EXPIRED: + throw new CredentialExpiredException(name()); + + case CREDENTIAL_NOT_FOUND: + throw new FailedLoginException(name()); + + case ACCOUNT_EXPIRED: + throw new AccountExpiredException(name()); + + case MAXIMUM_LOGINS_EXCEEDED: + throw new AccountLockedException(name()); + + case LOGIN_TIME_LIMITED: + throw new AccountLockedException(name()); + + case LOGIN_LOCKOUT: + throw new AccountLockedException(name()); + + case UNKNOWN: + throw new FailedLoginException(name()); + + default: + throw new IllegalStateException("Unknown FreeIPA error: " + this); + } + } + + + /** + * Returns the error for the supplied integer constant. + * + * @param code to find error for + * + * @return error + */ + public static Error valueOf(final int code) + { + for (Error e : Error.values()) { + if (e.getCode() == code) { + return e; + } + } + return ResultCode.valueOf(code) == ResultCode.SUCCESS ? null : UNKNOWN; + } + + + /** + * Parses the supplied error messages and returns the corresponding error enum. + * + * @param rc result code + * @param message to parse + * + * @return freeipa error + */ + public static Error parse(final ResultCode rc, final String message) + { + Error error = null; + if (rc != null && rc != ResultCode.SUCCESS) { + if (rc == ResultCode.NO_SUCH_OBJECT) { + error = ACCOUNT_NOT_FOUND; + } else if (rc == ResultCode.INVALID_CREDENTIALS) { + error = CREDENTIAL_NOT_FOUND; + } else if (rc == ResultCode.INSUFFICIENT_ACCESS_RIGHTS) { + error = FAILED_AUTHENTICATION; + } else if (rc == ResultCode.UNWILLING_TO_PERFORM) { + if ("Entry permanently locked.\n".equals(message)) { + error = LOGIN_LOCKOUT; + } else if ("Too many failed logins.\n".equals(message)) { + error = MAXIMUM_LOGINS_EXCEEDED; + } else if ("Account (Kerberos principal) is expired".equals(message)) { + error = ACCOUNT_EXPIRED; + } else if ("Account inactivated. Contact system administrator.".equals(message)) { + error = ACCOUNT_DISABLED; + } + } else { + error = UNKNOWN; + } + } + return error; + } + } + + /** freeipa specific enum. */ + private final Error fError; + + + /** + * Creates a new freeipa account state. + * + * @param exp account expiration + * @param remaining number of logins available + */ + public FreeIPAAccountState(final ZonedDateTime exp, final int remaining) + { + super(new AccountState.DefaultWarning(exp, remaining)); + fError = null; + } + + + /** + * Creates a new freeipa account state. + * + * @param error containing authentication failure details + */ + public FreeIPAAccountState(final FreeIPAAccountState.Error error) + { + super(error); + fError = error; + } + + + /** + * Returns the freeipa error for this account state. + * + * @return freeipa error + */ + public FreeIPAAccountState.Error getFreeIPAError() + { + return fError; + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/ext/FreeIPAAuthenticationResponseHandler.java b/core/src/main/java/org/ldaptive/auth/ext/FreeIPAAuthenticationResponseHandler.java new file mode 100644 index 0000000..1eca6c0 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/ext/FreeIPAAuthenticationResponseHandler.java
@@ -0,0 +1,205 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth.ext; + +import java.time.Period; +import java.time.ZonedDateTime; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.ResultCode; +import org.ldaptive.auth.AuthenticationResponse; +import org.ldaptive.auth.AuthenticationResponseHandler; +import org.ldaptive.io.GeneralizedTimeValueTranscoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Attempts to parse the authentication response and set the account state using data associated with FreeIPA. The + * {@link org.ldaptive.auth.Authenticator} should be configured to return 'krbPasswordExpiration', + * 'krbLoginFailedCount' and 'krbLastPwdChange' attributes so they can be consumed by this handler. + * + * @author tduehr + */ +public class FreeIPAAuthenticationResponseHandler implements AuthenticationResponseHandler +{ + + /** Attributes needed to enforce password policy. */ + public static final String[] ATTRIBUTES = new String[] { + "krbPasswordExpiration", + "krbLoginFailedCount", + "krbLastPwdChange", + }; + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Amount of time since a password was set until it will expire. Used if krbPasswordExpiration cannot be read. */ + private Period expirationPeriod; + + /** Amount of time before expiration to produce a warning. */ + private Period warningPeriod; + + /** Maximum number of login failures to allow. */ + private int maxLoginFailures; + + + /** Default constructor. */ + public FreeIPAAuthenticationResponseHandler() {} + + + /** + * Creates a new freeipa authentication response handler. + * + * @param warning length of time before expiration that should produce a warning + * @param loginFailures number of login failures to allow + */ + public FreeIPAAuthenticationResponseHandler(final Period warning, final int loginFailures) + { + setWarningPeriod(warning); + setMaxLoginFailures(loginFailures); + } + + + /** + * Creates a new freeipa authentication response handler. + * + * @param expiration length of time that a password is valid + * @param warning length of time before expiration that should produce a warning + * @param loginFailures number of login failures to allow + */ + public FreeIPAAuthenticationResponseHandler(final Period expiration, final Period warning, final int loginFailures) + { + setExpirationPeriod(expiration); + setWarningPeriod(warning); + setMaxLoginFailures(loginFailures); + } + + + @Override + public void handle(final AuthenticationResponse response) + { + if (response.getResultCode() != ResultCode.SUCCESS) { + final FreeIPAAccountState.Error fError = FreeIPAAccountState.Error.parse( + response.getResultCode(), + response.getMessage()); + if (fError != null) { + response.setAccountState(new FreeIPAAccountState(fError)); + } + } else if (response.getResult()) { + final LdapEntry entry = response.getLdapEntry(); + final LdapAttribute expTime = entry.getAttribute("krbPasswordExpiration"); + final LdapAttribute failedLogins = entry.getAttribute("krbLoginFailedCount"); + final LdapAttribute lastPwdChange = entry.getAttribute("krbLastPwdChange"); + ZonedDateTime exp = null; + + Integer loginRemaining = null; + if (failedLogins != null && maxLoginFailures > 0) { + loginRemaining = maxLoginFailures - Integer.parseInt(failedLogins.getStringValue()); + } + + if (expTime != null) { + exp = expTime.getValue(new GeneralizedTimeValueTranscoder()); + } else if (expirationPeriod != null && lastPwdChange != null) { + exp = lastPwdChange.getValue(new GeneralizedTimeValueTranscoder()).plus(expirationPeriod); + } + if (exp != null) { + if (warningPeriod != null) { + final ZonedDateTime warn = exp.minus(warningPeriod); + if (ZonedDateTime.now().isAfter(warn)) { + response.setAccountState( + new FreeIPAAccountState(exp, loginRemaining != null ? loginRemaining : 0)); + } + } else { + response.setAccountState( + new FreeIPAAccountState(exp, loginRemaining != null ? loginRemaining : 0)); + } + } else if (loginRemaining != null && loginRemaining < maxLoginFailures) { + response.setAccountState(new FreeIPAAccountState(null, loginRemaining)); + } + } + } + + + /** + * Returns the maximum login failures. + * + * @return maximum login failures before lockout. + */ + public int getMaxLoginFailures() + { + return maxLoginFailures; + } + + + /** + * Sets the maximum login failures. + * + * @param loginFailures before lockout. + */ + public void setMaxLoginFailures(final int loginFailures) + { + if (loginFailures < 0) { + throw new IllegalArgumentException("Login failures must be >= 0"); + } + maxLoginFailures = loginFailures; + } + + + /** + * Returns the amount of time since a password was set until it will expire. Only used if the krbPasswordExpiration + * attribute cannot be read from the directory. + * + * @return expiration period + */ + public Period getExpirationPeriod() + { + return expirationPeriod; + } + + + /** + * Sets the amount of time since a password was set until it will expire. Only used if the krbPasswordExpiration + * attribute cannot be read from the directory. + * + * @param period expiration period + */ + public void setExpirationPeriod(final Period period) + { + expirationPeriod = period; + } + + + /** + * Returns the amount of time before expiration to produce a warning. + * + * @return warning period + */ + public Period getWarningPeriod() + { + return warningPeriod; + } + + + /** + * Sets the amount of time before expiration to produce a warning. + * + * @param period warning period + */ + public void setWarningPeriod(final Period period) + { + warningPeriod = period; + } + + + @Override + public String toString() + { + return String.format( + "[%s@%d::expirationPeriod=%s, warningPeriod=%s, maxLoginFailures=%s]", + getClass().getName(), + hashCode(), + expirationPeriod, + warningPeriod, + maxLoginFailures); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/ext/PasswordExpirationAccountState.java b/core/src/main/java/org/ldaptive/auth/ext/PasswordExpirationAccountState.java new file mode 100644 index 0000000..8c3b9bb --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/ext/PasswordExpirationAccountState.java
@@ -0,0 +1,86 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth.ext; + +import java.time.ZonedDateTime; +import javax.security.auth.login.CredentialExpiredException; +import javax.security.auth.login.LoginException; +import org.ldaptive.auth.AccountState; + +/** + * Represents the state of an account in a directory that implements: + * http://tools.ietf.org/html/draft-vchu-ldap-pwd-policy-00. Note that the warning returned by this implementation + * always returns -1 for logins remaining as this specification doesn't include that feature. + * + * @author Middleware Services + */ +public class PasswordExpirationAccountState extends AccountState +{ + + + /** Enum to define password expiration error. */ + public enum Error implements AccountState.Error { + + /** password expired. */ + PASSWORD_EXPIRED; + + + @Override + public int getCode() + { + return 0; + } + + + @Override + public String getMessage() + { + return name(); + } + + + @Override + public void throwSecurityException() + throws LoginException + { + throw new CredentialExpiredException(name()); + } + } + + /** error enum. */ + private final Error nError; + + + /** + * Creates a new password expiration account state. + * + * @param exp account expiration + */ + public PasswordExpirationAccountState(final ZonedDateTime exp) + { + super(new AccountState.DefaultWarning(exp, -1)); + nError = null; + } + + + /** + * Creates a new password expiration account state. + * + * @param error containing authentication failure details + */ + public PasswordExpirationAccountState(final PasswordExpirationAccountState.Error error) + { + super(error); + nError = error; + } + + + /** + * Returns the password expiration error for this account state. + * + * @return password expiration error + */ + public PasswordExpirationAccountState.Error getPasswordExpirationError() + { + return nError; + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/ext/PasswordExpirationAuthenticationResponseHandler.java b/core/src/main/java/org/ldaptive/auth/ext/PasswordExpirationAuthenticationResponseHandler.java new file mode 100644 index 0000000..4bece18 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/ext/PasswordExpirationAuthenticationResponseHandler.java
@@ -0,0 +1,48 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth.ext; + +import java.time.ZonedDateTime; +import org.ldaptive.auth.AuthenticationResponse; +import org.ldaptive.auth.AuthenticationResponseHandler; +import org.ldaptive.control.PasswordExpiredControl; +import org.ldaptive.control.PasswordExpiringControl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Attempts to parse the authentication response and set the account state using data associated with the password + * expiring and password expired controls. See http://tools.ietf.org/html/draft-vchu-ldap-pwd-policy-00. + * + * @author Middleware Services + */ +public class PasswordExpirationAuthenticationResponseHandler implements AuthenticationResponseHandler +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + + @Override + public void handle(final AuthenticationResponse response) + { + final PasswordExpiringControl expiringControl = (PasswordExpiringControl) response.getControl( + PasswordExpiringControl.OID); + if (expiringControl != null) { + if (expiringControl.getTimeBeforeExpiration() > 0) { + final ZonedDateTime exp = ZonedDateTime.now().plusSeconds(expiringControl.getTimeBeforeExpiration()); + response.setAccountState(new PasswordExpirationAccountState(exp)); + } else { + logger.warn("Received password expiring control with non-positive value: %s", expiringControl); + } + } + + if (response.getAccountState() == null) { + final PasswordExpiredControl expiredControl = (PasswordExpiredControl) response.getControl( + PasswordExpiredControl.OID); + if (expiredControl != null) { + response.setAccountState( + new PasswordExpirationAccountState(PasswordExpirationAccountState.Error.PASSWORD_EXPIRED)); + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/ext/PasswordPolicyAccountState.java b/core/src/main/java/org/ldaptive/auth/ext/PasswordPolicyAccountState.java new file mode 100644 index 0000000..d0314be --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/ext/PasswordPolicyAccountState.java
@@ -0,0 +1,54 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth.ext; + +import java.time.ZonedDateTime; +import org.ldaptive.auth.AccountState; +import org.ldaptive.control.PasswordPolicyControl; + +/** + * Represents the state of an account as described by a password policy control. + * + * @author Middleware Services + */ +public class PasswordPolicyAccountState extends AccountState +{ + + /** password policy specific enum. */ + private final PasswordPolicyControl.Error ppError; + + + /** + * Creates a new password policy account state. + * + * @param exp account expiration + * @param remaining number of logins available + */ + public PasswordPolicyAccountState(final ZonedDateTime exp, final int remaining) + { + super(new AccountState.DefaultWarning(exp, remaining)); + ppError = null; + } + + + /** + * Creates a new password policy account state. + * + * @param error containing password policy error details + */ + public PasswordPolicyAccountState(final PasswordPolicyControl.Error error) + { + super(error); + ppError = error; + } + + + /** + * Returns the password policy error for this account state. + * + * @return password policy error + */ + public PasswordPolicyControl.Error getPasswordPolicyError() + { + return ppError; + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/ext/PasswordPolicyAuthenticationRequestHandler.java b/core/src/main/java/org/ldaptive/auth/ext/PasswordPolicyAuthenticationRequestHandler.java new file mode 100644 index 0000000..d161f5b --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/ext/PasswordPolicyAuthenticationRequestHandler.java
@@ -0,0 +1,24 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth.ext; + +import org.ldaptive.auth.AddControlAuthenticationRequestHandler; +import org.ldaptive.control.PasswordPolicyControl; +import org.ldaptive.control.RequestControl; + +/** + * Adds the {@link PasswordPolicyControl} to the {@link org.ldaptive.auth.AuthenticationRequest}. + * + * @author Middleware Services + */ +public class PasswordPolicyAuthenticationRequestHandler extends AddControlAuthenticationRequestHandler +{ + + + /** + * Creates a new password policy authentication request handler + */ + public PasswordPolicyAuthenticationRequestHandler() + { + super((dn, user) -> new RequestControl[] {new PasswordPolicyControl()}); + } +}
diff --git a/core/src/main/java/org/ldaptive/auth/ext/PasswordPolicyAuthenticationResponseHandler.java b/core/src/main/java/org/ldaptive/auth/ext/PasswordPolicyAuthenticationResponseHandler.java new file mode 100644 index 0000000..2581237 --- /dev/null +++ b/core/src/main/java/org/ldaptive/auth/ext/PasswordPolicyAuthenticationResponseHandler.java
@@ -0,0 +1,37 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth.ext; + +import java.time.ZonedDateTime; +import org.ldaptive.auth.AuthenticationResponse; +import org.ldaptive.auth.AuthenticationResponseHandler; +import org.ldaptive.control.PasswordPolicyControl; + +/** + * Attempts to parse the authentication response message and set the account state using data associated with a password + * policy control. + * + * @author Middleware Services + */ +public class PasswordPolicyAuthenticationResponseHandler implements AuthenticationResponseHandler +{ + + + @Override + public void handle(final AuthenticationResponse response) + { + final PasswordPolicyControl ppc = (PasswordPolicyControl) response.getControl(PasswordPolicyControl.OID); + if (ppc != null) { + if (ppc.getError() != null) { + response.setAccountState(new PasswordPolicyAccountState(ppc.getError())); + } else { + ZonedDateTime exp = null; + if (ppc.getTimeBeforeExpiration() > 0) { + exp = ZonedDateTime.now().plusSeconds(ppc.getTimeBeforeExpiration()); + } + if (exp != null || ppc.getGraceAuthNsRemaining() > 0) { + response.setAccountState(new PasswordPolicyAccountState(exp, ppc.getGraceAuthNsRemaining())); + } + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/cache/Cache.java b/core/src/main/java/org/ldaptive/cache/Cache.java new file mode 100644 index 0000000..2f8c151 --- /dev/null +++ b/core/src/main/java/org/ldaptive/cache/Cache.java
@@ -0,0 +1,35 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.cache; + +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; + +/** + * Interface for cache implementations. + * + * @param <Q> type of search request + * + * @author Middleware Services + */ +public interface Cache<Q extends SearchRequest> +{ + + + /** + * Returns the ldap result for the supplied request. + * + * @param request to find ldap result with + * + * @return ldap result + */ + SearchResult get(Q request); + + + /** + * Stores the ldap result for the supplied request. + * + * @param request used to find ldap result + * @param result found with request + */ + void put(Q request, SearchResult result); +}
diff --git a/core/src/main/java/org/ldaptive/cache/LRUCache.java b/core/src/main/java/org/ldaptive/cache/LRUCache.java new file mode 100644 index 0000000..16aed4d --- /dev/null +++ b/core/src/main/java/org/ldaptive/cache/LRUCache.java
@@ -0,0 +1,156 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.cache; + +import java.time.Duration; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; + +/** + * Least-Recently-Used cache implementation. Leverages a {@link LinkedHashMap}. + * + * @param <Q> type of search request + * + * @author Middleware Services + */ +public class LRUCache<Q extends SearchRequest> implements Cache<Q> +{ + + /** Initial capacity of the hash map. */ + private static final int INITIAL_CAPACITY = 16; + + /** Load factor of the hash map. */ + private static final float LOAD_FACTOR = 0.75f; + + /** Map to cache search results. */ + private Map<Q, Item> cache; + + /** Executor for performing eviction. */ + private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor( + // CheckStyle:JavadocVariable OFF + r -> { + final Thread t = new Thread(r); + t.setDaemon(true); + return t; + }); + // CheckStyle:JavadocVariable ON + + + /** + * Creates a new LRU cache. + * + * @param size number of results to cache + * @param timeToLive that results should stay in the cache + * @param interval to enforce timeToLive + */ + public LRUCache(final int size, final Duration timeToLive, final Duration interval) + { + cache = new LinkedHashMap<Q, Item>(INITIAL_CAPACITY, LOAD_FACTOR, true) { + + /** serialVersionUID. */ + private static final long serialVersionUID = -4082551016104288539L; + + + @Override + protected boolean removeEldestEntry(final Map.Entry<Q, Item> entry) + { + return size() > size; + } + }; + + final Runnable expire = () -> { + synchronized (cache) { + final Iterator<Item> i = cache.values().iterator(); + final long t = System.currentTimeMillis(); + while (i.hasNext()) { + final Item item = i.next(); + if (t - item.creationTime > timeToLive.toMillis()) { + i.remove(); + } + } + } + }; + executor.scheduleAtFixedRate(expire, interval.toMillis(), interval.toMillis(), TimeUnit.MILLISECONDS); + } + + + /** Removes all data from this cache. */ + public void clear() + { + synchronized (cache) { + cache.clear(); + } + } + + + @Override + public SearchResult get(final Q request) + { + synchronized (cache) { + if (cache.containsKey(request)) { + return cache.get(request).result; + } else { + return null; + } + } + } + + + @Override + public void put(final Q request, final SearchResult result) + { + synchronized (cache) { + cache.put(request, new Item(result)); + } + } + + + /** + * Returns the number of items in this cache. + * + * @return size of this cache + */ + public int size() + { + synchronized (cache) { + return cache.size(); + } + } + + + /** Frees any resources associated with this cache. */ + public void close() + { + executor.shutdown(); + cache = null; + } + + + /** Container for data related to cached ldap results. */ + private class Item + { + + /** Ldap result. */ + private final SearchResult result; + + /** Timestamp when this item is created. */ + private final long creationTime; + + + /** + * Creates a new item. + * + * @param sr search result + */ + Item(final SearchResult sr) + { + result = sr; + creationTime = System.currentTimeMillis(); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/cli/AbstractCli.java b/core/src/main/java/org/ldaptive/cli/AbstractCli.java new file mode 100644 index 0000000..01d2d1d --- /dev/null +++ b/core/src/main/java/org/ldaptive/cli/AbstractCli.java
@@ -0,0 +1,254 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.cli; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.ldaptive.BindConnectionInitializer; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.ConnectionInitializer; +import org.ldaptive.Credential; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.LdapException; +import org.ldaptive.props.DefaultConnectionFactoryPropertySource; +import org.ldaptive.props.PropertySource.PropertyDomain; + +/** + * Abstract base class for all CLI classes. + * + * @author Middleware Services + */ +public abstract class AbstractCli +{ + + /** option to print usage. */ + protected static final String OPT_HELP = "help"; + + /** option for provider properties. */ + protected static final String OPT_PROVIDER_PROPERTIES = "providerProperties"; + + /** command line options. */ + protected final Options options = new Options(); + + /** whether to output dsml version 1, the default is ldif. */ + protected boolean outputDsmlv1; + + + /** + * Parses command line options and dispatches to the requested action, or the default action if no action is + * specified. + * + * @param args command line arguments + * + * @return status code + */ + public final int performAction(final String[] args) + { + initOptions(); + + int status = -1; + try { + if (args.length > 0) { + final CommandLineParser parser = new DefaultParser(); + final CommandLine line = parser.parse(options, args, false); + status = dispatch(line); + } else { + printExamples(); + } + } catch (ParseException pex) { + System.err.println("Failed parsing command arguments: " + pex.getMessage()); + } catch (IllegalArgumentException iaex) { + String msg = "Operation failed: " + iaex.getMessage(); + if (iaex.getCause() != null) { + msg += " Underlying reason: " + iaex.getCause().getMessage(); + } + System.err.println(msg); + } catch (RuntimeException rex) { + throw rex; + } catch (LdapException ex) { + System.err.println("LDAP Operation failed:"); + ex.printStackTrace(System.err); + if (ex.getResultCode() != null) { + status = ex.getResultCode().value(); + } + } catch (Exception ex) { + System.err.println("Operation failed:"); + ex.printStackTrace(System.err); + } + return status; + } + + + /** Initialize CLI options. */ + protected void initOptions() + { + options.addOption(new Option(OPT_HELP, false, "display all options")); + options.addOption(new Option(OPT_PROVIDER_PROPERTIES, true, "provider specific properties")); + } + + + /** + * Initialize a connection factory with command line options. + * + * @param line parsed command line arguments + * + * @return connection factory that has been initialized + */ + protected ConnectionFactory initConnectionFactory(final CommandLine line) + { + final DefaultConnectionFactory factory = new DefaultConnectionFactory(); + final DefaultConnectionFactoryPropertySource cfSource = new DefaultConnectionFactoryPropertySource( + factory, + getPropertiesFromOptions(PropertyDomain.LDAP.value(), line)); + cfSource.initialize(); + + final ConnectionInitializer ci = factory.getConnectionConfig().getConnectionInitializer(); + if (ci instanceof BindConnectionInitializer) { + final BindConnectionInitializer bci = (BindConnectionInitializer) ci; + if (bci.getBindDn() != null && bci.getBindCredential() == null) { + // prompt the user to enter a password + final char[] pass = System.console().readPassword("[Enter password for %s]: ", bci.getBindDn()); + bci.setBindCredential(new Credential(pass)); + } + } + return factory; + } + + + /** + * Returns the name of the command for which this class provides a CLI interface. + * + * @return name of CLI command + */ + protected abstract String getCommandName(); + + + /** + * Dispatch command line data to the active that can perform the operation requested on the command line. + * + * @param line parsed command line arguments + * + * @return status code + * + * @throws Exception on errors thrown by action + */ + protected abstract int dispatch(final CommandLine line) + throws Exception; + + + /** Prints CLI help text. */ + protected void printHelp() + { + final HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp(getCommandName(), options); + } + + + /** Prints CLI usage examples. */ + protected void printExamples() + { + final String name = getClass().getSimpleName(); + final InputStream in = getClass().getResourceAsStream(name + ".examples"); + if (in != null) { + final BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + try { + System.out.println(); + + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } + } catch (IOException e) { + System.err.println("Error reading examples from resource stream."); + } finally { + try { + reader.close(); + } catch (IOException ex) { + System.err.println("Error closing example resource stream."); + } + System.out.println(); + } + } else { + System.out.println("No usage examples available for " + getCommandName()); + } + } + + + /** + * Returns the command line argument descriptions for this CLI. + * + * @param classes that contain arguments used by this CLI + * + * @return map of argument name to description + */ + protected Map<String, String> getArgDesc(final Class<?>... classes) + { + final Map<String, String> args = new HashMap<>(); + for (Class<?> c : classes) { + final String name = c.getSimpleName(); + final InputStream in = getClass().getResourceAsStream(name + ".args"); + if (in != null) { + final BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + try { + String line; + while ((line = reader.readLine()) != null) { + final String[] s = line.split(":"); + if (s.length > 1) { + args.put(s[0], s[1]); + } + } + } catch (IOException e) { + System.err.println("Error reading arguments from resource stream."); + } finally { + try { + reader.close(); + } catch (IOException ex) { + System.err.println("Error closing arguments resource stream."); + } + } + } + } + if (args.isEmpty()) { + System.err.println("No arguments available for " + getCommandName()); + } + return args; + } + + + /** + * Reads the options from the supplied command line and returns a properties containing those options. + * + * @param domain to place property names in + * @param line command line + * + * @return properties for each option and value + */ + protected Properties getPropertiesFromOptions(final String domain, final CommandLine line) + { + final Properties props = new Properties(); + for (Option o : line.getOptions()) { + if (o.hasArg()) { + // if provider property, split the value + // else add the domain to the ldaptive properties + if (o.getOpt().equals(OPT_PROVIDER_PROPERTIES)) { + final String[] s = o.getValue().split("="); + props.setProperty(s[0], s[1]); + } else { + props.setProperty(domain + o.getOpt(), o.getValue()); + } + } + } + return props; + } +}
diff --git a/core/src/main/java/org/ldaptive/cli/AddOperationCli.java b/core/src/main/java/org/ldaptive/cli/AddOperationCli.java new file mode 100644 index 0000000..4d41789 --- /dev/null +++ b/core/src/main/java/org/ldaptive/cli/AddOperationCli.java
@@ -0,0 +1,114 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.cli; + +import java.io.FileReader; +import java.util.Map; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Option; +import org.ldaptive.AddOperation; +import org.ldaptive.AddRequest; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.LdapEntry; +import org.ldaptive.SearchResult; +import org.ldaptive.io.LdifReader; +import org.ldaptive.props.BindConnectionInitializerPropertySource; +import org.ldaptive.props.ConnectionConfigPropertySource; +import org.ldaptive.props.SslConfigPropertySource; +import org.ldaptive.ssl.SslConfig; + +/** + * Command line interface for {@link AddOperation}. + * + * @author Middleware Services + */ +public class AddOperationCli extends AbstractCli +{ + + /** option for LDIF file. */ + private static final String OPT_FILE = "file"; + + /** name of operation provided by this class. */ + private static final String COMMAND_NAME = "ldapadd"; + + + /** + * CLI entry point method. + * + * @param args command line arguments. + */ + public static void main(final String[] args) + { + final AddOperationCli cli = new AddOperationCli(); + final int status = cli.performAction(args); + System.exit(status); + } + + + @Override + protected void initOptions() + { + options.addOption(new Option(OPT_FILE, true, "LDIF file")); + + final Map<String, String> desc = getArgDesc(ConnectionConfig.class, SslConfig.class); + for (String s : ConnectionConfigPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + for (String s : SslConfigPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + for (String s : BindConnectionInitializerPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + super.initOptions(); + } + + + @Override + protected int dispatch(final CommandLine line) + throws Exception + { + if (line.hasOption(OPT_HELP)) { + printHelp(); + } else { + return add(initConnectionFactory(line), line.getOptionValue(OPT_FILE)); + } + return -1; + } + + + /** + * Executes the ldap add operation. + * + * @param cf connection factory + * @param file to read ldif from + * + * @return status code + * + * @throws Exception on any LDAP search error + */ + protected int add(final ConnectionFactory cf, final String file) + throws Exception + { + final Connection conn = cf.getConnection(); + conn.open(); + + final LdifReader reader = new LdifReader(new FileReader(file)); + final SearchResult sr = reader.read(); + for (LdapEntry le : sr.getEntries()) { + final AddOperation op = new AddOperation(conn); + op.execute(new AddRequest(le.getDn(), le.getAttributes())); + System.out.println(String.format("Added entry: %s", le)); + } + conn.close(); + return 0; + } + + + @Override + protected String getCommandName() + { + return COMMAND_NAME; + } +}
diff --git a/core/src/main/java/org/ldaptive/cli/AuthenticatorCli.java b/core/src/main/java/org/ldaptive/cli/AuthenticatorCli.java new file mode 100644 index 0000000..7787063 --- /dev/null +++ b/core/src/main/java/org/ldaptive/cli/AuthenticatorCli.java
@@ -0,0 +1,192 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.cli; + +import java.io.BufferedWriter; +import java.io.OutputStreamWriter; +import java.util.Map; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Option; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.Credential; +import org.ldaptive.LdapEntry; +import org.ldaptive.ReturnAttributes; +import org.ldaptive.SearchResult; +import org.ldaptive.auth.AuthenticationRequest; +import org.ldaptive.auth.AuthenticationResponse; +import org.ldaptive.auth.Authenticator; +import org.ldaptive.auth.SearchDnResolver; +import org.ldaptive.auth.User; +import org.ldaptive.io.Dsmlv1Writer; +import org.ldaptive.io.LdifWriter; +import org.ldaptive.io.SearchResultWriter; +import org.ldaptive.props.AuthenticationRequestPropertySource; +import org.ldaptive.props.AuthenticatorPropertySource; +import org.ldaptive.props.BindConnectionInitializerPropertySource; +import org.ldaptive.props.ConnectionConfigPropertySource; +import org.ldaptive.props.PropertySource.PropertyDomain; +import org.ldaptive.props.SearchDnResolverPropertySource; + +/** + * Command line interface for {@link Authenticator}. + * + * @author Middleware Services + */ +public class AuthenticatorCli extends AbstractCli +{ + + /** option for dsmlv1 output. */ + private static final String OPT_DSMLV1 = "dsmlv1"; + + /** name of operation provided by this class. */ + private static final String COMMAND_NAME = "ldapauth"; + + + /** + * CLI entry point method. + * + * @param args command line arguments. + */ + public static void main(final String[] args) + { + final AuthenticatorCli cli = new AuthenticatorCli(); + final int status = cli.performAction(args); + System.exit(status); + } + + + @Override + protected void initOptions() + { + options.addOption(new Option(OPT_DSMLV1, false, "output results in DSML v1")); + + final Map<String, String> desc = getArgDesc( + ConnectionConfig.class, + Authenticator.class, + SearchDnResolver.class, + AuthenticationRequest.class); + for (String s : ConnectionConfigPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + for (String s : BindConnectionInitializerPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + for (String s : AuthenticatorPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + // ignore core search related properties + SearchDnResolverPropertySource.getProperties().stream().filter( + s -> !s.startsWith("search")).forEach(s -> options.addOption(new Option(s, true, desc.get(s)))); + for (String s : AuthenticationRequestPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + super.initOptions(); + } + + + /** + * Initialize an Authenticator with command line options. + * + * @param line parsed command line arguments + * + * @return authenticator that has been initialized + */ + protected Authenticator initAuthenticator(final CommandLine line) + { + final Authenticator auth = new Authenticator(); + final AuthenticatorPropertySource aSource = new AuthenticatorPropertySource( + auth, + getPropertiesFromOptions(PropertyDomain.AUTH.value(), line)); + aSource.initialize(); + return auth; + } + + + /** + * Initialize an authentication request with command line options. + * + * @param line parsed command line arguments + * + * @return authentication request that has been initialized + */ + protected AuthenticationRequest initAuthenticationRequest(final CommandLine line) + { + final AuthenticationRequest request = new AuthenticationRequest(); + final AuthenticationRequestPropertySource arSource = new AuthenticationRequestPropertySource( + request, + getPropertiesFromOptions(PropertyDomain.AUTH.value(), line)); + arSource.initialize(); + if (request.getUser() == null) { + // prompt for a user name + final String user = System.console().readLine("[Enter user name]: "); + request.setUser(new User(user)); + } + + if (request.getCredential() == null) { + // prompt the user to enter a password + final char[] pass = System.console().readPassword("[Enter password for %s]: ", request.getUser()); + request.setCredential(new Credential(pass)); + } + + return request; + } + + + @Override + protected int dispatch(final CommandLine line) + throws Exception + { + if (line.hasOption(OPT_DSMLV1)) { + outputDsmlv1 = true; + } + if (line.hasOption(OPT_HELP)) { + printHelp(); + } else { + return authenticate(initAuthenticator(line), initAuthenticationRequest(line)); + } + return -1; + } + + + /** + * Executes the authentication operation. + * + * @param auth authenticator + * @param request authentication request + * + * @return status code + * + * @throws Exception on any LDAP error + */ + protected int authenticate(final Authenticator auth, final AuthenticationRequest request) + throws Exception + { + // by default return all attributes + if (request.getReturnAttributes() != null && request.getReturnAttributes().length == 0) { + request.setReturnAttributes(ReturnAttributes.ALL_USER.value()); + } + + final AuthenticationResponse response = auth.authenticate(request); + final LdapEntry entry = response.getLdapEntry(); + if (response.getResult()) { + if (entry != null) { + SearchResultWriter writer; + if (outputDsmlv1) { + writer = new Dsmlv1Writer(new BufferedWriter(new OutputStreamWriter(System.out))); + } else { + writer = new LdifWriter(new BufferedWriter(new OutputStreamWriter(System.out))); + } + writer.write(new SearchResult(entry)); + } + } else { + System.out.println(String.format("Authentication failed for %s", entry)); + } + return response.getResultCode().value(); + } + + + @Override + protected String getCommandName() + { + return COMMAND_NAME; + } +}
diff --git a/core/src/main/java/org/ldaptive/cli/CompareOperationCli.java b/core/src/main/java/org/ldaptive/cli/CompareOperationCli.java new file mode 100644 index 0000000..acbf163 --- /dev/null +++ b/core/src/main/java/org/ldaptive/cli/CompareOperationCli.java
@@ -0,0 +1,121 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.cli; + +import java.util.Map; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Option; +import org.ldaptive.CompareOperation; +import org.ldaptive.CompareRequest; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapUtils; +import org.ldaptive.Response; +import org.ldaptive.props.BindConnectionInitializerPropertySource; +import org.ldaptive.props.ConnectionConfigPropertySource; +import org.ldaptive.props.SslConfigPropertySource; +import org.ldaptive.ssl.SslConfig; + +/** + * Command line interface for {@link CompareOperation}. + * + * @author Middleware Services + */ +public class CompareOperationCli extends AbstractCli +{ + + /** option for LDAP DN. */ + private static final String OPT_DN = "dn"; + + /** option for LDAP attribute name/value pair. */ + private static final String OPT_ATTR = "attribute"; + + /** name of operation provided by this class. */ + private static final String COMMAND_NAME = "ldapcompare"; + + + /** + * CLI entry point method. + * + * @param args command line arguments. + */ + public static void main(final String[] args) + { + final CompareOperationCli cli = new CompareOperationCli(); + final int status = cli.performAction(args); + System.exit(status); + } + + + @Override + protected void initOptions() + { + options.addOption(new Option(OPT_DN, true, "entry DN")); + options.addOption(new Option(OPT_ATTR, true, "colon delimited name value pair (attr:value|attr::b64value)")); + + final Map<String, String> desc = getArgDesc(ConnectionConfig.class, SslConfig.class); + for (String s : ConnectionConfigPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + for (String s : SslConfigPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + for (String s : BindConnectionInitializerPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + super.initOptions(); + } + + + @Override + protected int dispatch(final CommandLine line) + throws Exception + { + if (line.hasOption(OPT_HELP)) { + printHelp(); + } else { + LdapAttribute la; + final String[] attr = line.getOptionValue(OPT_ATTR).split(":", 2); + if (attr[1].startsWith(":")) { + la = new LdapAttribute(attr[0], LdapUtils.base64Decode(attr[1].substring(1))); + } else { + la = new LdapAttribute(attr[0], attr[1]); + } + return compare(initConnectionFactory(line), line.getOptionValue(OPT_DN), la); + } + return -1; + } + + + /** + * Executes the ldap compare operation. + * + * @param cf connection factory + * @param dn to compare attribute on + * @param attr attribute to compare + * + * @return status code + * + * @throws Exception on any LDAP search error + */ + protected int compare(final ConnectionFactory cf, final String dn, final LdapAttribute attr) + throws Exception + { + final Connection conn = cf.getConnection(); + conn.open(); + + final CompareOperation op = new CompareOperation(conn); + final Response<Boolean> response = op.execute(new CompareRequest(dn, attr)); + System.out.println(response.getResult()); + conn.close(); + return response.getResultCode().value(); + } + + + @Override + protected String getCommandName() + { + return COMMAND_NAME; + } +}
diff --git a/core/src/main/java/org/ldaptive/cli/DeleteOperationCli.java b/core/src/main/java/org/ldaptive/cli/DeleteOperationCli.java new file mode 100644 index 0000000..1ba539d --- /dev/null +++ b/core/src/main/java/org/ldaptive/cli/DeleteOperationCli.java
@@ -0,0 +1,108 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.cli; + +import java.util.Map; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Option; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.DeleteOperation; +import org.ldaptive.DeleteRequest; +import org.ldaptive.props.BindConnectionInitializerPropertySource; +import org.ldaptive.props.ConnectionConfigPropertySource; +import org.ldaptive.props.SslConfigPropertySource; +import org.ldaptive.ssl.SslConfig; + +/** + * Command line interface for {@link DeleteOperation}. + * + * @author Middleware Services + */ +public class DeleteOperationCli extends AbstractCli +{ + + /** option for LDAP DN. */ + private static final String OPT_DN = "dn"; + + /** name of operation provided by this class. */ + private static final String COMMAND_NAME = "ldapdelete"; + + + /** + * CLI entry point method. + * + * @param args command line arguments. + */ + public static void main(final String[] args) + { + final DeleteOperationCli cli = new DeleteOperationCli(); + final int status = cli.performAction(args); + System.exit(status); + } + + + @Override + protected void initOptions() + { + options.addOption(new Option(OPT_DN, true, "entry DN")); + + final Map<String, String> desc = getArgDesc(ConnectionConfig.class, SslConfig.class); + for (String s : ConnectionConfigPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + for (String s : SslConfigPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + for (String s : BindConnectionInitializerPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + super.initOptions(); + } + + + @Override + protected int dispatch(final CommandLine line) + throws Exception + { + if (line.hasOption(OPT_HELP)) { + printHelp(); + } else { + return delete(initConnectionFactory(line), line.getOptionValues(OPT_DN)); + } + return -1; + } + + + /** + * Executes the ldap delete operation. + * + * @param cf connection factory. + * @param entryDns to delete + * + * @return status code + * + * @throws Exception on any LDAP search error + */ + protected int delete(final ConnectionFactory cf, final String[] entryDns) + throws Exception + { + final Connection conn = cf.getConnection(); + conn.open(); + + for (String dn : entryDns) { + final DeleteOperation op = new DeleteOperation(conn); + op.execute(new DeleteRequest(dn)); + System.out.println(String.format("Deleted entry: %s", dn)); + } + conn.close(); + return 0; + } + + + @Override + protected String getCommandName() + { + return COMMAND_NAME; + } +}
diff --git a/core/src/main/java/org/ldaptive/cli/SearchOperationCli.java b/core/src/main/java/org/ldaptive/cli/SearchOperationCli.java new file mode 100644 index 0000000..f9ad6a9 --- /dev/null +++ b/core/src/main/java/org/ldaptive/cli/SearchOperationCli.java
@@ -0,0 +1,146 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.cli; + +import java.io.BufferedWriter; +import java.io.OutputStreamWriter; +import java.util.Map; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Option; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.Response; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.io.Dsmlv1Writer; +import org.ldaptive.io.LdifWriter; +import org.ldaptive.io.SearchResultWriter; +import org.ldaptive.props.BindConnectionInitializerPropertySource; +import org.ldaptive.props.ConnectionConfigPropertySource; +import org.ldaptive.props.PropertySource.PropertyDomain; +import org.ldaptive.props.SearchRequestPropertySource; +import org.ldaptive.props.SslConfigPropertySource; +import org.ldaptive.ssl.SslConfig; + +/** + * Command line interface for {@link SearchOperation}. + * + * @author Middleware Services + */ +public class SearchOperationCli extends AbstractCli +{ + + /** option for dsmlv1 output. */ + private static final String OPT_DSMLV1 = "dsmlv1"; + + /** name of operation provided by this class. */ + private static final String COMMAND_NAME = "ldapsearch"; + + + /** + * CLI entry point method. + * + * @param args command line arguments. + */ + public static void main(final String[] args) + { + final SearchOperationCli cli = new SearchOperationCli(); + final int status = cli.performAction(args); + System.exit(status); + } + + + @Override + protected void initOptions() + { + options.addOption(new Option(OPT_DSMLV1, false, "output results in DSML v1")); + + final Map<String, String> desc = getArgDesc(ConnectionConfig.class, SslConfig.class, SearchRequest.class); + for (String s : ConnectionConfigPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + for (String s : SslConfigPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + for (String s : BindConnectionInitializerPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + for (String s : SearchRequestPropertySource.getProperties()) { + options.addOption(new Option(s, true, desc.get(s))); + } + super.initOptions(); + } + + + /** + * Initialize a search request with command line options. + * + * @param line parsed command line arguments + * + * @return search request that has been initialized + */ + protected SearchRequest initSearchRequest(final CommandLine line) + { + final SearchRequest request = new SearchRequest(); + final SearchRequestPropertySource srSource = new SearchRequestPropertySource( + request, + getPropertiesFromOptions(PropertyDomain.LDAP.value(), line)); + srSource.initialize(); + return request; + } + + + @Override + protected int dispatch(final CommandLine line) + throws Exception + { + if (line.hasOption(OPT_DSMLV1)) { + outputDsmlv1 = true; + } + if (line.hasOption(OPT_HELP)) { + printHelp(); + } else { + return search(initConnectionFactory(line), initSearchRequest(line)); + } + return -1; + } + + + /** + * Executes the ldap search operation. + * + * @param cf connection factory + * @param request search request + * + * @return status code + * + * @throws Exception on any LDAP search error + */ + protected int search(final ConnectionFactory cf, final SearchRequest request) + throws Exception + { + final Connection conn = cf.getConnection(); + conn.open(); + + final SearchOperation op = new SearchOperation(conn); + final Response<SearchResult> response = op.execute(request); + final SearchResult result = response.getResult(); + SearchResultWriter writer; + if (outputDsmlv1) { + writer = new Dsmlv1Writer(new BufferedWriter(new OutputStreamWriter(System.out))); + } else { + writer = new LdifWriter(new BufferedWriter(new OutputStreamWriter(System.out))); + } + writer.write(result); + conn.close(); + return response.getResultCode().value(); + } + + + @Override + protected String getCommandName() + { + return COMMAND_NAME; + } +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/AbstractAggregateSearchExecutor.java b/core/src/main/java/org/ldaptive/concurrent/AbstractAggregateSearchExecutor.java new file mode 100644 index 0000000..5268891 --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/AbstractAggregateSearchExecutor.java
@@ -0,0 +1,133 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.Collection; +import java.util.concurrent.ExecutorService; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.LdapException; +import org.ldaptive.Response; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchResult; +import org.ldaptive.handler.SearchEntryHandler; + +/** + * Base class for aggregate search executors. + * + * @param <T> type of connection factory + * + * @author Middleware Services + */ +public abstract class AbstractAggregateSearchExecutor<T extends ConnectionFactory> extends AbstractSearchExecutor +{ + + /** + * Creates a new abstract aggregate search executor. + * + * @param es executor service + */ + public AbstractAggregateSearchExecutor(final ExecutorService es) + { + super(es); + } + + + /** + * Performs a search operation with the supplied connection factories. + * + * @param factories to get a connection from + * @param filters to search with + * + * @return search results + * + * @throws LdapException if the search fails + */ + public Collection<Response<SearchResult>> search(final T[] factories, final String... filters) + throws LdapException + { + final SearchFilter[] sf = new SearchFilter[filters.length]; + for (int i = 0; i < filters.length; i++) { + sf[i] = new SearchFilter(filters[i]); + } + return search(factories, sf, null, (SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factories. + * + * @param factories to get a connection from + * @param filters to search with + * + * @return search results + * + * @throws LdapException if the search fails + */ + public Collection<Response<SearchResult>> search(final T[] factories, final SearchFilter[] filters) + throws LdapException + { + return search(factories, filters, null, (SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factories. + * + * @param factories to get a connection from + * @param filters to search with + * @param attrs to return + * + * @return search results + * + * @throws LdapException if the search fails + */ + public Collection<Response<SearchResult>> search(final T[] factories, final String[] filters, final String... attrs) + throws LdapException + { + final SearchFilter[] sf = new SearchFilter[filters.length]; + for (int i = 0; i < filters.length; i++) { + sf[i] = new SearchFilter(filters[i]); + } + return search(factories, sf, attrs, (SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factories. + * + * @param factories to get a connection from + * @param filters to search with + * @param attrs to return + * + * @return search results + * + * @throws LdapException if the search fails + */ + public Collection<Response<SearchResult>> search( + final T[] factories, + final SearchFilter[] filters, + final String... attrs) + throws LdapException + { + return search(factories, filters, attrs, (SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factories. + * + * @param factories to get a connection from + * @param filters to search with + * @param attrs to return + * @param handlers entry handlers + * + * @return search results + * + * @throws LdapException if the search fails + */ + public abstract Collection<Response<SearchResult>> search( + final T[] factories, + final SearchFilter[] filters, + final String[] attrs, + final SearchEntryHandler... handlers) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/AbstractOperationWorker.java b/core/src/main/java/org/ldaptive/concurrent/AbstractOperationWorker.java new file mode 100644 index 0000000..dfdde89 --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/AbstractOperationWorker.java
@@ -0,0 +1,165 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletionService; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import org.ldaptive.Operation; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base class for worker operations. If no {@link ExecutorService} is provided a cached thread pool is used by default. + * + * @param <Q> type of ldap request + * @param <S> type of ldap response + * + * @author Middleware Services + */ +public abstract class AbstractOperationWorker<Q extends Request, S> implements OperationWorker<Q, S> +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** operation to execute. */ + private final Operation<Q, S> operation; + + /** to submit operations to. */ + private final ExecutorService service; + + + /** + * Creates a new abstract operation worker. + * + * @param op operation + */ + public AbstractOperationWorker(final Operation<Q, S> op) + { + this(op, Executors.newCachedThreadPool()); + } + + + /** + * Creates a new abstract operation worker. + * + * @param op operation + * @param es executor service + */ + public AbstractOperationWorker(final Operation<Q, S> op, final ExecutorService es) + { + operation = op; + service = es; + } + + + /** + * Execute an ldap operation on a separate thread. + * + * @param request containing the data required by this operation + * + * @return future response for this operation + */ + @Override + public Future<Response<S>> execute(final Q request) + { + return service.submit(createCallable(operation, request)); + } + + + /** + * Execute an ldap operation for each request on a separate thread. + * + * @param requests containing the data required by this operation + * + * @return future responses for this operation + */ + @Override + @SuppressWarnings("unchecked") + public Collection<Future<Response<S>>> execute(final Q... requests) + { + final List<Future<Response<S>>> results = new ArrayList<>(requests.length); + for (Q request : requests) { + results.add(service.submit(createCallable(operation, request))); + } + return results; + } + + + /** + * Execute an ldap operation for each request on a separate thread and waits for all operations to complete. + * + * @param requests containing the data required by this operation + * + * @return responses for this operation + */ + @Override + @SuppressWarnings("unchecked") + public Collection<Response<S>> executeToCompletion(final Q... requests) + { + final CompletionService<Response<S>> cs = new ExecutorCompletionService<>(service); + final List<Future<Response<S>>> futures = new ArrayList<>(requests.length); + for (Q request : requests) { + futures.add(cs.submit(createCallable(operation, request))); + } + + final List<Response<S>> responses = new ArrayList<>(requests.length); + for (Future<Response<S>> future : futures) { + try { + responses.add(future.get()); + } catch (ExecutionException e) { + logger.debug("ExecutionException thrown, ignoring", e); + } catch (InterruptedException e) { + logger.warn("InterruptedException thrown, ignoring", e); + } + } + return responses; + } + + + /** + * Returns a {@link Callable} that executes the supplied request with the supplied operation. + * + * @param <Q> type of ldap request + * @param <S> type of ldap response + * @param operation to execute + * @param request to pass to the operation + * + * @return callable for the supplied operation and request + */ + public static <Q extends Request, S> Callable<Response<S>> createCallable( + final Operation<Q, S> operation, + final Q request) + { + return + () -> operation.execute(request); + } + + + /** Invokes {@link ExecutorService#shutdown()} on the underlying executor service. */ + public void shutdown() + { + service.shutdown(); + } + + + @Override + protected void finalize() + throws Throwable + { + try { + shutdown(); + } finally { + super.finalize(); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/AbstractParallelSearchExecutor.java b/core/src/main/java/org/ldaptive/concurrent/AbstractParallelSearchExecutor.java new file mode 100644 index 0000000..1d9a89d --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/AbstractParallelSearchExecutor.java
@@ -0,0 +1,131 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.Collection; +import java.util.concurrent.ExecutorService; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.LdapException; +import org.ldaptive.Response; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchResult; +import org.ldaptive.handler.SearchEntryHandler; + +/** + * Base class for parallel search executors. + * + * @param <T> type of connection factory + * + * @author Middleware Services + */ +public abstract class AbstractParallelSearchExecutor<T extends ConnectionFactory> extends AbstractSearchExecutor +{ + + + /** + * Creates a new abstract parallel search executor. + * + * @param es executor service + */ + public AbstractParallelSearchExecutor(final ExecutorService es) + { + super(es); + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * @param filters to search with + * + * @return search results + * + * @throws LdapException if the search fails + */ + public Collection<Response<SearchResult>> search(final T factory, final String... filters) + throws LdapException + { + final SearchFilter[] sf = new SearchFilter[filters.length]; + for (int i = 0; i < filters.length; i++) { + sf[i] = new SearchFilter(filters[i]); + } + return search(factory, sf, null, (SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * @param filters to search with + * + * @return search results + * + * @throws LdapException if the search fails + */ + public Collection<Response<SearchResult>> search(final T factory, final SearchFilter[] filters) + throws LdapException + { + return search(factory, filters, null, (SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * @param filters to search with + * @param attrs to return + * + * @return search results + * + * @throws LdapException if the search fails + */ + public Collection<Response<SearchResult>> search(final T factory, final String[] filters, final String... attrs) + throws LdapException + { + final SearchFilter[] sf = new SearchFilter[filters.length]; + for (int i = 0; i < filters.length; i++) { + sf[i] = new SearchFilter(filters[i]); + } + return search(factory, sf, attrs, (SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * @param filters to search with + * @param attrs to return + * + * @return search results + * + * @throws LdapException if the search fails + */ + public Collection<Response<SearchResult>> search(final T factory, final SearchFilter[] filters, final String... attrs) + throws LdapException + { + return search(factory, filters, attrs, (SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * @param filters to search with + * @param attrs to return + * @param handlers entry handlers + * + * @return search results + * + * @throws LdapException if the search fails + */ + public abstract Collection<Response<SearchResult>> search( + final T factory, + final SearchFilter[] filters, + final String[] attrs, + final SearchEntryHandler... handlers) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/AbstractSearchExecutor.java b/core/src/main/java/org/ldaptive/concurrent/AbstractSearchExecutor.java new file mode 100644 index 0000000..f4f4b61 --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/AbstractSearchExecutor.java
@@ -0,0 +1,200 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ExecutorService; +import org.ldaptive.Connection; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.cache.Cache; +import org.ldaptive.handler.OperationExceptionHandler; +import org.ldaptive.handler.OperationResponseHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base class for concurrent search executors. + * + * @author Middleware Services + */ +public abstract class AbstractSearchExecutor extends SearchRequest +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** To submit operations to. */ + private final ExecutorService service; + + /** Handler to handle search exceptions. */ + private OperationExceptionHandler<SearchRequest, SearchResult> searchExceptionHandler; + + /** Handlers to handle search responses. */ + private OperationResponseHandler<SearchRequest, SearchResult>[] searchResponseHandlers; + + /** Cache to use when performing searches. */ + private Cache<SearchRequest> searchCache; + + + /** + * Creates a new abstract search executor. + * + * @param es executor service + */ + public AbstractSearchExecutor(final ExecutorService es) + { + if (es == null) { + throw new NullPointerException("ExecutorService cannot be null"); + } + service = es; + } + + + /** + * Returns the executor service for this search executor. + * + * @return executor service + */ + protected ExecutorService getExecutorService() + { + return service; + } + + + /** + * Returns the search exception handler. + * + * @return search exception handler + */ + public OperationExceptionHandler<SearchRequest, SearchResult> getSearchExceptionHandler() + { + return searchExceptionHandler; + } + + + /** + * Sets the search exception handler. + * + * @param handler search exception handler + */ + public void setSearchExceptionHandler(final OperationExceptionHandler<SearchRequest, SearchResult> handler) + { + searchExceptionHandler = handler; + } + + + /** + * Returns the search response handlers. + * + * @return search response handlers + */ + public OperationResponseHandler<SearchRequest, SearchResult>[] getSearchResponseHandlers() + { + return searchResponseHandlers; + } + + + /** + * Sets the search response handlers. + * + * @param handlers search response handlers + */ + @SuppressWarnings("unchecked") + public void setSearchResponseHandlers(final OperationResponseHandler<SearchRequest, SearchResult>... handlers) + { + searchResponseHandlers = handlers; + } + + + /** + * Returns the search cache. + * + * @return cache + */ + public Cache<SearchRequest> getSearchCache() + { + return searchCache; + } + + + /** + * Sets the search cache. + * + * @param cache to set + */ + public void setSearchCache(final Cache<SearchRequest> cache) + { + searchCache = cache; + } + + + /** Shuts down the executor service. See {@link ExecutorService#shutdown()}. */ + public void shutdown() + { + service.shutdown(); + } + + + /** + * Immediately shuts down the executor service. See {@link ExecutorService#shutdownNow()}. + * + * @return list of tasks that never executed + */ + public List<Runnable> shutdownNow() + { + return service.shutdownNow(); + } + + + /** + * Creates a new search operation configured with the properties on this search executor. + * + * @param conn to pass to the search operation + * + * @return search operation + */ + protected SearchOperation createSearchOperation(final Connection conn) + { + final SearchOperation op = new SearchOperation(conn); + if (searchExceptionHandler != null) { + op.setOperationExceptionHandler(searchExceptionHandler); + } + if (searchResponseHandlers != null) { + op.setOperationResponseHandlers(searchResponseHandlers); + } + if (searchCache != null) { + op.setCache(searchCache); + } + return op; + } + + + @Override + protected void finalize() + throws Throwable + { + try { + shutdown(); + } finally { + super.finalize(); + } + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::service=%s, searchExceptionHandler=%s, " + + "searchResponseHandlers=%s, searchCache=%s]", + getClass().getName(), + hashCode(), + service, + searchExceptionHandler, + Arrays.toString(searchResponseHandlers), + searchCache); + } +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/AddOperationWorker.java b/core/src/main/java/org/ldaptive/concurrent/AddOperationWorker.java new file mode 100644 index 0000000..2937b3e --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/AddOperationWorker.java
@@ -0,0 +1,38 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.concurrent.ExecutorService; +import org.ldaptive.AddOperation; +import org.ldaptive.AddRequest; + +/** + * Executes an ldap add operation on a separate thread. + * + * @author Middleware Services + */ +public class AddOperationWorker extends AbstractOperationWorker<AddRequest, Void> +{ + + + /** + * Creates a new add operation worker. + * + * @param op add operation to execute + */ + public AddOperationWorker(final AddOperation op) + { + super(op); + } + + + /** + * Creates a new add operation worker. + * + * @param op add operation to execute + * @param es executor service + */ + public AddOperationWorker(final AddOperation op, final ExecutorService es) + { + super(op, es); + } +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/AggregatePooledSearchExecutor.java b/core/src/main/java/org/ldaptive/concurrent/AggregatePooledSearchExecutor.java new file mode 100644 index 0000000..bc48d08 --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/AggregatePooledSearchExecutor.java
@@ -0,0 +1,126 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletionService; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.LdapException; +import org.ldaptive.Operation; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.handler.SearchEntryHandler; +import org.ldaptive.pool.PooledConnectionFactory; + +/** + * Executes a list of search filters in parallel over a list of connection factories, each search is performed on a + * separate connection in the pool. If you need to execute all searches on the same connection see {@link + * AggregateSearchExecutor}. A cached thread pool is used by default. + * + * @author Middleware Services + */ +public class AggregatePooledSearchExecutor extends AbstractAggregateSearchExecutor<PooledConnectionFactory> +{ + + + /** Default constructor. */ + public AggregatePooledSearchExecutor() + { + this(Executors.newCachedThreadPool()); + } + + + /** + * Creates a new aggregate pooled search executor. + * + * @param es executor service + */ + public AggregatePooledSearchExecutor(final ExecutorService es) + { + super(es); + } + + + @Override + public Collection<Response<SearchResult>> search( + final PooledConnectionFactory[] factories, + final SearchFilter[] filters, + final String[] attrs, + final SearchEntryHandler... handlers) + throws LdapException + { + final CompletionService<Response<SearchResult>> searches = new ExecutorCompletionService<>(getExecutorService()); + final List<Future<Response<SearchResult>>> futures = new ArrayList<>(factories.length * filters.length); + for (ConnectionFactory factory : factories) { + for (SearchFilter filter : filters) { + final SearchRequest sr = newSearchRequest(this); + if (filter != null) { + sr.setSearchFilter(filter); + } + if (attrs != null) { + sr.setReturnAttributes(attrs); + } + if (handlers != null) { + sr.setSearchEntryHandlers(handlers); + } + + final Connection conn = factory.getConnection(); + final SearchOperation op = createSearchOperation(conn); + futures.add(searches.submit(createCallable(conn, op, sr))); + } + } + + final List<Response<SearchResult>> responses = new ArrayList<>(factories.length * filters.length); + for (Future<Response<SearchResult>> future : futures) { + try { + responses.add(future.get()); + } catch (ExecutionException e) { + logger.debug("ExecutionException thrown, ignoring", e); + } catch (InterruptedException e) { + logger.warn("InterruptedException thrown, ignoring", e); + } + } + return responses; + } + + + /** + * Returns a {@link Callable} that executes the supplied request with the supplied operation in a try-finally block + * that opens and closes the connection. + * + * @param <Q> type of ldap request + * @param <S> type of ldap response + * @param conn connection that the operation will execute on + * @param operation to execute + * @param request to pass to the operation + * + * @return callable for the supplied operation and request + */ + protected static <Q extends Request, S> Callable<Response<S>> createCallable( + final Connection conn, + final Operation<Q, S> operation, + final Q request) + { + return + () -> { + try { + conn.open(); + return operation.execute(request); + } finally { + conn.close(); + } + }; + } +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/AggregateSearchExecutor.java b/core/src/main/java/org/ldaptive/concurrent/AggregateSearchExecutor.java new file mode 100644 index 0000000..70ffa93 --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/AggregateSearchExecutor.java
@@ -0,0 +1,128 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletionService; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.LdapException; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.handler.SearchEntryHandler; + +/** + * Executes a list of search filters in parallel over a list of connection factories. This implementation executes each + * search on the same connection in separate threads. If you need parallel searches over a pool of connections see + * {@link AggregatePooledSearchExecutor}. A cached thread pool is used by default. + * + * @author Middleware Services + */ +public class AggregateSearchExecutor extends AbstractAggregateSearchExecutor<ConnectionFactory> +{ + + + /** Default constructor. */ + public AggregateSearchExecutor() + { + this(Executors.newCachedThreadPool()); + } + + + /** + * Creates a new aggregate search executor. + * + * @param es executor service + */ + public AggregateSearchExecutor(final ExecutorService es) + { + super(es); + } + + + @Override + public Collection<Response<SearchResult>> search( + final ConnectionFactory[] factories, + final SearchFilter[] filters, + final String[] attrs, + final SearchEntryHandler... handlers) + throws LdapException + { + final CompletionService<Collection<Response<SearchResult>>> searches = new ExecutorCompletionService<>( + getExecutorService()); + final SearchRequest[] requests = new SearchRequest[filters.length]; + for (int i = 0; i < filters.length; i++) { + final SearchRequest sr = newSearchRequest(this); + if (filters[i] != null) { + sr.setSearchFilter(filters[i]); + } + if (attrs != null) { + sr.setReturnAttributes(attrs); + } + if (handlers != null) { + sr.setSearchEntryHandlers(handlers); + } + requests[i] = sr; + } + + final List<Future<Collection<Response<SearchResult>>>> futures = new ArrayList<>(factories.length * filters.length); + for (ConnectionFactory factory : factories) { + final Connection conn = factory.getConnection(); + final SearchOperation op = createSearchOperation(conn); + final SearchOperationWorker worker = new SearchOperationWorker(op, getExecutorService()); + futures.add(searches.submit(createCallable(conn, worker, requests))); + } + + final List<Response<SearchResult>> responses = new ArrayList<>(factories.length * filters.length); + for (Future<Collection<Response<SearchResult>>> future : futures) { + try { + responses.addAll(future.get()); + } catch (ExecutionException e) { + logger.debug("ExecutionException thrown, ignoring", e); + } catch (InterruptedException e) { + logger.warn("InterruptedException thrown, ignoring", e); + } + } + return responses; + } + + + /** + * Returns a {@link Callable} that executes the supplied request with the supplied worker in a try-finally block that + * opens and closes the connection. + * + * @param <Q> type of ldap request + * @param <S> type of ldap response + * @param conn connection that the worker will execute on + * @param worker to execute + * @param requests to pass to the worker + * + * @return callable for the supplied operation and request + */ + protected static <Q extends Request, S> Callable<Collection<Response<S>>> createCallable( + final Connection conn, + final OperationWorker<Q, S> worker, + final Q[] requests) + { + return + () -> { + try { + conn.open(); + return worker.executeToCompletion(requests); + } finally { + conn.close(); + } + }; + } +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/BindOperationWorker.java b/core/src/main/java/org/ldaptive/concurrent/BindOperationWorker.java new file mode 100644 index 0000000..dc7d2f5 --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/BindOperationWorker.java
@@ -0,0 +1,38 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.concurrent.ExecutorService; +import org.ldaptive.BindOperation; +import org.ldaptive.BindRequest; + +/** + * Executes an ldap bind operation on a separate thread. + * + * @author Middleware Services + */ +public class BindOperationWorker extends AbstractOperationWorker<BindRequest, Void> +{ + + + /** + * Creates a new bind operation worker. + * + * @param op bind operation to execute + */ + public BindOperationWorker(final BindOperation op) + { + super(op); + } + + + /** + * Creates a new bind operation worker. + * + * @param op bind operation to execute + * @param es executor service + */ + public BindOperationWorker(final BindOperation op, final ExecutorService es) + { + super(op, es); + } +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/CompareOperationWorker.java b/core/src/main/java/org/ldaptive/concurrent/CompareOperationWorker.java new file mode 100644 index 0000000..96b7be7 --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/CompareOperationWorker.java
@@ -0,0 +1,38 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.concurrent.ExecutorService; +import org.ldaptive.CompareOperation; +import org.ldaptive.CompareRequest; + +/** + * Executes an ldap compare operation on a separate thread. + * + * @author Middleware Services + */ +public class CompareOperationWorker extends AbstractOperationWorker<CompareRequest, Boolean> +{ + + + /** + * Creates a new compare operation worker. + * + * @param op compare operation to execute + */ + public CompareOperationWorker(final CompareOperation op) + { + super(op); + } + + + /** + * Creates a new compare operation worker. + * + * @param op compare operation to execute + * @param es executor service + */ + public CompareOperationWorker(final CompareOperation op, final ExecutorService es) + { + super(op, es); + } +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/DeleteOperationWorker.java b/core/src/main/java/org/ldaptive/concurrent/DeleteOperationWorker.java new file mode 100644 index 0000000..794ba15 --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/DeleteOperationWorker.java
@@ -0,0 +1,38 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.concurrent.ExecutorService; +import org.ldaptive.DeleteOperation; +import org.ldaptive.DeleteRequest; + +/** + * Executes an ldap delete operation on a separate thread. + * + * @author Middleware Services + */ +public class DeleteOperationWorker extends AbstractOperationWorker<DeleteRequest, Void> +{ + + + /** + * Creates a new delete operation worker. + * + * @param op delete operation to execute + */ + public DeleteOperationWorker(final DeleteOperation op) + { + super(op); + } + + + /** + * Creates a new delete operation worker. + * + * @param op delete operation to execute + * @param es executor service + */ + public DeleteOperationWorker(final DeleteOperation op, final ExecutorService es) + { + super(op, es); + } +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/ModifyDnOperationWorker.java b/core/src/main/java/org/ldaptive/concurrent/ModifyDnOperationWorker.java new file mode 100644 index 0000000..cd50999 --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/ModifyDnOperationWorker.java
@@ -0,0 +1,38 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.concurrent.ExecutorService; +import org.ldaptive.ModifyDnOperation; +import org.ldaptive.ModifyDnRequest; + +/** + * Executes an ldap modify dn operation on a separate thread. + * + * @author Middleware Services + */ +public class ModifyDnOperationWorker extends AbstractOperationWorker<ModifyDnRequest, Void> +{ + + + /** + * Creates a new modify dn operation worker. + * + * @param op modify dn operation to execute + */ + public ModifyDnOperationWorker(final ModifyDnOperation op) + { + super(op); + } + + + /** + * Creates a new modify dn operation worker. + * + * @param op modify dn operation to execute + * @param es executor service + */ + public ModifyDnOperationWorker(final ModifyDnOperation op, final ExecutorService es) + { + super(op, es); + } +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/ModifyOperationWorker.java b/core/src/main/java/org/ldaptive/concurrent/ModifyOperationWorker.java new file mode 100644 index 0000000..b8e4b24 --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/ModifyOperationWorker.java
@@ -0,0 +1,38 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.concurrent.ExecutorService; +import org.ldaptive.ModifyOperation; +import org.ldaptive.ModifyRequest; + +/** + * Executes an ldap modify operation on a separate thread. + * + * @author Middleware Services + */ +public class ModifyOperationWorker extends AbstractOperationWorker<ModifyRequest, Void> +{ + + + /** + * Creates a new modify operation worker. + * + * @param op modify operation to execute + */ + public ModifyOperationWorker(final ModifyOperation op) + { + super(op); + } + + + /** + * Creates a new modify operation worker. + * + * @param op modify operation to execute + * @param es executor service + */ + public ModifyOperationWorker(final ModifyOperation op, final ExecutorService es) + { + super(op, es); + } +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/OperationWorker.java b/core/src/main/java/org/ldaptive/concurrent/OperationWorker.java new file mode 100644 index 0000000..34d3622 --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/OperationWorker.java
@@ -0,0 +1,52 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.Collection; +import java.util.concurrent.Future; +import org.ldaptive.Request; +import org.ldaptive.Response; + +/** + * Interface for ldap operation workers. Operation workers leverage the java.util.concurrent package to execute + * non-blocking operations. + * + * @param <Q> type of ldap request + * @param <S> type of ldap response + * + * @author Middleware Services + */ +public interface OperationWorker<Q extends Request, S> +{ + + + /** + * Execute an ldap operation on a separate thread. + * + * @param request containing the data required by this operation + * + * @return future response for this operation + */ + Future<Response<S>> execute(Q request); + + + /** + * Execute an ldap operation for each request on a separate thread. + * + * @param requests containing the data required by this operation + * + * @return future responses for this operation + */ + @SuppressWarnings("unchecked") + Collection<Future<Response<S>>> execute(Q... requests); + + + /** + * Execute an ldap operation for each request on a separate thread and waits for each operation to complete. + * + * @param requests containing the data required by this operation + * + * @return responses for this operation + */ + @SuppressWarnings("unchecked") + Collection<Response<S>> executeToCompletion(Q... requests); +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/ParallelPooledSearchExecutor.java b/core/src/main/java/org/ldaptive/concurrent/ParallelPooledSearchExecutor.java new file mode 100644 index 0000000..a181e1c --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/ParallelPooledSearchExecutor.java
@@ -0,0 +1,123 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletionService; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Operation; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.handler.SearchEntryHandler; +import org.ldaptive.pool.PooledConnectionFactory; + +/** + * Executes a list of search filters in parallel, each search is performed on a separate connection in the pool. If you + * need to execute all searches on the same connection see {@link ParallelSearchExecutor}. A cached thread pool is used + * by default. + * + * @author Middleware Services + */ +public class ParallelPooledSearchExecutor extends AbstractParallelSearchExecutor<PooledConnectionFactory> +{ + + + /** Default constructor. */ + public ParallelPooledSearchExecutor() + { + this(Executors.newCachedThreadPool()); + } + + + /** + * Creates a new parallel pooled search executor. + * + * @param es executor service + */ + public ParallelPooledSearchExecutor(final ExecutorService es) + { + super(es); + } + + + @Override + public Collection<Response<SearchResult>> search( + final PooledConnectionFactory factory, + final SearchFilter[] filters, + final String[] attrs, + final SearchEntryHandler... handlers) + throws LdapException + { + final CompletionService<Response<SearchResult>> searches = new ExecutorCompletionService<>(getExecutorService()); + final List<Future<Response<SearchResult>>> futures = new ArrayList<>(filters.length); + for (SearchFilter filter : filters) { + final SearchRequest sr = newSearchRequest(this); + if (filter != null) { + sr.setSearchFilter(filter); + } + if (attrs != null) { + sr.setReturnAttributes(attrs); + } + if (handlers != null) { + sr.setSearchEntryHandlers(handlers); + } + + final Connection conn = factory.getConnection(); + final SearchOperation op = createSearchOperation(conn); + futures.add(searches.submit(createCallable(conn, op, sr))); + } + + final List<Response<SearchResult>> responses = new ArrayList<>(filters.length); + for (Future<Response<SearchResult>> future : futures) { + try { + responses.add(future.get()); + } catch (ExecutionException e) { + logger.debug("ExecutionException thrown, ignoring", e); + } catch (InterruptedException e) { + logger.warn("InterruptedException thrown, ignoring", e); + } + } + return responses; + } + + + /** + * Returns a {@link Callable} that executes the supplied request with the supplied operation in a try-finally block + * that opens and closes the connection. + * + * @param <Q> type of ldap request + * @param <S> type of ldap response + * @param conn connection that the operation will execute on + * @param operation to execute + * @param request to pass to the operation + * + * @return callable for the supplied operation and request + */ + protected static <Q extends Request, S> Callable<Response<S>> createCallable( + final Connection conn, + final Operation<Q, S> operation, + final Q request) + { + return + () -> { + try { + conn.open(); + return operation.execute(request); + } finally { + conn.close(); + } + }; + } +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/ParallelSearchExecutor.java b/core/src/main/java/org/ldaptive/concurrent/ParallelSearchExecutor.java new file mode 100644 index 0000000..a8a442e --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/ParallelSearchExecutor.java
@@ -0,0 +1,77 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.Collection; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.LdapException; +import org.ldaptive.Response; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.handler.SearchEntryHandler; + +/** + * Executes a list of search filters in parallel. This implementation executes each search on the same connection in + * separate threads. If you need parallel searches over a pool of connections see {@link ParallelPooledSearchExecutor}. + * A cached thread pool is used by default. + * + * @author Middleware Services + */ +public class ParallelSearchExecutor extends AbstractParallelSearchExecutor<ConnectionFactory> +{ + + /** Default constructor. */ + public ParallelSearchExecutor() + { + this(Executors.newCachedThreadPool()); + } + + + /** + * Creates a new parallel search executor. + * + * @param es executor service + */ + public ParallelSearchExecutor(final ExecutorService es) + { + super(es); + } + + + @Override + public Collection<Response<SearchResult>> search( + final ConnectionFactory factory, + final SearchFilter[] filters, + final String[] attrs, + final SearchEntryHandler... handlers) + throws LdapException + { + Collection<Response<SearchResult>> response; + try (Connection conn = factory.getConnection()) { + conn.open(); + + final SearchOperation op = createSearchOperation(conn); + + final SearchOperationWorker worker = new SearchOperationWorker(op, getExecutorService()); + final SearchRequest[] sr = new SearchRequest[filters.length]; + for (int i = 0; i < filters.length; i++) { + sr[i] = newSearchRequest(this); + if (filters[i] != null) { + sr[i].setSearchFilter(filters[i]); + } + if (attrs != null) { + sr[i].setReturnAttributes(attrs); + } + if (handlers != null) { + sr[i].setSearchEntryHandlers(handlers); + } + } + response = worker.executeToCompletion(sr); + } + return response; + } +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/QueueingSearchExecutor.java b/core/src/main/java/org/ldaptive/concurrent/QueueingSearchExecutor.java new file mode 100644 index 0000000..198e07f --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/QueueingSearchExecutor.java
@@ -0,0 +1,648 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.LdapException; +import org.ldaptive.LdapUtils; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchReference; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.handler.HandlerResult; +import org.ldaptive.intermediate.IntermediateResponse; + +/** + * Executes a search filter and places the results of the operation on a blocking queue. The capacity of the queue can + * be configured to address memory concerns related to large result sets. + * + * @author Middleware Services + */ +public class QueueingSearchExecutor extends AbstractSearchExecutor +{ + + /** Capacity of the blocking queue created by search operations. */ + private final int queueCapacity; + + + /** Default constructor. */ + public QueueingSearchExecutor() + { + this(Integer.MAX_VALUE, Executors.newCachedThreadPool()); + } + + + /** + * Creates a new blocking search executor. + * + * @param capacity of the blocking queue returned from search operations + */ + public QueueingSearchExecutor(final int capacity) + { + this(capacity, Executors.newCachedThreadPool()); + } + + + /** + * Creates a new blocking search executor. + * + * @param es executor service + */ + public QueueingSearchExecutor(final ExecutorService es) + { + this(Integer.MAX_VALUE, es); + } + + + /** + * Creates a new blocking search executor. + * + * @param capacity of the blocking queue returned from search operations + * @param es executor service + */ + public QueueingSearchExecutor(final int capacity, final ExecutorService es) + { + super(es); + queueCapacity = capacity; + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * + * @return blocking queue to receive search items + * + * @throws LdapException if the connection factory cannot create a connection + */ + public BlockingQueue<SearchItem> search(final ConnectionFactory factory) + throws LdapException + { + return search(factory, null, null, (org.ldaptive.handler.SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * @param filter to search with + * + * @return blocking queue to receive search items + * + * @throws LdapException if the connection factory cannot create a connection + */ + public BlockingQueue<SearchItem> search(final ConnectionFactory factory, final String filter) + throws LdapException + { + return search(factory, new SearchFilter(filter), null, (org.ldaptive.handler.SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * @param filter to search with + * + * @return blocking queue to receive search items + * + * @throws LdapException if the connection factory cannot create a connection + */ + public BlockingQueue<SearchItem> search(final ConnectionFactory factory, final SearchFilter filter) + throws LdapException + { + return search(factory, filter, null, (org.ldaptive.handler.SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * @param filter to search with + * @param attrs to return + * + * @return blocking queue to receive search items + * + * @throws LdapException if the connection factory cannot create a connection + */ + public BlockingQueue<SearchItem> search(final ConnectionFactory factory, final String filter, final String... attrs) + throws LdapException + { + return search(factory, new SearchFilter(filter), attrs, (org.ldaptive.handler.SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * @param filter to search with + * @param attrs to return + * + * @return blocking queue to receive search items + * + * @throws LdapException if the connection factory cannot create a connection + */ + public BlockingQueue<SearchItem> search( + final ConnectionFactory factory, + final SearchFilter filter, + final String... attrs) + throws LdapException + { + return search(factory, filter, attrs, (org.ldaptive.handler.SearchEntryHandler[]) null); + } + + + /** + * Performs a search operation with the supplied connection factory. + * + * @param factory to get a connection from + * @param filter to search with + * @param attrs to return + * @param handlers entry handlers + * + * @return blocking queue to receive search items + * + * @throws LdapException if the connection factory cannot create a connection + */ + public BlockingQueue<SearchItem> search( + final ConnectionFactory factory, + final SearchFilter filter, + final String[] attrs, + final org.ldaptive.handler.SearchEntryHandler... handlers) + throws LdapException + { + final BlockingQueue<SearchItem> queue = new LinkedBlockingQueue<>(queueCapacity); + + final SearchRequest sr = newSearchRequest(this); + if (filter != null) { + sr.setSearchFilter(filter); + } + if (attrs != null) { + sr.setReturnAttributes(attrs); + } + if (handlers != null) { + sr.setSearchEntryHandlers(handlers); + } + configureSearchRequest(sr, queue); + + final Connection conn = factory.getConnection(); + final SearchOperation op = createSearchOperation(conn); + + final ExecutorService service = getExecutorService(); + service.submit(createCallable(conn, op, sr, queue)); + + return queue; + } + + + /** + * Returns a {@link Callable} that executes the supplied request with the supplied operation in a try-finally block + * that opens and closes the connection. + * + * @param conn connection that the operation will execute on + * @param operation to execute + * @param request to pass to the operation + * @param queue to put search items on + * + * @return callable for the supplied operation and request + */ + protected Callable<Response<SearchResult>> createCallable( + final Connection conn, + final SearchOperation operation, + final SearchRequest request, + final BlockingQueue<SearchItem> queue) + { + return + () -> { + try { + conn.open(); + + SearchItem item; + try { + final Response<SearchResult> response = operation.execute(request); + item = new SearchItem(response); + } catch (Exception e) { + item = new SearchItem(e); + } + try { + logger.debug("received {}", item); + queue.put(item); + } catch (InterruptedException e1) { + logger.warn("Unable to insert item {}", item); + } + return null; + } finally { + conn.close(); + } + }; + } + + + /** + * Sets the appropriate handlers on the supplied search request so that entries, references, and intermediate + * responses are made available on the supplied queue. + * + * @param request search request to modify + * @param queue to use in the handlers + */ + protected void configureSearchRequest(final SearchRequest request, final BlockingQueue<SearchItem> queue) + { + if (request.getSearchEntryHandlers() != null) { + request.setSearchEntryHandlers( + LdapUtils.concatArrays( + request.getSearchEntryHandlers(), + new org.ldaptive.handler.SearchEntryHandler[] {new SearchEntryHandler(queue), })); + } else { + request.setSearchEntryHandlers(new SearchEntryHandler(queue)); + } + if (request.getSearchReferenceHandlers() != null) { + request.setSearchReferenceHandlers( + LdapUtils.concatArrays( + request.getSearchReferenceHandlers(), + new org.ldaptive.handler.SearchReferenceHandler[] {new SearchReferenceHandler(queue), })); + } else { + request.setSearchReferenceHandlers(new SearchReferenceHandler(queue)); + } + if (request.getIntermediateResponseHandlers() != null) { + request.setIntermediateResponseHandlers( + LdapUtils.concatArrays( + request.getIntermediateResponseHandlers(), + new org.ldaptive.handler.IntermediateResponseHandler[] {new IntermediateResponseHandler(queue), })); + } else { + request.setIntermediateResponseHandlers(new IntermediateResponseHandler(queue)); + } + } + + + /** Places search entries on a blocking queue. */ + protected class SearchEntryHandler extends AbstractHandler implements org.ldaptive.handler.SearchEntryHandler + { + + + /** + * Creates a new search entry handler. + * + * @param q blocking queue + */ + public SearchEntryHandler(final BlockingQueue<SearchItem> q) + { + super(q); + } + + + @Override + public HandlerResult<SearchEntry> handle( + final Connection conn, + final SearchRequest request, + final SearchEntry entry) + throws LdapException + { + insert(new SearchItem(entry)); + return new HandlerResult<>(entry); + } + + + @Override + public void initializeRequest(final SearchRequest request) {} + } + + + /** Places search references on a blocking queue. */ + protected class SearchReferenceHandler extends AbstractHandler implements org.ldaptive.handler.SearchReferenceHandler + { + + + /** + * Creates a new search reference handler. + * + * @param q blocking queue + */ + public SearchReferenceHandler(final BlockingQueue<SearchItem> q) + { + super(q); + } + + + @Override + public HandlerResult<SearchReference> handle( + final Connection conn, + final SearchRequest request, + final SearchReference reference) + throws LdapException + { + insert(new SearchItem(reference)); + return new HandlerResult<>(reference); + } + + + @Override + public void initializeRequest(final SearchRequest request) {} + } + + + /** Places intermediate responses on a blocking queue. */ + protected class IntermediateResponseHandler extends AbstractHandler + implements org.ldaptive.handler.IntermediateResponseHandler + { + + + /** + * Creates a new intermediate response handler. + * + * @param q blocking queue + */ + public IntermediateResponseHandler(final BlockingQueue<SearchItem> q) + { + super(q); + } + + + @Override + public HandlerResult<IntermediateResponse> handle( + final Connection conn, + final Request request, + final IntermediateResponse response) + throws LdapException + { + insert(new SearchItem(response)); + return new HandlerResult<>(response); + } + } + + + /** Common implementation for the handler classes. */ + protected abstract class AbstractHandler + { + + /** Blocking queue to put items on. */ + private final BlockingQueue<SearchItem> queue; + + + /** + * Creates a new abstract handler. + * + * @param q blocking queue to put items on + */ + public AbstractHandler(final BlockingQueue<SearchItem> q) + { + queue = q; + } + + + /** + * Places the supplied item on the blocking queue. + * + * @param item to insert + */ + protected void insert(final SearchItem item) + { + try { + logger.debug("received {}", item); + queue.put(item); + } catch (Exception e) { + logger.warn("Unable to insert item {}", item); + } + } + } + + + /** Contains data returned when using the {@link QueueingSearchExecutor}. */ + public static class SearchItem + { + + /** Search entry contained in this blocking search item. */ + private final SearchEntry searchEntry; + + /** Search reference contained in this blocking search item. */ + private final SearchReference searchReference; + + /** Intermediate response contained in this blocking search item. */ + private final IntermediateResponse intermediateResponse; + + /** Response contained in this blocking search item. */ + private final Response<SearchResult> searchResponse; + + /** Exception thrown by the search operation. */ + private final Exception searchException; + + + /** + * Creates a new blocking search item. + * + * @param entry that represents this item + */ + public SearchItem(final SearchEntry entry) + { + searchEntry = entry; + searchReference = null; + intermediateResponse = null; + searchResponse = null; + searchException = null; + } + + + /** + * Creates a new blocking search item. + * + * @param reference that represents this item + */ + public SearchItem(final SearchReference reference) + { + searchEntry = null; + searchReference = reference; + intermediateResponse = null; + searchResponse = null; + searchException = null; + } + + + /** + * Creates a new blocking search item. + * + * @param response that represents this item + */ + public SearchItem(final IntermediateResponse response) + { + searchEntry = null; + searchReference = null; + intermediateResponse = response; + searchResponse = null; + searchException = null; + } + + + /** + * Creates a new blocking search item. + * + * @param response that represents this item + */ + public SearchItem(final Response<SearchResult> response) + { + searchEntry = null; + searchReference = null; + intermediateResponse = null; + searchResponse = response; + searchException = null; + } + + + /** + * Creates a new blocking search item. + * + * @param exception that represents this item + */ + public SearchItem(final Exception exception) + { + searchEntry = null; + searchReference = null; + intermediateResponse = null; + searchResponse = null; + searchException = exception; + } + + + /** + * Returns whether this item represents a search entry. + * + * @return whether this item represents a search entry + */ + public boolean isEntry() + { + return searchEntry != null; + } + + + /** + * Returns the search entry contained in this item or null if this item does not contain a search entry. + * + * @return search entry + */ + public SearchEntry getEntry() + { + return searchEntry; + } + + + /** + * Returns whether this item represents a search reference. + * + * @return whether this item represents a search reference + */ + public boolean isReference() + { + return searchReference != null; + } + + + /** + * Returns the search reference contained in this item or null if this item does not contain a search reference. + * + * @return search entry + */ + public SearchReference getReference() + { + return searchReference; + } + + + /** + * Returns whether this item represents an intermediate response. + * + * @return whether this item represents an intermediate response + */ + public boolean isIntermediateResponse() + { + return intermediateResponse != null; + } + + + /** + * Returns the intermediate response contained in this item or null if this item does not contain an intermediate + * response. + * + * @return intermediate response + */ + public IntermediateResponse getIntermediateResponse() + { + return intermediateResponse; + } + + + /** + * Returns whether this item represents a response. + * + * @return whether this item represents a response + */ + public boolean isResponse() + { + return searchResponse != null; + } + + + /** + * Returns the response contained in this item or null if this item does not contain a response. + * + * @return response + */ + public Response<SearchResult> getResponse() + { + return searchResponse; + } + + + /** + * Returns whether this item represents an exception. + * + * @return whether this item represents an exception + */ + public boolean isException() + { + return searchException != null; + } + + + /** + * Returns the exception contained in this item or null if this item does not contain an exception. + * + * @return exception + */ + public Exception getException() + { + return searchException; + } + + + @Override + public String toString() + { + String s; + if (isEntry()) { + s = String.format("[%s@%d::searchEntry=%s]", getClass().getName(), hashCode(), searchEntry); + } else if (isReference()) { + s = String.format("[%s@%d::searchReference=%s]", getClass().getName(), hashCode(), searchReference); + } else if (isIntermediateResponse()) { + s = String.format("[%s@%d::intermediateResponse=%s]", getClass().getName(), hashCode(), intermediateResponse); + } else if (isResponse()) { + s = String.format("[%s@%d::searchResponse=%s]", getClass().getName(), hashCode(), searchResponse); + } else if (isException()) { + s = String.format("[%s@%d::searchException=%s]", getClass().getName(), hashCode(), searchException); + } else { + s = String.format("[%s@%d]", getClass().getName(), hashCode()); + } + return s; + } + } +}
diff --git a/core/src/main/java/org/ldaptive/concurrent/SearchOperationWorker.java b/core/src/main/java/org/ldaptive/concurrent/SearchOperationWorker.java new file mode 100644 index 0000000..6ac6610 --- /dev/null +++ b/core/src/main/java/org/ldaptive/concurrent/SearchOperationWorker.java
@@ -0,0 +1,39 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.concurrent; + +import java.util.concurrent.ExecutorService; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; + +/** + * Executes an ldap search operation on a separate thread. + * + * @author Middleware Services + */ +public class SearchOperationWorker extends AbstractOperationWorker<SearchRequest, SearchResult> +{ + + + /** + * Creates a new search operation worker. + * + * @param op search operation to execute + */ + public SearchOperationWorker(final SearchOperation op) + { + super(op); + } + + + /** + * Creates a new search operation worker. + * + * @param op search operation to execute + * @param es executor service + */ + public SearchOperationWorker(final SearchOperation op, final ExecutorService es) + { + super(op, es); + } +}
diff --git a/core/src/main/java/org/ldaptive/control/AbstractControl.java b/core/src/main/java/org/ldaptive/control/AbstractControl.java new file mode 100644 index 0000000..cc28361 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/AbstractControl.java
@@ -0,0 +1,87 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base class for ldap controls. + * + * @author Middleware Services + */ +public abstract class AbstractControl implements Control +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** control oid. */ + private final String oid; + + /** is control critical. */ + private final boolean criticality; + + + /** + * Creates a new abstract control. + * + * @param id OID of this control + */ + public AbstractControl(final String id) + { + oid = id; + criticality = false; + } + + + /** + * Creates a new abstract control. + * + * @param id OID of this control + * @param b whether this control is critical + */ + public AbstractControl(final String id, final boolean b) + { + oid = id; + criticality = b; + } + + + @Override + public String getOID() + { + return oid; + } + + + @Override + public boolean getCriticality() + { + return criticality; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof AbstractControl) { + final AbstractControl v = (AbstractControl) o; + return LdapUtils.areEqual(getOID(), v.getOID()) && + LdapUtils.areEqual(getCriticality(), v.getCriticality()); + } + return false; + } + + + /** + * Returns the hash code for this object. + * + * @return hash code + */ + @Override + public abstract int hashCode(); +}
diff --git a/core/src/main/java/org/ldaptive/control/AuthorizationIdentityRequestControl.java b/core/src/main/java/org/ldaptive/control/AuthorizationIdentityRequestControl.java new file mode 100644 index 0000000..c89c9ae --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/AuthorizationIdentityRequestControl.java
@@ -0,0 +1,68 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; + +/** + * Request control for authorization identify. See RFC 3829. + * + * @author Middleware Services + */ +public class AuthorizationIdentityRequestControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "2.16.840.1.113730.3.4.16"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 7013; + + + /** Default constructor. */ + public AuthorizationIdentityRequestControl() + { + super(OID); + } + + + /** + * Creates a new ManageDsaIT control. + * + * @param critical whether this control is critical + */ + public AuthorizationIdentityRequestControl(final boolean critical) + { + super(OID, critical); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + return o instanceof AuthorizationIdentityRequestControl && super.equals(o); + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality()); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::criticality=%s]", getClass().getName(), hashCode(), getCriticality()); + } + + + @Override + public byte[] encode() + { + return null; + } +}
diff --git a/core/src/main/java/org/ldaptive/control/AuthorizationIdentityResponseControl.java b/core/src/main/java/org/ldaptive/control/AuthorizationIdentityResponseControl.java new file mode 100644 index 0000000..dc0da20 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/AuthorizationIdentityResponseControl.java
@@ -0,0 +1,130 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.nio.ByteBuffer; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.OctetStringType; + +/** + * Response control for authorization identity. See RFC 3829. Control value contains the authorizationId. + * + * @author Middleware Services + */ +public class AuthorizationIdentityResponseControl extends AbstractControl implements ResponseControl +{ + + /** OID of this control. */ + public static final String OID = "2.16.840.1.113730.3.4.15"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 7019; + + /** Authorization identity. */ + private String authorizationId; + + + /** Default constructor. */ + public AuthorizationIdentityResponseControl() + { + super(OID); + } + + + /** + * Creates a new authorization identity response control. + * + * @param critical whether this control is critical + */ + public AuthorizationIdentityResponseControl(final boolean critical) + { + super(OID, critical); + } + + + /** + * Creates a new authorization identity response control. + * + * @param id authorization id + */ + public AuthorizationIdentityResponseControl(final String id) + { + this(id, false); + } + + + /** + * Creates a new authorization identity response control. + * + * @param id authorization id + * @param critical whether this control is critical + */ + public AuthorizationIdentityResponseControl(final String id, final boolean critical) + { + super(OID, critical); + setAuthorizationId(id); + } + + + /** + * Returns the authorization id. + * + * @return authorization id + */ + public String getAuthorizationId() + { + return authorizationId; + } + + + /** + * Sets the authorization identity. + * + * @param id authorization id + */ + public void setAuthorizationId(final String id) + { + authorizationId = id; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof AuthorizationIdentityResponseControl && super.equals(o)) { + final AuthorizationIdentityResponseControl v = (AuthorizationIdentityResponseControl) o; + return LdapUtils.areEqual(authorizationId, v.authorizationId); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality(), authorizationId); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, authorizationId=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + authorizationId); + } + + + @Override + public void decode(final byte[] berValue) + { + logger.trace("decoding control: {}", LdapUtils.base64Encode(berValue)); + setAuthorizationId(OctetStringType.decode(ByteBuffer.wrap(berValue))); + } +}
diff --git a/core/src/main/java/org/ldaptive/control/Control.java b/core/src/main/java/org/ldaptive/control/Control.java new file mode 100644 index 0000000..55f7b29 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/Control.java
@@ -0,0 +1,27 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +/** + * Marker interface for ldap controls. + * + * @author Middleware Services + */ +public interface Control +{ + + + /** + * Returns the OID for this control. + * + * @return oid + */ + String getOID(); + + + /** + * Returns whether the control is critical. + * + * @return whether the control is critical + */ + boolean getCriticality(); +}
diff --git a/core/src/main/java/org/ldaptive/control/ControlFactory.java b/core/src/main/java/org/ldaptive/control/ControlFactory.java new file mode 100644 index 0000000..f3fa007 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/ControlFactory.java
@@ -0,0 +1,105 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.ad.control.DirSyncControl; +import org.ldaptive.ad.control.GetStatsControl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utility class for creating controls. + * + * @author Middleware Services + */ +public final class ControlFactory +{ + + /** Logger for this class. */ + private static final Logger LOGGER = LoggerFactory.getLogger(ControlFactory.class); + + + /** Default constructor. */ + private ControlFactory() {} + + + /** + * Creates a response control from the supplied control data. + * + * @param oid of the control + * @param critical whether the control is critical + * @param encoded BER encoding of the control + * + * @return response control + */ + public static ResponseControl createResponseControl(final String oid, final boolean critical, final byte[] encoded) + { + ResponseControl ctl = null; + switch (oid) { + + case SortResponseControl.OID: + ctl = new SortResponseControl(critical); + ctl.decode(encoded); + break; + + case PagedResultsControl.OID: + ctl = new PagedResultsControl(critical); + ctl.decode(encoded); + break; + + case VirtualListViewResponseControl.OID: + ctl = new VirtualListViewResponseControl(critical); + ctl.decode(encoded); + break; + + case PasswordPolicyControl.OID: + ctl = new PasswordPolicyControl(critical); + ctl.decode(encoded); + break; + + case SyncStateControl.OID: + ctl = new SyncStateControl(critical); + ctl.decode(encoded); + break; + + case SyncDoneControl.OID: + ctl = new SyncDoneControl(critical); + ctl.decode(encoded); + break; + + case DirSyncControl.OID: + ctl = new DirSyncControl(critical); + ctl.decode(encoded); + break; + + case EntryChangeNotificationControl.OID: + ctl = new EntryChangeNotificationControl(critical); + ctl.decode(encoded); + break; + + case GetStatsControl.OID: + ctl = new GetStatsControl(critical); + ctl.decode(encoded); + break; + + case PasswordExpiredControl.OID: + ctl = new PasswordExpiredControl(critical); + ctl.decode(encoded); + break; + + case PasswordExpiringControl.OID: + ctl = new PasswordExpiringControl(critical); + ctl.decode(encoded); + break; + + case AuthorizationIdentityResponseControl.OID: + ctl = new AuthorizationIdentityResponseControl(critical); + ctl.decode(encoded); + break; + + default: + LOGGER.debug("Unsupported response control OID {}", oid); + break; + } + return ctl; + } +}
diff --git a/core/src/main/java/org/ldaptive/control/EntryChangeNotificationControl.java b/core/src/main/java/org/ldaptive/control/EntryChangeNotificationControl.java new file mode 100644 index 0000000..8f98c7a --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/EntryChangeNotificationControl.java
@@ -0,0 +1,327 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.nio.ByteBuffer; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.AbstractParseHandler; +import org.ldaptive.asn1.DERParser; +import org.ldaptive.asn1.DERPath; +import org.ldaptive.asn1.IntegerType; +import org.ldaptive.asn1.OctetStringType; + +/** + * Response control for persistent search. See http://tools.ietf.org/id/draft-ietf-ldapext-psearch-03.txt. Control is + * defined as: + * + * <pre> + EntryChangeNotification ::= SEQUENCE { + changeType ENUMERATED { + add (1), + delete (2), + modify (4), + modDN (8) + }, + previousDN LDAPDN OPTIONAL, -- modifyDN ops. only + changeNumber INTEGER OPTIONAL -- if supported + } + * </pre> + * + * @author Middleware Services + */ +public class EntryChangeNotificationControl extends AbstractControl implements ResponseControl +{ + + /** OID of this control. */ + public static final String OID = "2.16.840.1.113730.3.4.7"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 773; + + /** change type. */ + private PersistentSearchChangeType changeType; + + /** previous dn. */ + private String previousDn; + + /** change number. */ + private long changeNumber = -1; + + + /** Default constructor. */ + public EntryChangeNotificationControl() + { + super(OID); + } + + + /** + * Creates a new entry change notification control. + * + * @param critical whether this control is critical + */ + public EntryChangeNotificationControl(final boolean critical) + { + super(OID, critical); + } + + + /** + * Creates a new entry change notification control. + * + * @param type persistent search change type + */ + public EntryChangeNotificationControl(final PersistentSearchChangeType type) + { + this(type, false); + } + + + /** + * Creates a new entry change notification control. + * + * @param type persistent search change type + * @param critical whether this control is critical + */ + public EntryChangeNotificationControl(final PersistentSearchChangeType type, final boolean critical) + { + super(OID, critical); + setChangeType(type); + } + + + /** + * Creates a new entry change notification control. + * + * @param type persistent search change type + * @param dn previous dn + * @param number change number + */ + public EntryChangeNotificationControl(final PersistentSearchChangeType type, final String dn, final long number) + { + this(type, dn, number, false); + } + + + /** + * Creates a new entry change notification control. + * + * @param type persistent search change type + * @param dn previous dn + * @param number change number + * @param critical whether this control is critical + */ + public EntryChangeNotificationControl( + final PersistentSearchChangeType type, + final String dn, + final long number, + final boolean critical) + { + super(OID, critical); + setChangeType(type); + setPreviousDn(dn); + setChangeNumber(number); + } + + + /** + * Returns the change type. + * + * @return change type + */ + public PersistentSearchChangeType getChangeType() + { + return changeType; + } + + + /** + * Sets the change type. + * + * @param type change type + */ + public void setChangeType(final PersistentSearchChangeType type) + { + changeType = type; + } + + + /** + * Returns the previous dn. + * + * @return previous dn + */ + public String getPreviousDn() + { + return previousDn; + } + + + /** + * Sets the previous dn. + * + * @param dn previous dn + */ + public void setPreviousDn(final String dn) + { + previousDn = dn; + } + + + /** + * Returns the change number. + * + * @return change number + */ + public long getChangeNumber() + { + return changeNumber; + } + + + /** + * Sets the change number. + * + * @param number change number + */ + public void setChangeNumber(final long number) + { + changeNumber = number; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof EntryChangeNotificationControl && super.equals(o)) { + final EntryChangeNotificationControl v = (EntryChangeNotificationControl) o; + return LdapUtils.areEqual(changeType, v.changeType) && + LdapUtils.areEqual(previousDn, v.previousDn) && + LdapUtils.areEqual(changeNumber, v.changeNumber); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality(), changeType, previousDn, changeNumber); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, changeType=%s, previousDn=%s, changeNumber=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + changeType, + previousDn, + changeNumber); + } + + + @Override + public void decode(final byte[] berValue) + { + logger.trace("decoding control: {}", LdapUtils.base64Encode(berValue)); + + final DERParser parser = new DERParser(); + parser.registerHandler(ChangeTypeHandler.PATH, new ChangeTypeHandler(this)); + parser.registerHandler(PreviousDnHandler.PATH, new PreviousDnHandler(this)); + parser.registerHandler(ChangeNumberHandler.PATH, new ChangeNumberHandler(this)); + parser.parse(ByteBuffer.wrap(berValue)); + } + + + /** Parse handler implementation for the change type. */ + private static class ChangeTypeHandler extends AbstractParseHandler<EntryChangeNotificationControl> + { + + /** DER path to change type. */ + public static final DERPath PATH = new DERPath("/SEQ/ENUM"); + + + /** + * Creates a new change type handler. + * + * @param control to configure + */ + ChangeTypeHandler(final EntryChangeNotificationControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + final int typeValue = IntegerType.decode(encoded).intValue(); + final PersistentSearchChangeType ct = PersistentSearchChangeType.valueOf(typeValue); + if (ct == null) { + throw new IllegalArgumentException("Unknown change type code " + typeValue); + } + getObject().setChangeType(ct); + } + } + + + /** Parse handler implementation for the previous dn. */ + private static class PreviousDnHandler extends AbstractParseHandler<EntryChangeNotificationControl> + { + + /** DER path to previous dn. */ + public static final DERPath PATH = new DERPath("/SEQ/OCTSTR[1]"); + + + /** + * Creates a new previous dn handler. + * + * @param control to configure + */ + PreviousDnHandler(final EntryChangeNotificationControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setPreviousDn(OctetStringType.decode(encoded)); + } + } + + + /** Parse handler implementation for the change number. */ + private static class ChangeNumberHandler extends AbstractParseHandler<EntryChangeNotificationControl> + { + + /** DER path to change number. */ + public static final DERPath PATH = new DERPath("/SEQ/INT[2]"); + + + /** + * Creates a new change number handler. + * + * @param control to configure + */ + ChangeNumberHandler(final EntryChangeNotificationControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setChangeNumber(IntegerType.decode(encoded).intValue()); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/control/ManageDsaITControl.java b/core/src/main/java/org/ldaptive/control/ManageDsaITControl.java new file mode 100644 index 0000000..4a20bbc --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/ManageDsaITControl.java
@@ -0,0 +1,68 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; + +/** + * Request control for ManageDsaIT. See RFC 3296. + * + * @author Middleware Services + */ +public class ManageDsaITControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "2.16.840.1.113730.3.4.2"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 701; + + + /** Default constructor. */ + public ManageDsaITControl() + { + super(OID); + } + + + /** + * Creates a new ManageDsaIT control. + * + * @param critical whether this control is critical + */ + public ManageDsaITControl(final boolean critical) + { + super(OID, critical); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + return o instanceof ManageDsaITControl && super.equals(o); + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality()); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::criticality=%s]", getClass().getName(), hashCode(), getCriticality()); + } + + + @Override + public byte[] encode() + { + return null; + } +}
diff --git a/core/src/main/java/org/ldaptive/control/PagedResultsControl.java b/core/src/main/java/org/ldaptive/control/PagedResultsControl.java new file mode 100644 index 0000000..3ae23ab --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/PagedResultsControl.java
@@ -0,0 +1,265 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.nio.ByteBuffer; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.AbstractParseHandler; +import org.ldaptive.asn1.ConstructedDEREncoder; +import org.ldaptive.asn1.DERParser; +import org.ldaptive.asn1.DERPath; +import org.ldaptive.asn1.IntegerType; +import org.ldaptive.asn1.OctetStringType; +import org.ldaptive.asn1.UniversalDERTag; + +/** + * Request/response control for PagedResults. See RFC 2696. Control is defined as: + * + * <pre> + realSearchControlValue ::= SEQUENCE { + size INTEGER (0..maxInt), + -- requested page size from client + -- result set size estimate from server + cookie OCTET STRING + } + * </pre> + * + * @author Middleware Services + */ +public class PagedResultsControl extends AbstractControl implements RequestControl, ResponseControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.319"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 709; + + /** Empty byte array used for null cookies. */ + private static final byte[] EMPTY_COOKIE = new byte[0]; + + /** paged results size. */ + private int resultSize; + + /** server generated cookie. */ + private byte[] cookie; + + + /** Default constructor. */ + public PagedResultsControl() + { + super(OID); + } + + + /** + * Creates a new paged results control. + * + * @param critical whether this control is critical + */ + public PagedResultsControl(final boolean critical) + { + super(OID, critical); + } + + + /** + * Creates a new paged results control. + * + * @param size paged results size + */ + public PagedResultsControl(final int size) + { + super(OID); + setSize(size); + } + + + /** + * Creates a new paged results control. + * + * @param size paged results size + * @param critical whether this control is critical + */ + public PagedResultsControl(final int size, final boolean critical) + { + super(OID, critical); + setSize(size); + } + + + /** + * Creates a new paged results control. + * + * @param size paged results size + * @param value paged results cookie + * @param critical whether this control is critical + */ + public PagedResultsControl(final int size, final byte[] value, final boolean critical) + { + super(OID, critical); + setSize(size); + setCookie(value); + } + + + /** + * Returns the paged results size. For requests this is the requested page size. For responses this is the result size + * estimate from the server. + * + * @return paged results size + */ + public int getSize() + { + return resultSize; + } + + + /** + * Sets the paged results size. For requests this is the requested page size. For responses this is the result size + * estimate from the server. + * + * @param size paged results size + */ + public void setSize(final int size) + { + resultSize = size; + } + + + /** + * Returns the paged results cookie. + * + * @return paged results cookie + */ + public byte[] getCookie() + { + return cookie; + } + + + /** + * Sets the paged results cookie. + * + * @param value paged results cookie + */ + public void setCookie(final byte[] value) + { + cookie = value; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof PagedResultsControl && super.equals(o)) { + final PagedResultsControl v = (PagedResultsControl) o; + return LdapUtils.areEqual(resultSize, v.resultSize) && + LdapUtils.areEqual(cookie, v.cookie); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality(), resultSize, cookie); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, size=%s, cookie=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + resultSize, + LdapUtils.base64Encode(cookie)); + } + + + @Override + public byte[] encode() + { + final ConstructedDEREncoder se = new ConstructedDEREncoder( + UniversalDERTag.SEQ, + new IntegerType(getSize()), + new OctetStringType(getCookie() != null ? getCookie() : EMPTY_COOKIE)); + return se.encode(); + } + + + @Override + public void decode(final byte[] berValue) + { + logger.trace("decoding control: {}", LdapUtils.base64Encode(berValue)); + + final DERParser parser = new DERParser(); + parser.registerHandler(SizeHandler.PATH, new SizeHandler(this)); + parser.registerHandler(CookieHandler.PATH, new CookieHandler(this)); + parser.parse(ByteBuffer.wrap(berValue)); + } + + + /** Parse handler implementation for the size. */ + private static class SizeHandler extends AbstractParseHandler<PagedResultsControl> + { + + /** DER path to result size. */ + public static final DERPath PATH = new DERPath("/SEQ/INT"); + + + /** + * Creates a new size handler. + * + * @param control to configure + */ + SizeHandler(final PagedResultsControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setSize(IntegerType.decode(encoded).intValue()); + } + } + + + /** Parse handler implementation for the cookie. */ + private static class CookieHandler extends AbstractParseHandler<PagedResultsControl> + { + + /** DER path to cookie value. */ + public static final DERPath PATH = new DERPath("/SEQ/OCTSTR"); + + + /** + * Creates a new cookie handler. + * + * @param control to configure + */ + CookieHandler(final PagedResultsControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + final byte[] cookie = OctetStringType.readBuffer(encoded); + if (cookie != null && cookie.length > 0) { + getObject().setCookie(cookie); + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/control/PasswordExpiredControl.java b/core/src/main/java/org/ldaptive/control/PasswordExpiredControl.java new file mode 100644 index 0000000..da9d3c0 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/PasswordExpiredControl.java
@@ -0,0 +1,80 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.nio.ByteBuffer; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.OctetStringType; + +/** + * Response control indicating an expired password. See http://tools.ietf.org/html/draft-vchu-ldap-pwd-policy-00. + * Control is defined as: + * + * <pre> + controlValue ::= OCTET STRING -- always "0" + * </pre> + * + * @author Middleware Services + */ +public class PasswordExpiredControl extends AbstractControl implements ResponseControl +{ + + /** OID of this control. */ + public static final String OID = "2.16.840.1.113730.3.4.4"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 787; + + + /** Default constructor. */ + public PasswordExpiredControl() + { + super(OID); + } + + + /** + * Creates a new password expired control. + * + * @param critical whether this control is critical + */ + public PasswordExpiredControl(final boolean critical) + { + super(OID, critical); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + return o instanceof PasswordExpiredControl && super.equals(o); + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality()); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::criticality=%s]", getClass().getName(), hashCode(), getCriticality()); + } + + + @Override + public void decode(final byte[] berValue) + { + logger.trace("decoding control: {}", LdapUtils.base64Encode(berValue)); + + final String value = OctetStringType.decode(ByteBuffer.wrap(berValue)); + if (!"0".equals(value)) { + throw new IllegalArgumentException("Response control value should always be '0'"); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/control/PasswordExpiringControl.java b/core/src/main/java/org/ldaptive/control/PasswordExpiringControl.java new file mode 100644 index 0000000..4c6c24e --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/PasswordExpiringControl.java
@@ -0,0 +1,134 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.nio.ByteBuffer; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.OctetStringType; + +/** + * Response control indicating a password that will expire. See + * http://tools.ietf.org/html/draft-vchu-ldap-pwd-policy-00. Control is defined as: + * + * <pre> + controlValue ::= secondsUntilExpiration OCTET STRING + * </pre> + * + * @author Middleware Services + */ +public class PasswordExpiringControl extends AbstractControl implements ResponseControl +{ + + /** OID of this control. */ + public static final String OID = "2.16.840.1.113730.3.4.5"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 797; + + /** time in seconds until expiration. */ + private int timeBeforeExpiration; + + + /** Default constructor. */ + public PasswordExpiringControl() + { + super(OID); + } + + + /** + * Creates a new password expiring control. + * + * @param critical whether this control is critical + */ + public PasswordExpiringControl(final boolean critical) + { + super(OID, critical); + } + + + /** + * Creates a new password expiring control. + * + * @param time in seconds until expiration + */ + public PasswordExpiringControl(final int time) + { + super(OID); + setTimeBeforeExpiration(time); + } + + + /** + * Creates a new password expiring control. + * + * @param time in seconds until expiration + * @param critical whether this control is critical + */ + public PasswordExpiringControl(final int time, final boolean critical) + { + super(OID, critical); + setTimeBeforeExpiration(time); + } + + + /** + * Returns the time in seconds until password expiration. + * + * @return time in seconds until expiration + */ + public int getTimeBeforeExpiration() + { + return timeBeforeExpiration; + } + + + /** + * Sets the time in seconds until password expiration. + * + * @param time in seconds until expiration + */ + public void setTimeBeforeExpiration(final int time) + { + timeBeforeExpiration = time; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + return o instanceof PasswordExpiringControl && super.equals(o); + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality()); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, timeBeforeExpiration=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + timeBeforeExpiration); + } + + + @Override + public void decode(final byte[] berValue) + { + logger.trace("decoding control: {}", LdapUtils.base64Encode(berValue)); + + final String time = OctetStringType.decode(ByteBuffer.wrap(berValue)); + setTimeBeforeExpiration(Integer.valueOf(time)); + } +}
diff --git a/core/src/main/java/org/ldaptive/control/PasswordPolicyControl.java b/core/src/main/java/org/ldaptive/control/PasswordPolicyControl.java new file mode 100644 index 0000000..929a64f --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/PasswordPolicyControl.java
@@ -0,0 +1,408 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.nio.ByteBuffer; +import javax.security.auth.login.AccountException; +import javax.security.auth.login.AccountLockedException; +import javax.security.auth.login.CredentialException; +import javax.security.auth.login.CredentialExpiredException; +import javax.security.auth.login.LoginException; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.AbstractParseHandler; +import org.ldaptive.asn1.DERParser; +import org.ldaptive.asn1.DERPath; +import org.ldaptive.asn1.IntegerType; +import org.ldaptive.auth.AccountState; + +/** + * Request/response control for password policy. See http://tools.ietf.org/html/draft-behera-ldap-password-policy-10. + * Control is defined as: + * + * <pre> + PasswordPolicyResponseValue ::= SEQUENCE { + warning [0] CHOICE { + timeBeforeExpiration [0] INTEGER (0 .. maxInt), + graceAuthNsRemaining [1] INTEGER (0 .. maxInt) } OPTIONAL, + error [1] ENUMERATED { + passwordExpired (0), + accountLocked (1), + changeAfterReset (2), + passwordModNotAllowed (3), + mustSupplyOldPassword (4), + insufficientPasswordQuality (5), + passwordTooShort (6), + passwordTooYoung (7), + passwordInHistory (8) } OPTIONAL } + * </pre> + * + * @author Middleware Services + */ +public class PasswordPolicyControl extends AbstractControl implements RequestControl, ResponseControl +{ + + /** OID of this control. */ + public static final String OID = "1.3.6.1.4.1.42.2.27.8.5.1"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 719; + + /** Enum for ppolicy errors. */ + public enum Error implements AccountState.Error { + + /** password expired. */ + PASSWORD_EXPIRED(0), + + /** account locked. */ + ACCOUNT_LOCKED(1), + + /** change after reset. */ + CHANGE_AFTER_RESET(2), + + /** password modification not allowed. */ + PASSWORD_MOD_NOT_ALLOWED(3), + + /** must supply old password. */ + MUST_SUPPLY_OLD_PASSWORD(4), + + /** insufficient password quality. */ + INSUFFICIENT_PASSWORD_QUALITY(5), + + /** password too short. */ + PASSWORD_TOO_SHORT(6), + + /** password too young. */ + PASSWORD_TOO_YOUNG(7), + + /** password in history. */ + PASSWORD_IN_HISTORY(8); + + /** underlying error code. */ + private final int code; + + + /** + * Creates a new error. + * + * @param i error code + */ + Error(final int i) + { + code = i; + } + + + @Override + public int getCode() + { + return code; + } + + + @Override + public String getMessage() + { + return name(); + } + + + @Override + public void throwSecurityException() + throws LoginException + { + switch (this) { + + case PASSWORD_EXPIRED: + throw new CredentialExpiredException(name()); + + case ACCOUNT_LOCKED: + throw new AccountLockedException(name()); + + case CHANGE_AFTER_RESET: + throw new CredentialExpiredException(name()); + + case PASSWORD_MOD_NOT_ALLOWED: + throw new AccountException(name()); + + case MUST_SUPPLY_OLD_PASSWORD: + throw new AccountException(name()); + + case INSUFFICIENT_PASSWORD_QUALITY: + throw new CredentialException(name()); + + case PASSWORD_TOO_SHORT: + throw new CredentialException(name()); + + case PASSWORD_TOO_YOUNG: + throw new CredentialException(name()); + + case PASSWORD_IN_HISTORY: + throw new CredentialException(name()); + + default: + throw new IllegalStateException("Unknown password policy error: " + this); + } + } + + + /** + * Returns the error for the supplied integer constant. + * + * @param code to find error for + * + * @return error + */ + public static Error valueOf(final int code) + { + for (Error e : Error.values()) { + if (e.getCode() == code) { + return e; + } + } + return null; + } + } + + /** Ppolicy warning. */ + private int timeBeforeExpiration; + + /** Ppolicy warning. */ + private int graceAuthNsRemaining; + + /** Ppolicy error. */ + private Error error; + + + /** Default constructor. */ + public PasswordPolicyControl() + { + super(OID); + } + + + /** + * Creates a new password policy control. + * + * @param critical whether this control is critical + */ + public PasswordPolicyControl(final boolean critical) + { + super(OID, critical); + } + + + /** + * Returns the time before expiration in seconds. + * + * @return time before expiration + */ + public int getTimeBeforeExpiration() + { + return timeBeforeExpiration; + } + + + /** + * Sets the time before expiration in seconds. + * + * @param time before expiration + */ + public void setTimeBeforeExpiration(final int time) + { + timeBeforeExpiration = time; + } + + + /** + * Returns the number of grace authentications remaining. + * + * @return number of grace authentications remaining + */ + public int getGraceAuthNsRemaining() + { + return graceAuthNsRemaining; + } + + + /** + * Sets the number of grace authentications remaining. + * + * @param count number of grace authentications remaining + */ + public void setGraceAuthNsRemaining(final int count) + { + graceAuthNsRemaining = count; + } + + + /** + * Returns the password policy error. + * + * @return password policy error + */ + public Error getError() + { + return error; + } + + + /** + * Sets the password policy error. + * + * @param e password policy error + */ + public void setError(final Error e) + { + error = e; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof PasswordPolicyControl && super.equals(o)) { + final PasswordPolicyControl v = (PasswordPolicyControl) o; + return LdapUtils.areEqual(timeBeforeExpiration, v.timeBeforeExpiration) && + LdapUtils.areEqual(graceAuthNsRemaining, v.graceAuthNsRemaining) && + LdapUtils.areEqual(error, v.error); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + getOID(), + getCriticality(), + timeBeforeExpiration, + graceAuthNsRemaining, + error); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, timeBeforeExpiration=%s, graceAuthNsRemaining=%s, error=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + timeBeforeExpiration, + graceAuthNsRemaining, + error); + } + + + @Override + public byte[] encode() + { + return null; + } + + + @Override + public void decode(final byte[] berValue) + { + logger.trace("decoding control: {}", LdapUtils.base64Encode(berValue)); + + final DERParser parser = new DERParser(); + parser.registerHandler(TimeBeforeExpirationHandler.PATH, new TimeBeforeExpirationHandler(this)); + parser.registerHandler(GraceAuthnsRemainingHandler.PATH, new GraceAuthnsRemainingHandler(this)); + parser.registerHandler(ErrorHandler.PATH, new ErrorHandler(this)); + parser.parse(ByteBuffer.wrap(berValue)); + } + + + /** Parse handler implementation for the time before expiration. */ + private static class TimeBeforeExpirationHandler extends AbstractParseHandler<PasswordPolicyControl> + { + + /** DER path to warning. */ + public static final DERPath PATH = new DERPath("/SEQ/CTX(0)/CTX(0)"); + + + /** + * Creates a new time before expiration handler. + * + * @param control to configure + */ + TimeBeforeExpirationHandler(final PasswordPolicyControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setTimeBeforeExpiration(IntegerType.decode(encoded).intValue()); + } + } + + + /** Parse handler implementation for the grace authns remaining. */ + private static class GraceAuthnsRemainingHandler extends AbstractParseHandler<PasswordPolicyControl> + { + + /** DER path to warning. */ + public static final DERPath PATH = new DERPath("/SEQ/CTX(0)/CTX(1)"); + + + /** + * Creates a new grace authns remaining handler. + * + * @param control to configure + */ + GraceAuthnsRemainingHandler(final PasswordPolicyControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setGraceAuthNsRemaining(IntegerType.decode(encoded).intValue()); + } + } + + + /** Parse handler implementation for the error. */ + private static class ErrorHandler extends AbstractParseHandler<PasswordPolicyControl> + { + + /** DER path to error. */ + public static final DERPath PATH = new DERPath("/SEQ/CTX(1)"); + + + /** + * Creates a new error handler. + * + * @param control to configure + */ + ErrorHandler(final PasswordPolicyControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + final int errValue = IntegerType.decode(encoded).intValue(); + final PasswordPolicyControl.Error e = PasswordPolicyControl.Error.valueOf(errValue); + if (e == null) { + throw new IllegalArgumentException("Unknown error code " + errValue); + } + getObject().setError(e); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/control/PersistentSearchChangeType.java b/core/src/main/java/org/ldaptive/control/PersistentSearchChangeType.java new file mode 100644 index 0000000..bc67761 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/PersistentSearchChangeType.java
@@ -0,0 +1,66 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +/** + * The set of change types available for use with the {@link PersistentSearchRequestControl} and returned by the {@link + * EntryChangeNotificationControl}. See http://tools.ietf.org/id/draft-ietf-ldapext-psearch-03.txt. + * + * @author Middleware Services + */ +public enum PersistentSearchChangeType { + + /** add. */ + ADD(1), + + /** delete. */ + DELETE(2), + + /** modify. */ + MODIFY(4), + + /** modify dn. */ + MODDN(8); + + /** underlying value. */ + private final int value; + + + /** + * Creates a new persistent search change type. + * + * @param i value + */ + PersistentSearchChangeType(final int i) + { + value = i; + } + + + /** + * Returns the value. + * + * @return enum value + */ + public int value() + { + return value; + } + + + /** + * Returns the persistent search change type for the supplied integer constant. + * + * @param i to find change type for + * + * @return persistent search change type + */ + public static PersistentSearchChangeType valueOf(final int i) + { + for (PersistentSearchChangeType ct : PersistentSearchChangeType.values()) { + if (ct.value() == i) { + return ct; + } + } + return null; + } +}
diff --git a/core/src/main/java/org/ldaptive/control/PersistentSearchRequestControl.java b/core/src/main/java/org/ldaptive/control/PersistentSearchRequestControl.java new file mode 100644 index 0000000..4d8799a --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/PersistentSearchRequestControl.java
@@ -0,0 +1,234 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.util.EnumSet; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.BooleanType; +import org.ldaptive.asn1.ConstructedDEREncoder; +import org.ldaptive.asn1.IntegerType; +import org.ldaptive.asn1.UniversalDERTag; + +/** + * Request control for persistent search. See http://tools.ietf.org/id/draft-ietf-ldapext-psearch-03.txt. Control is + * defined as: + * + * <pre> + PersistentSearch ::= SEQUENCE { + changeTypes INTEGER, + changesOnly BOOLEAN, + returnECs BOOLEAN } + * </pre> + * + * @author Middleware Services + */ +public class PersistentSearchRequestControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "2.16.840.1.113730.3.4.3"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 761; + + /** persistent search change types. */ + private EnumSet<PersistentSearchChangeType> changeTypes; + + /** whether to return only changed entries. */ + private boolean changesOnly; + + /** whether to return an Entry Change Notification control. */ + private boolean returnEcs; + + + /** Default constructor. */ + public PersistentSearchRequestControl() + { + super(OID); + } + + + /** + * Creates a new persistent search request control. + * + * @param types persistent search change types + */ + public PersistentSearchRequestControl(final EnumSet<PersistentSearchChangeType> types) + { + super(OID); + setChangeTypes(types); + } + + + /** + * Creates a new persistent search request control. + * + * @param types persistent search change types + * @param critical whether this control is critical + */ + public PersistentSearchRequestControl(final EnumSet<PersistentSearchChangeType> types, final boolean critical) + { + super(OID, critical); + setChangeTypes(types); + } + + + /** + * Creates a new persistent search request control. + * + * @param types persistent search change types + * @param co whether only changed entries are returned + * @param re return an Entry Change Notification control + */ + public PersistentSearchRequestControl( + final EnumSet<PersistentSearchChangeType> types, + final boolean co, + final boolean re) + { + super(OID); + setChangeTypes(types); + setChangesOnly(co); + setReturnEcs(re); + } + + + /** + * Creates a new persistent search request control. + * + * @param types persistent search change types + * @param co whether only changed entries are returned + * @param re return an Entry Change Notification control + * @param critical whether this control is critical + */ + public PersistentSearchRequestControl( + final EnumSet<PersistentSearchChangeType> types, + final boolean co, + final boolean re, + final boolean critical) + { + super(OID, critical); + setChangeTypes(types); + setChangesOnly(co); + setReturnEcs(re); + } + + + /** + * Returns the persistent search change types. + * + * @return persistent search change types + */ + public EnumSet<PersistentSearchChangeType> getChangeTypes() + { + return changeTypes; + } + + + /** + * Sets the persistent search change types. + * + * @param types persistent search change types + */ + public void setChangeTypes(final EnumSet<PersistentSearchChangeType> types) + { + changeTypes = types; + } + + + /** + * Returns whether only changed entries are returned. + * + * @return whether only changed entries are returned + */ + public boolean getChangesOnly() + { + return changesOnly; + } + + + /** + * Sets whether only changed entries are returned. + * + * @param b whether only changed entries are returned + */ + public void setChangesOnly(final boolean b) + { + changesOnly = b; + } + + + /** + * Returns whether to return an Entry Change Notification control. + * + * @return whether to return an Entry Change Notification control + */ + public boolean getReturnEcs() + { + return returnEcs; + } + + + /** + * Sets whether to return an Entry Change Notification control. + * + * @param b return an Entry Change Notification control + */ + public void setReturnEcs(final boolean b) + { + returnEcs = b; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof PersistentSearchRequestControl && super.equals(o)) { + final PersistentSearchRequestControl v = (PersistentSearchRequestControl) o; + return LdapUtils.areEqual(changeTypes, v.changeTypes) && + LdapUtils.areEqual(changesOnly, v.changesOnly) && + LdapUtils.areEqual(returnEcs, v.returnEcs); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality(), changeTypes, changesOnly, returnEcs); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, changeTypes=%s, changesOnly=%s, returnEcs=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + changeTypes, + changesOnly, + returnEcs); + } + + + @Override + public byte[] encode() + { + int types = 0; + for (PersistentSearchChangeType type : getChangeTypes()) { + types |= type.value(); + } + + final ConstructedDEREncoder se = new ConstructedDEREncoder( + UniversalDERTag.SEQ, + new IntegerType(types), + new BooleanType(getChangesOnly()), + new BooleanType(getReturnEcs())); + return se.encode(); + } +}
diff --git a/core/src/main/java/org/ldaptive/control/ProxyAuthorizationControl.java b/core/src/main/java/org/ldaptive/control/ProxyAuthorizationControl.java new file mode 100644 index 0000000..a95c2de --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/ProxyAuthorizationControl.java
@@ -0,0 +1,112 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.OctetStringType; + +/** + * Request control for proxy authorization. See RFC 4370. Control is defined as: + * + * <pre> + controlValue ::= OCTET STRING -- authorizationId + * </pre> + * + * @author Middleware Services + */ +public class ProxyAuthorizationControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "2.16.840.1.113730.3.4.18"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 7001; + + /** empty byte array used for anonymous authz. */ + private static final byte[] EMPTY_AUTHZ = new byte[0]; + + /** authorization identity. */ + private String authorizationId; + + + /** Default constructor. */ + public ProxyAuthorizationControl() + { + super(OID, true); + } + + + /** + * Creates a new proxy authorization control. + * + * @param id authorization identity + */ + public ProxyAuthorizationControl(final String id) + { + super(OID, true); + setAuthorizationId(id); + } + + + /** + * Returns the authorization identity. + * + * @return authorization identity + */ + public String getAuthorizationId() + { + return authorizationId; + } + + + /** + * Sets the authorization identity. + * + * @param id authorization identity + */ + public void setAuthorizationId(final String id) + { + authorizationId = id; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof ProxyAuthorizationControl && super.equals(o)) { + final ProxyAuthorizationControl v = (ProxyAuthorizationControl) o; + return LdapUtils.areEqual(authorizationId, v.authorizationId); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality(), authorizationId); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, authorizationId=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + authorizationId); + } + + + @Override + public byte[] encode() + { + return getAuthorizationId() != null ? OctetStringType.toBytes(getAuthorizationId()) : EMPTY_AUTHZ; + } +}
diff --git a/core/src/main/java/org/ldaptive/control/RequestControl.java b/core/src/main/java/org/ldaptive/control/RequestControl.java new file mode 100644 index 0000000..f945575 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/RequestControl.java
@@ -0,0 +1,19 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +/** + * Marker interface for ldap request controls. + * + * @author Middleware Services + */ +public interface RequestControl extends Control +{ + + + /** + * Provides the BER encoding of this control. + * + * @return BER encoded request control + */ + byte[] encode(); +}
diff --git a/core/src/main/java/org/ldaptive/control/ResponseControl.java b/core/src/main/java/org/ldaptive/control/ResponseControl.java new file mode 100644 index 0000000..16f7167 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/ResponseControl.java
@@ -0,0 +1,19 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +/** + * Marker interface for ldap response controls. + * + * @author Middleware Services + */ +public interface ResponseControl extends Control +{ + + + /** + * Initializes this response control with the supplied BER encoded data. + * + * @param encoded BER encoded response control + */ + void decode(byte[] encoded); +}
diff --git a/core/src/main/java/org/ldaptive/control/SessionTrackingControl.java b/core/src/main/java/org/ldaptive/control/SessionTrackingControl.java new file mode 100644 index 0000000..8501af8 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/SessionTrackingControl.java
@@ -0,0 +1,368 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.AbstractParseHandler; +import org.ldaptive.asn1.ConstructedDEREncoder; +import org.ldaptive.asn1.DEREncoder; +import org.ldaptive.asn1.DERParser; +import org.ldaptive.asn1.DERPath; +import org.ldaptive.asn1.OctetStringType; +import org.ldaptive.asn1.UniversalDERTag; + +/** + * Request/response control for session tracking. See https://tools.ietf.org/html/draft-wahl-ldap-session-03. + * Control is defined as: + * + * <pre> + LDAPString ::= OCTET STRING -- UTF-8 encoded + LDAPOID ::= OCTET STRING -- Constrained to numericoid + + SessionIdentifierControlValue ::= SEQUENCE { + sessionSourceIp LDAPString, + sessionSourceName LDAPString, + formatOID LDAPOID, + sessionTrackingIdentifier LDAPString + } + * </pre> + * + * Note that criticality must be either false or absent. + * + * @author Middleware Services + */ +public class SessionTrackingControl extends AbstractControl implements RequestControl, ResponseControl +{ + + /** OID of this control. */ + public static final String OID = "1.3.6.1.4.1.21008.108.63.1"; + + /** OID for the Acct-Session-Id RADIUS attribute format. */ + public static final String RADIUS_ACCT_OID = "1.3.6.1.4.1.21008.108.63.1.1"; + + /** OID for the Acct-Multi-Session-Id RADIUS attribute format. */ + public static final String RADIUS_ACCT_MULTI_OID = "1.3.6.1.4.1.21008.108.63.1.2"; + + /** OID for the SASL authorization identity string format. */ + public static final String USERNAME_ACCT_OID = "1.3.6.1.4.1.21008.108.63.1.3"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 7027; + + /** Session source ip. */ + private String sessionSourceIp; + + /** Session source name. */ + private String sessionSourceName; + + /** Format OID. */ + private String formatOID; + + /** Session tracking identifier. */ + private String sessionTrackingIdentifier; + + + /** Default constructor. */ + public SessionTrackingControl() + { + super(OID); + } + + + /** + * Creates a new session tracking control. + * + * @param sourceIP session source ip + * @param sourceName session source name + * @param oid format OID + * @param trackingIdentifier session tracking identifier + */ + public SessionTrackingControl( + final String sourceIP, + final String sourceName, + final String oid, + final String trackingIdentifier) + { + super(OID); + setSessionSourceIp(sourceIP); + setSessionSourceName(sourceName); + setFormatOID(oid); + setSessionTrackingIdentifier(trackingIdentifier); + } + + + /** + * Returns the session source ip. + * + * @return session source ip + */ + public String getSessionSourceIp() + { + return sessionSourceIp; + } + + + /** + * Sets the session source ip. + * + * @param s session source ip + */ + public void setSessionSourceIp(final String s) + { + sessionSourceIp = s; + } + + + /** + * Returns the session source name. + * + * @return session source name + */ + public String getSessionSourceName() + { + return sessionSourceName; + } + + + /** + * Sets the session source name. + * + * @param s session source name + */ + public void setSessionSourceName(final String s) + { + sessionSourceName = s; + } + + + /** + * Returns the format OID. + * + * @return format OID + */ + public String getFormatOID() + { + return formatOID; + } + + + /** + * Sets the format OID. + * + * @param s format OID + */ + public void setFormatOID(final String s) + { + formatOID = s; + } + + + /** + * Returns the session tracking identifier. + * + * @return session tracking identifier + */ + public String getSessionTrackingIdentifier() + { + return sessionTrackingIdentifier; + } + + + /** + * Sets the session tracking identifier. + * + * @param s session tracking identifier + */ + public void setSessionTrackingIdentifier(final String s) + { + sessionTrackingIdentifier = s; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof SessionTrackingControl && super.equals(o)) { + final SessionTrackingControl v = (SessionTrackingControl) o; + return LdapUtils.areEqual(sessionSourceIp, v.sessionSourceIp) && + LdapUtils.areEqual(sessionSourceName, v.sessionSourceName) && + LdapUtils.areEqual(formatOID, v.formatOID) && + LdapUtils.areEqual(sessionTrackingIdentifier, v.sessionTrackingIdentifier); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + getOID(), + getCriticality(), + sessionSourceIp, + sessionSourceName, + formatOID, + sessionTrackingIdentifier); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, sessionSourceIp=%s, sessionSourceName=%s, formatOID=%s, sessionTrackingIdentifier=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + sessionSourceIp, + sessionSourceName, + formatOID, + sessionTrackingIdentifier); + } + + + @Override + public byte[] encode() + { + final List<DEREncoder> l = new ArrayList<>(); + l.add(new OctetStringType(getSessionSourceIp())); + l.add(new OctetStringType(getSessionSourceName())); + l.add(new OctetStringType(getFormatOID())); + l.add(new OctetStringType(getSessionTrackingIdentifier())); + + final ConstructedDEREncoder se = new ConstructedDEREncoder( + UniversalDERTag.SEQ, + l.toArray(new DEREncoder[l.size()])); + return se.encode(); + } + + + @Override + public void decode(final byte[] berValue) + { + logger.trace("decoding control: {}", LdapUtils.base64Encode(berValue)); + + final DERParser parser = new DERParser(); + parser.registerHandler(SourceIpHandler.PATH, new SourceIpHandler(this)); + parser.registerHandler(SourceNameHandler.PATH, new SourceNameHandler(this)); + parser.registerHandler(FormatOIDHandler.PATH, new FormatOIDHandler(this)); + parser.registerHandler(TrackingIdentifierHandler.PATH, new TrackingIdentifierHandler(this)); + parser.parse(ByteBuffer.wrap(berValue)); + } + + + /** Parse handler implementation for the source ip. */ + private static class SourceIpHandler extends AbstractParseHandler<SessionTrackingControl> + { + + /** DER path to source ip value. */ + public static final DERPath PATH = new DERPath("/SEQ/OCTSTR[0]"); + + + /** + * Creates a new source ip handler. + * + * @param control to configure + */ + SourceIpHandler(final SessionTrackingControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setSessionSourceIp(OctetStringType.decode(encoded)); + } + } + + + /** Parse handler implementation for the source name. */ + private static class SourceNameHandler extends AbstractParseHandler<SessionTrackingControl> + { + + /** DER path to source name value. */ + public static final DERPath PATH = new DERPath("/SEQ/OCTSTR[1]"); + + + /** + * Creates a new source name handler. + * + * @param control to configure + */ + SourceNameHandler(final SessionTrackingControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setSessionSourceName(OctetStringType.decode(encoded)); + } + } + + + /** Parse handler implementation for the format oid. */ + private static class FormatOIDHandler extends AbstractParseHandler<SessionTrackingControl> + { + + /** DER path to format oid value. */ + public static final DERPath PATH = new DERPath("/SEQ/OCTSTR[2]"); + + + /** + * Creates a new format oid handler. + * + * @param control to configure + */ + FormatOIDHandler(final SessionTrackingControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setFormatOID(OctetStringType.decode(encoded)); + } + } + + + /** Parse handler implementation for the tracking identifier. */ + private static class TrackingIdentifierHandler extends AbstractParseHandler<SessionTrackingControl> + { + + /** DER path to source name value. */ + public static final DERPath PATH = new DERPath("/SEQ/OCTSTR[3]"); + + + /** + * Creates a new tracking identifier handler. + * + * @param control to configure + */ + TrackingIdentifierHandler(final SessionTrackingControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setSessionTrackingIdentifier(OctetStringType.decode(encoded)); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/control/SortKey.java b/core/src/main/java/org/ldaptive/control/SortKey.java new file mode 100644 index 0000000..90b15d6 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/SortKey.java
@@ -0,0 +1,172 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; + +/** + * Used by {@link SortRequestControl} to declare how sorting should occur. See RFC 3698 for the definition of + * matchingRuleId. + * + * @author Middleware Services + */ +public class SortKey +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 739; + + /** attribute description. */ + private String attributeDescription; + + /** matching rule id. */ + private String matchingRuleId; + + /** reverse order. */ + private boolean reverseOrder; + + + /** Default constructor. */ + public SortKey() {} + + + /** + * Creates a new sort key. + * + * @param attrDescription attribute description + */ + public SortKey(final String attrDescription) + { + setAttributeDescription(attrDescription); + } + + + /** + * Creates a new sort key. + * + * @param attrDescription attribute description + * @param ruleId matching rule id + */ + public SortKey(final String attrDescription, final String ruleId) + { + setAttributeDescription(attrDescription); + setMatchingRuleId(ruleId); + } + + + /** + * Creates a new sort key. + * + * @param attrDescription attribute description + * @param ruleId matching rule id + * @param reverse reverse order + */ + public SortKey(final String attrDescription, final String ruleId, final boolean reverse) + { + setAttributeDescription(attrDescription); + setMatchingRuleId(ruleId); + setReverseOrder(reverse); + } + + + /** + * Returns the attribute description. + * + * @return attribute description + */ + public String getAttributeDescription() + { + return attributeDescription; + } + + + /** + * Sets the attribute description. + * + * @param s attribute description + */ + public void setAttributeDescription(final String s) + { + attributeDescription = s; + } + + + /** + * Returns the matching rule id. + * + * @return matching rule id + */ + public String getMatchingRuleId() + { + return matchingRuleId; + } + + + /** + * Sets the matching rule id. + * + * @param s matching rule id + */ + public void setMatchingRuleId(final String s) + { + matchingRuleId = s; + } + + + /** + * Returns whether results should be in reverse sorted order. + * + * @return whether results should be in reverse sorted order + */ + public boolean getReverseOrder() + { + return reverseOrder; + } + + + /** + * Sets whether results should be in reverse sorted order. + * + * @param b whether results should be in reverse sorted order + */ + public void setReverseOrder(final boolean b) + { + reverseOrder = b; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof SortKey) { + final SortKey v = (SortKey) o; + return LdapUtils.areEqual(attributeDescription, v.attributeDescription) && + LdapUtils.areEqual(matchingRuleId, v.matchingRuleId) && + LdapUtils.areEqual(reverseOrder, v.reverseOrder); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, attributeDescription, matchingRuleId, reverseOrder); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::attributeDescription=%s, matchingRuleId=%s, reverseOrder=%s]", + getClass().getName(), + hashCode(), + attributeDescription, + matchingRuleId, + reverseOrder); + } +}
diff --git a/core/src/main/java/org/ldaptive/control/SortRequestControl.java b/core/src/main/java/org/ldaptive/control/SortRequestControl.java new file mode 100644 index 0000000..ad8c1f5 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/SortRequestControl.java
@@ -0,0 +1,146 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.ConstructedDEREncoder; +import org.ldaptive.asn1.ContextType; +import org.ldaptive.asn1.DEREncoder; +import org.ldaptive.asn1.OctetStringType; +import org.ldaptive.asn1.UniversalDERTag; + +/** + * Request control for server side sorting. See RFC 2891. Control is defined as: + * + * <pre> + SortKeyList ::= SEQUENCE OF SEQUENCE { + attributeType AttributeDescription, + orderingRule [0] MatchingRuleId OPTIONAL, + reverseOrder [1] BOOLEAN DEFAULT FALSE } + * </pre> + * + * @author Middleware Services + */ +public class SortRequestControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.473"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 727; + + /** sort keys. */ + private SortKey[] sortKeys; + + + /** Default constructor. */ + public SortRequestControl() + { + super(OID); + } + + + /** + * Creates a new sort request control. + * + * @param keys sort keys + */ + public SortRequestControl(final SortKey[] keys) + { + super(OID); + setSortKeys(keys); + } + + + /** + * Creates a new sort request control. + * + * @param keys sort keys + * @param critical whether this control is critical + */ + public SortRequestControl(final SortKey[] keys, final boolean critical) + { + super(OID, critical); + setSortKeys(keys); + } + + + /** + * Returns the sort keys. + * + * @return sort keys + */ + public SortKey[] getSortKeys() + { + return sortKeys; + } + + + /** + * Sets the sort keys. + * + * @param keys sort keys + */ + public void setSortKeys(final SortKey[] keys) + { + sortKeys = keys; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof SortRequestControl && super.equals(o)) { + final SortRequestControl v = (SortRequestControl) o; + return LdapUtils.areEqual(sortKeys, v.sortKeys); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality(), sortKeys); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, sortKeys=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + Arrays.toString(sortKeys)); + } + + + @Override + public byte[] encode() + { + final DEREncoder[] keyEncoders = new DEREncoder[sortKeys.length]; + for (int i = 0; i < sortKeys.length; i++) { + final List<DEREncoder> l = new ArrayList<>(); + l.add(new OctetStringType(sortKeys[i].getAttributeDescription())); + if (sortKeys[i].getMatchingRuleId() != null) { + l.add(new ContextType(0, sortKeys[i].getMatchingRuleId())); + } + if (sortKeys[i].getReverseOrder()) { + l.add(new ContextType(1, sortKeys[i].getReverseOrder())); + } + keyEncoders[i] = new ConstructedDEREncoder(UniversalDERTag.SEQ, l.toArray(new DEREncoder[l.size()])); + } + + final ConstructedDEREncoder se = new ConstructedDEREncoder(UniversalDERTag.SEQ, keyEncoders); + return se.encode(); + } +}
diff --git a/core/src/main/java/org/ldaptive/control/SortResponseControl.java b/core/src/main/java/org/ldaptive/control/SortResponseControl.java new file mode 100644 index 0000000..47ae08d --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/SortResponseControl.java
@@ -0,0 +1,255 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.nio.ByteBuffer; +import org.ldaptive.LdapUtils; +import org.ldaptive.ResultCode; +import org.ldaptive.asn1.AbstractParseHandler; +import org.ldaptive.asn1.DERParser; +import org.ldaptive.asn1.DERPath; +import org.ldaptive.asn1.IntegerType; +import org.ldaptive.asn1.OctetStringType; + +/** + * Response control for server side sorting. See RFC 2891. Control is defined as: + * + * <pre> + SortResult ::= SEQUENCE { + sortResult ENUMERATED { + success (0), -- results are sorted + operationsError (1), -- server internal failure + timeLimitExceeded (3), -- timelimit reached before + -- sorting was completed + strongAuthRequired (8), -- refused to return sorted + -- results via insecure + -- protocol + adminLimitExceeded (11), -- too many matching entries + -- for the server to sort + noSuchAttribute (16), -- unrecognized attribute + -- type in sort key + inappropriateMatching (18), -- unrecognized or + -- inappropriate matching + -- rule in sort key + insufficientAccessRights (50), -- refused to return sorted + -- results to this client + busy (51), -- too busy to process + unwillingToPerform (53), -- unable to sort + other (80) + }, + attributeType [0] AttributeDescription OPTIONAL } + * </pre> + * + * @author Middleware Services + */ +public class SortResponseControl extends AbstractControl implements ResponseControl +{ + + /** OID of this control. */ + public static final String OID = "1.2.840.113556.1.4.474"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 733; + + /** Result of the server side sorting. */ + private ResultCode sortResult; + + /** Failed attribute name. */ + private String attributeName; + + + /** Default constructor. */ + public SortResponseControl() + { + super(OID); + } + + + /** + * Creates a new sort response control. + * + * @param critical whether this control is critical + */ + public SortResponseControl(final boolean critical) + { + super(OID, critical); + } + + + /** + * Creates a new sort response control. + * + * @param code result of the sort + * @param critical whether this control is critical + */ + public SortResponseControl(final ResultCode code, final boolean critical) + { + super(OID, critical); + setSortResult(code); + } + + + /** + * Creates a new sort response control. + * + * @param code result of the sort + * @param attrName name of the failed attribute + * @param critical whether this control is critical + */ + public SortResponseControl(final ResultCode code, final String attrName, final boolean critical) + { + super(OID, critical); + setSortResult(code); + setAttributeName(attrName); + } + + + /** + * Returns the result code of the server side sort. + * + * @return result code + */ + public ResultCode getSortResult() + { + return sortResult; + } + + + /** + * Sets the result code of the server side sort. + * + * @param code result code + */ + public void setSortResult(final ResultCode code) + { + sortResult = code; + } + + + /** + * Returns the attribute name that caused the sort to fail. + * + * @return attribute name + */ + public String getAttributeName() + { + return attributeName; + } + + + /** + * Sets the attribute name that caused the sort to fail. + * + * @param name of an attribute + */ + public void setAttributeName(final String name) + { + attributeName = name; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof SortResponseControl && super.equals(o)) { + final SortResponseControl v = (SortResponseControl) o; + return LdapUtils.areEqual(sortResult, v.sortResult) && + LdapUtils.areEqual(attributeName, v.attributeName); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality(), sortResult, attributeName); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, sortResult=%s, attributeName=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + sortResult, + attributeName); + } + + + @Override + public void decode(final byte[] berValue) + { + logger.trace("decoding control: {}", LdapUtils.base64Encode(berValue)); + + final DERParser parser = new DERParser(); + parser.registerHandler(SortResultHandler.PATH, new SortResultHandler(this)); + parser.registerHandler(AttributeTypeHandler.PATH, new AttributeTypeHandler(this)); + parser.parse(ByteBuffer.wrap(berValue)); + } + + + /** Parse handler implementation for the sort result. */ + private static class SortResultHandler extends AbstractParseHandler<SortResponseControl> + { + + /** DER path to result code. */ + public static final DERPath PATH = new DERPath("/SEQ/ENUM"); + + + /** + * Creates a new sort result handler. + * + * @param control to configure + */ + SortResultHandler(final SortResponseControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + final int resultValue = IntegerType.decode(encoded).intValue(); + final ResultCode rc = ResultCode.valueOf(resultValue); + if (rc == null) { + throw new IllegalArgumentException("Unknown result code " + resultValue); + } + getObject().setSortResult(rc); + } + } + + + /** Parse handler implementation for the attribute type. */ + private static class AttributeTypeHandler extends AbstractParseHandler<SortResponseControl> + { + + /** DER path to attr value. */ + public static final DERPath PATH = new DERPath("/SEQ/CTX(1)"); + + + /** + * Creates a new attribute type handler. + * + * @param control to configure + */ + AttributeTypeHandler(final SortResponseControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setAttributeName(OctetStringType.decode(encoded)); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/control/SyncDoneControl.java b/core/src/main/java/org/ldaptive/control/SyncDoneControl.java new file mode 100644 index 0000000..7095c26 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/SyncDoneControl.java
@@ -0,0 +1,245 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.nio.ByteBuffer; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.AbstractParseHandler; +import org.ldaptive.asn1.BooleanType; +import org.ldaptive.asn1.DERParser; +import org.ldaptive.asn1.DERPath; +import org.ldaptive.asn1.OctetStringType; + +/** + * Response control for ldap content synchronization. See RFC 4533. Control is defined as: + * + * <pre> + syncDoneValue ::= SEQUENCE { + cookie syncCookie OPTIONAL, + refreshDeletes BOOLEAN DEFAULT FALSE + } + * </pre> + * + * @author Middleware Services + */ +public class SyncDoneControl extends AbstractControl implements ResponseControl +{ + + /** OID of this control. */ + public static final String OID = "1.3.6.1.4.1.4203.1.9.1.3"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 757; + + /** server generated cookie. */ + private byte[] cookie; + + /** refresh deletes. */ + private boolean refreshDeletes; + + + /** Default constructor. */ + public SyncDoneControl() + { + super(OID); + } + + + /** + * Creates a new sync done control. + * + * @param critical whether this control is critical + */ + public SyncDoneControl(final boolean critical) + { + super(OID, critical); + } + + + /** + * Creates a new sync done control. + * + * @param value sync done cookie + */ + public SyncDoneControl(final byte[] value) + { + super(OID); + setCookie(value); + } + + + /** + * Creates a new sync done control. + * + * @param value sync done cookie + * @param critical whether this control is critical + */ + public SyncDoneControl(final byte[] value, final boolean critical) + { + super(OID, critical); + setCookie(value); + } + + + /** + * Creates a new sync done control. + * + * @param value sync done cookie + * @param refresh whether to refresh deletes + * @param critical whether this control is critical + */ + public SyncDoneControl(final byte[] value, final boolean refresh, final boolean critical) + { + super(OID, critical); + setCookie(value); + setRefreshDeletes(refresh); + } + + + /** + * Returns the sync done cookie. + * + * @return sync done cookie + */ + public byte[] getCookie() + { + return cookie; + } + + + /** + * Sets the sync done cookie. + * + * @param value sync done cookie + */ + public void setCookie(final byte[] value) + { + cookie = value; + } + + + /** + * Returns whether to refresh deletes. + * + * @return refresh deletes + */ + public boolean getRefreshDeletes() + { + return refreshDeletes; + } + + + /** + * Sets whether to refresh deletes. + * + * @param b refresh deletes + */ + public void setRefreshDeletes(final boolean b) + { + refreshDeletes = b; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof SyncDoneControl && super.equals(o)) { + final SyncDoneControl v = (SyncDoneControl) o; + return LdapUtils.areEqual(cookie, v.cookie) && + LdapUtils.areEqual(refreshDeletes, v.refreshDeletes); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality(), cookie, refreshDeletes); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, cookie=%s, refreshDeletes=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + LdapUtils.base64Encode(cookie), + refreshDeletes); + } + + + @Override + public void decode(final byte[] berValue) + { + logger.trace("decoding control: {}", LdapUtils.base64Encode(berValue)); + + final DERParser parser = new DERParser(); + parser.registerHandler(CookieHandler.PATH, new CookieHandler(this)); + parser.registerHandler(RefreshDeletesHandler.PATH, new RefreshDeletesHandler(this)); + parser.parse(ByteBuffer.wrap(berValue)); + } + + + /** Parse handler implementation for the cookie. */ + private static class CookieHandler extends AbstractParseHandler<SyncDoneControl> + { + + /** DER path to cookie value. */ + public static final DERPath PATH = new DERPath("/SEQ/OCTSTR"); + + + /** + * Creates a new cookie handler. + * + * @param control to configure + */ + CookieHandler(final SyncDoneControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + final byte[] cookie = OctetStringType.readBuffer(encoded); + if (cookie != null && cookie.length > 0) { + getObject().setCookie(cookie); + } + } + } + + + /** Parse handler implementation for the refresh deletes flag. */ + private static class RefreshDeletesHandler extends AbstractParseHandler<SyncDoneControl> + { + + /** DER path to the boolean. */ + public static final DERPath PATH = new DERPath("/SEQ/BOOL"); + + + /** + * Creates a new refresh deletes handler. + * + * @param control to configure + */ + RefreshDeletesHandler(final SyncDoneControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setRefreshDeletes(BooleanType.decode(encoded)); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/control/SyncRequestControl.java b/core/src/main/java/org/ldaptive/control/SyncRequestControl.java new file mode 100644 index 0000000..f034fec --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/SyncRequestControl.java
@@ -0,0 +1,287 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.BooleanType; +import org.ldaptive.asn1.ConstructedDEREncoder; +import org.ldaptive.asn1.IntegerType; +import org.ldaptive.asn1.OctetStringType; +import org.ldaptive.asn1.UniversalDERTag; + +/** + * Request control for ldap content synchronization. See RFC 4533. Control is defined as: + * + * <pre> + syncRequestValue ::= SEQUENCE { + mode ENUMERATED { + -- 0 unused + refreshOnly (1), + -- 2 reserved + refreshAndPersist (3) + }, + cookie syncCookie OPTIONAL, + reloadHint BOOLEAN DEFAULT FALSE + } + * </pre> + * + * @author Middleware Services + */ +public class SyncRequestControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "1.3.6.1.4.1.4203.1.9.1.1"; + + /** hash value seed. */ + private static final int HASH_CODE_SEED = 743; + + /** Types of request modes. */ + public enum Mode { + + /** refresh only. */ + REFRESH_ONLY(1), + + /** refresh and persist. */ + REFRESH_AND_PERSIST(3); + + /** underlying value. */ + private final int value; + + + /** + * Creates a new mode. + * + * @param i value + */ + Mode(final int i) + { + value = i; + } + + + /** + * Returns the value. + * + * @return enum value + */ + public int value() + { + return value; + } + + + /** + * Returns the mode for the supplied integer constant. + * + * @param i to find mode for + * + * @return mode + */ + public static Mode valueOf(final int i) + { + for (Mode m : Mode.values()) { + if (m.value() == i) { + return m; + } + } + return null; + } + } + + /** request mode. */ + private Mode requestMode = Mode.REFRESH_ONLY; + + /** server generated cookie. */ + private byte[] cookie; + + /** reload hint. */ + private boolean reloadHint; + + + /** Default constructor. */ + public SyncRequestControl() + { + super(OID); + } + + + /** + * Creates a new sync request control. + * + * @param mode request mode + */ + public SyncRequestControl(final Mode mode) + { + super(OID); + setRequestMode(mode); + } + + + /** + * Creates a new sync request control. + * + * @param mode request mode + * @param critical whether this control is critical + */ + public SyncRequestControl(final Mode mode, final boolean critical) + { + super(OID, critical); + setRequestMode(mode); + } + + + /** + * Creates a new sync request control. + * + * @param mode request mode + * @param value sync request cookie + * @param critical whether this control is critical + */ + public SyncRequestControl(final Mode mode, final byte[] value, final boolean critical) + { + super(OID, critical); + setRequestMode(mode); + setCookie(value); + } + + + /** + * Creates a new sync request control. + * + * @param mode request mode + * @param value sync request cookie + * @param hint reload hint + * @param critical whether this control is critical + */ + public SyncRequestControl(final Mode mode, final byte[] value, final boolean hint, final boolean critical) + { + super(OID, critical); + setRequestMode(mode); + setCookie(value); + setReloadHint(hint); + } + + + /** + * Returns the request mode. + * + * @return request mode + */ + public Mode getRequestMode() + { + return requestMode; + } + + + /** + * Sets the request mode. + * + * @param mode request mode + */ + public void setRequestMode(final Mode mode) + { + requestMode = mode; + } + + + /** + * Returns the sync request cookie. + * + * @return sync request cookie + */ + public byte[] getCookie() + { + return cookie; + } + + + /** + * Sets the sync request cookie. + * + * @param value sync request cookie + */ + public void setCookie(final byte[] value) + { + cookie = value; + } + + + /** + * Returns the reload hint. + * + * @return reload hint + */ + public boolean getReloadHint() + { + return reloadHint; + } + + + /** + * Sets the reload hint. + * + * @param b reload hint + */ + public void setReloadHint(final boolean b) + { + reloadHint = b; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof SyncRequestControl && super.equals(o)) { + final SyncRequestControl v = (SyncRequestControl) o; + return LdapUtils.areEqual(requestMode, v.requestMode) && + LdapUtils.areEqual(cookie, v.cookie) && + LdapUtils.areEqual(reloadHint, v.reloadHint); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality(), requestMode, cookie, reloadHint); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, requestMode=%s, cookie=%s, reloadHint=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + requestMode, + LdapUtils.base64Encode(cookie), + reloadHint); + } + + + @Override + public byte[] encode() + { + ConstructedDEREncoder se; + if (getCookie() != null) { + se = new ConstructedDEREncoder( + UniversalDERTag.SEQ, + new IntegerType(getRequestMode().value()), + new OctetStringType(getCookie()), + new BooleanType(getReloadHint())); + } else { + se = new ConstructedDEREncoder( + UniversalDERTag.SEQ, + new IntegerType(getRequestMode().value()), + new BooleanType(getReloadHint())); + } + return se.encode(); + } +}
diff --git a/core/src/main/java/org/ldaptive/control/SyncStateControl.java b/core/src/main/java/org/ldaptive/control/SyncStateControl.java new file mode 100644 index 0000000..8ea2e9d --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/SyncStateControl.java
@@ -0,0 +1,391 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.nio.ByteBuffer; +import java.util.UUID; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.AbstractParseHandler; +import org.ldaptive.asn1.DERParser; +import org.ldaptive.asn1.DERPath; +import org.ldaptive.asn1.IntegerType; +import org.ldaptive.asn1.OctetStringType; +import org.ldaptive.asn1.UuidType; + +/** + * Response control for ldap content synchronization. See RFC 4533. Control is defined as: + * + * <pre> + syncStateValue ::= SEQUENCE { + state ENUMERATED { + present (0), + add (1), + modify (2), + delete (3) + }, + entryUUID syncUUID, + cookie syncCookie OPTIONAL + } + * </pre> + * + * @author Middleware Services + */ +public class SyncStateControl extends AbstractControl implements ResponseControl +{ + + /** OID of this control. */ + public static final String OID = "1.3.6.1.4.1.4203.1.9.1.2"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 751; + + /** Types of states. */ + public enum State { + + /** present. */ + PRESET(0), + + /** add. */ + ADD(1), + + /** modify. */ + MODIFY(2), + + /** delete. */ + DELETE(3); + + /** underlying value. */ + private final int value; + + + /** + * Creates a new mode. + * + * @param i value + */ + State(final int i) + { + value = i; + } + + + /** + * Returns the value. + * + * @return enum value + */ + public int value() + { + return value; + } + + + /** + * Returns the state for the supplied integer constant. + * + * @param i to find state for + * + * @return state + */ + public static State valueOf(final int i) + { + for (State s : State.values()) { + if (s.value() == i) { + return s; + } + } + return null; + } + } + + /** sync state. */ + private State syncState; + + /** sync UUID. */ + private UUID entryUuid; + + /** server generated cookie. */ + private byte[] cookie; + + + /** Default constructor. */ + public SyncStateControl() + { + super(OID); + } + + + /** + * Creates a new sync state control. + * + * @param critical whether this control is critical + */ + public SyncStateControl(final boolean critical) + { + super(OID, critical); + } + + + /** + * Creates a new sync state control. + * + * @param state sync state + */ + public SyncStateControl(final State state) + { + super(OID); + setSyncState(state); + } + + + /** + * Creates a new sync state control. + * + * @param state sync state + * @param critical whether this control is critical + */ + public SyncStateControl(final State state, final boolean critical) + { + super(OID, critical); + setSyncState(state); + } + + + /** + * Creates a new sync state control. + * + * @param state sync state + * @param uuid sync entry uuid + * @param critical whether this control is critical + */ + public SyncStateControl(final State state, final UUID uuid, final boolean critical) + { + super(OID, critical); + setSyncState(state); + setEntryUuid(uuid); + } + + + /** + * Creates a new sync state control. + * + * @param state sync state + * @param uuid sync entry uuid + * @param value sync state cookie + * @param critical whether this control is critical + */ + public SyncStateControl(final State state, final UUID uuid, final byte[] value, final boolean critical) + { + super(OID, critical); + setSyncState(state); + setEntryUuid(uuid); + setCookie(value); + } + + + /** + * Returns the sync state. + * + * @return sync state + */ + public State getSyncState() + { + return syncState; + } + + + /** + * Sets the sync state. + * + * @param state sync state + */ + public void setSyncState(final State state) + { + syncState = state; + } + + + /** + * Returns the entry uuid. + * + * @return entry uuid + */ + public UUID getEntryUuid() + { + return entryUuid; + } + + + /** + * Sets the entry uuid. + * + * @param uuid entry uuid + */ + public void setEntryUuid(final UUID uuid) + { + entryUuid = uuid; + } + + + /** + * Returns the sync state cookie. + * + * @return sync state cookie + */ + public byte[] getCookie() + { + return cookie; + } + + + /** + * Sets the sync state cookie. + * + * @param value sync state cookie + */ + public void setCookie(final byte[] value) + { + cookie = value; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof SyncStateControl && super.equals(o)) { + final SyncStateControl v = (SyncStateControl) o; + return LdapUtils.areEqual(syncState, v.syncState) && + LdapUtils.areEqual(entryUuid, v.entryUuid) && + LdapUtils.areEqual(cookie, v.cookie); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, getOID(), getCriticality(), syncState, entryUuid, cookie); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, syncState=%s, entryUuid=%s, cookie=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + syncState, + entryUuid, + LdapUtils.base64Encode(cookie)); + } + + + @Override + public void decode(final byte[] berValue) + { + logger.trace("decoding control: {}", LdapUtils.base64Encode(berValue)); + + final DERParser parser = new DERParser(); + parser.registerHandler(StateHandler.PATH, new StateHandler(this)); + parser.registerHandler(EntryUuidHandler.PATH, new EntryUuidHandler(this)); + parser.registerHandler(CookieHandler.PATH, new CookieHandler(this)); + parser.parse(ByteBuffer.wrap(berValue)); + } + + + /** Parse handler implementation for the sync state. */ + private static class StateHandler extends AbstractParseHandler<SyncStateControl> + { + + /** DER path to the state. */ + public static final DERPath PATH = new DERPath("/SEQ/ENUM"); + + + /** + * Creates a new state handler. + * + * @param control to configure + */ + StateHandler(final SyncStateControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + final int stateValue = IntegerType.decode(encoded).intValue(); + final State s = State.valueOf(stateValue); + if (s == null) { + throw new IllegalArgumentException("Unknown state value " + stateValue); + } + getObject().setSyncState(s); + } + } + + + /** Parse handler implementation for the entry uuid. */ + private static class EntryUuidHandler extends AbstractParseHandler<SyncStateControl> + { + + /** DER path to the uuid. */ + public static final DERPath PATH = new DERPath("/SEQ/OCTSTR[1]"); + + + /** + * Creates a new entry uuid handler. + * + * @param control to configure + */ + EntryUuidHandler(final SyncStateControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + if (encoded.hasRemaining()) { + getObject().setEntryUuid(UuidType.decode(encoded)); + } + } + } + + + /** Parse handler implementation for the cookie. */ + private static class CookieHandler extends AbstractParseHandler<SyncStateControl> + { + + /** DER path to cookie value. */ + public static final DERPath PATH = new DERPath("/SEQ/OCTSTR[2]"); + + + /** + * Creates a new cookie handler. + * + * @param control to configure + */ + CookieHandler(final SyncStateControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + final byte[] cookie = OctetStringType.readBuffer(encoded); + if (cookie != null && cookie.length > 0) { + getObject().setCookie(cookie); + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/control/VirtualListViewRequestControl.java b/core/src/main/java/org/ldaptive/control/VirtualListViewRequestControl.java new file mode 100644 index 0000000..310ad4b --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/VirtualListViewRequestControl.java
@@ -0,0 +1,447 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.util.ArrayList; +import java.util.List; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.ConstructedDEREncoder; +import org.ldaptive.asn1.ContextDERTag; +import org.ldaptive.asn1.DEREncoder; +import org.ldaptive.asn1.IntegerType; +import org.ldaptive.asn1.OctetStringType; +import org.ldaptive.asn1.UniversalDERTag; + +/** + * Request control for virtual list view. See http://tools.ietf.org/html/draft-ietf-ldapext-ldapv3-vlv-09. Control is + * defined as: + * + * <pre> + VirtualListViewRequest ::= SEQUENCE { + beforeCount INTEGER (0..maxInt), + afterCount INTEGER (0..maxInt), + target CHOICE { + byOffset [0] SEQUENCE { + offset INTEGER (1 .. maxInt), + contentCount INTEGER (0 .. maxInt) }, + greaterThanOrEqual [1] AssertionValue }, + contextID OCTET STRING OPTIONAL } + * </pre> + * + * @author Middleware Services + */ +public class VirtualListViewRequestControl extends AbstractControl implements RequestControl +{ + + /** OID of this control. */ + public static final String OID = "2.16.840.1.113730.3.4.9"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 761; + + /** number of entries before the target entry the server should send. */ + private int beforeCount; + + /** number of entries after the target entry the server should send. */ + private int afterCount; + + /** target entry's offset within the ordered search result set. */ + private int targetOffset; + + /** server's estimate of the current number of entries in the ordered search result set. */ + private int contentCount; + + /** value to match against the ordering matching rule for the attributeDescription in the sort control. */ + private String assertionValue; + + /** + * value that clients should send back to the server to indicate that the server is willing to return contiguous data + * from a subsequent search request which uses the same search criteria. + */ + private byte[] contextID; + + + /** Default constructor. */ + public VirtualListViewRequestControl() + { + super(OID); + } + + + /** + * Creates a new virtual list view request control. + * + * @param offset target entry offset + * @param before number of entries before the target + * @param after number of entries after the target + */ + public VirtualListViewRequestControl(final int offset, final int before, final int after) + { + this(offset, before, after, 0, null, false); + } + + + /** + * Creates a new virtual list view request control. + * + * @param offset target entry offset + * @param before number of entries before the target + * @param after number of entries after the target + * @param critical whether this control is critical + */ + public VirtualListViewRequestControl(final int offset, final int before, final int after, final boolean critical) + { + this(offset, before, after, 0, null, critical); + } + + + /** + * Creates a new virtual list view request control. + * + * @param offset target entry offset + * @param before number of entries before the target + * @param after number of entries after the target + * @param count server estimate of the number of entries + * @param context server context id + */ + public VirtualListViewRequestControl( + final int offset, + final int before, + final int after, + final int count, + final byte[] context) + { + this(offset, before, after, count, context, false); + } + + + /** + * Creates a new virtual list view request control. + * + * @param offset target entry offset + * @param before number of entries before the target + * @param after number of entries after the target + * @param count server estimate of the number of entries + * @param context server context id + * @param critical whether this control is critical + */ + public VirtualListViewRequestControl( + final int offset, + final int before, + final int after, + final int count, + final byte[] context, + final boolean critical) + { + super(OID, critical); + setTargetOffset(offset); + setBeforeCount(before); + setAfterCount(after); + setContentCount(count); + setContextID(context); + } + + + /** + * Creates a new virtual list view request control. + * + * @param assertion value to match in the sort control + * @param before number of entries before the target + * @param after number of entries after the target + */ + public VirtualListViewRequestControl(final String assertion, final int before, final int after) + { + this(assertion, before, after, null, false); + } + + + /** + * Creates a new virtual list view request control. + * + * @param assertion value to match in the sort control + * @param before number of entries before the target + * @param after number of entries after the target + * @param critical whether this control is critical + */ + public VirtualListViewRequestControl( + final String assertion, + final int before, + final int after, + final boolean critical) + { + this(assertion, before, after, null, critical); + } + + + /** + * Creates a new virtual list view request control. + * + * @param assertion value to match in the sort control + * @param before number of entries before the target + * @param after number of entries after the target + * @param context server context id + */ + public VirtualListViewRequestControl(final String assertion, final int before, final int after, final byte[] context) + { + this(assertion, before, after, context, false); + } + + + /** + * Creates a new virtual list view request control. + * + * @param assertion value to match in the sort control + * @param before number of entries before the target + * @param after number of entries after the target + * @param context server context id + * @param critical whether this control is critical + */ + public VirtualListViewRequestControl( + final String assertion, + final int before, + final int after, + final byte[] context, + final boolean critical) + { + super(OID, critical); + setAssertionValue(assertion); + setBeforeCount(before); + setAfterCount(after); + setContextID(context); + } + + + /** + * Returns the before count. This indicates how many entries before the target entry the client wants the server to + * send. + * + * @return before count + */ + public int getBeforeCount() + { + return beforeCount; + } + + + /** + * Sets the before count. + * + * @param count before count + */ + public void setBeforeCount(final int count) + { + beforeCount = count; + } + + + /** + * Returns the after count. This indicates how many entries after the target entry the client wants the server to + * send. + * + * @return after count + */ + public int getAfterCount() + { + return afterCount; + } + + + /** + * Sets the after count. + * + * @param count after count + */ + public void setAfterCount(final int count) + { + afterCount = count; + } + + + /** + * Returns the target offset. This indicates the return entry's offset within the ordered search result set. + * + * @return target offset + */ + public int getTargetOffset() + { + return targetOffset; + } + + + /** + * Sets the target offset. + * + * @param offset target offset + */ + public void setTargetOffset(final int offset) + { + targetOffset = offset; + } + + + /** + * Returns the content count. From the RFC: + * + * <p>contentCount gives the server's estimate of the current number of entries in the list. Together these give + * sufficient information for the client to update a list box slider position to match the newly retrieved entries and + * identify the target entry. The contentCount value returned SHOULD be used in a subsequent VirtualListViewRequest + * control.</p> + * + * @return content count + */ + public int getContentCount() + { + return contentCount; + } + + + /** + * Sets the content count. + * + * @param count content count + */ + public void setContentCount(final int count) + { + contentCount = count; + } + + + /** + * Returns the assertion value. From the RFC: + * + * <p>The assertion value is encoded according to the ORDERING matching rule for the attributeDescription in the sort + * control [SSS]. If present, the value supplied in greaterThanOrEqual is used to determine the target entry by + * comparison with the values of the attribute specified as the primary sort key. The first list entry who's value is + * no less than (less than or equal to when the sort order is reversed) the supplied value is the target entry.</p> + * + * @return assertion value + */ + public String getAssertionValue() + { + return assertionValue; + } + + + /** + * Sets the assertion value. + * + * @param value assertion value + */ + public void setAssertionValue(final String value) + { + assertionValue = value; + } + + + /** + * Returns the context id. From the RFC: + * + * <p>The contextID is a server-defined octet string. If present, the contents of the contextID field SHOULD be + * returned to the server by a client in a subsequent virtual list request. The presence of a contextID here indicates + * that the server is willing to return contiguous data from a subsequent search request which uses the same search + * criteria, accompanied by a VirtualListViewRequest which indicates that the client wishes to receive an adjoining + * page of data.</p> + * + * @return context id + */ + public byte[] getContextID() + { + return contextID; + } + + + /** + * Sets the context id. + * + * @param id context id + */ + public void setContextID(final byte[] id) + { + contextID = id; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof VirtualListViewRequestControl && super.equals(o)) { + final VirtualListViewRequestControl v = (VirtualListViewRequestControl) o; + return LdapUtils.areEqual(beforeCount, v.beforeCount) && + LdapUtils.areEqual(afterCount, v.afterCount) && + LdapUtils.areEqual(targetOffset, v.targetOffset) && + LdapUtils.areEqual(contentCount, v.contentCount) && + LdapUtils.areEqual(assertionValue, v.assertionValue) && + LdapUtils.areEqual(contextID, v.contextID); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + getOID(), + getCriticality(), + beforeCount, + afterCount, + targetOffset, + contentCount, + assertionValue, + contextID); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, beforeCount=%s, afterCount=%s, targetOffset=%s, contentCount=%s, assertionValue=%s, " + + "contextID=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + beforeCount, + afterCount, + targetOffset, + contentCount, + assertionValue, + LdapUtils.base64Encode(contextID)); + } + + + @Override + public byte[] encode() + { + final List<DEREncoder> l = new ArrayList<>(); + if (getAssertionValue() != null) { + l.add(new IntegerType(getBeforeCount())); + l.add(new IntegerType(getAfterCount())); + l.add(new OctetStringType(new ContextDERTag(1, false), getAssertionValue())); + if (getContextID() != null) { + l.add(new OctetStringType(getContextID())); + } + } else { + l.add(new IntegerType(getBeforeCount())); + l.add(new IntegerType(getAfterCount())); + l.add( + new ConstructedDEREncoder( + new ContextDERTag(0, true), + new IntegerType(getTargetOffset()), + new IntegerType(getContentCount()))); + if (getContextID() != null) { + l.add(new OctetStringType(getContextID())); + } + } + + final ConstructedDEREncoder se = new ConstructedDEREncoder( + UniversalDERTag.SEQ, + l.toArray(new DEREncoder[l.size()])); + return se.encode(); + } +}
diff --git a/core/src/main/java/org/ldaptive/control/VirtualListViewResponseControl.java b/core/src/main/java/org/ldaptive/control/VirtualListViewResponseControl.java new file mode 100644 index 0000000..72eaa39 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/VirtualListViewResponseControl.java
@@ -0,0 +1,399 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.nio.ByteBuffer; +import org.ldaptive.LdapUtils; +import org.ldaptive.ResultCode; +import org.ldaptive.asn1.AbstractParseHandler; +import org.ldaptive.asn1.DERParser; +import org.ldaptive.asn1.DERPath; +import org.ldaptive.asn1.IntegerType; +import org.ldaptive.asn1.OctetStringType; + +/** + * Response control for virtual list view. See http://tools.ietf.org/html/draft-ietf-ldapext-ldapv3-vlv-09. Control is + * defined as: + * + * <pre> + VirtualListViewResponse ::= SEQUENCE { + targetPosition INTEGER (0 .. maxInt), + contentCount INTEGER (0 .. maxInt), + virtualListViewResult ENUMERATED { + success (0), + operationsError (1), + protocolError (2), + unwillingToPerform (53), + insufficientAccessRights (50), + timeLimitExceeded (3), + adminLimitExceeded (11), + innapropriateMatching (18), + sortControlMissing (60), + offsetRangeError (61), + other(80), + ... }, + contextID OCTET STRING OPTIONAL } + * </pre> + * + * @author Middleware Services + */ +public class VirtualListViewResponseControl extends AbstractControl implements ResponseControl +{ + + /** OID of this control. */ + public static final String OID = "2.16.840.1.113730.3.4.10"; + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 773; + + /** list offset for the target entry. */ + private int targetPosition; + + /** server's estimate of the current number of entries in the ordered search result set. */ + private int contentCount; + + /** Result of the vlv operation. */ + private ResultCode viewResult; + + /** + * value that clients should send back to the server to indicate that the server is willing to return contiguous data + * from a subsequent search request which uses the same search criteria. + */ + private byte[] contextID; + + + /** Default constructor. */ + public VirtualListViewResponseControl() + { + super(OID); + } + + + /** + * Creates a new virtual list view response control. + * + * @param critical whether this control is critical + */ + public VirtualListViewResponseControl(final boolean critical) + { + super(OID, critical); + } + + + /** + * Creates a new virtual list view response control. + * + * @param position offset for the target entry + * @param count server estimate of the number of entries + * @param code operation result code + * @param context server context id + */ + public VirtualListViewResponseControl( + final int position, + final int count, + final ResultCode code, + final byte[] context) + { + this(position, count, code, context, false); + } + + + /** + * Creates a new virtual list view response control. + * + * @param position offset for the target entry + * @param count server estimate of the number of entries + * @param code operation result code + * @param context server context id + * @param critical whether this control is critical + */ + public VirtualListViewResponseControl( + final int position, + final int count, + final ResultCode code, + final byte[] context, + final boolean critical) + { + super(OID, critical); + setTargetPosition(position); + setContentCount(count); + setViewResult(code); + setContextID(context); + } + + + /** + * Returns the target position. This indicates the list offset for the target entry. + * + * @return target position + */ + public int getTargetPosition() + { + return targetPosition; + } + + + /** + * Sets the target position. + * + * @param position target position + */ + public void setTargetPosition(final int position) + { + targetPosition = position; + } + + + /** + * Returns the content count. From the RFC: + * + * <p>contentCount gives the server's estimate of the current number of entries in the list. Together these give + * sufficient information for the client to update a list box slider position to match the newly retrieved entries and + * identify the target entry. The contentCount value returned SHOULD be used in a subsequent VirtualListViewRequest + * control.</p> + * + * @return content count + */ + public int getContentCount() + { + return contentCount; + } + + + /** + * Sets the content count. + * + * @param count content count + */ + public void setContentCount(final int count) + { + contentCount = count; + } + + + /** + * Returns the result code of the virtual list view. + * + * @return result code + */ + public ResultCode getViewResult() + { + return viewResult; + } + + + /** + * Sets the result code of the virtual list view. + * + * @param code result code + */ + public void setViewResult(final ResultCode code) + { + viewResult = code; + } + + + /** + * Returns the context id. From the RFC: + * + * <p>The contextID is a server-defined octet string. If present, the contents of the contextID field SHOULD be + * returned to the server by a client in a subsequent virtual list request. The presence of a contextID here indicates + * that the server is willing to return contiguous data from a subsequent search request which uses the same search + * criteria, accompanied by a VirtualListViewRequest which indicates that the client wishes to receive an adjoining + * page of data.</p> + * + * @return context id + */ + public byte[] getContextID() + { + return contextID; + } + + + /** + * Sets the context id. + * + * @param id context id + */ + public void setContextID(final byte[] id) + { + contextID = id; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof VirtualListViewResponseControl && super.equals(o)) { + final VirtualListViewResponseControl v = (VirtualListViewResponseControl) o; + return LdapUtils.areEqual(targetPosition, v.targetPosition) && + LdapUtils.areEqual(contentCount, v.contentCount) && + LdapUtils.areEqual(viewResult, v.viewResult) && + LdapUtils.areEqual(contextID, v.contextID); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + getOID(), + getCriticality(), + targetPosition, + contentCount, + viewResult, + contextID); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::criticality=%s, targetPosition=%s, contentCount=%s, viewResult=%s, contextID=%s]", + getClass().getName(), + hashCode(), + getCriticality(), + targetPosition, + contentCount, + viewResult, + LdapUtils.base64Encode(contextID)); + } + + + @Override + public void decode(final byte[] berValue) + { + logger.trace("decoding control: {}", LdapUtils.base64Encode(berValue)); + + final DERParser parser = new DERParser(); + parser.registerHandler(TargetPositionHandler.PATH, new TargetPositionHandler(this)); + parser.registerHandler(ContentCountHandler.PATH, new ContentCountHandler(this)); + parser.registerHandler(ViewResultHandler.PATH, new ViewResultHandler(this)); + parser.registerHandler(ContextIDHandler.PATH, new ContextIDHandler(this)); + parser.parse(ByteBuffer.wrap(berValue)); + } + + + /** Parse handler implementation for the target position. */ + private static class TargetPositionHandler extends AbstractParseHandler<VirtualListViewResponseControl> + { + + /** DER path to target position. */ + public static final DERPath PATH = new DERPath("/SEQ/INT[0]"); + + + /** + * Creates a new target position handler. + * + * @param control to configure + */ + TargetPositionHandler(final VirtualListViewResponseControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setTargetPosition(IntegerType.decode(encoded).intValue()); + } + } + + + /** Parse handler implementation for the content count. */ + private static class ContentCountHandler extends AbstractParseHandler<VirtualListViewResponseControl> + { + + /** DER path to content count. */ + public static final DERPath PATH = new DERPath("/SEQ/INT[1]"); + + + /** + * Creates a new content count handler. + * + * @param control to configure + */ + ContentCountHandler(final VirtualListViewResponseControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setContentCount(IntegerType.decode(encoded).intValue()); + } + } + + + /** Parse handler implementation for the view result. */ + private static class ViewResultHandler extends AbstractParseHandler<VirtualListViewResponseControl> + { + + /** DER path to result code. */ + public static final DERPath PATH = new DERPath("/SEQ/INT[2]"); + + + /** + * Creates a new view result handler. + * + * @param control to configure + */ + ViewResultHandler(final VirtualListViewResponseControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + final int resultValue = IntegerType.decode(encoded).intValue(); + final ResultCode rc = ResultCode.valueOf(resultValue); + if (rc == null) { + throw new IllegalArgumentException("Unknown result code " + resultValue); + } + getObject().setViewResult(rc); + } + } + + + /** Parse handler implementation for the context ID. */ + private static class ContextIDHandler extends AbstractParseHandler<VirtualListViewResponseControl> + { + + /** DER path to context value. */ + public static final DERPath PATH = new DERPath("/SEQ/OCTSTR"); + + + /** + * Creates a new context ID handler. + * + * @param control to configure + */ + ContextIDHandler(final VirtualListViewResponseControl control) + { + super(control); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + final byte[] cookie = OctetStringType.readBuffer(encoded); + if (cookie != null && cookie.length > 0) { + getObject().setContextID(cookie); + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/control/util/CookieManager.java b/core/src/main/java/org/ldaptive/control/util/CookieManager.java new file mode 100644 index 0000000..fb35b08 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/util/CookieManager.java
@@ -0,0 +1,27 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control.util; + +/** + * Interface for the reading and writing of control related cookies. + * + * @author Middleware Services + */ +public interface CookieManager +{ + + + /** + * Read and return a cookie from storage. + * + * @return cookie read from storage + */ + byte[] readCookie(); + + + /** + * Writes a cookie to storage. + * + * @param cookie to write + */ + void writeCookie(byte[] cookie); +}
diff --git a/core/src/main/java/org/ldaptive/control/util/DefaultCookieManager.java b/core/src/main/java/org/ldaptive/control/util/DefaultCookieManager.java new file mode 100644 index 0000000..ed301a8 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/util/DefaultCookieManager.java
@@ -0,0 +1,43 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control.util; + +/** + * Cookie manager that stores a cookie in memory. + * + * @author Middleware Services + */ +public class DefaultCookieManager implements CookieManager +{ + + /** Control cookie. */ + private byte[] cookie; + + + /** Creates a new default cookie manager. */ + public DefaultCookieManager() {} + + + /** + * Creates a new default cookie manager. + * + * @param b control cookie + */ + public DefaultCookieManager(final byte[] b) + { + cookie = b; + } + + + @Override + public byte[] readCookie() + { + return cookie; + } + + + @Override + public void writeCookie(final byte[] b) + { + cookie = b; + } +}
diff --git a/core/src/main/java/org/ldaptive/control/util/PagedResultsClient.java b/core/src/main/java/org/ldaptive/control/util/PagedResultsClient.java new file mode 100644 index 0000000..325372e --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/util/PagedResultsClient.java
@@ -0,0 +1,236 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control.util; + +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Response; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.control.PagedResultsControl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Client that simplifies using the paged results control. + * + * @author Middleware Services + */ +public class PagedResultsClient +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Connection to invoke the search operation on. */ + private final Connection connection; + + /** Results page size. */ + private final int resultSize; + + + /** + * Creates a new paged results client. + * + * @param conn to execute the search operation on + * @param size the results page size to request + */ + public PagedResultsClient(final Connection conn, final int size) + { + connection = conn; + resultSize = size; + } + + + /** + * Performs a search operation with the {@link PagedResultsControl}. The supplied request is modified in the following + * way: + * + * <ul> + * <li>{@link SearchRequest#setControls( org.ldaptive.control.RequestControl...)} is invoked with {@link + * PagedResultsControl}</li> + * </ul> + * + * @param request search request to execute + * + * @return search operation response + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> execute(final SearchRequest request) + throws LdapException + { + return execute(request, new DefaultCookieManager()); + } + + + /** + * Performs a search operation with the {@link PagedResultsControl}. The supplied request is modified in the following + * way: + * + * <ul> + * <li>{@link SearchRequest#setControls( org.ldaptive.control.RequestControl...)} is invoked with {@link + * PagedResultsControl}</li> + * </ul> + * + * <p>The cookie is extracted from the supplied response and replayed in the request.</p> + * + * @param request search request to execute + * @param response of a previous paged results operation + * + * @return search operation response + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> execute(final SearchRequest request, final Response<SearchResult> response) + throws LdapException + { + final byte[] cookie = getPagedResultsCookie(response); + if (cookie == null) { + throw new IllegalArgumentException("Response does not contain a paged results cookie"); + } + + return execute(request, new DefaultCookieManager(cookie)); + } + + + /** + * Performs a search operation with the {@link PagedResultsControl}. The supplied request is modified in the following + * way: + * + * <ul> + * <li>{@link SearchRequest#setControls( org.ldaptive.control.RequestControl...)} is invoked with {@link + * PagedResultsControl}</li> + * </ul> + * + * <p>The cookie used in the request is read from the cookie manager and written to the cookie manager after a + * successful search, if the response contains a cookie.</p> + * + * @param request search request to execute + * @param manager for reading and writing cookies + * + * @return search operation response + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> execute(final SearchRequest request, final CookieManager manager) + throws LdapException + { + final SearchOperation search = new SearchOperation(connection); + request.setControls(new PagedResultsControl(resultSize, manager.readCookie(), true)); + + final Response<SearchResult> response = search.execute(request); + final byte[] cookie = getPagedResultsCookie(response); + if (cookie != null) { + manager.writeCookie(cookie); + } + return response; + } + + + /** + * Returns whether {@link #execute(SearchRequest, Response)} can be invoked again. + * + * @param response of a previous paged results operation + * + * @return whether more paged search results can be retrieved from the server + */ + public boolean hasMore(final Response<SearchResult> response) + { + return getPagedResultsCookie(response) != null; + } + + + /** + * Performs a search operation with the {@link PagedResultsControl}. The supplied request is modified in the following + * way: + * + * <ul> + * <li>{@link SearchRequest#setControls( org.ldaptive.control.RequestControl...)} is invoked with {@link + * PagedResultsControl}</li> + * </ul> + * + * <p>This method will continue to execute search operations until all paged search results have been retrieved from + * the server. The returned response contains the response data of the last paged result operation plus the entries + * and references returned by all previous search operations.</p> + * + * @param request search request to execute + * + * @return search operation response of the last paged result operation + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> executeToCompletion(final SearchRequest request) + throws LdapException + { + return executeToCompletion(request, new DefaultCookieManager()); + } + + + /** + * Performs a search operation with the {@link PagedResultsControl}. The supplied request is modified in the following + * way: + * + * <ul> + * <li>{@link SearchRequest#setControls( org.ldaptive.control.RequestControl...)} is invoked with {@link + * PagedResultsControl}</li> + * </ul> + * + * <p>This method will continue to execute search operations until all paged search results have been retrieved from + * the server. The returned response contains the response data of the last paged result operation plus the entries + * and references returned by all previous search operations.</p> + * + * <p>The cookie used for each request is read from the cookie manager and written to the cookie manager after a + * successful search, if the response contains a cookie.</p> + * + * @param request search request to execute + * @param manager for reading and writing cookies + * + * @return search operation response of the last paged result operation + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> executeToCompletion(final SearchRequest request, final CookieManager manager) + throws LdapException + { + Response<SearchResult> response = null; + final SearchResult result = new SearchResult(); + final SearchOperation search = new SearchOperation(connection); + byte[] cookie = manager.readCookie(); + do { + if (response != null && response.getResult() != null) { + result.addEntries(response.getResult().getEntries()); + result.addReferences(response.getResult().getReferences()); + } + request.setControls(new PagedResultsControl(resultSize, cookie, true)); + response = search.execute(request); + cookie = getPagedResultsCookie(response); + if (cookie != null) { + manager.writeCookie(cookie); + } + } while (cookie != null); + response.getResult().addEntries(result.getEntries()); + response.getResult().addReferences(result.getReferences()); + return response; + } + + + /** + * Returns the paged results cookie in the supplied response or null if no cookie exists. + * + * @param response of a previous paged results operation + * + * @return paged results cookie or null + */ + protected byte[] getPagedResultsCookie(final Response<SearchResult> response) + { + byte[] cookie = null; + final PagedResultsControl ctl = (PagedResultsControl) response.getControl(PagedResultsControl.OID); + if (ctl != null) { + if (ctl.getCookie() != null && ctl.getCookie().length > 0) { + cookie = ctl.getCookie(); + } + } + return cookie; + } +}
diff --git a/core/src/main/java/org/ldaptive/control/util/PersistentSearchClient.java b/core/src/main/java/org/ldaptive/control/util/PersistentSearchClient.java new file mode 100644 index 0000000..79c4509 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/util/PersistentSearchClient.java
@@ -0,0 +1,210 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control.util; + +import java.util.EnumSet; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.async.AbandonOperation; +import org.ldaptive.async.AsyncRequest; +import org.ldaptive.async.AsyncSearchOperation; +import org.ldaptive.async.handler.AsyncRequestHandler; +import org.ldaptive.control.PersistentSearchChangeType; +import org.ldaptive.control.PersistentSearchRequestControl; +import org.ldaptive.handler.HandlerResult; +import org.ldaptive.handler.OperationResponseHandler; +import org.ldaptive.handler.SearchEntryHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Client that simplifies using the persistent search control. + * + * @author Middleware Services + */ +public class PersistentSearchClient +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Connection to invoke the search operation on. */ + private final Connection connection; + + /** Change types. */ + private final EnumSet<PersistentSearchChangeType> changeTypes; + + /** Whether to return only changed entries. */ + private final boolean changesOnly; + + /** Whether to return an Entry Change Notification control. */ + private final boolean returnEcs; + + + /** + * Creates a new persistent search client. + * + * @param conn to execute the async search operation on + * @param types persistent search change types + * @param co whether only changed entries are returned + * @param re return an Entry Change Notification control + */ + public PersistentSearchClient( + final Connection conn, + final EnumSet<PersistentSearchChangeType> types, + final boolean co, + final boolean re) + { + connection = conn; + changeTypes = types; + changesOnly = co; + returnEcs = re; + } + + + /** + * Invokes {@link #execute(SearchRequest, int)} with a capacity of {@link Integer#MAX_VALUE}. + * + * @param request search request to execute + * + * @return blocking queue to wait for persistent search items + * + * @throws LdapException if the search fails + */ + public BlockingQueue<PersistentSearchItem> execute(final SearchRequest request) + throws LdapException + { + return execute(request, Integer.MAX_VALUE); + } + + + /** + * Performs an async search operation with the {@link PersistentSearchRequestControl}. The supplied request is + * modified in the following way: + * + * <ul> + * <li>{@link SearchRequest#setControls( org.ldaptive.control.RequestControl...)} is invoked with {@link + * PersistentSearchRequestControl}</li> + * <li>{@link SearchRequest#setSearchEntryHandlers(SearchEntryHandler...)} is invoked with a custom handler that + * places persistent search data in a blocking queue.</li> + * <li>{@link AsyncSearchOperation#setExceptionHandler(org.ldaptive.async.handler.ExceptionHandler)} is invoked with + * a custom handler that places the exception in a blocking queue.</li> + * </ul> + * + * <p>The search request object should not be reused for any other search operations.</p> + * + * @param request search request to execute + * @param capacity of the returned blocking queue + * + * @return blocking queue to wait for persistent search items + * + * @throws LdapException if the search fails + */ + @SuppressWarnings("unchecked") + public BlockingQueue<PersistentSearchItem> execute(final SearchRequest request, final int capacity) + throws LdapException + { + final BlockingQueue<PersistentSearchItem> queue = new LinkedBlockingQueue<>(capacity); + + final AsyncSearchOperation search = new AsyncSearchOperation(connection); + search.setOperationResponseHandlers( + new OperationResponseHandler<SearchRequest, SearchResult>() { + @Override + public HandlerResult<Response<SearchResult>> handle( + final Connection conn, + final SearchRequest request, + final Response<SearchResult> response) + throws LdapException + { + try { + logger.debug("received {}", response); + search.shutdown(); + + queue.put(new PersistentSearchItem(response)); + } catch (Exception e) { + logger.warn("Unable to enqueue response {}", response); + } + return new HandlerResult<>(response); + } + }); + search.setAsyncRequestHandlers( + new AsyncRequestHandler() { + @Override + public HandlerResult<AsyncRequest> handle( + final Connection conn, + final Request request, + final AsyncRequest asyncRequest) + throws LdapException + { + try { + logger.debug("received {}", asyncRequest); + queue.put(new PersistentSearchItem(asyncRequest)); + } catch (Exception e) { + logger.warn("Unable to enqueue async request {}", asyncRequest); + } + return new HandlerResult<>(null); + } + }); + search.setExceptionHandler( + (conn, request1, exception) -> { + try { + logger.debug("received exception:", exception); + search.shutdown(); + queue.put(new PersistentSearchItem(exception)); + } catch (Exception e) { + logger.warn("Unable to enqueue exception:", exception); + } + return new HandlerResult<>(null); + }); + + request.setControls(new PersistentSearchRequestControl(changeTypes, changesOnly, returnEcs, true)); + request.setSearchEntryHandlers( + new SearchEntryHandler() { + @Override + public HandlerResult<SearchEntry> handle( + final Connection conn, + final SearchRequest request, + final SearchEntry entry) + throws LdapException + { + try { + logger.debug("received {}", entry); + + final PersistentSearchItem item = new PersistentSearchItem(new PersistentSearchItem.Entry(entry)); + queue.put(item); + } catch (Exception e) { + logger.warn("Unable to enqueue entry {}", entry); + } + return new HandlerResult<>(null); + } + + @Override + public void initializeRequest(final SearchRequest request) {} + }); + + search.execute(request); + return queue; + } + + + /** + * Invokes an abandon operation on the supplied ldap message id. Convenience method supplied to abandon persistent + * search operations. + * + * @param messageId of the operation to abandon + * + * @throws LdapException if the abandon operation fails + */ + public void abandon(final int messageId) + throws LdapException + { + final AbandonOperation abandon = new AbandonOperation(connection); + abandon.execute(messageId); + } +}
diff --git a/core/src/main/java/org/ldaptive/control/util/PersistentSearchItem.java b/core/src/main/java/org/ldaptive/control/util/PersistentSearchItem.java new file mode 100644 index 0000000..15e1023 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/util/PersistentSearchItem.java
@@ -0,0 +1,256 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control.util; + +import org.ldaptive.Response; +import org.ldaptive.SearchEntry; +import org.ldaptive.async.AsyncRequest; +import org.ldaptive.control.EntryChangeNotificationControl; + +/** + * Contains data returned when using the persistent search request control. + * + * @author Middleware Services + */ +public class PersistentSearchItem +{ + + /** Async request from the search operation. */ + private final AsyncRequest asyncRequest; + + /** Entry contained in this persistent search item. */ + private final Entry persistentSearchEntry; + + /** Response contained in this persistent search item. */ + private final Response persistentSearchResponse; + + /** Exception thrown by the search operation. */ + private final Exception persistentSearchException; + + + /** + * Creates a new persistent search item. + * + * @param request that represents this item + */ + public PersistentSearchItem(final AsyncRequest request) + { + asyncRequest = request; + persistentSearchEntry = null; + persistentSearchResponse = null; + persistentSearchException = null; + } + + + /** + * Creates a new persistent search item. + * + * @param entry that represents this item + */ + public PersistentSearchItem(final Entry entry) + { + asyncRequest = null; + persistentSearchEntry = entry; + persistentSearchResponse = null; + persistentSearchException = null; + } + + + /** + * Creates a new persistent search item. + * + * @param response that represents this item + */ + public PersistentSearchItem(final Response response) + { + asyncRequest = null; + persistentSearchEntry = null; + persistentSearchResponse = response; + persistentSearchException = null; + } + + + /** + * Creates a new persistent search item. + * + * @param exception that represents this item + */ + public PersistentSearchItem(final Exception exception) + { + asyncRequest = null; + persistentSearchEntry = null; + persistentSearchResponse = null; + persistentSearchException = exception; + } + + + /** + * Returns whether this item represents an async request. + * + * @return whether this item represents an async request + */ + public boolean isAsyncRequest() + { + return asyncRequest != null; + } + + + /** + * Returns the async request contained in this item or null if this item does not contain an async request. + * + * @return async request + */ + public AsyncRequest getAsyncRequest() + { + return asyncRequest; + } + + + /** + * Returns whether this item represents a search entry. + * + * @return whether this item represents a search entry + */ + public boolean isEntry() + { + return persistentSearchEntry != null; + } + + + /** + * Returns the entry contained in this item or null if this item does not contain an entry. + * + * @return search entry + */ + public Entry getEntry() + { + return persistentSearchEntry; + } + + + /** + * Returns whether this item represents a response. + * + * @return whether this item represents a response + */ + public boolean isResponse() + { + return persistentSearchResponse != null; + } + + + /** + * Returns the response contained in this item or null if this item does not contain a response. + * + * @return response + */ + public Response getResponse() + { + return persistentSearchResponse; + } + + + /** + * Returns whether this item represents an exception. + * + * @return whether this item represents an exception + */ + public boolean isException() + { + return persistentSearchException != null; + } + + + /** + * Returns the exception contained in this item or null if this item does not contain an exception. + * + * @return exception + */ + public Exception getException() + { + return persistentSearchException; + } + + + @Override + public String toString() + { + String s; + if (isAsyncRequest()) { + s = String.format("[%s@%d::asyncRequest=%s]", getClass().getName(), hashCode(), asyncRequest); + } else if (isEntry()) { + s = String.format("[%s@%d::persistentSearchEntry=%s]", getClass().getName(), hashCode(), persistentSearchEntry); + } else if (isResponse()) { + s = String.format( + "[%s@%d::persistentSearchResponse=%s]", + getClass().getName(), + hashCode(), + persistentSearchResponse); + } else if (isException()) { + s = String.format( + "[%s@%d::persistentSearchException=%s]", + getClass().getName(), + hashCode(), + persistentSearchException); + } else { + s = String.format("[%s@%d]", getClass().getName(), hashCode()); + } + return s; + } + + + /** + * Wrapper class that provides easy access to the {@link EntryChangeNotificationControl} contained in a search entry. + */ + public static class Entry + { + + /** Search entry that this class wraps. */ + private final SearchEntry searchEntry; + + /** Control to search the entry for. */ + private final EntryChangeNotificationControl entryChangeNotificationControl; + + + /** + * Creates a new entry. If the supplied search entry contains a {@link EntryChangeNotificationControl} it is made + * available via {@link #getEntryChangeNotificationControl()}. + * + * @param entry to search for entry change notification control in + */ + public Entry(final SearchEntry entry) + { + searchEntry = entry; + entryChangeNotificationControl = (EntryChangeNotificationControl) entry.getControl( + EntryChangeNotificationControl.OID); + } + + + /** + * Returns the underlying search entry. + * + * @return underlying search entry + */ + public SearchEntry getSearchEntry() + { + return searchEntry; + } + + + /** + * Returns the entry change notification control or null if no such control exists in the search entry. + * + * @return entry change notification control + */ + public EntryChangeNotificationControl getEntryChangeNotificationControl() + { + return entryChangeNotificationControl; + } + + + @Override + public String toString() + { + return String.format("[%s@%d::searchEntry=%s]", getClass().getName(), hashCode(), searchEntry); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/control/util/SyncReplClient.java b/core/src/main/java/org/ldaptive/control/util/SyncReplClient.java new file mode 100644 index 0000000..046f88a --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/util/SyncReplClient.java
@@ -0,0 +1,268 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control.util; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.async.AsyncRequest; +import org.ldaptive.async.AsyncSearchOperation; +import org.ldaptive.async.handler.AsyncRequestHandler; +import org.ldaptive.control.SyncRequestControl; +import org.ldaptive.extended.CancelOperation; +import org.ldaptive.extended.CancelRequest; +import org.ldaptive.handler.HandlerResult; +import org.ldaptive.handler.IntermediateResponseHandler; +import org.ldaptive.handler.OperationResponseHandler; +import org.ldaptive.handler.SearchEntryHandler; +import org.ldaptive.intermediate.IntermediateResponse; +import org.ldaptive.intermediate.SyncInfoMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Client that simplifies using the sync repl control. + * + * @author Middleware Services + */ +public class SyncReplClient +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Connection to invoke the search operation on. */ + private final Connection connection; + + /** Controls which mode the sync repl control should use. */ + private final boolean refreshAndPersist; + + + /** + * Creates a new sync repl client. + * + * @param conn to execute the async search operation on + * @param persist whether to refresh and persist or just refresh + */ + public SyncReplClient(final Connection conn, final boolean persist) + { + connection = conn; + refreshAndPersist = persist; + } + + + /** + * Invokes {@link #execute(SearchRequest, CookieManager, int)} with a {@link DefaultCookieManager} and a capacity of + * {@link Integer#MAX_VALUE}. + * + * @param request search request to execute + * + * @return blocking queue to wait for sync repl items + * + * @throws LdapException if the search fails + */ + public BlockingQueue<SyncReplItem> execute(final SearchRequest request) + throws LdapException + { + return execute(request, new DefaultCookieManager(), Integer.MAX_VALUE); + } + + + /** + * Invokes {@link #execute(SearchRequest, CookieManager, int)} with a capacity of {@link Integer#MAX_VALUE}. + * + * @param request search request to execute + * @param manager for reading and writing cookies + * + * @return blocking queue to wait for sync repl items + * + * @throws LdapException if the search fails + */ + public BlockingQueue<SyncReplItem> execute(final SearchRequest request, final CookieManager manager) + throws LdapException + { + return execute(request, manager, Integer.MAX_VALUE); + } + + + /** + * Performs an async search operation with the {@link SyncRequestControl}. The supplied request is modified in the + * following way: + * + * <ul> + * <li>{@link SearchRequest#setControls( org.ldaptive.control.RequestControl...)} is invoked with {@link + * SyncRequestControl}</li> + * <li>{@link SearchRequest#setSearchEntryHandlers(SearchEntryHandler...)} is invoked with a custom handler that + * places sync repl data in a blocking queue.</li> + * <li>{@link SearchRequest#setIntermediateResponseHandlers( IntermediateResponseHandler...)} is invoked with a + * custom handler that places sync repl data in a blocking queue.</li> + * <li>{@link AsyncSearchOperation#setOperationResponseHandlers( OperationResponseHandler[])} is invoked with a + * custom handler that places the sync repl response in a blocking queue.</li> + * <li>{@link AsyncSearchOperation#setExceptionHandler(org.ldaptive.async.handler.ExceptionHandler)} is invoked with + * a custom handler that places the exception in a blocking queue.</li> + * </ul> + * + * <p>The search request object should not be reused for any other search operations.</p> + * + * @param request search request to execute + * @param manager for reading and writing cookies + * @param capacity of the returned blocking queue + * + * @return blocking queue to wait for sync repl items + * + * @throws LdapException if the search fails + */ + @SuppressWarnings("unchecked") + public BlockingQueue<SyncReplItem> execute( + final SearchRequest request, + final CookieManager manager, + final int capacity) + throws LdapException + { + final BlockingQueue<SyncReplItem> queue = new LinkedBlockingQueue<>(capacity); + + final AsyncSearchOperation search = new AsyncSearchOperation(connection); + search.setOperationResponseHandlers( + new OperationResponseHandler<SearchRequest, SearchResult>() { + @Override + public HandlerResult<Response<SearchResult>> handle( + final Connection conn, + final SearchRequest request, + final Response<SearchResult> response) + throws LdapException + { + try { + logger.debug("received {}", response); + search.shutdown(); + + final SyncReplItem item = new SyncReplItem(new SyncReplItem.Response(response)); + if (item.getResponse().getSyncDoneControl() != null) { + final byte[] cookie = item.getResponse().getSyncDoneControl().getCookie(); + if (cookie != null) { + manager.writeCookie(cookie); + } + } + queue.put(item); + } catch (Exception e) { + logger.warn("Unable to enqueue response {}", response); + } + return new HandlerResult<>(response); + } + }); + search.setAsyncRequestHandlers( + new AsyncRequestHandler() { + @Override + public HandlerResult<AsyncRequest> handle( + final Connection conn, + final Request request, + final AsyncRequest asyncRequest) + throws LdapException + { + try { + logger.debug("received {}", asyncRequest); + queue.put(new SyncReplItem(asyncRequest)); + } catch (Exception e) { + logger.warn("Unable to enqueue async request {}", asyncRequest); + } + return new HandlerResult<>(null); + } + }); + search.setExceptionHandler( + (conn, request1, exception) -> { + try { + logger.debug("received exception:", exception); + search.shutdown(); + queue.put(new SyncReplItem(exception)); + } catch (Exception e) { + logger.warn("Unable to enqueue exception:", exception); + } + return new HandlerResult<>(null); + }); + + request.setControls( + new SyncRequestControl( + refreshAndPersist ? SyncRequestControl.Mode.REFRESH_AND_PERSIST : SyncRequestControl.Mode.REFRESH_ONLY, + manager.readCookie(), + true)); + request.setSearchEntryHandlers( + new SearchEntryHandler() { + @Override + public HandlerResult<SearchEntry> handle( + final Connection conn, + final SearchRequest request, + final SearchEntry entry) + throws LdapException + { + try { + logger.debug("received {}", entry); + + final SyncReplItem item = new SyncReplItem(new SyncReplItem.Entry(entry)); + if (item.getEntry().getSyncStateControl() != null) { + final byte[] cookie = item.getEntry().getSyncStateControl().getCookie(); + if (cookie != null) { + manager.writeCookie(cookie); + } + } + queue.put(item); + } catch (Exception e) { + logger.warn("Unable to enqueue entry {}", entry); + } + return new HandlerResult<>(null); + } + + @Override + public void initializeRequest(final SearchRequest request) {} + }); + request.setIntermediateResponseHandlers( + new IntermediateResponseHandler() { + @Override + public HandlerResult<IntermediateResponse> handle( + final Connection conn, + final Request request, + final IntermediateResponse response) + throws LdapException + { + if (SyncInfoMessage.OID.equals(response.getOID())) { + try { + logger.debug("received {}", response); + + final SyncInfoMessage message = (SyncInfoMessage) response; + if (message.getCookie() != null) { + manager.writeCookie(message.getCookie()); + } + queue.put(new SyncReplItem(message)); + } catch (Exception e) { + logger.warn("Unable to enqueue intermediate response {}", response); + } + } + return new HandlerResult<>(null); + } + }); + + search.execute(request); + return queue; + } + + + /** + * Invokes a cancel operation on the supplied ldap message id. Convenience method supplied to cancel sync repl + * operations. + * + * @param messageId of the operation to cancel + * + * @return cancel operation response + * + * @throws LdapException if the cancel operation fails + */ + public Response<Void> cancel(final int messageId) + throws LdapException + { + final CancelOperation cancel = new CancelOperation(connection); + return cancel.execute(new CancelRequest(messageId)); + } +}
diff --git a/core/src/main/java/org/ldaptive/control/util/SyncReplItem.java b/core/src/main/java/org/ldaptive/control/util/SyncReplItem.java new file mode 100644 index 0000000..acee030 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/util/SyncReplItem.java
@@ -0,0 +1,347 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control.util; + +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchResult; +import org.ldaptive.async.AsyncRequest; +import org.ldaptive.control.SyncDoneControl; +import org.ldaptive.control.SyncStateControl; +import org.ldaptive.intermediate.SyncInfoMessage; + +/** + * Contains data returned when using the sync repl search control. + * + * @author Middleware Services + */ +public class SyncReplItem +{ + + /** Async request from the search operation. */ + private final AsyncRequest asyncRequest; + + /** Entry contained in this sync repl item. */ + private final Entry syncReplEntry; + + /** Message contained in this sync repl item. */ + private final SyncInfoMessage syncInfoMessage; + + /** Response contained in this sync repl item. */ + private final Response syncReplResponse; + + /** Exception thrown by the search operation. */ + private final Exception syncReplException; + + + /** + * Creates a new sync repl item. + * + * @param request that represents this item + */ + public SyncReplItem(final AsyncRequest request) + { + asyncRequest = request; + syncReplEntry = null; + syncInfoMessage = null; + syncReplResponse = null; + syncReplException = null; + } + + + /** + * Creates a new sync repl item. + * + * @param entry that represents this item + */ + public SyncReplItem(final Entry entry) + { + asyncRequest = null; + syncReplEntry = entry; + syncInfoMessage = null; + syncReplResponse = null; + syncReplException = null; + } + + + /** + * Creates a new sync repl item. + * + * @param message that represents this item + */ + public SyncReplItem(final SyncInfoMessage message) + { + asyncRequest = null; + syncReplEntry = null; + syncInfoMessage = message; + syncReplResponse = null; + syncReplException = null; + } + + + /** + * Creates a new sync repl item. + * + * @param response that represents this item + */ + public SyncReplItem(final Response response) + { + asyncRequest = null; + syncReplEntry = null; + syncInfoMessage = null; + syncReplResponse = response; + syncReplException = null; + } + + + /** + * Creates a new sync repl item. + * + * @param exception that represents this item + */ + public SyncReplItem(final Exception exception) + { + asyncRequest = null; + syncReplEntry = null; + syncInfoMessage = null; + syncReplResponse = null; + syncReplException = exception; + } + + + /** + * Returns whether this item represents an async request. + * + * @return whether this item represents an async request + */ + public boolean isAsyncRequest() + { + return asyncRequest != null; + } + + + /** + * Returns the async request contained in this item or null if this item does not contain an async request. + * + * @return async request + */ + public AsyncRequest getAsyncRequest() + { + return asyncRequest; + } + + + /** + * Returns whether this item represents a search entry. + * + * @return whether this item represents a search entry + */ + public boolean isEntry() + { + return syncReplEntry != null; + } + + + /** + * Returns the entry contained in this item or null if this item does not contain an entry. + * + * @return sync repl entry + */ + public Entry getEntry() + { + return syncReplEntry; + } + + + /** + * Returns whether this item represents an intermediate message. + * + * @return whether this item represents an intermediate message + */ + public boolean isMessage() + { + return syncInfoMessage != null; + } + + + /** + * Returns the intermediate message contained in this item or null if this item does not contain a message. + * + * @return sync info message + */ + public SyncInfoMessage getMessage() + { + return syncInfoMessage; + } + + + /** + * Returns whether this item represents a response. + * + * @return whether this item represents a response + */ + public boolean isResponse() + { + return syncReplResponse != null; + } + + + /** + * Returns the response contained in this item or null if this item does not contain a response. + * + * @return response + */ + public Response getResponse() + { + return syncReplResponse; + } + + + /** + * Returns whether this item represents an exception. + * + * @return whether this item represents an exception + */ + public boolean isException() + { + return syncReplException != null; + } + + + /** + * Returns the exception contained in this item or null if this item does not contain an exception. + * + * @return exception + */ + public Exception getException() + { + return syncReplException; + } + + + @Override + public String toString() + { + String s; + if (isAsyncRequest()) { + s = String.format("[%s@%d::asyncRequest=%s]", getClass().getName(), hashCode(), asyncRequest); + } else if (isEntry()) { + s = String.format("[%s@%d::syncReplEntry=%s]", getClass().getName(), hashCode(), syncReplEntry); + } else if (isMessage()) { + s = String.format("[%s@%d::syncInfoMessage=%s]", getClass().getName(), hashCode(), syncInfoMessage); + } else if (isResponse()) { + s = String.format("[%s@%d::syncReplResponse=%s]", getClass().getName(), hashCode(), syncReplResponse); + } else if (isException()) { + s = String.format("[%s@%d::syncReplException=%s]", getClass().getName(), hashCode(), syncReplException); + } else { + s = String.format("[%s@%d]", getClass().getName(), hashCode()); + } + return s; + } + + + /** Wrapper class that provides easy access to the {@link SyncStateControl} contained in a search entry. */ + public static class Entry + { + + /** Search entry that this class wraps. */ + private final SearchEntry searchEntry; + + /** Control to search the entry for. */ + private final SyncStateControl syncStateControl; + + + /** + * Creates a new entry. If the supplied search entry contains a {@link SyncStateControl} it is made available via + * {@link #getSyncStateControl()}. + * + * @param entry to search for sync state control in + */ + public Entry(final SearchEntry entry) + { + searchEntry = entry; + syncStateControl = (SyncStateControl) entry.getControl(SyncStateControl.OID); + } + + + /** + * Returns the underlying search entry. + * + * @return underlying search entry + */ + public SearchEntry getSearchEntry() + { + return searchEntry; + } + + + /** + * Returns the sync state control or null if no such control exists in the search entry. + * + * @return sync state control + */ + public SyncStateControl getSyncStateControl() + { + return syncStateControl; + } + + + @Override + public String toString() + { + return String.format("[%s@%d::searchEntry=%s]", getClass().getName(), hashCode(), searchEntry); + } + } + + + /** Wrapper class that provides easy access to the {@link SyncDoneControl} contained in a response. */ + public static class Response + { + + /** Response that this class wraps. */ + private final org.ldaptive.Response<SearchResult> response; + + /** Control to search the response for. */ + private final SyncDoneControl syncDoneControl; + + + /** + * Creates a new response. If the supplied response contains a {@link SyncDoneControl} it is made available via + * {@link #getSyncDoneControl()}. + * + * @param res to search for sync done control in + */ + public Response(final org.ldaptive.Response<SearchResult> res) + { + response = res; + syncDoneControl = (SyncDoneControl) response.getControl(SyncDoneControl.OID); + } + + + /** + * Returns the underlying response. + * + * @return underlying response + */ + public org.ldaptive.Response<SearchResult> getResponse() + { + return response; + } + + + /** + * Returns the sync done control or null if no such control exists in the response. + * + * @return sync done control + */ + public SyncDoneControl getSyncDoneControl() + { + return syncDoneControl; + } + + + @Override + public String toString() + { + return String.format("[%s@%d::response=%s]", getClass().getName(), hashCode(), response); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/control/util/VirtualListViewClient.java b/core/src/main/java/org/ldaptive/control/util/VirtualListViewClient.java new file mode 100644 index 0000000..33d9820 --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/util/VirtualListViewClient.java
@@ -0,0 +1,101 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control.util; + +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Response; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.control.SortKey; +import org.ldaptive.control.SortRequestControl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Client that simplifies using the virtual list view control. + * + * @author Middleware Services + */ +public class VirtualListViewClient +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Connection to invoke the search operation on. */ + private final Connection connection; + + /** Used on the search operation. */ + private final SortRequestControl sortControl; + + + /** + * Creates a new virtual list view client. + * + * @param conn to execute the search operation on + * @param keys to supply to a sort request control + */ + public VirtualListViewClient(final Connection conn, final SortKey... keys) + { + connection = conn; + sortControl = new SortRequestControl(keys); + } + + + /** + * Performs a search operation with the {@link org.ldaptive.control.VirtualListViewRequestControl}. The supplied + * request is modified in the following way: + * + * <ul> + * <li>{@link SearchRequest#setControls( org.ldaptive.control.RequestControl...)} is invoked with {@link + * SortRequestControl} and {@link org.ldaptive.control.VirtualListViewRequestControl}</li> + * </ul> + * + * @param request search request to execute + * @param params virtual list view data + * + * @return search operation response + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> execute(final SearchRequest request, final VirtualListViewParams params) + throws LdapException + { + final SearchOperation search = new SearchOperation(connection); + request.setControls(sortControl, params.createRequestControl(true)); + return search.execute(request); + } + + + /** + * Performs a search operation with the {@link org.ldaptive.control.VirtualListViewRequestControl}. The supplied + * request is modified in the following way: + * + * <ul> + * <li>{@link SearchRequest#setControls( org.ldaptive.control.RequestControl...)} is invoked with {@link + * SortRequestControl} and {@link org.ldaptive.control.VirtualListViewRequestControl}</li> + * </ul> + * + * <p>The content count and context id are extracted from the supplied response and replayed as appropriate in the + * request.</p> + * + * @param request search request to execute + * @param params virtual list view data + * @param response of a previous VLV operation + * + * @return search operation response + * + * @throws LdapException if the search fails + */ + public Response<SearchResult> execute( + final SearchRequest request, + final VirtualListViewParams params, + final Response<SearchResult> response) + throws LdapException + { + final SearchOperation search = new SearchOperation(connection); + request.setControls(sortControl, params.createRequestControl(response, true)); + return search.execute(request); + } +}
diff --git a/core/src/main/java/org/ldaptive/control/util/VirtualListViewParams.java b/core/src/main/java/org/ldaptive/control/util/VirtualListViewParams.java new file mode 100644 index 0000000..9486aee --- /dev/null +++ b/core/src/main/java/org/ldaptive/control/util/VirtualListViewParams.java
@@ -0,0 +1,178 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control.util; + +import org.ldaptive.Response; +import org.ldaptive.SearchResult; +import org.ldaptive.control.VirtualListViewRequestControl; +import org.ldaptive.control.VirtualListViewResponseControl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Contains data required by the virtual list view operation. + * + * @author Middleware Services + */ +public class VirtualListViewParams +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** VLV before count. */ + private final int beforeCount; + + /** VLV after count. */ + private final int afterCount; + + /** VLV target offset; mutually exclusive with the assertion value. */ + private final int targetOffset; + + /** VLV assertion value; mutually exclusive with the target offset. */ + private final String assertionValue; + + + /** + * Creates a new virtual list view params. + * + * @param offset target offset + * @param before before count + * @param after after count + */ + public VirtualListViewParams(final int offset, final int before, final int after) + { + targetOffset = offset; + beforeCount = before; + afterCount = after; + assertionValue = null; + } + + + /** + * Creates a new virtual list view params. + * + * @param assertion assertion value + * @param before before count + * @param after after count + */ + public VirtualListViewParams(final String assertion, final int before, final int after) + { + assertionValue = assertion; + beforeCount = before; + afterCount = after; + targetOffset = 0; + } + + + /** + * Returns the before count. + * + * @return before count + */ + public int getBeforeCount() + { + return beforeCount; + } + + + /** + * Returns the after count. + * + * @return after count + */ + public int getAfterCount() + { + return afterCount; + } + + + /** + * Returns the target offset. + * + * @return target offset + */ + public int getTargetOffset() + { + return targetOffset; + } + + + /** + * Returns the assertion value. + * + * @return assertion value + */ + public String getAssertionValue() + { + return assertionValue; + } + + + /** + * Creates a new virtual list view request control using the properties in this VLV params. + * + * @param critical whether the returned control is critical + * + * @return virtual list view request control + */ + public VirtualListViewRequestControl createRequestControl(final boolean critical) + { + if (assertionValue != null) { + return new VirtualListViewRequestControl(assertionValue, beforeCount, afterCount, critical); + } else { + return new VirtualListViewRequestControl(targetOffset, beforeCount, afterCount, critical); + } + } + + + /** + * Creates a new virtual list view request control using the properties in this VLV params. The supplied response is + * inspected and if it contains a VLV response control, it's contextID and/or content count will be passed into the + * created request control. + * + * @param response response of a previous VLV operation + * @param critical whether the returned control is critical + * + * @return virtual list view request control + */ + public VirtualListViewRequestControl createRequestControl( + final Response<SearchResult> response, + final boolean critical) + { + final VirtualListViewRequestControl control = createRequestControl(critical); + final VirtualListViewResponseControl responseControl = (VirtualListViewResponseControl) response.getControl( + VirtualListViewResponseControl.OID); + if (responseControl != null) { + if (assertionValue == null) { + control.setContentCount(responseControl.getContentCount()); + } + control.setContextID(responseControl.getContextID()); + } + return control; + } + + + @Override + public String toString() + { + String s; + if (assertionValue != null) { + s = String.format( + "[%s@%d::assertionValue=%s, beforeCount=%s, afterCount=%s]", + getClass().getName(), + hashCode(), + assertionValue, + beforeCount, + afterCount); + } else { + s = String.format( + "[%s@%d::targetOffset=%s, beforeCount=%s, afterCount=%s]", + getClass().getName(), + hashCode(), + targetOffset, + beforeCount, + afterCount); + } + return s; + } +}
diff --git a/core/src/main/java/org/ldaptive/ext/MergeOperation.java b/core/src/main/java/org/ldaptive/ext/MergeOperation.java new file mode 100644 index 0000000..b0d7b7a --- /dev/null +++ b/core/src/main/java/org/ldaptive/ext/MergeOperation.java
@@ -0,0 +1,230 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ext; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.ldaptive.AbstractOperation; +import org.ldaptive.AddOperation; +import org.ldaptive.AddRequest; +import org.ldaptive.AttributeModification; +import org.ldaptive.Connection; +import org.ldaptive.DeleteOperation; +import org.ldaptive.DeleteRequest; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.ModifyOperation; +import org.ldaptive.ModifyRequest; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; + +/** + * The merge operation performs the LDAP operations necessary to synchronize the data in an {@link LdapEntry} with it's + * corresponding entry in the LDAP. The following logic is executed: + * + * <ul> + * <li>if the entry does not exist in the LDAP, execute an add</li> + * <li>if the request is for a delete, execute a delete</li> + * <li>if the entry exists in the LDAP, execute a modify</li> + * </ul> + * + * <p>{@link LdapEntry#computeModifications(LdapEntry, LdapEntry)} is used to determine the list of attribute + * modifications that are necessary to perform the merge. Either {@link MergeRequest#getIncludeAttributes()} or {@link + * MergeRequest#getExcludeAttributes()} will be used, but not both.</p> + * + * @author Middleware Services + */ +public class MergeOperation extends AbstractOperation<MergeRequest, Void> +{ + + + /** + * Creates a new merge operation. + * + * @param conn connection + */ + public MergeOperation(final Connection conn) + { + super(conn); + } + + + /** + * Executes the ldap operation necessary to perform a merge. One of {@link AddOperation}, {@link ModifyOperation}, or + * {@link DeleteOperation}. + * + * @param request merge request + * + * @return response associated with whatever underlying operation was performed by the merge or an empty response if + * no operation was performed + * + * @throws LdapException if the invocation fails + */ + @Override + protected Response<Void> invoke(final MergeRequest request) + throws LdapException + { + final LdapEntry sourceEntry = request.getEntry(); + Response<Void> response; + + // search for existing entry + Response<SearchResult> searchResponse = null; + try { + final SearchOperation search = new SearchOperation(getConnection()); + searchResponse = search.execute( + SearchRequest.newObjectScopeSearchRequest(sourceEntry.getDn(), request.getSearchAttributes())); + } catch (LdapException e) { + if (e.getResultCode() != ResultCode.NO_SUCH_OBJECT) { + throw e; + } + } + if ( + searchResponse != null && + searchResponse.getResultCode() != ResultCode.SUCCESS && + searchResponse.getResultCode() != ResultCode.NO_SUCH_OBJECT) { + throw new LdapException( + String.format( + "Error searching for entry: %s, response did not return success or " + + "no_such_object: %s", + sourceEntry, + searchResponse)); + } + + if (searchResponse == null || searchResponse.getResult().size() == 0) { + if (request.getDeleteEntry()) { + logger.info("target entry does not exist, no delete performed for request {}", request); + response = new Response<>(null, null); + } else { + // entry does not exist, add it + response = add(request, sourceEntry); + } + } else if (request.getDeleteEntry()) { + // delete entry + response = delete(request, sourceEntry); + } else { + // entry exists, merge attributes + response = modify(request, sourceEntry, searchResponse.getResult().getEntry()); + } + return response; + } + + + /** + * Retrieves the attribute modifications from {@link LdapEntry#computeModifications(LdapEntry, LdapEntry)} and + * executes a {@link ModifyOperation} with those results. If no modifications are necessary, no operation is + * performed. + * + * @param request merge request + * @param source ldap entry to merge into the LDAP + * @param target ldap entry that exists in the LDAP + * + * @return response of the modify operation or an empty response if no operation is performed + * + * @throws LdapException if an error occurs executing the modify operation + */ + protected Response<Void> modify(final MergeRequest request, final LdapEntry source, final LdapEntry target) + throws LdapException + { + Response<Void> response; + final AttributeModification[] modifications = LdapEntry.computeModifications(source, target); + if (modifications != null && modifications.length > 0) { + final List<AttributeModification> resultModifications = new ArrayList<>(modifications.length); + final String[] includeAttrs = request.getIncludeAttributes(); + final String[] excludeAttrs = request.getExcludeAttributes(); + if (includeAttrs != null && includeAttrs.length > 0) { + final List<String> l = Arrays.asList(includeAttrs); + for (AttributeModification am : modifications) { + if (l.contains(am.getAttribute().getName())) { + resultModifications.add(am); + } + } + } else if (excludeAttrs != null && excludeAttrs.length > 0) { + final List<String> l = Arrays.asList(excludeAttrs); + for (AttributeModification am : modifications) { + if (!l.contains(am.getAttribute().getName())) { + resultModifications.add(am); + } + } + } else { + Collections.addAll(resultModifications, modifications); + } + if (!resultModifications.isEmpty()) { + logger.info( + "modifying target entry {} with modifications {} from source entry " + + "{} for request {}", + target, + resultModifications, + source, + request); + + final ModifyOperation modify = new ModifyOperation(getConnection()); + response = modify.execute( + new ModifyRequest( + target.getDn(), + resultModifications.toArray(new AttributeModification[resultModifications.size()]))); + logger.info( + "modified target entry {} with modifications {} from source entry " + + "{} for request {}", + target, + resultModifications, + source, + request); + return response; + } + } + response = new Response<>(null, null); + logger.info( + "target entry {} equals source entry {}, no modification performed for " + + "request {}", + target, + source, + request); + return response; + } + + + /** + * Executes an {@link AddOperation} for the supplied entry. + * + * @param request merge request + * @param entry to add to the LDAP + * + * @return response of the add operation + * + * @throws LdapException if an error occurs executing the add operation + */ + protected Response<Void> add(final MergeRequest request, final LdapEntry entry) + throws LdapException + { + Response<Void> response; + final AddOperation add = new AddOperation(getConnection()); + response = add.execute(new AddRequest(entry.getDn(), entry.getAttributes())); + logger.info("added entry {} for request {}", entry, request); + return response; + } + + + /** + * Executes a {@link DeleteOperation} for the supplied entry. + * + * @param request merge request + * @param entry to delete from the LDAP + * + * @return response of the delete operation + * + * @throws LdapException if an error occurs executing the deleting operation + */ + protected Response<Void> delete(final MergeRequest request, final LdapEntry entry) + throws LdapException + { + Response<Void> response; + final DeleteOperation delete = new DeleteOperation(getConnection()); + response = delete.execute(new DeleteRequest(entry.getDn())); + logger.info("delete entry {} for request {}", entry, request); + return response; + } +}
diff --git a/core/src/main/java/org/ldaptive/ext/MergeRequest.java b/core/src/main/java/org/ldaptive/ext/MergeRequest.java new file mode 100644 index 0000000..ff57db4 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ext/MergeRequest.java
@@ -0,0 +1,189 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ext; + +import java.util.Arrays; +import org.ldaptive.AbstractRequest; +import org.ldaptive.LdapEntry; + +/** + * Contains the data required to perform a merge operation. + * + * @author Middleware Services + */ +public class MergeRequest extends AbstractRequest +{ + + /** Ldap entry to merge. */ + private LdapEntry ldapEntry; + + /** Whether to delete the entry. */ + private boolean deleteEntry; + + /** Attribute names to include in the search. */ + private String[] searchAttrs; + + /** Attribute names to include when performing a merge. */ + private String[] includeAttrs; + + /** Attribute names to exclude when performing a merge. */ + private String[] excludeAttrs; + + + /** Default constructor. */ + public MergeRequest() {} + + + /** + * Creates a new merge request. + * + * @param entry to merge into the LDAP + */ + public MergeRequest(final LdapEntry entry) + { + setEntry(entry); + } + + + /** + * Creates a new merge request. + * + * @param entry to merge into the LDAP + * @param delete whether the supplied entry should be deleted + */ + public MergeRequest(final LdapEntry entry, final boolean delete) + { + setEntry(entry); + setDeleteEntry(delete); + } + + + /** + * Returns the ldap entry to merge. + * + * @return ldap entry to merge + */ + public LdapEntry getEntry() + { + return ldapEntry; + } + + + /** + * Sets the ldap entry to merge into the LDAP. + * + * @param entry to merge + */ + public void setEntry(final LdapEntry entry) + { + ldapEntry = entry; + } + + + /** + * Returns whether to delete the entry. + * + * @return whether to delete the entry + */ + public boolean getDeleteEntry() + { + return deleteEntry; + } + + + /** + * Sets whether to delete the entry. + * + * @param b whether to delete the entry + */ + public void setDeleteEntry(final boolean b) + { + deleteEntry = b; + } + + + /** + * Returns the names of attributes that are used when searching for the entry. + * + * @return attribute names to return when searching + */ + public String[] getSearchAttributes() + { + return searchAttrs; + } + + + /** + * Sets the list of attribute names that are used when searching for the entry. + * + * @param attrs names to return when searching + */ + public void setSearchAttributes(final String... attrs) + { + searchAttrs = attrs; + } + + + /** + * Returns the names of attributes that are included when performing a modify. + * + * @return attribute names to include + */ + public String[] getIncludeAttributes() + { + return includeAttrs; + } + + + /** + * Sets the list of attribute names to include when performing modify. + * + * @param attrs names to include + */ + public void setIncludeAttributes(final String... attrs) + { + includeAttrs = attrs; + } + + + /** + * Returns the names of attributes that are excluded when performing a modify. + * + * @return attribute names to exclude + */ + public String[] getExcludeAttributes() + { + return excludeAttrs; + } + + + /** + * Sets the list of attribute names to exclude when performing a modify. + * + * @param attrs names to exclude + */ + public void setExcludeAttributes(final String... attrs) + { + excludeAttrs = attrs; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::ldapEntry=%s, deleteEntry=%s, searchAttributes=%s, " + + "includeAttributes=%s, excludeAttributes=%s, controls=%s, " + + "referralHandler=%s, intermediateResponseHandlers=%s]", + getClass().getName(), + hashCode(), + ldapEntry, + deleteEntry, + Arrays.toString(searchAttrs), + Arrays.toString(includeAttrs), + Arrays.toString(excludeAttrs), + Arrays.toString(getControls()), + getReferralHandler(), + Arrays.toString(getIntermediateResponseHandlers())); + } +}
diff --git a/core/src/main/java/org/ldaptive/extended/AbstractExtendedResponse.java b/core/src/main/java/org/ldaptive/extended/AbstractExtendedResponse.java new file mode 100644 index 0000000..b9c7cb8 --- /dev/null +++ b/core/src/main/java/org/ldaptive/extended/AbstractExtendedResponse.java
@@ -0,0 +1,34 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +/** + * Provides common implementation for extended responses. + * + * @param <T> type of response value + * + * @author Middleware Services + */ +public abstract class AbstractExtendedResponse<T> implements ExtendedResponse<T> +{ + + /** Response value. */ + private T value; + + + @Override + public T getValue() + { + return value; + } + + + /** + * Sets the response value for this extended operation. + * + * @param t response value + */ + protected void setValue(final T t) + { + value = t; + } +}
diff --git a/core/src/main/java/org/ldaptive/extended/CancelOperation.java b/core/src/main/java/org/ldaptive/extended/CancelOperation.java new file mode 100644 index 0000000..8529bdc --- /dev/null +++ b/core/src/main/java/org/ldaptive/extended/CancelOperation.java
@@ -0,0 +1,37 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +import org.ldaptive.AbstractOperation; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Response; + +/** + * Executes an ldap cancel operation. See RFC 3909. + * + * @author Middleware Services + */ +public class CancelOperation extends AbstractOperation<CancelRequest, Void> +{ + + + /** + * Creates a new cancel operation. + * + * @param conn connection + */ + public CancelOperation(final Connection conn) + { + super(conn); + } + + + @Override + protected Response<Void> invoke(final CancelRequest request) + throws LdapException + { + @SuppressWarnings("unchecked") + final Response<Void> response = (Response<Void>) getConnection().getProviderConnection().extendedOperation(request); + return response; + } +}
diff --git a/core/src/main/java/org/ldaptive/extended/CancelRequest.java b/core/src/main/java/org/ldaptive/extended/CancelRequest.java new file mode 100644 index 0000000..59d34aa --- /dev/null +++ b/core/src/main/java/org/ldaptive/extended/CancelRequest.java
@@ -0,0 +1,91 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +import java.util.Arrays; +import org.ldaptive.AbstractRequest; +import org.ldaptive.asn1.ConstructedDEREncoder; +import org.ldaptive.asn1.IntegerType; +import org.ldaptive.asn1.UniversalDERTag; + +/** + * Contains the data required to perform an ldap cancel operation. See RFC 3909. + * + * @author Middleware Services + */ +public class CancelRequest extends AbstractRequest implements ExtendedRequest +{ + + /** OID of this extended request. */ + public static final String OID = "1.3.6.1.1.8"; + + /** message id to cancel. */ + private int messageId; + + + /** Default constructor. */ + public CancelRequest() {} + + + /** + * Creates a new cancel request. + * + * @param id of the message to cancel + */ + public CancelRequest(final int id) + { + setMessageId(id); + } + + + /** + * Returns the message id to cancel. + * + * @return message id + */ + public int getMessageId() + { + return messageId; + } + + + /** + * Sets the message id to cancel. + * + * @param id of the message to cancel + */ + public void setMessageId(final int id) + { + messageId = id; + } + + + @Override + public byte[] encode() + { + final ConstructedDEREncoder se = new ConstructedDEREncoder(UniversalDERTag.SEQ, new IntegerType(getMessageId())); + return se.encode(); + } + + + @Override + public String getOID() + { + return OID; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::messageId=%s, controls=%s, referralHandler=%s, " + + "intermediateResponseHandlers=%s]", + getClass().getName(), + hashCode(), + messageId, + Arrays.toString(getControls()), + getReferralHandler(), + Arrays.toString(getIntermediateResponseHandlers())); + } +}
diff --git a/core/src/main/java/org/ldaptive/extended/CancelResponse.java b/core/src/main/java/org/ldaptive/extended/CancelResponse.java new file mode 100644 index 0000000..54082a9 --- /dev/null +++ b/core/src/main/java/org/ldaptive/extended/CancelResponse.java
@@ -0,0 +1,29 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +/** + * Contains the response from an ldap cancel operation. See RFC 3909. + * + * @author Middleware Services + */ +public class CancelResponse extends AbstractExtendedResponse<Void> +{ + + + @Override + public String getOID() + { + return null; + } + + + @Override + public void decode(final byte[] encoded) {} + + + @Override + public String toString() + { + return String.format("[%s@%d]", getClass().getName(), hashCode()); + } +}
diff --git a/core/src/main/java/org/ldaptive/extended/ExtendedRequest.java b/core/src/main/java/org/ldaptive/extended/ExtendedRequest.java new file mode 100644 index 0000000..2b2a622 --- /dev/null +++ b/core/src/main/java/org/ldaptive/extended/ExtendedRequest.java
@@ -0,0 +1,29 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +import org.ldaptive.Request; + +/** + * Marker interface for ldap extended requests. + * + * @author Middleware Services + */ +public interface ExtendedRequest extends Request +{ + + + /** + * Returns the OID for this extended request. + * + * @return oid + */ + String getOID(); + + + /** + * Provides the BER encoding of this request. + * + * @return BER encoded request + */ + byte[] encode(); +}
diff --git a/core/src/main/java/org/ldaptive/extended/ExtendedResponse.java b/core/src/main/java/org/ldaptive/extended/ExtendedResponse.java new file mode 100644 index 0000000..93c23e4 --- /dev/null +++ b/core/src/main/java/org/ldaptive/extended/ExtendedResponse.java
@@ -0,0 +1,38 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +/** + * Marker interface for ldap extended responses. + * + * @param <T> type of response value + * + * @author Middleware Services + */ +public interface ExtendedResponse<T> +{ + + + /** + * Returns the OID for this extended response. Response OIDs are optional and this value may be null. + * + * @return oid + */ + String getOID(); + + + /** + * Initializes this response with the supplied BER encoded data. + * + * @param encoded BER encoded response + */ + void decode(byte[] encoded); + + + /** + * Returns the response value associated with this extended operation or null if no value was generated by this + * operation. + * + * @return response value + */ + T getValue(); +}
diff --git a/core/src/main/java/org/ldaptive/extended/ExtendedResponseFactory.java b/core/src/main/java/org/ldaptive/extended/ExtendedResponseFactory.java new file mode 100644 index 0000000..293328a --- /dev/null +++ b/core/src/main/java/org/ldaptive/extended/ExtendedResponseFactory.java
@@ -0,0 +1,64 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +import org.ldaptive.ad.extended.FastBindRequest; +import org.ldaptive.ad.extended.FastBindResponse; + +/** + * Utility class for creating extended responses. + * + * @author Middleware Services + */ +public final class ExtendedResponseFactory +{ + + + /** Default constructor. */ + private ExtendedResponseFactory() {} + + + /** + * Creates an extended response from the supplied response data. + * + * @param requestOID of the extended request + * @param responseOID of the extended response + * @param encoded BER encoding of the extended response + * + * @return extended response + */ + public static ExtendedResponse<?> createExtendedResponse( + final String requestOID, + final String responseOID, + final byte[] encoded) + { + ExtendedResponse<?> res; + switch (requestOID) { + + case PasswordModifyRequest.OID: + res = new PasswordModifyResponse(); + if (encoded != null) { + res.decode(encoded); + } + break; + + case WhoAmIRequest.OID: + res = new WhoAmIResponse(); + if (encoded != null) { + res.decode(encoded); + } + break; + + case CancelRequest.OID: + res = new CancelResponse(); + break; + + case FastBindRequest.OID: + res = new FastBindResponse(); + break; + + default: + throw new IllegalArgumentException("Unknown OID: " + responseOID); + } + return res; + } +}
diff --git a/core/src/main/java/org/ldaptive/extended/PasswordModifyOperation.java b/core/src/main/java/org/ldaptive/extended/PasswordModifyOperation.java new file mode 100644 index 0000000..484b97c --- /dev/null +++ b/core/src/main/java/org/ldaptive/extended/PasswordModifyOperation.java
@@ -0,0 +1,39 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +import org.ldaptive.AbstractOperation; +import org.ldaptive.Connection; +import org.ldaptive.Credential; +import org.ldaptive.LdapException; +import org.ldaptive.Response; + +/** + * Executes an ldap password modify operation. See RFC 3062. + * + * @author Middleware Services + */ +public class PasswordModifyOperation extends AbstractOperation<PasswordModifyRequest, Credential> +{ + + + /** + * Creates a new password modify operation. + * + * @param conn connection + */ + public PasswordModifyOperation(final Connection conn) + { + super(conn); + } + + + @Override + protected Response<Credential> invoke(final PasswordModifyRequest request) + throws LdapException + { + @SuppressWarnings("unchecked") + final Response<Credential> response = + (Response<Credential>) getConnection().getProviderConnection().extendedOperation(request); + return response; + } +}
diff --git a/core/src/main/java/org/ldaptive/extended/PasswordModifyRequest.java b/core/src/main/java/org/ldaptive/extended/PasswordModifyRequest.java new file mode 100644 index 0000000..f601b49 --- /dev/null +++ b/core/src/main/java/org/ldaptive/extended/PasswordModifyRequest.java
@@ -0,0 +1,180 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.ldaptive.AbstractRequest; +import org.ldaptive.Credential; +import org.ldaptive.asn1.ConstructedDEREncoder; +import org.ldaptive.asn1.ContextType; +import org.ldaptive.asn1.DEREncoder; +import org.ldaptive.asn1.UniversalDERTag; + +/** + * Contains the data required to perform an ldap password modify operation. See RFC 3062. Request is defined as: + * + * <pre> + PasswdModifyRequestValue ::= SEQUENCE { + userIdentity [0] OCTET STRING OPTIONAL + oldPasswd [1] OCTET STRING OPTIONAL + newPasswd [2] OCTET STRING OPTIONAL } + * </pre> + * + * @author Middleware Services + */ +public class PasswordModifyRequest extends AbstractRequest implements ExtendedRequest +{ + + /** OID of this extended request. */ + public static final String OID = "1.3.6.1.4.1.4203.1.11.1"; + + /** User to modify. */ + private String userIdentity; + + /** Current password. */ + private Credential oldPassword; + + /** Desired password. */ + private Credential newPassword; + + + /** Default constructor. */ + public PasswordModifyRequest() {} + + + /** + * Creates a new password modify request. + * + * @param identity to modify + */ + public PasswordModifyRequest(final String identity) + { + setUserIdentity(identity); + } + + + /** + * Creates a new password modify request. + * + * @param identity to modify + * @param oldPass current password for the dn + * @param newPass desired password for the dn + */ + public PasswordModifyRequest(final String identity, final Credential oldPass, final Credential newPass) + { + setUserIdentity(identity); + setOldPassword(oldPass); + setNewPassword(newPass); + } + + + /** + * Returns the user to modify. + * + * @return user identity + */ + public String getUserIdentity() + { + return userIdentity; + } + + + /** + * Sets the user to modify. + * + * @param identity to modify + */ + public void setUserIdentity(final String identity) + { + userIdentity = identity; + } + + + /** + * Returns the old password. + * + * @return old password + */ + public Credential getOldPassword() + { + return oldPassword; + } + + + /** + * Sets the old password. + * + * @param oldPass to verify + */ + public void setOldPassword(final Credential oldPass) + { + oldPassword = oldPass; + } + + + /** + * Returns the new password. + * + * @return new password + */ + public Credential getNewPassword() + { + return newPassword; + } + + + /** + * Sets the new password. + * + * @param newPass to set + */ + public void setNewPassword(final Credential newPass) + { + newPassword = newPass; + } + + + @Override + public byte[] encode() + { + final List<DEREncoder> l = new ArrayList<>(); + if (getUserIdentity() != null) { + l.add(new ContextType(0, getUserIdentity())); + } + if (getOldPassword() != null) { + l.add(new ContextType(1, getOldPassword().getString())); + } + if (getNewPassword() != null) { + l.add(new ContextType(2, getNewPassword().getString())); + } + + final ConstructedDEREncoder se = new ConstructedDEREncoder( + UniversalDERTag.SEQ, + l.toArray(new DEREncoder[l.size()])); + return se.encode(); + } + + + @Override + public String getOID() + { + return OID; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::userIdentity=%s, controls=%s, referralHandler=%s, " + + "intermediateResponseHandlers=%s]", + getClass().getName(), + hashCode(), + userIdentity, + Arrays.toString(getControls()), + getReferralHandler(), + Arrays.toString(getIntermediateResponseHandlers())); + } +}
diff --git a/core/src/main/java/org/ldaptive/extended/PasswordModifyResponse.java b/core/src/main/java/org/ldaptive/extended/PasswordModifyResponse.java new file mode 100644 index 0000000..581a8c7 --- /dev/null +++ b/core/src/main/java/org/ldaptive/extended/PasswordModifyResponse.java
@@ -0,0 +1,74 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +import java.nio.ByteBuffer; +import org.ldaptive.Credential; +import org.ldaptive.asn1.AbstractParseHandler; +import org.ldaptive.asn1.DERParser; +import org.ldaptive.asn1.DERPath; +import org.ldaptive.asn1.OctetStringType; + +/** + * Contains the response from an ldap password modify operation. See RFC 3062. Response is defined as: + * + * <pre> + PasswdModifyResponseValue ::= SEQUENCE { + genPasswd [0] OCTET STRING OPTIONAL } + * </pre> + * + * @author Middleware Services + */ +public class PasswordModifyResponse extends AbstractExtendedResponse<Credential> +{ + + + @Override + public String getOID() + { + // RFC defines the response name as absent + return null; + } + + + @Override + public void decode(final byte[] encoded) + { + final DERParser parser = new DERParser(); + parser.registerHandler(GenPasswdHandler.PATH, new GenPasswdHandler(this)); + parser.parse(ByteBuffer.wrap(encoded)); + } + + + @Override + public String toString() + { + return String.format("[%s@%d]", getClass().getName(), hashCode()); + } + + + /** Parse handler implementation for the genPasswd. */ + private static class GenPasswdHandler extends AbstractParseHandler<PasswordModifyResponse> + { + + /** DER path to generated password. */ + public static final DERPath PATH = new DERPath("/SEQ/CTX(0)"); + + + /** + * Creates a new gen passwd handler. + * + * @param response to configure + */ + GenPasswdHandler(final PasswordModifyResponse response) + { + super(response); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setValue(new Credential(OctetStringType.decode(encoded))); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/extended/UnsolicitedNotificationListener.java b/core/src/main/java/org/ldaptive/extended/UnsolicitedNotificationListener.java new file mode 100644 index 0000000..ea9a4c0 --- /dev/null +++ b/core/src/main/java/org/ldaptive/extended/UnsolicitedNotificationListener.java
@@ -0,0 +1,25 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +import org.ldaptive.Response; + +/** + * Processes an unsolicited notification. + * + * @author Middleware Services + */ +public interface UnsolicitedNotificationListener +{ + + /** OID for the notice of disconnection notification. */ + String NOTICE_OF_DISCONNECTION_OID = "1.3.6.1.4.1.1466.20036"; + + + /** + * Processes an unsolicited notification from the server. + * + * @param oid of the unsolicited notification + * @param response server response + */ + void notificationReceived(String oid, Response<Void> response); +}
diff --git a/core/src/main/java/org/ldaptive/extended/UnsolicitedNotifications.java b/core/src/main/java/org/ldaptive/extended/UnsolicitedNotifications.java new file mode 100644 index 0000000..9fb6ed9 --- /dev/null +++ b/core/src/main/java/org/ldaptive/extended/UnsolicitedNotifications.java
@@ -0,0 +1,49 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +import org.ldaptive.Connection; + +/** + * Adds and removes unsolicited notification listeners to provider connections. + * + * @author Middleware Services + */ +public class UnsolicitedNotifications +{ + + /** Connection to configure unsolicited notifications on. */ + private final Connection connection; + + + /** + * Creates a new unsolicited notifications. + * + * @param conn connection + */ + public UnsolicitedNotifications(final Connection conn) + { + connection = conn; + } + + + /** + * Adds a listener to receive unsolicited notifications. + * + * @param listener to receive unsolicited notifications + */ + public void addListener(final UnsolicitedNotificationListener listener) + { + connection.getProviderConnection().addUnsolicitedNotificationListener(listener); + } + + + /** + * Removes a listener from receiving unsolicited notifications. + * + * @param listener to no longer receive unsolicited notifications + */ + public void removeListener(final UnsolicitedNotificationListener listener) + { + connection.getProviderConnection().removeUnsolicitedNotificationListener(listener); + } +}
diff --git a/core/src/main/java/org/ldaptive/extended/WhoAmIOperation.java b/core/src/main/java/org/ldaptive/extended/WhoAmIOperation.java new file mode 100644 index 0000000..2776711 --- /dev/null +++ b/core/src/main/java/org/ldaptive/extended/WhoAmIOperation.java
@@ -0,0 +1,38 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +import org.ldaptive.AbstractOperation; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Response; + +/** + * Executes an ldap who am i operation. See RFC 4532. + * + * @author Middleware Services + */ +public class WhoAmIOperation extends AbstractOperation<WhoAmIRequest, String> +{ + + + /** + * Creates a new who am i operation. + * + * @param conn connection + */ + public WhoAmIOperation(final Connection conn) + { + super(conn); + } + + + @Override + protected Response<String> invoke(final WhoAmIRequest request) + throws LdapException + { + @SuppressWarnings("unchecked") + final Response<String> response = (Response<String>) getConnection().getProviderConnection().extendedOperation( + request); + return response; + } +}
diff --git a/core/src/main/java/org/ldaptive/extended/WhoAmIRequest.java b/core/src/main/java/org/ldaptive/extended/WhoAmIRequest.java new file mode 100644 index 0000000..0f662cf --- /dev/null +++ b/core/src/main/java/org/ldaptive/extended/WhoAmIRequest.java
@@ -0,0 +1,46 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +import java.util.Arrays; +import org.ldaptive.AbstractRequest; + +/** + * Contains the data required to perform an ldap who am i operation. See RFC 4532. + * + * @author Middleware Services + */ +public class WhoAmIRequest extends AbstractRequest implements ExtendedRequest +{ + + /** OID of this extended request. */ + public static final String OID = "1.3.6.1.4.1.4203.1.11.3"; + + + @Override + public byte[] encode() + { + return null; + } + + + @Override + public String getOID() + { + return OID; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::controls=%s, referralHandler=%s, " + + "intermediateResponseHandlers=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(getControls()), + getReferralHandler(), + Arrays.toString(getIntermediateResponseHandlers())); + } +}
diff --git a/core/src/main/java/org/ldaptive/extended/WhoAmIResponse.java b/core/src/main/java/org/ldaptive/extended/WhoAmIResponse.java new file mode 100644 index 0000000..49ee6c4 --- /dev/null +++ b/core/src/main/java/org/ldaptive/extended/WhoAmIResponse.java
@@ -0,0 +1,36 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +import java.nio.ByteBuffer; +import org.ldaptive.asn1.OctetStringType; + +/** + * Contains the response from an ldap who am i operation. See RFC 4532. + * + * @author Middleware Services + */ +public class WhoAmIResponse extends AbstractExtendedResponse<String> +{ + + + @Override + public String getOID() + { + // RFC defines the response name as absent + return null; + } + + + @Override + public void decode(final byte[] encoded) + { + setValue(OctetStringType.decode(ByteBuffer.wrap(encoded))); + } + + + @Override + public String toString() + { + return String.format("[%s@%d]", getClass().getName(), hashCode()); + } +}
diff --git a/core/src/main/java/org/ldaptive/handler/AbstractRetryOperationExceptionHandler.java b/core/src/main/java/org/ldaptive/handler/AbstractRetryOperationExceptionHandler.java new file mode 100644 index 0000000..a104766 --- /dev/null +++ b/core/src/main/java/org/ldaptive/handler/AbstractRetryOperationExceptionHandler.java
@@ -0,0 +1,188 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.handler; + +import java.util.concurrent.TimeUnit; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides common implementation for retrying after an operation exception. + * + * @param <Q> type of ldap request + * @param <S> type of ldap response + * + * @author Middleware Services + */ +public abstract class AbstractRetryOperationExceptionHandler<Q extends Request, S> + implements OperationExceptionHandler<Q, S> +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Number of times to retry. */ + private int retry; + + /** Amount of time in seconds to wait before retries. */ + private long retryWait; + + /** Factor to multiply retry wait by. */ + private int retryBackoff; + + + /** + * Returns the retry. This is the number of times the handler will retry when it fails. + * + * @return retry + */ + public int getRetry() + { + return retry; + } + + + /** + * Sets the number of retries. + * + * @param i to set + */ + public void setRetry(final int i) + { + logger.trace("setting retry: {}", i); + retry = i; + } + + + /** + * Returns the retry wait. This is the amount of time in seconds that the executing thread will sleep before + * attempting to retry again. + * + * @return retry wait + */ + public long getRetryWait() + { + return retryWait; + } + + + /** + * Sets the retry wait. Time must be >= 0. + * + * @param time in seconds + */ + public void setRetryWait(final long time) + { + if (time >= 0) { + logger.trace("setting retryWait: {}", time); + retryWait = time; + } + } + + + /** + * Returns the retry backoff. This is the factor by which the retry wait will be multiplied in order to progressively + * delay the amount of time between each retry. + * + * @return retry backoff + */ + public int getRetryBackoff() + { + return retryBackoff; + } + + + /** + * Sets the retry backoff. + * + * @param backoff to set + */ + public void setRetryBackoff(final int backoff) + { + logger.trace("setting retryBackoff: {}", backoff); + retryBackoff = backoff; + } + + + @Override + public HandlerResult<Response<S>> handle(final Connection conn, final Q request, final Response<S> response) + throws LdapException + { + for (int i = 0; i <= retry || retry == -1; i++) { + try { + handleInternal(conn, request, response); + break; + } catch (LdapException e) { + logger.error("unable to handle operation exception", e); + if (!retry(i)) { + // handle failed, throw the original exception + return new HandlerResult<>(null, true); + } + } + } + return createResult(conn, request, response); + } + + + /** + * Perform any operations required to recover from the operation exception. + * + * @param conn connection the operation was executed on + * @param request executed by the operation + * @param response typically null + * + * @throws LdapException if the retry fails + */ + protected abstract void handleInternal(final Connection conn, final Q request, final Response<S> response) + throws LdapException; + + + /** + * Invoked if {@link #handleInternal} succeeded. Creates a response for the original invocation that failed. + * + * @param conn connection the operation was executed on + * @param request executed by the operation + * @param response typically null + * + * @return handler result containing a response for the original invocation + * + * @throws LdapException if the operation fails + */ + protected abstract HandlerResult<Response<S>> createResult( + final Connection conn, + final Q request, + final Response<S> response) + throws LdapException; + + + /** + * Returns whether the supplied count indicates that the operation should be retried. If a retry wait has been + * configured, this method will sleep the current thread for the configured time. + * + * @param count number of times the operation has been retried + * + * @return whether to retry + */ + protected boolean retry(final int count) + { + if (count < retry || retry == -1) { + logger.warn("Retry attempt {} of {}: wait={}, backoff={}", count + 1, retry, retryWait, retryBackoff); + if (retryWait > 0) { + long sleepTime = retryWait; + if (retryBackoff > 0 && count > 0) { + sleepTime = sleepTime * retryBackoff * count; + } + try { + Thread.sleep(TimeUnit.SECONDS.toMillis(sleepTime)); + } catch (InterruptedException ie) { + logger.debug("Retry wait interrupted", ie); + } + } + return true; + } + return false; + } +}
diff --git a/core/src/main/java/org/ldaptive/handler/AbstractSearchEntryHandler.java b/core/src/main/java/org/ldaptive/handler/AbstractSearchEntryHandler.java new file mode 100644 index 0000000..6667d48 --- /dev/null +++ b/core/src/main/java/org/ldaptive/handler/AbstractSearchEntryHandler.java
@@ -0,0 +1,158 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.handler; + +import java.util.Set; +import java.util.stream.Collectors; +import org.ldaptive.Connection; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapException; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base class for entry handlers which simply returns values unaltered. + * + * @author Middleware Services + */ +public abstract class AbstractSearchEntryHandler implements SearchEntryHandler +{ + + /** Log for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + + @Override + public HandlerResult<SearchEntry> handle(final Connection conn, final SearchRequest request, final SearchEntry entry) + throws LdapException + { + if (entry != null) { + entry.setDn(handleDn(conn, request, entry)); + handleAttributes(conn, request, entry); + } + return new HandlerResult<>(entry); + } + + + /** + * Handle the dn of a search entry. + * + * @param conn the search was performed on + * @param request used to find the search entry + * @param entry search entry to extract the dn from + * + * @return handled dn + */ + protected String handleDn(final Connection conn, final SearchRequest request, final SearchEntry entry) + { + return entry.getDn(); + } + + + /** + * Handle the attributes of a search entry. + * + * @param conn the search was performed on + * @param request used to find the search entry + * @param entry search entry to extract the attributes from + * + * @throws LdapException if the LDAP returns an error + */ + protected void handleAttributes(final Connection conn, final SearchRequest request, final SearchEntry entry) + throws LdapException + { + for (LdapAttribute la : entry.getAttributes()) { + handleAttribute(conn, request, la); + } + } + + + /** + * Handle a single attribute. + * + * @param conn the search was performed on + * @param request used to find the search entry + * @param attr to handle + * + * @throws LdapException if the LDAP returns an error + */ + protected void handleAttribute(final Connection conn, final SearchRequest request, final LdapAttribute attr) + throws LdapException + { + if (attr != null) { + attr.setName(handleAttributeName(conn, request, attr.getName())); + if (attr.isBinary()) { + final Set<byte[]> newValues = attr.getBinaryValues().stream().map( + b -> handleAttributeValue(conn, request, b)).collect(Collectors.toSet()); + attr.clear(); + attr.addBinaryValues(newValues); + } else { + final Set<String> newValues = attr.getStringValues().stream().map( + s -> handleAttributeValue(conn, request, s)).collect(Collectors.toSet()); + attr.clear(); + attr.addStringValues(newValues); + } + } + } + + + /** + * Returns the supplied attribute name unaltered. + * + * @param conn the search was performed on + * @param request used to find the search entry + * @param name to handle + * + * @return handled name + */ + protected String handleAttributeName(final Connection conn, final SearchRequest request, final String name) + { + return name; + } + + + /** + * Returns the supplied attribute value unaltered. + * + * @param conn the search was performed on + * @param request used to find the search entry + * @param value to handle + * + * @return handled value + */ + protected String handleAttributeValue(final Connection conn, final SearchRequest request, final String value) + { + return value; + } + + + /** + * Returns the supplied attribute value unaltered. + * + * @param conn the search was performed on + * @param request used to find the search entry + * @param value to handle + * + * @return handled value + */ + protected byte[] handleAttributeValue(final Connection conn, final SearchRequest request, final byte[] value) + { + return value; + } + + + @Override + public void initializeRequest(final SearchRequest request) {} + + + @Override + public boolean equals(final Object o) + { + return super.equals(o); + } + + + @Override + public abstract int hashCode(); +}
diff --git a/core/src/main/java/org/ldaptive/handler/CaseChangeEntryHandler.java b/core/src/main/java/org/ldaptive/handler/CaseChangeEntryHandler.java new file mode 100644 index 0000000..c80f985 --- /dev/null +++ b/core/src/main/java/org/ldaptive/handler/CaseChangeEntryHandler.java
@@ -0,0 +1,247 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.handler; + +import java.util.Arrays; +import org.ldaptive.Connection; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapException; +import org.ldaptive.LdapUtils; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchRequest; + +/** + * Provides the ability to modify the case of search entry DNs, attribute names, and attribute values. + * + * @author Middleware Services + */ +public class CaseChangeEntryHandler extends AbstractSearchEntryHandler +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 821; + + /** Enum to define the type of case change. */ + public enum CaseChange { + + /** no case change. */ + NONE, + + /** lower case. */ + LOWER, + + /** upper case. */ + UPPER; + + + /** + * This changes the supplied string based on the supplied case change. + * + * @param cc case change to perform + * @param string to modify + * + * @return string that has been changed + */ + public static String perform(final CaseChange cc, final String string) + { + String s = null; + if (CaseChange.LOWER == cc) { + s = string.toLowerCase(); + } else if (CaseChange.UPPER == cc) { + s = string.toUpperCase(); + } else if (CaseChange.NONE == cc) { + s = string; + } + return s; + } + } + + /** Type of case modification to make to the entry DN. */ + private CaseChange dnCaseChange = CaseChange.NONE; + + /** Type of case modification to make to the attribute names. */ + private CaseChange attributeNameCaseChange = CaseChange.NONE; + + /** Type of case modification to make to the attributes values. */ + private CaseChange attributeValueCaseChange = CaseChange.NONE; + + /** Attribute names to modify. */ + private String[] attributeNames; + + + /** + * Returns the DN case change. + * + * @return case change + */ + public CaseChange getDnCaseChange() + { + return dnCaseChange; + } + + + /** + * Sets the DN case change. + * + * @param cc case change + */ + public void setDnCaseChange(final CaseChange cc) + { + dnCaseChange = cc; + } + + + /** + * Returns the attribute name case change. + * + * @return case change + */ + public CaseChange getAttributeNameCaseChange() + { + return attributeNameCaseChange; + } + + + /** + * Sets the attribute name case change. + * + * @param cc case change + */ + public void setAttributeNameCaseChange(final CaseChange cc) + { + attributeNameCaseChange = cc; + } + + + /** + * Returns the attribute value case change. + * + * @return case change + */ + public CaseChange getAttributeValueCaseChange() + { + return attributeValueCaseChange; + } + + + /** + * Sets the attribute value case change. + * + * @param cc case change + */ + public void setAttributeValueCaseChange(final CaseChange cc) + { + attributeValueCaseChange = cc; + } + + + /** + * Returns the attribute names. + * + * @return attribute names + */ + public String[] getAttributeNames() + { + return attributeNames; + } + + + /** + * Sets the attribute names. + * + * @param names of the attributes + */ + public void setAttributeNames(final String... names) + { + attributeNames = names; + } + + + @Override + protected String handleDn(final Connection conn, final SearchRequest request, final SearchEntry entry) + { + return CaseChange.perform(dnCaseChange, entry.getDn()); + } + + + @Override + protected void handleAttributes(final Connection conn, final SearchRequest request, final SearchEntry entry) + throws LdapException + { + if (attributeNames == null) { + super.handleAttributes(conn, request, entry); + } else { + for (String s : attributeNames) { + final LdapAttribute la = entry.getAttribute(s); + if (la != null) { + handleAttribute(conn, request, la); + } + } + } + } + + + @Override + protected String handleAttributeName(final Connection conn, final SearchRequest request, final String name) + { + return CaseChange.perform(attributeNameCaseChange, name); + } + + + @Override + protected String handleAttributeValue(final Connection conn, final SearchRequest request, final String value) + { + return CaseChange.perform(attributeValueCaseChange, value); + } + + + @Override + protected byte[] handleAttributeValue(final Connection conn, final SearchRequest request, final byte[] value) + { + return value; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof CaseChangeEntryHandler) { + final CaseChangeEntryHandler v = (CaseChangeEntryHandler) o; + return LdapUtils.areEqual(dnCaseChange, v.dnCaseChange) && + LdapUtils.areEqual(attributeNameCaseChange, v.attributeNameCaseChange) && + LdapUtils.areEqual(attributeValueCaseChange, v.attributeValueCaseChange) && + LdapUtils.areEqual(attributeNames, v.attributeNames); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + dnCaseChange, + attributeNameCaseChange, + attributeValueCaseChange, + attributeNames); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::dnCaseChange=%s, attributeNameCaseChange=%s, attributeValueCaseChange=%s, attributeNames=%s]", + getClass().getName(), + hashCode(), + dnCaseChange, + attributeNameCaseChange, + attributeValueCaseChange, + Arrays.toString(attributeNames)); + } +}
diff --git a/core/src/main/java/org/ldaptive/handler/DnAttributeEntryHandler.java b/core/src/main/java/org/ldaptive/handler/DnAttributeEntryHandler.java new file mode 100644 index 0000000..c26b89f --- /dev/null +++ b/core/src/main/java/org/ldaptive/handler/DnAttributeEntryHandler.java
@@ -0,0 +1,120 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.handler; + +import org.ldaptive.Connection; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapException; +import org.ldaptive.LdapUtils; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchRequest; + +/** + * Adds the entry DN as an attribute to the result set. Provides a client side implementation of RFC 5020. + * + * @author Middleware Services + */ +public class DnAttributeEntryHandler extends AbstractSearchEntryHandler +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 823; + + /** Attribute name for the entry dn. */ + private String dnAttributeName = "entryDN"; + + /** + * Whether to add the entry dn if an attribute of the same name exists. + */ + private boolean addIfExists; + + + /** + * Returns the DN attribute name. + * + * @return DN attribute name + */ + public String getDnAttributeName() + { + return dnAttributeName; + } + + + /** + * Sets the DN attribute name. + * + * @param name of the DN attribute + */ + public void setDnAttributeName(final String name) + { + dnAttributeName = name; + } + + + /** + * Returns whether to add the entryDN if an attribute of the same name exists. + * + * @return whether to add the entryDN if an attribute of the same name exists + */ + public boolean isAddIfExists() + { + return addIfExists; + } + + + /** + * Sets whether to add the entryDN if an attribute of the same name exists. + * + * @param b whether to add the entryDN if an attribute of the same name exists + */ + public void setAddIfExists(final boolean b) + { + addIfExists = b; + } + + + @Override + protected void handleAttributes(final Connection conn, final SearchRequest request, final SearchEntry entry) + throws LdapException + { + if (entry.getAttribute(dnAttributeName) == null) { + entry.addAttribute(new LdapAttribute(dnAttributeName, entry.getDn())); + } else if (addIfExists) { + entry.getAttribute(dnAttributeName).addStringValue(entry.getDn()); + } + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof DnAttributeEntryHandler) { + final DnAttributeEntryHandler v = (DnAttributeEntryHandler) o; + return LdapUtils.areEqual(addIfExists, v.addIfExists) && + LdapUtils.areEqual(dnAttributeName, v.dnAttributeName); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, addIfExists, dnAttributeName); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::dnAttributeName=%s, addIfExists=%s]", + getClass().getName(), + hashCode(), + dnAttributeName, + addIfExists); + } +}
diff --git a/core/src/main/java/org/ldaptive/handler/Handler.java b/core/src/main/java/org/ldaptive/handler/Handler.java new file mode 100644 index 0000000..c806f25 --- /dev/null +++ b/core/src/main/java/org/ldaptive/handler/Handler.java
@@ -0,0 +1,33 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.handler; + +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Request; + +/** + * Interface for ldap handlers. + * + * @param <Q> type of ldap request + * @param <S> type of ldap response + * + * @author Middleware Services + */ +public interface Handler<Q extends Request, S> +{ + + + /** + * Handle the supplied result. + * + * @param conn connection the operation was executed on + * @param request executed by the operation + * @param result produced from the operation + * + * @return handler result + * + * @throws LdapException if handling fails + */ + HandlerResult<S> handle(Connection conn, Q request, S result) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/handler/HandlerResult.java b/core/src/main/java/org/ldaptive/handler/HandlerResult.java new file mode 100644 index 0000000..ac3c293 --- /dev/null +++ b/core/src/main/java/org/ldaptive/handler/HandlerResult.java
@@ -0,0 +1,66 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.handler; + +/** + * Handler result data. + * + * @param <T> type of result + * + * @author Middleware Services + */ +public class HandlerResult<T> +{ + + /** Result produced by a handler. */ + private final T result; + + /** Whether the operation should be aborted. */ + private final boolean abort; + + + /** + * Creates a new handler result. + * + * @param t produced by a handler + */ + public HandlerResult(final T t) + { + result = t; + abort = false; + } + + + /** + * Creates a new handler result. + * + * @param t produced by a handler + * @param b whether the operation should be aborted + */ + public HandlerResult(final T t, final boolean b) + { + result = t; + abort = b; + } + + + /** + * Returns the result produced by a handler. + * + * @return result + */ + public T getResult() + { + return result; + } + + + /** + * Returns whether the operation should be aborted. + * + * @return whether the operation should be aborted + */ + public boolean getAbort() + { + return abort; + } +}
diff --git a/core/src/main/java/org/ldaptive/handler/IntermediateResponseHandler.java b/core/src/main/java/org/ldaptive/handler/IntermediateResponseHandler.java new file mode 100644 index 0000000..1585be6 --- /dev/null +++ b/core/src/main/java/org/ldaptive/handler/IntermediateResponseHandler.java
@@ -0,0 +1,21 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.handler; + +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Request; +import org.ldaptive.intermediate.IntermediateResponse; + +/** + * Provides handling of an ldap intermediate response. + * + * @author Middleware Services + */ +public interface IntermediateResponseHandler extends Handler<Request, IntermediateResponse> +{ + + + @Override + HandlerResult<IntermediateResponse> handle(Connection conn, Request request, IntermediateResponse response) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/handler/MergeAttributeEntryHandler.java b/core/src/main/java/org/ldaptive/handler/MergeAttributeEntryHandler.java new file mode 100644 index 0000000..463809b --- /dev/null +++ b/core/src/main/java/org/ldaptive/handler/MergeAttributeEntryHandler.java
@@ -0,0 +1,135 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.handler; + +import java.util.Arrays; +import org.ldaptive.Connection; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapException; +import org.ldaptive.LdapUtils; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchRequest; + +/** + * Merges the values of one or more attributes into a single attribute. The merged attribute may or may not already + * exist on the entry. If it does exist it's existing values will remain intact. + * + * @author Middleware Services + */ +public class MergeAttributeEntryHandler extends AbstractSearchEntryHandler +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 827; + + /** Attribute name to add merge values into. */ + private String mergeAttributeName; + + /** Attribute names to read values from. */ + private String[] attributeNames; + + + /** + * Returns the merge attribute name. + * + * @return merge attribute name + */ + public String getMergeAttributeName() + { + return mergeAttributeName; + } + + + /** + * Sets the merge attribute name. + * + * @param name of the merge attribute + */ + public void setMergeAttributeName(final String name) + { + mergeAttributeName = name; + } + + + /** + * Returns the attribute names. + * + * @return attribute names + */ + public String[] getAttributeNames() + { + return attributeNames; + } + + + /** + * Sets the attribute names. + * + * @param names of the attributes + */ + public void setAttributeNames(final String... names) + { + attributeNames = names; + } + + + @Override + protected void handleAttributes(final Connection conn, final SearchRequest request, final SearchEntry entry) + throws LdapException + { + boolean newAttribute = false; + LdapAttribute mergedAttribute = entry.getAttribute(mergeAttributeName); + if (mergedAttribute == null) { + mergedAttribute = new LdapAttribute(mergeAttributeName); + newAttribute = true; + } + for (String s : attributeNames) { + final LdapAttribute la = entry.getAttribute(s); + if (la != null) { + if (la.isBinary()) { + mergedAttribute.addBinaryValues(la.getBinaryValues()); + } else { + mergedAttribute.addStringValues(la.getStringValues()); + } + } + } + + if (mergedAttribute.size() > 0 && newAttribute) { + entry.addAttribute(mergedAttribute); + } + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof MergeAttributeEntryHandler) { + final MergeAttributeEntryHandler v = (MergeAttributeEntryHandler) o; + return LdapUtils.areEqual(attributeNames, v.attributeNames) && + LdapUtils.areEqual(mergeAttributeName, v.mergeAttributeName); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, attributeNames, mergeAttributeName); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::mergeAttributeName=%s, attributeNames=%s]", + getClass().getName(), + hashCode(), + mergeAttributeName, + Arrays.toString(attributeNames)); + } +}
diff --git a/core/src/main/java/org/ldaptive/handler/NoOpOperationExceptionHandler.java b/core/src/main/java/org/ldaptive/handler/NoOpOperationExceptionHandler.java new file mode 100644 index 0000000..1dedf93 --- /dev/null +++ b/core/src/main/java/org/ldaptive/handler/NoOpOperationExceptionHandler.java
@@ -0,0 +1,27 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.handler; + +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Request; +import org.ldaptive.Response; + +/** + * Returns a handler result containing the response passed to {@link #handle(Connection, Request, Response)}. + * + * @param <Q> type of ldap request + * @param <S> type of ldap response + * + * @author Middleware Services + */ +public class NoOpOperationExceptionHandler<Q extends Request, S> implements OperationExceptionHandler<Q, S> +{ + + + @Override + public HandlerResult<Response<S>> handle(final Connection conn, final Q request, final Response<S> response) + throws LdapException + { + return new HandlerResult<>(response); + } +}
diff --git a/core/src/main/java/org/ldaptive/handler/OperationExceptionHandler.java b/core/src/main/java/org/ldaptive/handler/OperationExceptionHandler.java new file mode 100644 index 0000000..05e94be --- /dev/null +++ b/core/src/main/java/org/ldaptive/handler/OperationExceptionHandler.java
@@ -0,0 +1,24 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.handler; + +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Request; +import org.ldaptive.Response; + +/** + * Provides handling of operation exceptions. + * + * @param <Q> type of ldap request + * @param <S> type of ldap response + * + * @author Middleware Services + */ +public interface OperationExceptionHandler<Q extends Request, S> extends Handler<Q, Response<S>> +{ + + + @Override + HandlerResult<Response<S>> handle(Connection conn, Q request, Response<S> response) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/handler/OperationResponseHandler.java b/core/src/main/java/org/ldaptive/handler/OperationResponseHandler.java new file mode 100644 index 0000000..d3333c6 --- /dev/null +++ b/core/src/main/java/org/ldaptive/handler/OperationResponseHandler.java
@@ -0,0 +1,24 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.handler; + +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Request; +import org.ldaptive.Response; + +/** + * Provides handling of operation responses. + * + * @param <Q> type of ldap request + * @param <T> type of ldap result contained in the response + * + * @author Middleware Services + */ +public interface OperationResponseHandler<Q extends Request, T> extends Handler<Q, Response<T>> +{ + + + @Override + HandlerResult<Response<T>> handle(Connection conn, Q request, Response<T> response) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/handler/RecursiveEntryHandler.java b/core/src/main/java/org/ldaptive/handler/RecursiveEntryHandler.java new file mode 100644 index 0000000..47def3d --- /dev/null +++ b/core/src/main/java/org/ldaptive/handler/RecursiveEntryHandler.java
@@ -0,0 +1,277 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.handler; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.ldaptive.Connection; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.LdapUtils; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; + +/** + * This recursively searches based on a supplied attribute and merges those results into the original entry. For the + * following LDIF: + * + * <pre> + dn: uugid=group1,ou=groups,dc=ldaptive,dc=org + uugid: group1 + member: uugid=group2,ou=groups,dc=ldaptive,dc=org + + dn: uugid=group2,ou=groups,dc=ldaptive,dc=org + uugid: group2 + * </pre> + * + * <p>With the following code:</p> + * + * <pre> + RecursiveEntryHandler reh = new RecursiveEntryHandler("member", "uugid"); + * </pre> + * + * <p>Will produce this result for the query (uugid=group1):</p> + * + * <pre> + dn: uugid=group1,ou=groups,dc=ldaptive,dc=org + uugid: group1 + uugid: group2 + member: uugid=group2,ou=groups,dc=ldaptive,dc=org + * </pre> + * + * @author Middleware Services + */ +public class RecursiveEntryHandler extends AbstractSearchEntryHandler +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 829; + + /** Attribute to recursively search on. */ + private String searchAttribute; + + /** Attribute(s) to merge. */ + private String[] mergeAttributes; + + /** Attributes to return when searching, mergeAttributes + searchAttribute. */ + private String[] retAttrs; + + + /** Default constructor. */ + public RecursiveEntryHandler() {} + + + /** + * Creates a new recursive entry handler. + * + * @param searchAttr attribute to search on + * @param mergeAttrs attribute names to merge + */ + public RecursiveEntryHandler(final String searchAttr, final String... mergeAttrs) + { + searchAttribute = searchAttr; + mergeAttributes = mergeAttrs; + initalizeReturnAttributes(); + } + + + /** + * Returns the attribute name that will be recursively searched on. + * + * @return attribute name + */ + public String getSearchAttribute() + { + return searchAttribute; + } + + + /** + * Sets the attribute name that will be recursively searched on. + * + * @param name of the search attribute + */ + public void setSearchAttribute(final String name) + { + searchAttribute = name; + initalizeReturnAttributes(); + } + + + /** + * Returns the attribute names that will be merged by the recursive search. + * + * @return attribute names + */ + public String[] getMergeAttributes() + { + return mergeAttributes; + } + + + /** + * Sets the attribute name that will be merged by the recursive search. + * + * @param mergeAttrs attribute names to merge + */ + public void setMergeAttributes(final String... mergeAttrs) + { + mergeAttributes = mergeAttrs; + initalizeReturnAttributes(); + } + + + /** + * Initializes the return attributes array. Must be called after both searchAttribute and mergeAttributes have been + * set. + */ + protected void initalizeReturnAttributes() + { + if (mergeAttributes != null && searchAttribute != null) { + // return attributes must include the search attribute + retAttrs = new String[mergeAttributes.length + 1]; + System.arraycopy(mergeAttributes, 0, retAttrs, 0, mergeAttributes.length); + retAttrs[retAttrs.length - 1] = searchAttribute; + } + } + + + @Override + public HandlerResult<SearchEntry> handle(final Connection conn, final SearchRequest request, final SearchEntry entry) + throws LdapException + { + // Recursively searches a list of attributes and merges those results with + // the existing entry. + final List<String> searchedDns = new ArrayList<>(); + if (entry.getAttribute(searchAttribute) != null) { + searchedDns.add(entry.getDn()); + readSearchAttribute(conn, entry, searchedDns); + } else { + recursiveSearch(conn, entry.getDn(), entry, searchedDns); + } + return new HandlerResult<>(entry); + } + + + /** + * Reads the values of {@link #searchAttribute} from the supplied attributes and calls {@link #recursiveSearch} for + * each. + * + * @param conn to perform search operation on + * @param entry to read + * @param searchedDns list of DNs whose attributes have been read + * + * @throws LdapException if a search error occurs + */ + private void readSearchAttribute(final Connection conn, final LdapEntry entry, final List<String> searchedDns) + throws LdapException + { + if (entry != null) { + final LdapAttribute attr = entry.getAttribute(searchAttribute); + if (attr != null && !attr.isBinary()) { + final Set<String> values = new HashSet<>(attr.getStringValues()); + for (String s : values) { + recursiveSearch(conn, s, entry, searchedDns); + } + } + } + } + + + /** + * Recursively gets the attribute(s) {@link #mergeAttributes} for the supplied dn and adds the values to the supplied + * attributes. + * + * @param conn to perform search operation on + * @param dn to get attribute(s) for + * @param entry to merge with + * @param searchedDns list of DNs that have been searched for + * + * @throws LdapException if a search error occurs + */ + private void recursiveSearch( + final Connection conn, + final String dn, + final LdapEntry entry, + final List<String> searchedDns) + throws LdapException + { + if (!searchedDns.contains(dn)) { + + LdapEntry newEntry = null; + try { + final SearchOperation search = new SearchOperation(conn); + final SearchRequest sr = SearchRequest.newObjectScopeSearchRequest(dn, retAttrs); + final SearchResult result = search.execute(sr).getResult(); + newEntry = result.getEntry(dn); + } catch (LdapException e) { + logger.warn("Error retrieving attribute(s): {}", Arrays.toString(retAttrs), e); + } + searchedDns.add(dn); + + if (newEntry != null) { + // recursively search new attributes + readSearchAttribute(conn, newEntry, searchedDns); + + // merge new attribute values + for (String s : mergeAttributes) { + final LdapAttribute newAttr = newEntry.getAttribute(s); + if (newAttr != null) { + final LdapAttribute oldAttr = entry.getAttribute(s); + if (oldAttr == null) { + entry.addAttribute(newAttr); + } else { + if (newAttr.isBinary()) { + newAttr.getBinaryValues().forEach(oldAttr::addBinaryValue); + } else { + newAttr.getStringValues().forEach(oldAttr::addStringValue); + } + } + } + } + } + } + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof RecursiveEntryHandler) { + final RecursiveEntryHandler v = (RecursiveEntryHandler) o; + return LdapUtils.areEqual(mergeAttributes, v.mergeAttributes) && + LdapUtils.areEqual(retAttrs, v.retAttrs) && + LdapUtils.areEqual(searchAttribute, v.searchAttribute); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, mergeAttributes, retAttrs, searchAttribute); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::searchAttribute=%s, mergeAttributes=%s, retAttrs=%s]", + getClass().getName(), + hashCode(), + searchAttribute, + Arrays.toString(mergeAttributes), + Arrays.toString(retAttrs)); + } +}
diff --git a/core/src/main/java/org/ldaptive/handler/SearchEntryHandler.java b/core/src/main/java/org/ldaptive/handler/SearchEntryHandler.java new file mode 100644 index 0000000..42f7dda --- /dev/null +++ b/core/src/main/java/org/ldaptive/handler/SearchEntryHandler.java
@@ -0,0 +1,29 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.handler; + +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchRequest; + +/** + * Provides post search handling of a search entry. + * + * @author Middleware Services + */ +public interface SearchEntryHandler extends Handler<SearchRequest, SearchEntry> +{ + + + @Override + HandlerResult<SearchEntry> handle(Connection conn, SearchRequest request, SearchEntry entry) + throws LdapException; + + + /** + * Initialize the search request for use with this entry handler. + * + * @param request to initialize for this entry handler + */ + void initializeRequest(SearchRequest request); +}
diff --git a/core/src/main/java/org/ldaptive/handler/SearchReferenceHandler.java b/core/src/main/java/org/ldaptive/handler/SearchReferenceHandler.java new file mode 100644 index 0000000..1375b96 --- /dev/null +++ b/core/src/main/java/org/ldaptive/handler/SearchReferenceHandler.java
@@ -0,0 +1,29 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.handler; + +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.SearchReference; +import org.ldaptive.SearchRequest; + +/** + * Provides post search handling of a search reference. + * + * @author Middleware Services + */ +public interface SearchReferenceHandler extends Handler<SearchRequest, SearchReference> +{ + + + @Override + HandlerResult<SearchReference> handle(Connection conn, SearchRequest request, SearchReference reference) + throws LdapException; + + + /** + * Initialize the search request for use with this reference handler. + * + * @param request to initialize for this reference handler + */ + void initializeRequest(SearchRequest request); +}
diff --git a/core/src/main/java/org/ldaptive/intermediate/AbstractIntermediateResponse.java b/core/src/main/java/org/ldaptive/intermediate/AbstractIntermediateResponse.java new file mode 100644 index 0000000..72d35b9 --- /dev/null +++ b/core/src/main/java/org/ldaptive/intermediate/AbstractIntermediateResponse.java
@@ -0,0 +1,72 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.intermediate; + +import org.ldaptive.control.ResponseControl; + +/** + * Base class for ldap intermediate response messages. + * + * @author Middleware Services + */ +public abstract class AbstractIntermediateResponse implements IntermediateResponse +{ + + /** response oid. */ + private final String responseOid; + + /** response controls. */ + private final ResponseControl[] responseControls; + + /** message ID. */ + private final int messageId; + + + /** + * Creates a new abstract intermediate response. + * + * @param oid OID of this message + * @param c response controls + * @param i message id + */ + public AbstractIntermediateResponse(final String oid, final ResponseControl[] c, final int i) + { + responseOid = oid; + responseControls = c; + messageId = i; + } + + + @Override + public String getOID() + { + return responseOid; + } + + + @Override + public ResponseControl[] getControls() + { + return responseControls; + } + + + @Override + public ResponseControl getControl(final String oid) + { + if (getControls() != null) { + for (ResponseControl c : getControls()) { + if (c.getOID().equals(oid)) { + return c; + } + } + } + return null; + } + + + @Override + public int getMessageId() + { + return messageId; + } +}
diff --git a/core/src/main/java/org/ldaptive/intermediate/IntermediateResponse.java b/core/src/main/java/org/ldaptive/intermediate/IntermediateResponse.java new file mode 100644 index 0000000..160043f --- /dev/null +++ b/core/src/main/java/org/ldaptive/intermediate/IntermediateResponse.java
@@ -0,0 +1,29 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.intermediate; + +import org.ldaptive.ResponseMessage; + +/** + * Interface for ldap intermediate responses. + * + * @author Middleware Services + */ +public interface IntermediateResponse extends ResponseMessage +{ + + + /** + * Returns the OID for this response. + * + * @return oid + */ + String getOID(); + + + /** + * Initializes this response with the supplied BER encoded data. + * + * @param encoded BER encoded response value + */ + void decode(byte[] encoded); +}
diff --git a/core/src/main/java/org/ldaptive/intermediate/IntermediateResponseFactory.java b/core/src/main/java/org/ldaptive/intermediate/IntermediateResponseFactory.java new file mode 100644 index 0000000..e3b5d70 --- /dev/null +++ b/core/src/main/java/org/ldaptive/intermediate/IntermediateResponseFactory.java
@@ -0,0 +1,44 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.intermediate; + +import org.ldaptive.control.ResponseControl; + +/** + * Utility class for creating intermediate responses. + * + * @author Middleware Services + */ +public final class IntermediateResponseFactory +{ + + + /** Default constructor. */ + private IntermediateResponseFactory() {} + + + /** + * Creates an intermediate response from the supplied response data. + * + * @param oid of the response + * @param encoded BER encoding of the response + * @param responseControls associated with this response + * @param msgId message id associated with this response + * + * @return intermediate response + */ + public static IntermediateResponse createIntermediateResponse( + final String oid, + final byte[] encoded, + final ResponseControl[] responseControls, + final int msgId) + { + IntermediateResponse res; + if (SyncInfoMessage.OID.equals(oid)) { + res = new SyncInfoMessage(responseControls, msgId); + res.decode(encoded); + } else { + throw new IllegalArgumentException("Unknown OID: " + oid); + } + return res; + } +}
diff --git a/core/src/main/java/org/ldaptive/intermediate/SyncInfoMessage.java b/core/src/main/java/org/ldaptive/intermediate/SyncInfoMessage.java new file mode 100644 index 0000000..f2f84b0 --- /dev/null +++ b/core/src/main/java/org/ldaptive/intermediate/SyncInfoMessage.java
@@ -0,0 +1,598 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.intermediate; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.AbstractParseHandler; +import org.ldaptive.asn1.BooleanType; +import org.ldaptive.asn1.DERParser; +import org.ldaptive.asn1.DERPath; +import org.ldaptive.asn1.OctetStringType; +import org.ldaptive.asn1.UuidType; +import org.ldaptive.control.ResponseControl; + +/** + * Intermediate response message for ldap content synchronization. See RFC 4533. Message is defined as: + * + * <pre> + syncInfoValue ::= CHOICE { + newcookie [0] syncCookie, + refreshDelete [1] SEQUENCE { + cookie syncCookie OPTIONAL, + refreshDone BOOLEAN DEFAULT TRUE + }, + refreshPresent [2] SEQUENCE { + cookie syncCookie OPTIONAL, + refreshDone BOOLEAN DEFAULT TRUE + }, + syncIdSet [3] SEQUENCE { + cookie syncCookie OPTIONAL, + refreshDeletes BOOLEAN DEFAULT FALSE, + syncUUIDs SET OF syncUUID + } + } + * </pre> + * + * @author Middleware Services + */ +public class SyncInfoMessage extends AbstractIntermediateResponse +{ + + + /** OID of this response. */ + public static final String OID = "1.3.6.1.4.1.4203.1.9.1.4"; + + /** hash value seed. */ + private static final int HASH_CODE_SEED = 761; + + /** Types of request modes. */ + public enum Type { + + /** new cookie. */ + NEW_COOKIE, + + /** refresh delete. */ + REFRESH_DELETE, + + /** refresh present. */ + REFRESH_PRESENT, + + /** sync id set. */ + SYNC_ID_SET + } + + /** message type. */ + private Type messageType; + + /** server generated cookie. */ + private byte[] cookie; + + /** refresh done. */ + private boolean refreshDone = true; + + /** refresh deletes. */ + private boolean refreshDeletes; + + /** entry uuids. */ + private Set<UUID> entryUuids = new HashSet<>(); + + + /** Default constructor. */ + public SyncInfoMessage() + { + super(OID, null, -1); + } + + + /** + * Creates a new sync info message. + * + * @param responseControls for this message + * @param id message id + */ + public SyncInfoMessage(final ResponseControl[] responseControls, final int id) + { + super(OID, responseControls, id); + } + + + /** + * Returns the message type. + * + * @return message type + */ + public Type getMessageType() + { + return messageType; + } + + + /** + * Sets the message type. + * + * @param type message type + */ + public void setMessageType(final Type type) + { + messageType = type; + } + + + /** + * Returns the sync request cookie. + * + * @return sync request cookie + */ + public byte[] getCookie() + { + return cookie; + } + + + /** + * Sets the sync request cookie. + * + * @param value sync request cookie + */ + public void setCookie(final byte[] value) + { + cookie = value; + } + + + /** + * Returns whether refreshes are done. + * + * @return refresh done + */ + public boolean getRefreshDone() + { + return refreshDone; + } + + + /** + * Sets whether refreshes are done. + * + * @param b refresh done + */ + public void setRefreshDone(final boolean b) + { + refreshDone = b; + } + + + /** + * Returns whether to refresh deletes. + * + * @return whether to refresh deletes + */ + public boolean getRefreshDeletes() + { + return refreshDeletes; + } + + + /** + * Sets whether to refresh deletes. + * + * @param b whether to refresh deletes + */ + public void setRefreshDeletes(final boolean b) + { + refreshDeletes = b; + } + + + /** + * Returns the entry uuids. + * + * @return entry uuids + */ + public Set<UUID> getEntryUuids() + { + return entryUuids; + } + + + /** + * Sets the entry uuids. + * + * @param uuids entry uuids + */ + public void setEntryUuids(final Set<UUID> uuids) + { + entryUuids = uuids; + } + + + @Override + public void decode(final byte[] berValue) + { + final DERParser parser = new DERParser(); + parser.registerHandler(NewCookieHandler.PATH, new NewCookieHandler(this)); + parser.registerHandler(RefreshDeleteHandler.PATH, new RefreshDeleteHandler(this)); + parser.registerHandler(RefreshDeleteCookieHandler.PATH, new RefreshDeleteCookieHandler(this)); + parser.registerHandler(RefreshDeleteDoneHandler.PATH, new RefreshDeleteDoneHandler(this)); + parser.registerHandler(RefreshPresentHandler.PATH, new RefreshPresentHandler(this)); + parser.registerHandler(RefreshPresentCookieHandler.PATH, new RefreshPresentCookieHandler(this)); + parser.registerHandler(RefreshPresentDoneHandler.PATH, new RefreshPresentDoneHandler(this)); + parser.registerHandler(SyncIdSetHandler.PATH, new SyncIdSetHandler(this)); + parser.registerHandler(SyncIdSetCookieHandler.PATH, new SyncIdSetCookieHandler(this)); + parser.registerHandler(SyncIdSetDeletesHandler.PATH, new SyncIdSetDeletesHandler(this)); + parser.registerHandler(SyncIdSetUuidsHandler.PATH, new SyncIdSetUuidsHandler(this)); + parser.parse(ByteBuffer.wrap(berValue)); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof SyncInfoMessage) { + final SyncInfoMessage v = (SyncInfoMessage) o; + return LdapUtils.areEqual(getOID(), v.getOID()) && + LdapUtils.areEqual(messageType, v.messageType) && + LdapUtils.areEqual(cookie, v.cookie) && + LdapUtils.areEqual(refreshDone, v.refreshDone) && + LdapUtils.areEqual(refreshDeletes, v.refreshDeletes) && + LdapUtils.areEqual(entryUuids, v.entryUuids) && + LdapUtils.areEqual(getControls(), v.getControls()) && + LdapUtils.areEqual(getMessageId(), v.getMessageId()); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + getOID(), + messageType, + cookie, + refreshDone, + refreshDeletes, + entryUuids, + getControls(), + getMessageId()); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::messageType=%s, cookie=%s, refreshDone=%s, " + + "refreshDeletes=%s, entryUuids=%s, responseControls=%s, messageId=%s]", + getClass().getName(), + hashCode(), + messageType, + LdapUtils.base64Encode(cookie), + refreshDone, + refreshDeletes, + entryUuids, + Arrays.toString(getControls()), + getMessageId()); + } + + + /** Parse handler implementation for new cookie. */ + private static class NewCookieHandler extends AbstractParseHandler<SyncInfoMessage> + { + + /** DER path to value. */ + public static final DERPath PATH = new DERPath("/CTX(0)"); + + + /** + * Creates a new cookie handler. + * + * @param message to configure + */ + NewCookieHandler(final SyncInfoMessage message) + { + super(message); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setMessageType(Type.NEW_COOKIE); + + final byte[] cookie = OctetStringType.readBuffer(encoded); + if (cookie != null && cookie.length > 0) { + getObject().setCookie(cookie); + } + } + } + + + /** Parse handler implementation for refresh delete. */ + private static class RefreshDeleteHandler extends AbstractParseHandler<SyncInfoMessage> + { + + /** DER path to value. */ + public static final DERPath PATH = new DERPath("/CTX(1)"); + + + /** + * Creates a refresh delete handler. + * + * @param message to configure + */ + RefreshDeleteHandler(final SyncInfoMessage message) + { + super(message); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setMessageType(Type.REFRESH_DELETE); + } + } + + + /** Parse handler implementation for refresh delete cookie. */ + private static class RefreshDeleteCookieHandler extends AbstractParseHandler<SyncInfoMessage> + { + + /** DER path to value. */ + public static final DERPath PATH = new DERPath("/CTX(1)/OCTSTR"); + + + /** + * Creates a refresh delete cookie handler. + * + * @param message to configure + */ + RefreshDeleteCookieHandler(final SyncInfoMessage message) + { + super(message); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + final byte[] cookie = OctetStringType.readBuffer(encoded); + if (cookie != null && cookie.length > 0) { + getObject().setCookie(cookie); + } + } + } + + + /** Parse handler implementation for refresh delete done. */ + private static class RefreshDeleteDoneHandler extends AbstractParseHandler<SyncInfoMessage> + { + + /** DER path to value. */ + public static final DERPath PATH = new DERPath("/CTX(1)/BOOL"); + + + /** + * Creates a refresh delete done handler. + * + * @param message to configure + */ + RefreshDeleteDoneHandler(final SyncInfoMessage message) + { + super(message); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setRefreshDone(BooleanType.decode(encoded)); + } + } + + + /** Parse handler implementation for refresh present. */ + private static class RefreshPresentHandler extends AbstractParseHandler<SyncInfoMessage> + { + + /** DER path to value. */ + public static final DERPath PATH = new DERPath("/CTX(2)"); + + + /** + * Creates a refresh present handler. + * + * @param message to configure + */ + RefreshPresentHandler(final SyncInfoMessage message) + { + super(message); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setMessageType(Type.REFRESH_PRESENT); + } + } + + + /** Parse handler implementation for refresh present cookie. */ + private static class RefreshPresentCookieHandler extends AbstractParseHandler<SyncInfoMessage> + { + + /** DER path to value. */ + public static final DERPath PATH = new DERPath("/CTX(2)/OCTSTR"); + + + /** + * Creates a refresh present cookie handler. + * + * @param message to configure + */ + RefreshPresentCookieHandler(final SyncInfoMessage message) + { + super(message); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + final byte[] cookie = OctetStringType.readBuffer(encoded); + if (cookie != null && cookie.length > 0) { + getObject().setCookie(cookie); + } + } + } + + + /** Parse handler implementation for refresh present done. */ + private static class RefreshPresentDoneHandler extends AbstractParseHandler<SyncInfoMessage> + { + + /** DER path to value. */ + public static final DERPath PATH = new DERPath("/CTX(2)/BOOL"); + + + /** + * Creates a refresh present done handler. + * + * @param message to configure + */ + RefreshPresentDoneHandler(final SyncInfoMessage message) + { + super(message); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setRefreshDone(BooleanType.decode(encoded)); + } + } + + + /** Parse handler implementation for sync id set. */ + private static class SyncIdSetHandler extends AbstractParseHandler<SyncInfoMessage> + { + + /** DER path to value. */ + public static final DERPath PATH = new DERPath("/CTX(3)"); + + + /** + * Creates a sync id set handler. + * + * @param message to configure + */ + SyncIdSetHandler(final SyncInfoMessage message) + { + super(message); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setMessageType(Type.SYNC_ID_SET); + } + } + + + /** Parse handler implementation for sync id set cookie. */ + private static class SyncIdSetCookieHandler extends AbstractParseHandler<SyncInfoMessage> + { + + /** DER path to value. */ + public static final DERPath PATH = new DERPath("/CTX(3)/OCTSTR"); + + + /** + * Creates a sync id set cookie handler. + * + * @param message to configure + */ + SyncIdSetCookieHandler(final SyncInfoMessage message) + { + super(message); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + final byte[] cookie = OctetStringType.readBuffer(encoded); + if (cookie != null && cookie.length > 0) { + getObject().setCookie(cookie); + } + } + } + + + /** Parse handler implementation for sync id set deletes. */ + private static class SyncIdSetDeletesHandler extends AbstractParseHandler<SyncInfoMessage> + { + + /** DER path to value. */ + public static final DERPath PATH = new DERPath("/CTX(3)/BOOL"); + + + /** + * Creates a sync id set deletes handler. + * + * @param message to configure + */ + SyncIdSetDeletesHandler(final SyncInfoMessage message) + { + super(message); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().setRefreshDeletes(BooleanType.decode(encoded)); + } + } + + + /** Parse handler implementation for sync id set uuids. */ + private static class SyncIdSetUuidsHandler extends AbstractParseHandler<SyncInfoMessage> + { + + /** DER path to value. */ + public static final DERPath PATH = new DERPath("/CTX(3)/SET/OCTSTR"); + + + /** + * Creates a sync id set uuids handler. + * + * @param message to configure + */ + SyncIdSetUuidsHandler(final SyncInfoMessage message) + { + super(message); + } + + + @Override + public void handle(final DERParser parser, final ByteBuffer encoded) + { + getObject().getEntryUuids().add(UuidType.decode(encoded)); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/io/AbstractBinaryValueTranscoder.java b/core/src/main/java/org/ldaptive/io/AbstractBinaryValueTranscoder.java new file mode 100644 index 0000000..a06bdde --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/AbstractBinaryValueTranscoder.java
@@ -0,0 +1,30 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import org.ldaptive.LdapUtils; + +/** + * Value transcoder which decodes and encodes to a byte array and therefore the string methods simply delegate to the + * binary methods. + * + * @param <T> type of object to transcode + * + * @author Middleware Services + */ +public abstract class AbstractBinaryValueTranscoder<T> implements ValueTranscoder<T> +{ + + + @Override + public T decodeStringValue(final String value) + { + return decodeBinaryValue(LdapUtils.utf8Encode(value)); + } + + + @Override + public String encodeStringValue(final T value) + { + return LdapUtils.utf8Encode(encodeBinaryValue(value)); + } +}
diff --git a/core/src/main/java/org/ldaptive/io/AbstractPrimitiveValueTranscoder.java b/core/src/main/java/org/ldaptive/io/AbstractPrimitiveValueTranscoder.java new file mode 100644 index 0000000..29c16b0 --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/AbstractPrimitiveValueTranscoder.java
@@ -0,0 +1,45 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +/** + * Base class for primitive value transcoders. + * + * @param <T> type of object to transcode + * + * @author Middleware Services + */ +public abstract class AbstractPrimitiveValueTranscoder<T> extends AbstractStringValueTranscoder<T> +{ + + /** Whether this transcoder operates on a primitive or an object. */ + private boolean primitive; + + + /** + * Returns whether this transcoder operates on a primitive value. + * + * @return whether this transcoder operates on a primitive value + */ + public boolean isPrimitive() + { + return primitive; + } + + + /** + * Sets whether this transcoder operates on a primitive value. + * + * @param b whether this transcoder operates on a primitive value + */ + public void setPrimitive(final boolean b) + { + primitive = b; + } + + + @Override + public String encodeStringValue(final T value) + { + return value.toString(); + } +}
diff --git a/core/src/main/java/org/ldaptive/io/AbstractStringValueTranscoder.java b/core/src/main/java/org/ldaptive/io/AbstractStringValueTranscoder.java new file mode 100644 index 0000000..361223a --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/AbstractStringValueTranscoder.java
@@ -0,0 +1,30 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import org.ldaptive.LdapUtils; + +/** + * Value transcoder which decodes and encodes to a String and therefore the binary methods simply delegate to the string + * methods. + * + * @param <T> type of object to transcode + * + * @author Middleware Services + */ +public abstract class AbstractStringValueTranscoder<T> implements ValueTranscoder<T> +{ + + + @Override + public T decodeBinaryValue(final byte[] value) + { + return decodeStringValue(LdapUtils.utf8Encode(value)); + } + + + @Override + public byte[] encodeBinaryValue(final T value) + { + return LdapUtils.utf8Encode(encodeStringValue(value)); + } +}
diff --git a/core/src/main/java/org/ldaptive/io/BooleanValueTranscoder.java b/core/src/main/java/org/ldaptive/io/BooleanValueTranscoder.java new file mode 100644 index 0000000..f4a6f1d --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/BooleanValueTranscoder.java
@@ -0,0 +1,40 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +/** + * Decodes and encodes a boolean for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class BooleanValueTranscoder extends AbstractPrimitiveValueTranscoder<Boolean> +{ + + + /** Default constructor. */ + public BooleanValueTranscoder() {} + + + /** + * Creates a new boolean value transcoder. + * + * @param b whether this transcoder is operating on a primitive + */ + public BooleanValueTranscoder(final boolean b) + { + setPrimitive(b); + } + + + @Override + public Boolean decodeStringValue(final String value) + { + return Boolean.valueOf(value); + } + + + @Override + public Class<Boolean> getType() + { + return isPrimitive() ? boolean.class : Boolean.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/ByteArrayValueTranscoder.java b/core/src/main/java/org/ldaptive/io/ByteArrayValueTranscoder.java new file mode 100644 index 0000000..ef7443a --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/ByteArrayValueTranscoder.java
@@ -0,0 +1,32 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +/** + * Decodes and encodes a byte array for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class ByteArrayValueTranscoder extends AbstractBinaryValueTranscoder<byte[]> +{ + + + @Override + public byte[] decodeBinaryValue(final byte[] value) + { + return value; + } + + + @Override + public byte[] encodeBinaryValue(final byte[] value) + { + return value; + } + + + @Override + public Class<byte[]> getType() + { + return byte[].class; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/CertificateValueTranscoder.java b/core/src/main/java/org/ldaptive/io/CertificateValueTranscoder.java new file mode 100644 index 0000000..126738c --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/CertificateValueTranscoder.java
@@ -0,0 +1,72 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.io.ByteArrayInputStream; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import org.ldaptive.LdapUtils; + +/** + * Decodes and encodes a certificate for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class CertificateValueTranscoder implements ValueTranscoder<Certificate> +{ + + /** PEM cert header. */ + private static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----" + System.getProperty("line.separator"); + + /** PEM cert footer. */ + private static final String END_CERT = System.getProperty("line.separator") + "-----END CERTIFICATE-----"; + + + @Override + public Certificate decodeStringValue(final String value) + { + return decodeBinaryValue(LdapUtils.utf8Encode(value)); + } + + + @Override + public Certificate decodeBinaryValue(final byte[] value) + { + try { + final CertificateFactory cf = CertificateFactory.getInstance("X.509"); + return cf.generateCertificate(new ByteArrayInputStream(value)); + } catch (CertificateException e) { + throw new IllegalArgumentException("Attribute value could not be decoded as a certificate", e); + } + } + + + @Override + public String encodeStringValue(final Certificate value) + { + final StringBuilder sb = new StringBuilder(); + sb.append(BEGIN_CERT); + sb.append(LdapUtils.base64Encode(encodeBinaryValue(value))); + sb.append(END_CERT); + return sb.toString(); + } + + + @Override + public byte[] encodeBinaryValue(final Certificate value) + { + try { + return value.getEncoded(); + } catch (CertificateEncodingException e) { + throw new IllegalArgumentException("Certificate could not be encoded", e); + } + } + + + @Override + public Class<Certificate> getType() + { + return Certificate.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/CharArrayValueTranscoder.java b/core/src/main/java/org/ldaptive/io/CharArrayValueTranscoder.java new file mode 100644 index 0000000..ba21b2a --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/CharArrayValueTranscoder.java
@@ -0,0 +1,32 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +/** + * Decodes and encodes a character array for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class CharArrayValueTranscoder extends AbstractStringValueTranscoder<char[]> +{ + + + @Override + public char[] decodeStringValue(final String value) + { + return value.toCharArray(); + } + + + @Override + public String encodeStringValue(final char[] value) + { + return String.valueOf(value); + } + + + @Override + public Class<char[]> getType() + { + return char[].class; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/DoubleValueTranscoder.java b/core/src/main/java/org/ldaptive/io/DoubleValueTranscoder.java new file mode 100644 index 0000000..758d575 --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/DoubleValueTranscoder.java
@@ -0,0 +1,40 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +/** + * Decodes and encodes a double for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class DoubleValueTranscoder extends AbstractPrimitiveValueTranscoder<Double> +{ + + + /** Default constructor. */ + public DoubleValueTranscoder() {} + + + /** + * Creates a new double value transcoder. + * + * @param b whether this transcoder is operating on a primitive + */ + public DoubleValueTranscoder(final boolean b) + { + setPrimitive(b); + } + + + @Override + public Double decodeStringValue(final String value) + { + return Double.valueOf(value); + } + + + @Override + public Class<Double> getType() + { + return isPrimitive() ? double.class : Double.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/Dsmlv1Reader.java b/core/src/main/java/org/ldaptive/io/Dsmlv1Reader.java new file mode 100644 index 0000000..4169cb2 --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/Dsmlv1Reader.java
@@ -0,0 +1,210 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.io.IOException; +import java.io.Reader; +import java.util.HashSet; +import java.util.Set; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapUtils; +import org.ldaptive.SearchResult; +import org.ldaptive.SortBehavior; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Reads DSML version 1 from a {@link Reader} and returns a {@link SearchResult}. + * + * @author Middleware Services + */ +public class Dsmlv1Reader implements SearchResultReader +{ + + /** Document builder factory. */ + private static final DocumentBuilderFactory DOC_BUILDER_FACTORY = DocumentBuilderFactory.newInstance(); + + + /** + * Initialize the document builder factory. + */ + static { + DOC_BUILDER_FACTORY.setNamespaceAware(true); + } + + /** Reader to read from. */ + private final Reader dsmlReader; + + /** Sort behavior. */ + private final SortBehavior sortBehavior; + + + /** + * Creates a new dsml reader. + * + * @param reader to read DSML from + */ + public Dsmlv1Reader(final Reader reader) + { + this(reader, SortBehavior.getDefaultSortBehavior()); + } + + + /** + * Creates a new dsml reader. + * + * @param reader to read DSML from + * @param sb sort behavior of the ldap result + */ + public Dsmlv1Reader(final Reader reader, final SortBehavior sb) + { + dsmlReader = reader; + if (sb == null) { + throw new IllegalArgumentException("Sort behavior cannot be null"); + } + sortBehavior = sb; + } + + + /** + * Reads DSML data from the reader and returns a search result. + * + * @return search result derived from the DSML + * + * @throws IOException if an error occurs using the reader + */ + @Override + public SearchResult read() + throws IOException + { + try { + final DocumentBuilder db = DOC_BUILDER_FACTORY.newDocumentBuilder(); + final Document dsml = db.parse(new InputSource(dsmlReader)); + return createSearchResult(dsml); + } catch (ParserConfigurationException | SAXException e) { + throw new IOException(e); + } + } + + + /** + * Creates a search result that corresponds to the supplied DSML document. + * + * @param doc DSML to parse + * + * @return search result + */ + protected SearchResult createSearchResult(final Document doc) + { + final SearchResult result = new SearchResult(sortBehavior); + + if (doc != null && doc.hasChildNodes()) { + final NodeList nodes = doc.getElementsByTagName("dsml:entry"); + for (int i = 0; i < nodes.getLength(); i++) { + final LdapEntry le = createLdapEntry((Element) nodes.item(i)); + result.addEntry(le); + } + } + + return result; + } + + + /** + * Converts the supplied DSML entry element into an ldap entry object. + * + * @param entryElement to parse + * + * @return ldap entry + */ + protected LdapEntry createLdapEntry(final Element entryElement) + { + final LdapEntry ldapEntry = new LdapEntry(sortBehavior); + ldapEntry.setDn(""); + + if (entryElement != null) { + + final String name = entryElement.getAttribute("dn"); + if (name != null) { + ldapEntry.setDn(name); + } + + if (entryElement.hasChildNodes()) { + + final NodeList ocNodes = entryElement.getElementsByTagName("dsml:objectclass"); + if (ocNodes.getLength() > 0) { + final Element ocElement = (Element) ocNodes.item(0); + if (ocElement != null && ocElement.hasChildNodes()) { + final LdapAttribute ldapAttribute = createLdapAttribute( + "objectClass", + ocElement.getElementsByTagName("dsml:oc-value")); + ldapEntry.addAttribute(ldapAttribute); + } + } + + final NodeList attrNodes = entryElement.getElementsByTagName("dsml:attr"); + for (int i = 0; i < attrNodes.getLength(); i++) { + final Element attrElement = (Element) attrNodes.item(i); + final String attrName = attrElement.hasAttribute("name") ? attrElement.getAttribute("name") : null; + if (attrName != null && attrElement.hasChildNodes()) { + final LdapAttribute ldapAttribute = createLdapAttribute( + attrName, + attrElement.getElementsByTagName("dsml:value")); + ldapEntry.addAttribute(ldapAttribute); + } + } + } + } + + return ldapEntry; + } + + + /** + * Returns an ldap attribute derived from the supplied node list. + * + * @param name of the ldap attribute + * @param nodes to parse + * + * @return ldap attribute + */ + protected LdapAttribute createLdapAttribute(final String name, final NodeList nodes) + { + boolean isBase64 = false; + final Set<Object> values = new HashSet<>(); + for (int i = 0; i < nodes.getLength(); i++) { + final Element valueElement = (Element) nodes.item(i); + if (valueElement != null) { + if (valueElement.hasAttribute("encoding") && "base64".equals(valueElement.getAttribute("encoding"))) { + isBase64 = true; + } + values.add(getAttrValue(valueElement, isBase64)); + } + } + return LdapAttribute.createLdapAttribute(sortBehavior, name, values); + } + + + /** + * Returns the value of the supplied element taking into account whether the value needs to be base64 decoded. + * + * @param valueElement to read value from + * @param base64 whether to base64 decode the value + * + * @return String or byte[] depending on the base64 flag + */ + protected Object getAttrValue(final Element valueElement, final boolean base64) + { + final String value = valueElement.getChildNodes().item(0).getNodeValue(); + if (base64) { + return LdapUtils.base64Decode(value); + } + return value; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/Dsmlv1Writer.java b/core/src/main/java/org/ldaptive/io/Dsmlv1Writer.java new file mode 100644 index 0000000..cc18db3 --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/Dsmlv1Writer.java
@@ -0,0 +1,253 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.SearchResult; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * Writes a {@link SearchResult} as DSML version 1 to a {@link Writer}. + * + * @author Middleware Services + */ +public class Dsmlv1Writer implements SearchResultWriter +{ + + /** Document builder factory. */ + private static final DocumentBuilderFactory DOC_BUILDER_FACTORY = DocumentBuilderFactory.newInstance(); + + /** Transformer factory. */ + private static final TransformerFactory TRANSFORMER_FACTORY = TransformerFactory.newInstance(); + + + /** + * Initialize the document builder factory. + */ + static { + DOC_BUILDER_FACTORY.setNamespaceAware(true); + } + + /** Writer to write to. */ + private final Writer dsmlWriter; + + /** Transformer output properties. See {@link Transformer#setOutputProperty(String, String)}. */ + private Map<String, String> outputProperties = new HashMap<>(); + + + /** + * Creates a new dsml writer. The following transformer output properties are set by default: + * + * <ul> + * <li>"doctype-public", "yes"</li> + * <li>"indent", "yes"</li> + * <li>"{http://xml.apache.org/xslt}indent-amount", "2"</li> + * </ul> + * + * @param writer to write DSML to + */ + public Dsmlv1Writer(final Writer writer) + { + dsmlWriter = writer; + outputProperties.put(OutputKeys.DOCTYPE_PUBLIC, "yes"); + outputProperties.put(OutputKeys.INDENT, "yes"); + outputProperties.put("{http://xml.apache.org/xslt}indent-amount", "2"); + } + + + /** + * Returns the transformer output properties used by this writer. + * + * @return transformer output properties + */ + public Map<String, String> getOutputProperties() + { + return outputProperties; + } + + + /** + * Sets the transformer output properties used by this writer. + * + * @param properties transformer output properties + */ + public void setOutputProperties(final Map<String, String> properties) + { + outputProperties = properties; + } + + + /** + * Writes the supplied search result to the writer. + * + * @param result search result to write + * + * @throws IOException if an error occurs using the writer + */ + @Override + public void write(final SearchResult result) + throws IOException + { + try { + final Transformer transformer = TRANSFORMER_FACTORY.newTransformer(); + for (Map.Entry<String, String> prop : outputProperties.entrySet()) { + transformer.setOutputProperty(prop.getKey(), prop.getValue()); + } + + final StreamResult sr = new StreamResult(dsmlWriter); + final DOMSource source = new DOMSource(createDsml(result)); + transformer.transform(source, sr); + dsmlWriter.flush(); + } catch (ParserConfigurationException | TransformerException e) { + throw new IOException(e); + } + } + + + /** + * Creates DSML that corresponds to the supplied search result. + * + * @param result search result to parse + * + * @return DSML + * + * @throws ParserConfigurationException if a document builder cannot be created + */ + protected Document createDsml(final SearchResult result) + throws ParserConfigurationException + { + final DocumentBuilder db = DOC_BUILDER_FACTORY.newDocumentBuilder(); + final DOMImplementation domImpl = db.getDOMImplementation(); + final Document doc = domImpl.createDocument("http://www.dsml.org/DSML", "dsml:dsml", null); + doc.setXmlStandalone(true); + + final Element entriesElement = doc.createElement("dsml:directory-entries"); + doc.getDocumentElement().appendChild(entriesElement); + + // build document object from result + if (result != null) { + for (LdapEntry le : result.getEntries()) { + final Element entryElement = doc.createElement("dsml:entry"); + if (le.getDn() != null) { + entryElement.setAttribute("dn", le.getDn()); + } + createDsmlAttributes(doc, le.getAttributes()).forEach(entryElement::appendChild); + entriesElement.appendChild(entryElement); + } + } + + return doc; + } + + + /** + * Returns a list of <dsml:attr/> elements for the supplied attributes. + * + * @param doc to source elements from + * @param attrs to iterate over + * + * @return list of elements contains attributes + */ + protected List<Element> createDsmlAttributes(final Document doc, final Collection<LdapAttribute> attrs) + { + final List<Element> attrElements = new ArrayList<>(); + for (LdapAttribute attr : attrs) { + final String attrName = attr.getName(); + Element attrElement; + if ("objectclass".equalsIgnoreCase(attrName)) { + attrElement = createObjectclassElement(doc, attr); + if (attrElement.hasChildNodes()) { + attrElements.add(0, attrElement); + } + } else { + attrElement = createAttrElement(doc, attr); + if (attrElement.hasChildNodes()) { + attrElements.add(attrElement); + } + } + } + return attrElements; + } + + + /** + * Returns a <dsml:attr/> element for the supplied ldap attribute. + * + * @param doc to source elements from + * @param attr ldap attribute to add + * + * @return element containing the attribute + */ + protected Element createAttrElement(final Document doc, final LdapAttribute attr) + { + final Element attrElement = doc.createElement("dsml:attr"); + attrElement.setAttribute("name", attr.getName()); + for (String s : attr.getStringValues()) { + final Element valueElement = doc.createElement("dsml:value"); + attrElement.appendChild(valueElement); + setAttrValue(doc, valueElement, s, attr.isBinary()); + } + return attrElement; + } + + + /** + * Returns a <dsml:objectclass/> element for the supplied ldap attribute. + * + * @param doc to source elements from + * @param attr ldap attribute to add + * + * @return element containing the attribute values + */ + protected Element createObjectclassElement(final Document doc, final LdapAttribute attr) + { + final Element ocElement = doc.createElement("dsml:objectclass"); + for (String s : attr.getStringValues()) { + final Element ocValueElement = doc.createElement("dsml:oc-value"); + ocElement.appendChild(ocValueElement); + setAttrValue(doc, ocValueElement, s, attr.isBinary()); + } + return ocElement; + } + + + /** + * Adds the supplied string to the value element. + * + * @param doc to create nodes with + * @param valueElement to append value to + * @param value to create node for + * @param isBase64 whether the value is base64 encoded + */ + protected void setAttrValue( + final Document doc, + final Element valueElement, + final String value, + final boolean isBase64) + { + if (value != null) { + valueElement.appendChild(doc.createTextNode(value)); + if (isBase64) { + valueElement.setAttribute("encoding", "base64"); + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/io/FloatValueTranscoder.java b/core/src/main/java/org/ldaptive/io/FloatValueTranscoder.java new file mode 100644 index 0000000..2c434ea --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/FloatValueTranscoder.java
@@ -0,0 +1,40 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +/** + * Decodes and encodes a float for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class FloatValueTranscoder extends AbstractPrimitiveValueTranscoder<Float> +{ + + + /** Default constructor. */ + public FloatValueTranscoder() {} + + + /** + * Creates a new float value transcoder. + * + * @param b whether this transcoder is operating on a primitive + */ + public FloatValueTranscoder(final boolean b) + { + setPrimitive(b); + } + + + @Override + public Float decodeStringValue(final String value) + { + return Float.valueOf(value); + } + + + @Override + public Class<Float> getType() + { + return isPrimitive() ? float.class : Float.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/GeneralizedTimeValueTranscoder.java b/core/src/main/java/org/ldaptive/io/GeneralizedTimeValueTranscoder.java new file mode 100644 index 0000000..d9b4add --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/GeneralizedTimeValueTranscoder.java
@@ -0,0 +1,190 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.text.ParseException; +import java.time.DateTimeException; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Decodes and encodes a generalized time for use in an ldap attribute value. See + * http://tools.ietf.org/html/rfc4517#section-3.3.13 + * + * @author Middleware Services + */ +public class GeneralizedTimeValueTranscoder extends AbstractStringValueTranscoder<ZonedDateTime> +{ + + /** Pattern for capturing the year in generalized time. */ + private static final String YEAR_PATTERN = "(\\d{4})"; + + /** Pattern for capturing the month in generalized time. */ + private static final String MONTH_PATTERN = "((?:\\x30[\\x31-\\x39])|(?:\\x31[\\x30-\\x32]))"; + + /** Pattern for capturing the day in generalized time. */ + private static final String DAY_PATTERN = "((?:\\x30[\\x31-\\x39])" + + "|(?:[\\x31-\\x32][\\x30-\\x39])" + + "|(?:\\x33[\\x30-\\x31]))"; + + /** Pattern for capturing hours in generalized time. */ + private static final String HOUR_PATTERN = "((?:[\\x30-\\x31][\\x30-\\x39])|(?:\\x32[\\x30-\\x33]))"; + + /** Pattern for capturing optional minutes in generalized time. */ + private static final String MIN_PATTERN = "([\\x30-\\x35][\\x30-\\x39])?"; + + /** Pattern for capturing optional seconds in generalized time. */ + private static final String SECOND_PATTERN = "([\\x30-\\x35][\\x30-\\x39])?"; + + /** Pattern for capturing optional fraction in generalized time. */ + private static final String FRACTION_PATTERN = "([,.](\\d+))?"; + + /** Pattern for capturing timezone in generalized time. */ + private static final String TIMEZONE_PATTERN = "(Z|(?:[+-]" + HOUR_PATTERN + MIN_PATTERN + "))"; + + /** Generalized time format regular expression. */ + private static final Pattern TIME_REGEX = Pattern.compile( + YEAR_PATTERN + MONTH_PATTERN + DAY_PATTERN + HOUR_PATTERN + MIN_PATTERN + SECOND_PATTERN + FRACTION_PATTERN + + TIMEZONE_PATTERN); + + /** Date format. */ + private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHHmmss.SSS'Z'"); + + /** Describes the fractional part of a generalized time string. */ + private enum FractionalPart { + + /** Fractional hours. */ + Hours(3600000), + + /** Fractional minutes. */ + Minutes(60000), + + /** Fractional seconds. */ + Seconds(1000); + + /** Scale factor to convert units to millis. */ + private final int scaleFactor; + + + /** + * Creates a new fractional part. + * + * @param scale scale factor. + */ + FractionalPart(final int scale) + { + scaleFactor = scale; + } + + + /** + * Converts the given fractional date part to milliseconds. + * + * @param fraction digits of fractional date part + * + * @return fraction converted to milliseconds. + */ + int toMillis(final String fraction) + { + return (int) (Double.parseDouble('.' + fraction) * scaleFactor); + } + } + + + @Override + public ZonedDateTime decodeStringValue(final String value) + { + try { + return parseGeneralizedTime(value); + } catch (ParseException | DateTimeException e) { + throw new IllegalArgumentException(e); + } + } + + + @Override + public String encodeStringValue(final ZonedDateTime value) + { + if (value.getZone().normalized().equals(ZoneOffset.UTC)) { + return value.format(DATE_FORMAT); + } else { + return value.withZoneSameInstant(ZoneOffset.UTC).format(DATE_FORMAT); + } + } + + + @Override + public Class<ZonedDateTime> getType() + { + return ZonedDateTime.class; + } + + + /** + * Parses the supplied value and returns a date time. + * + * @param value of generalized time to parse + * + * @return date time initialized to the correct time + * + * @throws ParseException if the value does not contain correct generalized time syntax + */ + protected ZonedDateTime parseGeneralizedTime(final String value) + throws ParseException + { + if (value == null) { + throw new IllegalArgumentException("String to parse cannot be null."); + } + + final Matcher m = TIME_REGEX.matcher(value); + if (!m.matches()) { + throw new ParseException("Invalid generalized time string.", value.length()); + } + + // CheckStyle:MagicNumber OFF + final ZoneId zoneId; + final String tzString = m.group(9); + if ("Z".equals(tzString)) { + zoneId = ZoneOffset.UTC; + } else { + zoneId = ZoneId.of("GMT" + tzString); + } + + // Set required time fields + final int year = Integer.parseInt(m.group(1)); + final int month = Integer.parseInt(m.group(2)); + final int dayOfMonth = Integer.parseInt(m.group(3)); + final int hour = Integer.parseInt(m.group(4)); + + FractionalPart fraction = FractionalPart.Hours; + + // Set optional minutes + int minutes = 0; + if (m.group(5) != null) { + fraction = FractionalPart.Minutes; + minutes = Integer.parseInt(m.group(5)); + } + + // Set optional seconds + int seconds = 0; + if (m.group(6) != null) { + fraction = FractionalPart.Seconds; + seconds = Integer.parseInt(m.group(6)); + } + + // Set optional fractional part + int millis = 0; + if (m.group(7) != null) { + millis = fraction.toMillis(m.group(8)); + } + // CheckStyle:MagicNumber ON + + return ZonedDateTime.of( + LocalDateTime.of(year, month, dayOfMonth, hour, minutes, seconds).plus(millis, ChronoUnit.MILLIS), zoneId); + } +}
diff --git a/core/src/main/java/org/ldaptive/io/Hex.java b/core/src/main/java/org/ldaptive/io/Hex.java new file mode 100644 index 0000000..ec0cc60 --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/Hex.java
@@ -0,0 +1,153 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.util.Arrays; + +/** + * Utility for hexidecimal encoding and decoding. + * + * @author Middleware Services + */ +public final class Hex +{ + + /** Hexidecimal characters. */ + private static final char[] HEX_CHARS = { + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + }; + + /** + * Decode table which stores characters from 0 to f. Anything higher than 'f' is invalid so that is the max size of + * the array. + */ + private static final byte[] DECODE = new byte['f' + 1]; + + /** + * Initialize the DECODE table. + */ + // CheckStyle:MagicNumber OFF + static { + // set all values to -1 to indicate error + Arrays.fill(DECODE, (byte) -1); + // set values for hex 0-9 + for (int i = '0'; i <= '9'; i++) { + DECODE[i] = (byte) (i - '0'); + } + // set values for hex A-F + for (int i = 'A'; i <= 'F'; i++) { + DECODE[i] = (byte) (i - 'A' + 10); + } + // set values for hex a-f + for (int i = 'a'; i <= 'f'; i++) { + DECODE[i] = (byte) (i - 'a' + 10); + } + } + // CheckStyle:MagicNumber ON + + + /** Default constructor. */ + private Hex() {} + + + /** + * This will convert the supplied value to a hex encoded string. Returns null if the supplied value is null. + * + * @param value to hex encode + * + * @return hex encoded value + */ + public static char[] encode(final byte[] value) + { + if (value == null) { + return null; + } + + final int l = value.length; + final char[] encoded = new char[l << 1]; + // CheckStyle:MagicNumber OFF + for (int i = 0, j = 0; i < l; i++) { + encoded[j++] = HEX_CHARS[(0xF0 & value[i]) >>> 4]; + encoded[j++] = HEX_CHARS[0x0F & value[i]]; + } + // CheckStyle:MagicNumber ON + return encoded; + } + + + /** + * This will convert the supplied value from a hex encoded string. Returns null if the supplied value is null. + * + * @param value to hex decode + * + * @return hex decoded value + * + * @throws IllegalArgumentException if value is not valid hexidecimal + */ + public static byte[] decode(final char[] value) + { + if (value == null) { + return null; + } + + final int l = value.length; + // CheckStyle:MagicNumber OFF + if ((l & 0x01) != 0) { + throw new IllegalArgumentException( + String.format("Cannot decode odd number of characters for %s", String.valueOf(value))); + } + // CheckStyle:MagicNumber ON + + final byte[] decoded = new byte[l >> 1]; + + // CheckStyle:MagicNumber OFF + for (int i = 0, j = 0; j < l; i++, j += 2) { + final int high = decode(value, j) << 4; + final int low = decode(value, j + 1); + decoded[i] = (byte) ((high | low) & 0xFF); + } + // CheckStyle:MagicNumber ON + return decoded; + } + + + /** + * Decodes the supplied character to it's corresponding nibble. + * + * @param hex to read character from + * @param i index of hex to read + * + * @return 0-15 integer + * + * @throws IllegalArgumentException if the character is not valid hex + */ + protected static int decode(final char[] hex, final int i) + { + final char c = hex[i]; + if (c > 'f') { + throw new IllegalArgumentException( + String.format("Invalid hex character '%s' at position %s in %s", c, i, Arrays.toString(hex))); + } + + final byte b = DECODE[c]; + if (b < 0) { + throw new IllegalArgumentException( + String.format("Invalid hex character '%s' at position %s in %s", c, i, Arrays.toString(hex))); + } + return b; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/IntegerValueTranscoder.java b/core/src/main/java/org/ldaptive/io/IntegerValueTranscoder.java new file mode 100644 index 0000000..dee504a --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/IntegerValueTranscoder.java
@@ -0,0 +1,40 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +/** + * Decodes and encodes an integer for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class IntegerValueTranscoder extends AbstractPrimitiveValueTranscoder<Integer> +{ + + + /** Default constructor. */ + public IntegerValueTranscoder() {} + + + /** + * Creates a new integer value transcoder. + * + * @param b whether this transcoder is operating on a primitive + */ + public IntegerValueTranscoder(final boolean b) + { + setPrimitive(b); + } + + + @Override + public Integer decodeStringValue(final String value) + { + return Integer.valueOf(value); + } + + + @Override + public Class<Integer> getType() + { + return isPrimitive() ? int.class : Integer.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/LdifReader.java b/core/src/main/java/org/ldaptive/io/LdifReader.java new file mode 100644 index 0000000..c760a1b --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/LdifReader.java
@@ -0,0 +1,142 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.net.URL; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapUtils; +import org.ldaptive.SearchResult; +import org.ldaptive.SortBehavior; + +/** + * Reads an LDIF from a {@link Reader} and returns a {@link SearchResult}. + * + * @author Middleware Services + */ +public class LdifReader implements SearchResultReader +{ + + /** Reader to read from. */ + private final Reader ldifReader; + + /** Sort behavior. */ + private final SortBehavior sortBehavior; + + + /** + * Creates a new ldif reader. + * + * @param reader to read LDIF from + */ + public LdifReader(final Reader reader) + { + this(reader, SortBehavior.getDefaultSortBehavior()); + } + + + /** + * Creates a new ldif reader. + * + * @param reader to read LDIF from + * @param sb sort behavior of the ldap result + */ + public LdifReader(final Reader reader, final SortBehavior sb) + { + ldifReader = reader; + if (sb == null) { + throw new IllegalArgumentException("Sort behavior cannot be null"); + } + sortBehavior = sb; + } + + + /** + * Reads LDIF data from the reader and returns a search result. + * + * @return search result derived from the LDIF + * + * @throws IOException if an error occurs using the reader + */ + @Override + public SearchResult read() + throws IOException + { + final SearchResult result = new SearchResult(sortBehavior); + final BufferedReader br = new BufferedReader(ldifReader); + String line; + int lineCount = 0; + LdapEntry ldapEntry = null; + StringBuffer lineValue = new StringBuffer(); + + while ((line = br.readLine()) != null) { + lineCount++; + if (line.startsWith("dn:")) { + lineValue.append(line); + ldapEntry = new LdapEntry(sortBehavior); + break; + } + } + + boolean read = true; + while (read) { + line = br.readLine(); + if (line == null) { + read = false; + line = ""; + } + if (!line.startsWith("#")) { + if (line.startsWith("dn:")) { + result.addEntry(ldapEntry); + ldapEntry = new LdapEntry(sortBehavior); + } + if (line.startsWith(" ")) { + lineValue.append(line.substring(1)); + } else { + final String s = lineValue.toString(); + if (s.contains(":")) { + boolean isBinary = false; + boolean isUrl = false; + final String[] parts = s.split(":", 2); + final String attrName = parts[0]; + String attrValue = parts[1]; + if (attrValue.startsWith(":")) { + isBinary = true; + attrValue = attrValue.substring(1); + } else if (attrValue.startsWith("<")) { + isUrl = true; + attrValue = attrValue.substring(1); + } + if (attrValue.startsWith(" ")) { + attrValue = attrValue.substring(1); + } + if ("dn".equals(attrName)) { + ldapEntry.setDn(attrValue); + } else { + LdapAttribute ldapAttr = ldapEntry.getAttribute(attrName); + if (ldapAttr == null) { + ldapAttr = new LdapAttribute(sortBehavior, isBinary || isUrl); + ldapAttr.setName(attrName); + ldapEntry.addAttribute(ldapAttr); + } + if (isBinary) { + ldapAttr.addValue(new ByteArrayValueTranscoder(), LdapUtils.base64Decode(attrValue)); + } else if (isUrl) { + ldapAttr.addValue(new ByteArrayValueTranscoder(), LdapUtils.readURL(new URL(attrValue))); + } else { + ldapAttr.addValue(new StringValueTranscoder(), attrValue); + } + } + } + lineValue = new StringBuffer(line); + } + } + } + if (ldapEntry != null) { + result.addEntry(ldapEntry); + } + return result; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/LdifWriter.java b/core/src/main/java/org/ldaptive/io/LdifWriter.java new file mode 100644 index 0000000..dd4e83d --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/LdifWriter.java
@@ -0,0 +1,210 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.io.IOException; +import java.io.Writer; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapUtils; +import org.ldaptive.SearchReference; +import org.ldaptive.SearchResult; + +/** + * Writes a {@link SearchResult} as LDIF to a {@link Writer}. + * + * @author Middleware Services + */ +public class LdifWriter implements SearchResultWriter +{ + + /** ASCII decimal value of nul. */ + private static final int NUL_CHAR = 0; + + /** ASCII decimal value of line feed. */ + private static final int LF_CHAR = 10; + + /** ASCII decimal value of carriage return. */ + private static final int CR_CHAR = 13; + + /** ASCII decimal value of space. */ + private static final int SP_CHAR = 32; + + /** ASCII decimal value of colon. */ + private static final int COLON_CHAR = 58; + + /** ASCII decimal value of left arrow. */ + private static final int LA_CHAR = 60; + + /** ASCII decimal value of highest character. */ + private static final int MAX_ASCII_CHAR = 127; + + /** Line separator. */ + private static final String LINE_SEPARATOR = System.getProperty("line.separator"); + + /** Writer to write to. */ + private final Writer ldifWriter; + + + /** + * Creates a new ldif writer. + * + * @param writer to write LDIF to + */ + public LdifWriter(final Writer writer) + { + ldifWriter = writer; + } + + + /** + * Writes the supplied search result to the writer. + * + * @param result search result to write + * + * @throws IOException if an error occurs using the writer + */ + @Override + public void write(final SearchResult result) + throws IOException + { + ldifWriter.write(createLdif(result)); + ldifWriter.flush(); + } + + + /** + * Creates an LDIF using the supplied search result. + * + * @param result search result + * + * @return LDIF + */ + protected String createLdif(final SearchResult result) + { + // build string from results + final StringBuilder ldif = new StringBuilder(); + if (result != null) { + for (LdapEntry le : result.getEntries()) { + ldif.append(createLdifEntry(le)); + } + for (SearchReference sr : result.getReferences()) { + ldif.append(createSearchReference(sr)); + } + } + + return ldif.toString(); + } + + + /** + * Creates an LDIF using the supplied ldap entry. + * + * @param entry ldap entry + * + * @return LDIF + */ + protected String createLdifEntry(final LdapEntry entry) + { + if (entry == null) { + return ""; + } + + final StringBuilder entryLdif = new StringBuilder(); + final String dn = entry.getDn(); + if (dn != null) { + if (encodeData(dn)) { + entryLdif.append("dn:: ").append(LdapUtils.base64Encode(dn)).append(LINE_SEPARATOR); + } else { + entryLdif.append("dn: ").append(dn).append(LINE_SEPARATOR); + } + } + + for (LdapAttribute attr : entry.getAttributes()) { + final String attrName = attr.getName(); + for (String attrValue : attr.getStringValues()) { + if (attr.isBinary()) { + entryLdif.append(attrName).append(":: ").append(attrValue).append(LINE_SEPARATOR); + } else if (encodeData(attrValue)) { + entryLdif.append(attrName).append(":: ").append(LdapUtils.base64Encode(attrValue)).append(LINE_SEPARATOR); + } else { + entryLdif.append(attrName).append(": ").append(attrValue).append(LINE_SEPARATOR); + } + } + } + + if (entryLdif.length() > 0) { + entryLdif.append(LINE_SEPARATOR); + } + return entryLdif.toString(); + } + + + /** + * Creates an LDIF using the supplied search reference. + * + * @param ref search reference + * + * @return LDIF + */ + protected String createSearchReference(final SearchReference ref) + { + if (ref == null) { + return ""; + } + + final StringBuilder refLdif = new StringBuilder(); + for (String url : ref.getReferralUrls()) { + if (encodeData(url)) { + refLdif.append("ref:: ").append(LdapUtils.base64Encode(url)).append(LINE_SEPARATOR); + } else { + refLdif.append("ref: ").append(url).append(LINE_SEPARATOR); + } + } + + if (refLdif.length() > 0) { + refLdif.append(LINE_SEPARATOR); + } + return refLdif.toString(); + } + + + /** + * Determines whether the supplied data should be base64 encoded. See http://www.faqs.org/rfcs/rfc2849.html for more + * details. + * + * @param data to inspect + * + * @return whether the data should be base64 encoded + */ + private boolean encodeData(final String data) + { + boolean encode = false; + final char[] dataCharArray = data.toCharArray(); + for (int i = 0; i < dataCharArray.length; i++) { + final int charInt = (int) dataCharArray[i]; + // check for NUL + if (charInt == NUL_CHAR) { + encode = true; + // check for LF + } else if (charInt == LF_CHAR) { + encode = true; + // check for CR + } else if (charInt == CR_CHAR) { + encode = true; + // check for SP at beginning or end of string + } else if (charInt == SP_CHAR && (i == 0 || i == dataCharArray.length - 1)) { + encode = true; + // check for colon(:) at beginning of string + } else if (charInt == COLON_CHAR && i == 0) { + encode = true; + // check for left arrow(<) at beginning of string + } else if (charInt == LA_CHAR && i == 0) { + encode = true; + // check for any character above 127 + } else if (charInt > MAX_ASCII_CHAR) { + encode = true; + } + } + return encode; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/LongValueTranscoder.java b/core/src/main/java/org/ldaptive/io/LongValueTranscoder.java new file mode 100644 index 0000000..ba44222 --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/LongValueTranscoder.java
@@ -0,0 +1,40 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +/** + * Decodes and encodes a long for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class LongValueTranscoder extends AbstractPrimitiveValueTranscoder<Long> +{ + + + /** Default constructor. */ + public LongValueTranscoder() {} + + + /** + * Creates a new long value transcoder. + * + * @param b whether this transcoder is operating on a primitive + */ + public LongValueTranscoder(final boolean b) + { + setPrimitive(b); + } + + + @Override + public Long decodeStringValue(final String value) + { + return Long.valueOf(value); + } + + + @Override + public Class<Long> getType() + { + return isPrimitive() ? long.class : Long.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/ObjectValueTranscoder.java b/core/src/main/java/org/ldaptive/io/ObjectValueTranscoder.java new file mode 100644 index 0000000..5c8f1aa --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/ObjectValueTranscoder.java
@@ -0,0 +1,48 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import org.ldaptive.LdapUtils; + +/** + * Decodes and encodes an object for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class ObjectValueTranscoder implements ValueTranscoder<Object> +{ + + + @Override + public Object decodeStringValue(final String value) + { + return value; + } + + + @Override + public Object decodeBinaryValue(final byte[] value) + { + return value; + } + + + @Override + public String encodeStringValue(final Object value) + { + return value.toString(); + } + + + @Override + public byte[] encodeBinaryValue(final Object value) + { + return LdapUtils.utf8Encode(encodeStringValue(value)); + } + + + @Override + public Class<Object> getType() + { + return Object.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/SearchResultReader.java b/core/src/main/java/org/ldaptive/io/SearchResultReader.java new file mode 100644 index 0000000..aaa1e5e --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/SearchResultReader.java
@@ -0,0 +1,25 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.io.IOException; +import org.ldaptive.SearchResult; + +/** + * Interface for reading ldap search results. + * + * @author Middleware Services + */ +public interface SearchResultReader +{ + + + /** + * Reads an ldap result. + * + * @return ldap result + * + * @throws IOException if an error occurs using the reader + */ + SearchResult read() + throws IOException; +}
diff --git a/core/src/main/java/org/ldaptive/io/SearchResultWriter.java b/core/src/main/java/org/ldaptive/io/SearchResultWriter.java new file mode 100644 index 0000000..6fa4859 --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/SearchResultWriter.java
@@ -0,0 +1,25 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.io.IOException; +import org.ldaptive.SearchResult; + +/** + * Interface for writing ldap search results. + * + * @author Middleware Services + */ +public interface SearchResultWriter +{ + + + /** + * Writes the supplied ldap result. + * + * @param result ldap result to write + * + * @throws IOException if an error occurs using the writer + */ + void write(SearchResult result) + throws IOException; +}
diff --git a/core/src/main/java/org/ldaptive/io/ShortValueTranscoder.java b/core/src/main/java/org/ldaptive/io/ShortValueTranscoder.java new file mode 100644 index 0000000..e662e03 --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/ShortValueTranscoder.java
@@ -0,0 +1,40 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +/** + * Decodes and encodes a short for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class ShortValueTranscoder extends AbstractPrimitiveValueTranscoder<Short> +{ + + + /** Default constructor. */ + public ShortValueTranscoder() {} + + + /** + * Creates a new short value transcoder. + * + * @param b whether this transcoder is operating on a primitive + */ + public ShortValueTranscoder(final boolean b) + { + setPrimitive(b); + } + + + @Override + public Short decodeStringValue(final String value) + { + return Short.valueOf(value); + } + + + @Override + public Class<Short> getType() + { + return isPrimitive() ? short.class : Short.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/StringValueTranscoder.java b/core/src/main/java/org/ldaptive/io/StringValueTranscoder.java new file mode 100644 index 0000000..42ee65f --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/StringValueTranscoder.java
@@ -0,0 +1,32 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +/** + * Decodes and encodes a string for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class StringValueTranscoder extends AbstractStringValueTranscoder<String> +{ + + + @Override + public String decodeStringValue(final String value) + { + return value; + } + + + @Override + public String encodeStringValue(final String value) + { + return value; + } + + + @Override + public Class<String> getType() + { + return String.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/UUIDValueTranscoder.java b/core/src/main/java/org/ldaptive/io/UUIDValueTranscoder.java new file mode 100644 index 0000000..243102d --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/UUIDValueTranscoder.java
@@ -0,0 +1,34 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.util.UUID; + +/** + * Decodes and encodes a UUID for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class UUIDValueTranscoder extends AbstractStringValueTranscoder<UUID> +{ + + + @Override + public UUID decodeStringValue(final String value) + { + return UUID.fromString(value); + } + + + @Override + public String encodeStringValue(final UUID value) + { + return value.toString(); + } + + + @Override + public Class<UUID> getType() + { + return UUID.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/io/ValueTranscoder.java b/core/src/main/java/org/ldaptive/io/ValueTranscoder.java new file mode 100644 index 0000000..c8fcaa9 --- /dev/null +++ b/core/src/main/java/org/ldaptive/io/ValueTranscoder.java
@@ -0,0 +1,61 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +/** + * Interface for decoding and encoding custom types for ldap attribute values. + * + * @param <T> type of value + * + * @author Middleware Services + */ +public interface ValueTranscoder<T> +{ + + + /** + * Decodes the supplied ldap attribute value into a custom type. + * + * @param value to decode + * + * @return decoded value + */ + T decodeStringValue(String value); + + + /** + * Decodes the supplied ldap attribute value into a custom type. + * + * @param value to decode + * + * @return decoded value + */ + T decodeBinaryValue(byte[] value); + + + /** + * Encodes the supplied value into an ldap attribute value. + * + * @param value to encode + * + * @return encoded value + */ + String encodeStringValue(T value); + + + /** + * Encodes the supplied value into an ldap attribute value. + * + * @param value to encode + * + * @return encoded value + */ + byte[] encodeBinaryValue(T value); + + + /** + * Returns the type produced by this value transcoder. + * + * @return type produced by this value transcoder + */ + Class<T> getType(); +}
diff --git a/core/src/main/java/org/ldaptive/jaas/AbstractLoginModule.java b/core/src/main/java/org/ldaptive/jaas/AbstractLoginModule.java new file mode 100644 index 0000000..574d8ac --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/AbstractLoginModule.java
@@ -0,0 +1,361 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.io.IOException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides functionality common to ldap based JAAS login modules. + * + * @author Middleware Services + */ +public abstract class AbstractLoginModule implements LoginModule +{ + + /** Constant for login name stored in shared state. */ + public static final String LOGIN_NAME = "javax.security.auth.login.name"; + + /** Constant for entryDn stored in shared state. */ + public static final String LOGIN_DN = "org.ldaptive.jaas.login.entryDn"; + + /** Constant for login password stored in shared state. */ + public static final String LOGIN_PASSWORD = "javax.security.auth.login.password"; + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Default roles. */ + protected final List<LdapRole> defaultRole = new ArrayList<>(); + + /** Initialized subject. */ + protected Subject subject; + + /** Initialized callback handler. */ + protected CallbackHandler callbackHandler; + + /** Shared state from other login module. */ + protected Map sharedState; + + /** Whether credentials from the shared state should be used. */ + protected boolean useFirstPass; + + /** Whether credentials from the shared state should be used if they are available. */ + protected boolean tryFirstPass; + + /** Whether credentials should be stored in the shared state map. */ + protected boolean storePass; + + /** Whether credentials should be removed from the shared state map. */ + protected boolean clearPass; + + /** Whether ldap principal data should be set. */ + protected boolean setLdapPrincipal; + + /** Whether ldap dn principal data should be set. */ + protected boolean setLdapDnPrincipal; + + /** Whether ldap credential data should be set. */ + protected boolean setLdapCredential; + + /** Name of group to add all principals to. */ + protected String principalGroupName; + + /** Name of group to add all roles to. */ + protected String roleGroupName; + + /** Whether authentication was successful. */ + protected boolean loginSuccess; + + /** Whether commit was successful. */ + protected boolean commitSuccess; + + /** Principals to add to the subject. */ + protected Set<Principal> principals; + + /** Credentials to add to the subject. */ + protected Set<LdapCredential> credentials; + + /** Roles to add to the subject. */ + protected Set<Principal> roles; + + + @Override + public void initialize( + final Subject subj, + final CallbackHandler handler, + final Map<String, ?> state, + final Map<String, ?> options) + { + logger.trace("Begin initialize"); + subject = subj; + callbackHandler = handler; + sharedState = state; + + for (String key : options.keySet()) { + final String value = (String) options.get(key); + if ("useFirstPass".equalsIgnoreCase(key)) { + useFirstPass = Boolean.valueOf(value); + } else if ("tryFirstPass".equalsIgnoreCase(key)) { + tryFirstPass = Boolean.valueOf(value); + } else if ("storePass".equalsIgnoreCase(key)) { + storePass = Boolean.valueOf(value); + } else if ("clearPass".equalsIgnoreCase(key)) { + clearPass = Boolean.valueOf(value); + } else if ("setLdapPrincipal".equalsIgnoreCase(key)) { + setLdapPrincipal = Boolean.valueOf(value); + } else if ("setLdapDnPrincipal".equalsIgnoreCase(key)) { + setLdapDnPrincipal = Boolean.valueOf(value); + } else if ("setLdapCredential".equalsIgnoreCase(key)) { + setLdapCredential = Boolean.valueOf(value); + } else if ("defaultRole".equalsIgnoreCase(key)) { + for (String s : value.split(",")) { + defaultRole.add(new LdapRole(s.trim())); + } + } else if ("principalGroupName".equalsIgnoreCase(key)) { + principalGroupName = value; + } else if ("roleGroupName".equalsIgnoreCase(key)) { + roleGroupName = value; + } + } + + logger.trace( + "useFirstPass = {}, tryFirstPass = {}, storePass = {}, clearPass = {}, " + + "setLdapPrincipal = {}, setLdapDnPrincipal = {}, " + + "setLdapCredential = {}, defaultRole = {}, principalGroupName = {}, " + + "roleGroupName = {}", + Boolean.toString(useFirstPass), + Boolean.toString(tryFirstPass), + Boolean.toString(storePass), + Boolean.toString(clearPass), + Boolean.toString(setLdapPrincipal), + Boolean.toString(setLdapDnPrincipal), + Boolean.toString(setLdapCredential), + defaultRole, + principalGroupName, + roleGroupName); + + principals = new TreeSet<>(); + credentials = new HashSet<>(); + roles = new TreeSet<>(); + } + + + @Override + public boolean login() + throws LoginException + { + final NameCallback nameCb = new NameCallback("Enter user: "); + final PasswordCallback passCb = new PasswordCallback("Enter user password: ", false); + return login(nameCb, passCb); + } + + + /** + * Authenticates a {@link Subject} with the supplied callbacks. + * + * @param nameCb callback handler for subject's name + * @param passCb callback handler for subject's password + * + * @return true if authentication succeeded, false to ignore this module + * + * @throws LoginException if the authentication fails + */ + protected abstract boolean login(final NameCallback nameCb, final PasswordCallback passCb) + throws LoginException; + + + @Override + public boolean commit() + throws LoginException + { + logger.trace("Begin commit"); + if (!loginSuccess) { + logger.debug("Login failed"); + return false; + } + + if (subject.isReadOnly()) { + clearState(); + throw new LoginException("Subject is read-only."); + } + subject.getPrincipals().addAll(principals); + logger.debug("Committed the following principals: {}", principals); + subject.getPrivateCredentials().addAll(credentials); + subject.getPrincipals().addAll(roles); + logger.debug("Committed the following roles: {}", roles); + if (principalGroupName != null) { + final LdapGroup group = new LdapGroup(principalGroupName); + principals.forEach(group::addMember); + subject.getPrincipals().add(group); + logger.debug("Committed the following principal group: {}", group); + } + if (roleGroupName != null) { + final LdapGroup group = new LdapGroup(roleGroupName); + roles.forEach(group::addMember); + subject.getPrincipals().add(group); + logger.debug("Committed the following role group: {}", group); + } + clearState(); + commitSuccess = true; + return true; + } + + + @Override + public boolean abort() + throws LoginException + { + logger.trace("Begin abort"); + if (!loginSuccess) { + return false; + } else if (!commitSuccess) { + loginSuccess = false; + clearState(); + } else { + logout(); + } + return true; + } + + + @Override + public boolean logout() + throws LoginException + { + logger.trace("Begin logout"); + if (subject.isReadOnly()) { + clearState(); + throw new LoginException("Subject is read-only."); + } + + for (LdapPrincipal ldapPrincipal : subject.getPrincipals(LdapPrincipal.class)) { + subject.getPrincipals().remove(ldapPrincipal); + } + + for (LdapDnPrincipal ldapDnPrincipal : subject.getPrincipals(LdapDnPrincipal.class)) { + subject.getPrincipals().remove(ldapDnPrincipal); + } + + for (LdapRole ldapRole : subject.getPrincipals(LdapRole.class)) { + subject.getPrincipals().remove(ldapRole); + } + + for (LdapGroup ldapGroup : subject.getPrincipals(LdapGroup.class)) { + subject.getPrincipals().remove(ldapGroup); + } + + for (LdapCredential ldapCredential : subject.getPrivateCredentials(LdapCredential.class)) { + subject.getPrivateCredentials().remove(ldapCredential); + } + + clearState(); + loginSuccess = false; + commitSuccess = false; + return true; + } + + + /** + * Removes any stateful principals, credentials, or roles stored by login. Also removes shared state name, dn, and + * password if clearPass is set. + */ + protected void clearState() + { + principals.clear(); + credentials.clear(); + roles.clear(); + if (clearPass) { + sharedState.remove(LOGIN_NAME); + sharedState.remove(LOGIN_PASSWORD); + sharedState.remove(LOGIN_DN); + } + } + + + /** + * Attempts to retrieve credentials for the supplied name and password callbacks. If useFirstPass or tryFirstPass is + * set, then name and password data is retrieved from shared state. Otherwise a callback handler is used to get the + * data. Set useCallback to force a callback handler to be used. + * + * @param nameCb to set name for + * @param passCb to set password for + * @param useCallback whether to force a callback handler + * + * @throws LoginException if the callback handler fails + */ + protected void getCredentials(final NameCallback nameCb, final PasswordCallback passCb, final boolean useCallback) + throws LoginException + { + logger.trace( + "Begin getCredentials: useFistPass = {}, tryFistPass = {}, " + + "useCallback = {}, callbackhandler class = {}, " + + "name callback class = {}, password callback class = {}", + Boolean.toString(useFirstPass), + Boolean.toString(tryFirstPass), + Boolean.toString(useCallback), + callbackHandler.getClass().getName(), + nameCb.getClass().getName(), + passCb.getClass().getName()); + try { + if ((useFirstPass || tryFirstPass) && !useCallback) { + nameCb.setName((String) sharedState.get(LOGIN_NAME)); + passCb.setPassword((char[]) sharedState.get(LOGIN_PASSWORD)); + } else if (callbackHandler != null) { + callbackHandler.handle(new Callback[] {nameCb, passCb}); + } else { + throw new LoginException( + "No CallbackHandler available. " + + "Set useFirstPass, tryFirstPass, or provide a CallbackHandler"); + } + } catch (IOException e) { + logger.error("Error reading data from callback handler", e); + loginSuccess = false; + throw new LoginException(e.getMessage()); + } catch (UnsupportedCallbackException e) { + logger.error("Unsupported callback", e); + loginSuccess = false; + throw new LoginException(e.getMessage()); + } + } + + + /** + * Stores the supplied name, password, and entry dn in the stored state map. storePass must be set for this method to + * have any affect. + * + * @param nameCb to store + * @param passCb to store + * @param loginDn to store + */ + @SuppressWarnings("unchecked") + protected void storeCredentials(final NameCallback nameCb, final PasswordCallback passCb, final String loginDn) + { + if (storePass) { + if (nameCb != null && nameCb.getName() != null) { + sharedState.put(LOGIN_NAME, nameCb.getName()); + } + if (passCb != null && passCb.getPassword() != null) { + sharedState.put(LOGIN_PASSWORD, passCb.getPassword()); + } + if (loginDn != null) { + sharedState.put(LOGIN_DN, loginDn); + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/jaas/AbstractPropertiesFactory.java b/core/src/main/java/org/ldaptive/jaas/AbstractPropertiesFactory.java new file mode 100644 index 0000000..77cb875 --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/AbstractPropertiesFactory.java
@@ -0,0 +1,46 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.util.Map; +import java.util.Properties; +import org.ldaptive.props.PropertySource.PropertyDomain; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides implementation common to properties based factories. + * + * @author Middleware Services + */ +public abstract class AbstractPropertiesFactory +{ + + /** Cache ID option used on the JAAS config. */ + public static final String CACHE_ID = "cacheId"; + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + + /** + * Returns context specific properties based on the supplied JAAS options. + * + * @param options to read properties from + * + * @return properties + */ + protected static Properties createProperties(final Map<String, ?> options) + { + final Properties p = new Properties(); + for (Map.Entry<String, ?> entry : options.entrySet()) { + // if property name contains a dot, it isn't an ldaptive property + // else add the domain to the ldaptive properties + if (entry.getKey().contains(".")) { + p.setProperty(entry.getKey(), entry.getValue().toString()); + } else { + p.setProperty(PropertyDomain.AUTH.value() + entry.getKey(), entry.getValue().toString()); + } + } + return p; + } +}
diff --git a/core/src/main/java/org/ldaptive/jaas/AbstractSearchRoleResolver.java b/core/src/main/java/org/ldaptive/jaas/AbstractSearchRoleResolver.java new file mode 100644 index 0000000..189b024 --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/AbstractSearchRoleResolver.java
@@ -0,0 +1,47 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.util.Set; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.auth.AbstractSearchOperationFactory; + +/** + * Base class for search role resolver implementations. + * + * @author Middleware Services + */ +public abstract class AbstractSearchRoleResolver extends AbstractSearchOperationFactory implements RoleResolver +{ + + + @Override + public Set<LdapRole> search(final SearchRequest request) + throws LdapException + { + Connection conn = null; + try { + conn = getConnection(); + + final SearchOperation op = createSearchOperation(conn); + return LdapRole.toRoles(op.execute(request).getResult()); + } finally { + if (conn != null) { + conn.close(); + } + } + } + + + /** + * Retrieve a connection that is ready for use. + * + * @return connection + * + * @throws LdapException if an error occurs opening the connection + */ + protected abstract Connection getConnection() + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/jaas/AuthenticatorFactory.java b/core/src/main/java/org/ldaptive/jaas/AuthenticatorFactory.java new file mode 100644 index 0000000..c86152b --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/AuthenticatorFactory.java
@@ -0,0 +1,35 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.util.Map; +import org.ldaptive.auth.AuthenticationRequest; +import org.ldaptive.auth.Authenticator; + +/** + * Provides an interface for creating authenticators needed by various JAAS modules. + * + * @author Middleware Services + */ +public interface AuthenticatorFactory +{ + + + /** + * Creates a new authenticator with the supplied JAAS options. + * + * @param jaasOptions JAAS configuration options + * + * @return authenticator + */ + Authenticator createAuthenticator(Map<String, ?> jaasOptions); + + + /** + * Creates a new authentication request with the supplied JAAS options. + * + * @param jaasOptions JAAS configuration options + * + * @return authentication request + */ + AuthenticationRequest createAuthenticationRequest(Map<String, ?> jaasOptions); +}
diff --git a/core/src/main/java/org/ldaptive/jaas/LdapCredential.java b/core/src/main/java/org/ldaptive/jaas/LdapCredential.java new file mode 100644 index 0000000..a3677a0 --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/LdapCredential.java
@@ -0,0 +1,73 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.io.Serializable; +import org.ldaptive.LdapUtils; + +/** + * Provides a custom implementation for adding LDAP credentials to a subject. + * + * @author Middleware Services + */ +public class LdapCredential implements Serializable +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 401; + + /** serial version uid. */ + private static final long serialVersionUID = 1965949592374728021L; + + /** LDAP credential. */ + private final Object credential; + + + /** + * Creates a new ldap credential with the supplied credential. + * + * @param o credential to store + */ + public LdapCredential(final Object o) + { + credential = o; + } + + + /** + * Returns the credential for this ldap credential. + * + * @return credential + */ + public Object getCredential() + { + return credential; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof LdapCredential) { + final LdapCredential v = (LdapCredential) o; + return LdapUtils.areEqual(credential, v.credential); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, credential); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::%s]", getClass().getName(), hashCode(), credential); + } +}
diff --git a/core/src/main/java/org/ldaptive/jaas/LdapDnAuthorizationModule.java b/core/src/main/java/org/ldaptive/jaas/LdapDnAuthorizationModule.java new file mode 100644 index 0000000..6973ce4 --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/LdapDnAuthorizationModule.java
@@ -0,0 +1,136 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.security.Principal; +import java.util.Map; +import java.util.Set; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; +import com.sun.security.auth.callback.TextCallbackHandler; +import org.ldaptive.LdapException; +import org.ldaptive.auth.Authenticator; +import org.ldaptive.auth.User; + +/** + * Provides a JAAS authentication hook into LDAP DNs. No authentication is performed by this module. The LDAP entry DN + * can be stored and shared with other JAAS modules. + * + * @author Middleware Services + */ +public class LdapDnAuthorizationModule extends AbstractLoginModule +{ + + /** Whether failing to find a DN should raise an exception. */ + private boolean noResultsIsError; + + /** Factory for creating authenticators with JAAS options. */ + private AuthenticatorFactory authenticatorFactory; + + /** Authenticator to use against the LDAP. */ + private Authenticator auth; + + + @Override + public void initialize( + final Subject subject, + final CallbackHandler callbackHandler, + final Map<String, ?> sharedState, + final Map<String, ?> options) + { + super.initialize(subject, callbackHandler, sharedState, options); + + for (String key : options.keySet()) { + final String value = (String) options.get(key); + if ("noResultsIsError".equalsIgnoreCase(key)) { + noResultsIsError = Boolean.valueOf(value); + } else if ("authenticatorFactory".equalsIgnoreCase(key)) { + try { + authenticatorFactory = (AuthenticatorFactory) Class.forName(value).newInstance(); + } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) { + throw new IllegalArgumentException(e); + } + } + } + + if (authenticatorFactory == null) { + authenticatorFactory = new PropertiesAuthenticatorFactory(); + } + + logger.trace("authenticatorFactory = {}, noResultsIsError = {}", authenticatorFactory, noResultsIsError); + + auth = authenticatorFactory.createAuthenticator(options); + logger.debug("Retrieved authenticator from factory: {}", auth); + } + + + @Override + protected boolean login(final NameCallback nameCb, final PasswordCallback passCb) + throws LoginException + { + try { + getCredentials(nameCb, passCb, false); + + if (nameCb.getName() == null && tryFirstPass) { + getCredentials(nameCb, passCb, true); + } + + final String loginName = nameCb.getName(); + if (loginName != null && setLdapPrincipal) { + principals.add(new LdapPrincipal(loginName, null)); + loginSuccess = true; + } + + final String loginDn = auth.resolveDn(new User(nameCb.getName())); + if (loginDn == null && noResultsIsError) { + loginSuccess = false; + throw new LoginException("Could not find DN for " + nameCb.getName()); + } + if (loginDn != null && setLdapDnPrincipal) { + principals.add(new LdapDnPrincipal(loginDn, null)); + loginSuccess = true; + } + if (defaultRole != null && !defaultRole.isEmpty()) { + roles.addAll(defaultRole); + loginSuccess = true; + } + storeCredentials(nameCb, passCb, loginDn); + } catch (LdapException e) { + logger.debug("Error occurred attempting DN lookup", e); + loginSuccess = false; + throw new LoginException(e != null ? e.getMessage() : "DN resolution error"); + } + return true; + } + + + /** + * This provides command line access to this JAAS module. + * + * @param args command line arguments + * + * @throws Exception if an error occurs + */ + public static void main(final String[] args) + throws Exception + { + String name = "ldaptive-dn"; + if (args.length > 0) { + name = args[0]; + } + + final LoginContext lc = new LoginContext(name, new TextCallbackHandler()); + lc.login(); + + final Set<Principal> principals = lc.getSubject().getPrincipals(); + System.out.println("Subject Principal(s): "); + + for (Principal p : principals) { + System.out.println(" " + p.getName()); + } + lc.logout(); + } +}
diff --git a/core/src/main/java/org/ldaptive/jaas/LdapDnPrincipal.java b/core/src/main/java/org/ldaptive/jaas/LdapDnPrincipal.java new file mode 100644 index 0000000..ad4a4d7 --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/LdapDnPrincipal.java
@@ -0,0 +1,94 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.io.Serializable; +import java.security.Principal; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapUtils; + +/** + * Provides a custom implementation for adding LDAP principals to a subject. + * + * @author Middleware Services + */ +public class LdapDnPrincipal implements Principal, Serializable, Comparable<Principal> +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 409; + + /** serial version uid. */ + private static final long serialVersionUID = 8345846704852267195L; + + /** LDAP user name. */ + private final String ldapDn; + + /** User ldap entry. */ + private final LdapEntry ldapEntry; + + + /** + * Creates a new ldap principal with the supplied name. + * + * @param name of an ldap DN + * @param entry ldap entry associated with this principal + */ + public LdapDnPrincipal(final String name, final LdapEntry entry) + { + ldapDn = name; + ldapEntry = entry; + } + + + @Override + public String getName() + { + return ldapDn; + } + + + /** + * Returns the ldap entry for this ldap principal. + * + * @return ldap entry + */ + public LdapEntry getLdapEntry() + { + return ldapEntry; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof LdapDnPrincipal) { + final LdapDnPrincipal v = (LdapDnPrincipal) o; + return LdapUtils.areEqual(ldapDn, v.ldapDn); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, ldapDn); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::%s%s]", getClass().getName(), hashCode(), ldapDn, ldapEntry != null ? ldapEntry : ""); + } + + + @Override + public int compareTo(final Principal p) + { + return ldapDn.compareTo(p.getName()); + } +}
diff --git a/core/src/main/java/org/ldaptive/jaas/LdapGroup.java b/core/src/main/java/org/ldaptive/jaas/LdapGroup.java new file mode 100644 index 0000000..8d79b15 --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/LdapGroup.java
@@ -0,0 +1,123 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.io.Serializable; +import java.security.Principal; +import java.security.acl.Group; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Set; +import org.ldaptive.LdapUtils; + +/** + * Provides a custom implementation for grouping principals. + * + * @author Middleware Services + */ +public class LdapGroup implements Group, Serializable +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 431; + + /** serial version uid. */ + private static final long serialVersionUID = 2075424472884533862L; + + /** LDAP role name. */ + private final String roleName; + + /** Principal members. */ + private final Set<Principal> members = new HashSet<>(); + + + /** + * Creates a new ldap group with the supplied name. + * + * @param name of the group + */ + public LdapGroup(final String name) + { + roleName = name; + } + + + @Override + public String getName() + { + return roleName; + } + + + @Override + public boolean addMember(final Principal user) + { + return members.add(user); + } + + + @Override + public boolean removeMember(final Principal user) + { + return members.remove(user); + } + + + @Override + public boolean isMember(final Principal member) + { + for (Principal p : members) { + if (p.getName() != null && p.getName().equals(member.getName())) { + return true; + } + } + return false; + } + + + @Override + public Enumeration<? extends Principal> members() + { + return Collections.enumeration(members); + } + + + /** + * Returns an unmodifiable set of the members in this group. + * + * @return set of member principals + */ + public Set<Principal> getMembers() + { + return Collections.unmodifiableSet(members); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof LdapGroup) { + final LdapGroup v = (LdapGroup) o; + return LdapUtils.areEqual(roleName, v.roleName) && + LdapUtils.areEqual(members, v.members); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, roleName, members); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::%s%s]", getClass().getName(), hashCode(), roleName, members); + } +}
diff --git a/core/src/main/java/org/ldaptive/jaas/LdapLoginModule.java b/core/src/main/java/org/ldaptive/jaas/LdapLoginModule.java new file mode 100644 index 0000000..a85bab1 --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/LdapLoginModule.java
@@ -0,0 +1,189 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.security.Principal; +import java.util.Arrays; +import java.util.Map; +import java.util.Set; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; +import com.sun.security.auth.callback.TextCallbackHandler; +import org.ldaptive.Credential; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.ReturnAttributes; +import org.ldaptive.auth.AuthenticationRequest; +import org.ldaptive.auth.AuthenticationResponse; +import org.ldaptive.auth.Authenticator; +import org.ldaptive.auth.User; + +/** + * Provides a JAAS authentication hook for LDAP authentication. + * + * @author Middleware Services + */ +public class LdapLoginModule extends AbstractLoginModule +{ + + /** User attribute to add to role data. */ + private String[] userRoleAttribute = ReturnAttributes.NONE.value(); + + /** Factory for creating authenticators with JAAS options. */ + private AuthenticatorFactory authenticatorFactory; + + /** Authenticator to use against the LDAP. */ + private Authenticator auth; + + /** Authentication request to use for authentication. */ + private AuthenticationRequest authRequest; + + + @Override + public void initialize( + final Subject subject, + final CallbackHandler callbackHandler, + final Map<String, ?> sharedState, + final Map<String, ?> options) + { + setLdapPrincipal = true; + setLdapCredential = true; + + super.initialize(subject, callbackHandler, sharedState, options); + + for (String key : options.keySet()) { + final String value = (String) options.get(key); + if ("userRoleAttribute".equalsIgnoreCase(key)) { + if ("".equals(value)) { + userRoleAttribute = ReturnAttributes.NONE.value(); + } else if ("*".equals(value)) { + userRoleAttribute = ReturnAttributes.ALL_USER.value(); + } else { + userRoleAttribute = value.split(","); + } + } else if ("authenticatorFactory".equalsIgnoreCase(key)) { + try { + authenticatorFactory = (AuthenticatorFactory) Class.forName(value).newInstance(); + } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) { + throw new IllegalArgumentException(e); + } + } + } + + if (authenticatorFactory == null) { + authenticatorFactory = new PropertiesAuthenticatorFactory(); + } + + logger.trace( + "authenticatorFactory = {}, userRoleAttribute = {}", + authenticatorFactory, + Arrays.toString(userRoleAttribute)); + + auth = authenticatorFactory.createAuthenticator(options); + logger.debug("Retrieved authenticator from factory: {}", auth); + + authRequest = authenticatorFactory.createAuthenticationRequest(options); + authRequest.setReturnAttributes(userRoleAttribute); + logger.debug("Retrieved authentication request from factory: {}", authRequest); + } + + + @Override + protected boolean login(final NameCallback nameCb, final PasswordCallback passCb) + throws LoginException + { + try { + getCredentials(nameCb, passCb, false); + authRequest.setUser(new User(nameCb.getName())); + authRequest.setCredential(new Credential(passCb.getPassword())); + + AuthenticationResponse response = auth.authenticate(authRequest); + LdapEntry entry = null; + if (response.getResult()) { + entry = response.getLdapEntry(); + if (entry != null) { + roles.addAll(LdapRole.toRoles(entry)); + if (defaultRole != null && !defaultRole.isEmpty()) { + roles.addAll(defaultRole); + } + } + loginSuccess = true; + } else { + if (tryFirstPass) { + getCredentials(nameCb, passCb, true); + response = auth.authenticate(authRequest); + if (response.getResult()) { + entry = response.getLdapEntry(); + if (entry != null) { + roles.addAll(LdapRole.toRoles(entry)); + } + if (defaultRole != null && !defaultRole.isEmpty()) { + roles.addAll(defaultRole); + } + loginSuccess = true; + } else { + loginSuccess = false; + } + } else { + loginSuccess = false; + } + } + + if (!loginSuccess) { + logger.debug("Authentication failed: " + response); + throw new LoginException("Authentication failed: " + response); + } else { + if (setLdapPrincipal) { + principals.add(new LdapPrincipal(nameCb.getName(), entry)); + } + + final String loginDn = response.getResolvedDn(); + if (loginDn != null && setLdapDnPrincipal) { + principals.add(new LdapDnPrincipal(loginDn, entry)); + } + + if (setLdapCredential) { + credentials.add(new LdapCredential(passCb.getPassword())); + } + storeCredentials(nameCb, passCb, loginDn); + } + } catch (LdapException e) { + logger.debug("Error occurred attempting authentication", e); + loginSuccess = false; + throw new LoginException(e != null ? e.getMessage() : "Authentication Error"); + } + return true; + } + + + /** + * This provides command line access to this JAAS module. + * + * @param args command line arguments + * + * @throws Exception if an error occurs + */ + public static void main(final String[] args) + throws Exception + { + String name = "ldaptive"; + if (args.length > 0) { + name = args[0]; + } + + final LoginContext lc = new LoginContext(name, new TextCallbackHandler()); + lc.login(); + System.out.println("Authentication/Authorization succeeded"); + + final Set<Principal> principals = lc.getSubject().getPrincipals(); + System.out.println("Subject Principal(s): "); + + for (Principal p : principals) { + System.out.println(" " + p); + } + lc.logout(); + } +}
diff --git a/core/src/main/java/org/ldaptive/jaas/LdapPrincipal.java b/core/src/main/java/org/ldaptive/jaas/LdapPrincipal.java new file mode 100644 index 0000000..e679aba --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/LdapPrincipal.java
@@ -0,0 +1,95 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.io.Serializable; +import java.security.Principal; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapUtils; + +/** + * Provides a custom implementation for adding LDAP principals to a subject. + * + * @author Middleware Services + */ +public class LdapPrincipal implements Principal, Serializable, Comparable<Principal> +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 419; + + /** serial version uid. */ + private static final long serialVersionUID = 762147223399104252L; + + /** LDAP user name. */ + private final String ldapName; + + /** User ldap entry. */ + private final LdapEntry ldapEntry; + + + /** + * Creates a new ldap principal with the supplied name. + * + * @param name of this principal + * @param entry ldap entry associated with this principal + */ + public LdapPrincipal(final String name, final LdapEntry entry) + { + ldapName = name; + ldapEntry = entry; + } + + + @Override + public String getName() + { + return ldapName; + } + + + /** + * Returns the ldap entry for this ldap principal. + * + * @return ldap entry + */ + public LdapEntry getLdapEntry() + { + return ldapEntry; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof LdapPrincipal) { + final LdapPrincipal v = (LdapPrincipal) o; + return LdapUtils.areEqual(ldapName, v.ldapName); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, ldapName); + } + + + @Override + public String toString() + { + return + String.format("[%s@%d::%s%s]", getClass().getName(), hashCode(), ldapName, ldapEntry != null ? ldapEntry : ""); + } + + + @Override + public int compareTo(final Principal p) + { + return ldapName.compareTo(p.getName()); + } +}
diff --git a/core/src/main/java/org/ldaptive/jaas/LdapRole.java b/core/src/main/java/org/ldaptive/jaas/LdapRole.java new file mode 100644 index 0000000..87e82a1 --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/LdapRole.java
@@ -0,0 +1,133 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.io.Serializable; +import java.security.Principal; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapUtils; +import org.ldaptive.SearchResult; + +/** + * Provides a custom implementation for adding LDAP principals to a subject that represent roles. + * + * @author Middleware Services + */ +public class LdapRole implements Principal, Serializable, Comparable<Principal> +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 421; + + /** serial version uid. */ + private static final long serialVersionUID = 1578734888816839199L; + + /** LDAP role name. */ + private final String roleName; + + + /** + * Creates a new ldap role with the supplied name. + * + * @param name of this role + */ + public LdapRole(final String name) + { + roleName = name; + } + + + @Override + public String getName() + { + return roleName; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof LdapRole) { + final LdapRole v = (LdapRole) o; + return LdapUtils.areEqual(roleName, v.roleName); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, roleName); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::%s]", getClass().getName(), hashCode(), roleName); + } + + + @Override + public int compareTo(final Principal p) + { + return roleName.compareTo(p.getName()); + } + + + /** + * Iterates over the supplied result and returns all attributes as a set of ldap roles. + * + * @param result to read + * + * @return ldap roles + */ + public static Set<LdapRole> toRoles(final SearchResult result) + { + final Set<LdapRole> r = new HashSet<>(); + for (LdapEntry le : result.getEntries()) { + r.addAll(toRoles(le)); + } + return r; + } + + + /** + * Iterates over the supplied entry and returns all attributes as a set of ldap roles. + * + * @param entry to read + * + * @return ldap roles + */ + public static Set<LdapRole> toRoles(final LdapEntry entry) + { + return toRoles(entry.getAttributes()); + } + + + /** + * Iterates over the supplied attributes and returns all values as a set of ldap roles. + * + * @param attributes to read + * + * @return ldap roles + */ + public static Set<LdapRole> toRoles(final Collection<LdapAttribute> attributes) + { + final Set<LdapRole> r = new HashSet<>(); + if (attributes != null) { + for (LdapAttribute ldapAttr : attributes) { + r.addAll(ldapAttr.getStringValues().stream().map(LdapRole::new).collect(Collectors.toList())); + } + } + return r; + } +}
diff --git a/core/src/main/java/org/ldaptive/jaas/LdapRoleAuthorizationModule.java b/core/src/main/java/org/ldaptive/jaas/LdapRoleAuthorizationModule.java new file mode 100644 index 0000000..5007a2f --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/LdapRoleAuthorizationModule.java
@@ -0,0 +1,176 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.security.Principal; +import java.util.Arrays; +import java.util.Map; +import java.util.Set; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; +import com.sun.security.auth.callback.TextCallbackHandler; +import org.ldaptive.LdapException; +import org.ldaptive.ReturnAttributes; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchRequest; + +/** + * Provides a JAAS authentication hook into LDAP roles. No authentication is performed in this module. Role data is set + * for the login name in the shared state or for the name returned by the CallbackHandler. + * + * @author Middleware Services + */ +public class LdapRoleAuthorizationModule extends AbstractLoginModule +{ + + /** Ldap filter for role searches. */ + private String roleFilter; + + /** Role attribute to add to role data. */ + private String[] roleAttribute = ReturnAttributes.NONE.value(); + + /** Whether failing to find any roles should raise an exception. */ + private boolean noResultsIsError; + + /** Factory for creating role resolvers with JAAS options. */ + private RoleResolverFactory roleResolverFactory; + + /** To search for roles. */ + private RoleResolver roleResolver; + + /** Search request to use for roles. */ + private SearchRequest searchRequest; + + + @Override + public void initialize( + final Subject subject, + final CallbackHandler callbackHandler, + final Map<String, ?> sharedState, + final Map<String, ?> options) + { + super.initialize(subject, callbackHandler, sharedState, options); + + for (String key : options.keySet()) { + final String value = (String) options.get(key); + if ("roleFilter".equalsIgnoreCase(key)) { + roleFilter = value; + } else if ("roleAttribute".equalsIgnoreCase(key)) { + if ("".equals(value)) { + roleAttribute = ReturnAttributes.NONE.value(); + } else if ("*".equals(value)) { + roleAttribute = ReturnAttributes.ALL_USER.value(); + } else { + roleAttribute = value.split(","); + } + } else if ("noResultsIsError".equalsIgnoreCase(key)) { + noResultsIsError = Boolean.valueOf(value); + } else if ("roleResolverFactory".equalsIgnoreCase(key)) { + try { + roleResolverFactory = (RoleResolverFactory) Class.forName(value).newInstance(); + } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) { + throw new IllegalArgumentException(e); + } + } + } + + if (roleResolverFactory == null) { + roleResolverFactory = new PropertiesRoleResolverFactory(); + } + + logger.trace( + "roleResolverFactory = {}, roleFilter = {}, roleAttribute = {}, noResultsIsError = {}", + roleResolverFactory, + roleFilter, + Arrays.toString(roleAttribute), + noResultsIsError); + + roleResolver = roleResolverFactory.createRoleResolver(options); + logger.debug("Retrieved role resolver from factory: {}", roleResolver); + + searchRequest = roleResolverFactory.createSearchRequest(options); + searchRequest.setReturnAttributes(roleAttribute); + logger.debug("Retrieved search request from factory: {}", searchRequest); + } + + + @Override + protected boolean login(final NameCallback nameCb, final PasswordCallback passCb) + throws LoginException + { + try { + getCredentials(nameCb, passCb, false); + + if (nameCb.getName() == null && tryFirstPass) { + getCredentials(nameCb, passCb, true); + } + + final String loginName = nameCb.getName(); + if (loginName != null && setLdapPrincipal) { + principals.add(new LdapPrincipal(loginName, null)); + loginSuccess = true; + } + + final String loginDn = (String) sharedState.get(LOGIN_DN); + if (loginDn != null && setLdapDnPrincipal) { + principals.add(new LdapDnPrincipal(loginDn, null)); + loginSuccess = true; + } + + final SearchFilter filter = new SearchFilter(roleFilter); + filter.setParameter("dn", loginDn); + filter.setParameter("user", loginName); + searchRequest.setSearchFilter(filter); + + final Set<LdapRole> lr = roleResolver.search(searchRequest); + if (lr.isEmpty() && noResultsIsError) { + loginSuccess = false; + throw new LoginException("Could not find roles using " + roleFilter); + } + roles.addAll(lr); + if (defaultRole != null && !defaultRole.isEmpty()) { + roles.addAll(defaultRole); + } + if (!roles.isEmpty()) { + loginSuccess = true; + } + storeCredentials(nameCb, passCb, null); + } catch (LdapException e) { + logger.debug("Error occurred attempting role lookup", e); + loginSuccess = false; + throw new LoginException(e.getMessage()); + } + return true; + } + + + /** + * This provides command line access to this JAAS module. + * + * @param args command line arguments + * + * @throws Exception if an error occurs + */ + public static void main(final String[] args) + throws Exception + { + String name = "ldaptive-role"; + if (args.length > 0) { + name = args[0]; + } + + final LoginContext lc = new LoginContext(name, new TextCallbackHandler()); + lc.login(); + + final Set<Principal> principals = lc.getSubject().getPrincipals(); + System.out.println("Subject Principal(s): "); + + for (Principal p : principals) { + System.out.println(" " + p.getName()); + } + lc.logout(); + } +}
diff --git a/core/src/main/java/org/ldaptive/jaas/PooledSearchRoleResolver.java b/core/src/main/java/org/ldaptive/jaas/PooledSearchRoleResolver.java new file mode 100644 index 0000000..d657322 --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/PooledSearchRoleResolver.java
@@ -0,0 +1,73 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.pool.PooledConnectionFactoryManager; + +/** + * Looks up a user's roles using a pool of connections. + * + * @author Middleware Services + */ +public class PooledSearchRoleResolver extends AbstractSearchRoleResolver implements PooledConnectionFactoryManager +{ + + /** Connection factory. */ + private PooledConnectionFactory factory; + + + /** Default constructor. */ + public PooledSearchRoleResolver() {} + + + /** + * Creates a new pooled role resolver. + * + * @param cf connection factory + */ + public PooledSearchRoleResolver(final PooledConnectionFactory cf) + { + setConnectionFactory(cf); + } + + + /** + * Returns the connection factory. + * + * @return connection factory + */ + @Override + public PooledConnectionFactory getConnectionFactory() + { + return factory; + } + + + /** + * Sets the connection factory. + * + * @param cf connection factory + */ + @Override + public void setConnectionFactory(final PooledConnectionFactory cf) + { + factory = cf; + } + + + @Override + protected Connection getConnection() + throws LdapException + { + return factory.getConnection(); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::factory=%s]", getClass().getName(), hashCode(), factory); + } +}
diff --git a/core/src/main/java/org/ldaptive/jaas/PropertiesAuthenticatorFactory.java b/core/src/main/java/org/ldaptive/jaas/PropertiesAuthenticatorFactory.java new file mode 100644 index 0000000..c97c363 --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/PropertiesAuthenticatorFactory.java
@@ -0,0 +1,95 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.util.HashMap; +import java.util.Map; +import org.ldaptive.auth.AuthenticationHandler; +import org.ldaptive.auth.AuthenticationRequest; +import org.ldaptive.auth.Authenticator; +import org.ldaptive.pool.PooledConnectionFactoryManager; +import org.ldaptive.props.AuthenticationRequestPropertySource; +import org.ldaptive.props.AuthenticatorPropertySource; + +/** + * Provides a module authenticator factory implementation that uses the properties package in this library. + * + * @author Middleware Services + */ +public class PropertiesAuthenticatorFactory extends AbstractPropertiesFactory implements AuthenticatorFactory +{ + + /** Object CACHE. */ + private static final Map<String, Authenticator> CACHE = new HashMap<>(); + + + @Override + public Authenticator createAuthenticator(final Map<String, ?> jaasOptions) + { + Authenticator a; + if (jaasOptions.containsKey(CACHE_ID)) { + final String cacheId = (String) jaasOptions.get(CACHE_ID); + synchronized (CACHE) { + if (!CACHE.containsKey(cacheId)) { + a = createAuthenticatorInternal(jaasOptions); + logger.trace("Created authenticator: {}", a); + CACHE.put(cacheId, a); + } else { + a = CACHE.get(cacheId); + logger.trace("Retrieved authenticator from CACHE: {}", a); + } + } + } else { + a = createAuthenticatorInternal(jaasOptions); + logger.trace("Created authenticator {} from {}", a, jaasOptions); + } + return a; + } + + + /** + * Initializes an authenticator using an authenticator property source. + * + * @param options to initialize authenticator + * + * @return authenticator + */ + protected Authenticator createAuthenticatorInternal(final Map<String, ?> options) + { + final Authenticator a = new Authenticator(); + final AuthenticatorPropertySource source = new AuthenticatorPropertySource(a, createProperties(options)); + source.initialize(); + return a; + } + + + @Override + public AuthenticationRequest createAuthenticationRequest(final Map<String, ?> jaasOptions) + { + final AuthenticationRequest ar = new AuthenticationRequest(); + final AuthenticationRequestPropertySource source = new AuthenticationRequestPropertySource( + ar, + createProperties(jaasOptions)); + source.initialize(); + logger.trace("Created authentication request {} from {}", ar, jaasOptions); + return ar; + } + + + /** Iterates over the CACHE and closes any managed dn resolvers and managed authentication handlers. */ + public static void close() + { + for (Map.Entry<String, Authenticator> e : CACHE.entrySet()) { + final Authenticator a = e.getValue(); + if (a.getDnResolver() instanceof PooledConnectionFactoryManager) { + final PooledConnectionFactoryManager cfm = (PooledConnectionFactoryManager) a.getDnResolver(); + cfm.getConnectionFactory().getConnectionPool().close(); + } + + final AuthenticationHandler ah = a.getAuthenticationHandler(); + if (ah instanceof PooledConnectionFactoryManager) { + final PooledConnectionFactoryManager cfm = (PooledConnectionFactoryManager) ah; + cfm.getConnectionFactory().getConnectionPool().close(); + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/jaas/PropertiesRoleResolverFactory.java b/core/src/main/java/org/ldaptive/jaas/PropertiesRoleResolverFactory.java new file mode 100644 index 0000000..23776f0 --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/PropertiesRoleResolverFactory.java
@@ -0,0 +1,118 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.util.HashMap; +import java.util.Map; +import org.ldaptive.ConnectionFactoryManager; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.SearchRequest; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.pool.PooledConnectionFactoryManager; +import org.ldaptive.props.DefaultConnectionFactoryPropertySource; +import org.ldaptive.props.PooledConnectionFactoryPropertySource; +import org.ldaptive.props.PropertySource.PropertyDomain; +import org.ldaptive.props.SearchRequestPropertySource; + +/** + * Provides a module role resolver factory implementation that uses the properties package in this library. + * + * @author Middleware Services + */ +public class PropertiesRoleResolverFactory extends AbstractPropertiesFactory implements RoleResolverFactory +{ + + /** Object CACHE. */ + private static final Map<String, RoleResolver> CACHE = new HashMap<>(); + + + @Override + public RoleResolver createRoleResolver(final Map<String, ?> jaasOptions) + { + RoleResolver rr; + if (jaasOptions.containsKey(CACHE_ID)) { + final String cacheId = (String) jaasOptions.get(CACHE_ID); + synchronized (CACHE) { + if (!CACHE.containsKey(cacheId)) { + rr = createRoleResolverInternal(jaasOptions); + logger.trace("Created role resolver: {}", rr); + CACHE.put(cacheId, rr); + } else { + rr = CACHE.get(cacheId); + logger.trace("Retrieved role resolver from CACHE: {}", rr); + } + } + } else { + rr = createRoleResolverInternal(jaasOptions); + logger.trace("Created role resolver {} from {}", rr, jaasOptions); + } + return rr; + } + + + /** + * Initializes a role resolver using a role resolver property source. + * + * @param options to initialize role resolver + * + * @return role resolver + */ + protected RoleResolver createRoleResolverInternal(final Map<String, ?> options) + { + RoleResolver rr; + if (options.containsKey("roleResolver")) { + try { + final String className = (String) options.get("roleResolver"); + rr = (RoleResolver) Class.forName(className).newInstance(); + } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) { + throw new IllegalArgumentException(e); + } + } else { + rr = new SearchRoleResolver(); + } + if (rr instanceof PooledConnectionFactoryManager) { + final PooledConnectionFactoryManager cfm = (PooledConnectionFactoryManager) rr; + final PooledConnectionFactory cf = new PooledConnectionFactory(); + final PooledConnectionFactoryPropertySource source = new PooledConnectionFactoryPropertySource( + cf, + PropertyDomain.AUTH, + createProperties(options)); + source.initialize(); + cfm.setConnectionFactory(cf); + } + if (rr instanceof ConnectionFactoryManager) { + final ConnectionFactoryManager cfm = (ConnectionFactoryManager) rr; + final DefaultConnectionFactory cf = new DefaultConnectionFactory(); + final DefaultConnectionFactoryPropertySource source = new DefaultConnectionFactoryPropertySource( + cf, + PropertyDomain.AUTH, + createProperties(options)); + source.initialize(); + cfm.setConnectionFactory(cf); + } + return rr; + } + + + @Override + public SearchRequest createSearchRequest(final Map<String, ?> jaasOptions) + { + final SearchRequest sr = new SearchRequest(); + final SearchRequestPropertySource source = new SearchRequestPropertySource( + sr, + PropertyDomain.AUTH, + createProperties(jaasOptions)); + source.initialize(); + logger.trace("Created search request {} from {}", sr, jaasOptions); + return sr; + } + + + /** Iterates over the CACHE and closes all role resolvers. */ + public static void close() + { + CACHE.values().stream().filter(rr -> rr instanceof PooledConnectionFactoryManager).forEach(rr -> { + final PooledConnectionFactoryManager cfm = (PooledConnectionFactoryManager) rr; + cfm.getConnectionFactory().getConnectionPool().close(); + }); + } +}
diff --git a/core/src/main/java/org/ldaptive/jaas/RoleResolver.java b/core/src/main/java/org/ldaptive/jaas/RoleResolver.java new file mode 100644 index 0000000..4bed006 --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/RoleResolver.java
@@ -0,0 +1,28 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.util.Set; +import org.ldaptive.LdapException; +import org.ldaptive.SearchRequest; + +/** + * Looks up a user's roles using an LDAP search. + * + * @author Middleware Services + */ +public interface RoleResolver +{ + + + /** + * Executes a search request and converts any attributes to ldap roles. + * + * @param request to execute + * + * @return ldap roles + * + * @throws LdapException if the ldap operation fails + */ + Set<LdapRole> search(SearchRequest request) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/jaas/RoleResolverFactory.java b/core/src/main/java/org/ldaptive/jaas/RoleResolverFactory.java new file mode 100644 index 0000000..609ad66 --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/RoleResolverFactory.java
@@ -0,0 +1,34 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.util.Map; +import org.ldaptive.SearchRequest; + +/** + * Provides an interface for creating role resolver needed by various JAAS modules. + * + * @author Middleware Services + */ +public interface RoleResolverFactory +{ + + + /** + * Creates a new role resolver with the supplied JAAS options. + * + * @param jaasOptions JAAS configuration options + * + * @return role resolver + */ + RoleResolver createRoleResolver(Map<String, ?> jaasOptions); + + + /** + * Creates a new search request with the supplied JAAS options. + * + * @param jaasOptions JAAS configuration options + * + * @return search request + */ + SearchRequest createSearchRequest(Map<String, ?> jaasOptions); +}
diff --git a/core/src/main/java/org/ldaptive/jaas/SearchRoleResolver.java b/core/src/main/java/org/ldaptive/jaas/SearchRoleResolver.java new file mode 100644 index 0000000..f87d2c6 --- /dev/null +++ b/core/src/main/java/org/ldaptive/jaas/SearchRoleResolver.java
@@ -0,0 +1,82 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import org.ldaptive.Connection; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.ConnectionFactoryManager; +import org.ldaptive.LdapException; + +/** + * Looks up a user's roles using an LDAP search. + * + * @author Middleware Services + */ +public class SearchRoleResolver extends AbstractSearchRoleResolver implements ConnectionFactoryManager +{ + + /** Connection factory. */ + private ConnectionFactory factory; + + + /** Default constructor. */ + public SearchRoleResolver() {} + + + /** + * Creates a new role resolver. + * + * @param cf connection factory + */ + public SearchRoleResolver(final ConnectionFactory cf) + { + setConnectionFactory(cf); + } + + + /** + * Returns the connection factory. + * + * @return connection factory + */ + @Override + public ConnectionFactory getConnectionFactory() + { + return factory; + } + + + /** + * Sets the connection factory. + * + * @param cf connection factory + */ + @Override + public void setConnectionFactory(final ConnectionFactory cf) + { + factory = cf; + } + + + /** + * Retrieve a connection that is ready for use. + * + * @return connection + * + * @throws LdapException if an error occurs opening the connection + */ + @Override + protected Connection getConnection() + throws LdapException + { + final Connection conn = factory.getConnection(); + conn.open(); + return conn; + } + + + @Override + public String toString() + { + return String.format("[%s@%d::factory=%s]", getClass().getName(), hashCode(), factory); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/AbstractConnectionPool.java b/core/src/main/java/org/ldaptive/pool/AbstractConnectionPool.java new file mode 100644 index 0000000..29af361 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/AbstractConnectionPool.java
@@ -0,0 +1,1044 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; +import org.ldaptive.Connection; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.LdapException; +import org.ldaptive.LdapUtils; +import org.ldaptive.Response; + +/** + * Contains the base implementation for pooling connections. The main design objective for the supplied pooling + * implementations is to provide a pool that does not block on connection creation or destruction. This is what accounts + * for the multiple locks available on this class. The pool is backed by two queues, one for available connections and + * one for active connections. Connections that are available via {@link #getConnection()} exist in the available queue. + * Connections that are actively in use exist in the active queue. This implementation uses FIFO operations for each + * queue. + * + * @author Middleware Services + */ +public abstract class AbstractConnectionPool extends AbstractPool<Connection> implements ConnectionPool +{ + + /** Lock for the entire pool. */ + protected final ReentrantLock poolLock = new ReentrantLock(); + + /** Condition for notifying threads that a connection was returned. */ + protected final Condition poolNotEmpty = poolLock.newCondition(); + + /** Lock for check ins. */ + protected final ReentrantLock checkInLock = new ReentrantLock(); + + /** Lock for check outs. */ + protected final ReentrantLock checkOutLock = new ReentrantLock(); + + /** List of available connections in the pool. */ + protected Queue<PooledConnectionProxy> available; + + /** List of connections in use. */ + protected Queue<PooledConnectionProxy> active; + + /** Connection factory to create connections with. */ + private DefaultConnectionFactory connectionFactory; + + /** Whether to connect to the ldap on connection creation. */ + private boolean connectOnCreate = true; + + /** Type of queue. LIFO or FIFO. */ + private QueueType queueType = QueueType.LIFO; + + /** Executor for scheduling pool tasks. */ + private ScheduledExecutorService poolExecutor; + + /** Whether {@link #initialize()} has been invoked. */ + private boolean initialized; + + /** + * Whether {@link #initialize()} should throw if pooling configuration requirements are not met. + */ + private boolean failFastInitialize = true; + + + /** + * Returns the connection factory for this pool. + * + * @return connection factory + */ + public DefaultConnectionFactory getConnectionFactory() + { + return connectionFactory; + } + + + /** + * Sets the connection factory for this pool. + * + * @param cf connection factory + */ + public void setConnectionFactory(final DefaultConnectionFactory cf) + { + logger.trace("setting connectionFactory: {}", cf); + connectionFactory = cf; + } + + + /** + * Returns whether connections will attempt to connect after creation. Default is true. + * + * @return whether connections will attempt to connect after creation + */ + public boolean getConnectOnCreate() + { + return connectOnCreate; + } + + + /** + * Sets whether newly created connections will attempt to connect. Default is true. + * + * @param b connect on create + */ + public void setConnectOnCreate(final boolean b) + { + logger.trace("setting connectOnCreate: {}", b); + connectOnCreate = b; + } + + + /** + * Returns the type of queue used for this connection pool. + * + * @return queue type + */ + public QueueType getQueueType() + { + return queueType; + } + + + /** + * Sets the type of queue used for this connection pool. This property may have an impact on the success of the prune + * strategy. + * + * @param type of queue + */ + public void setQueueType(final QueueType type) + { + logger.trace("setting queueType: {}", type); + queueType = type; + } + + + /** + * Returns whether {@link #initialize()} should throw if pooling configuration requirements are not met. + * + * @return whether {@link #initialize()} should throw + */ + public boolean getFailFastInitialize() + { + return failFastInitialize; + } + + + /** + * Sets whether {@link #initialize()} should throw if pooling configuration requirements are not met. + * + * @param b whether {@link #initialize()} should throw + */ + public void setFailFastInitialize(final boolean b) + { + logger.trace("setting failFastInitialize: {}", b); + failFastInitialize = b; + } + + + /** + * Returns whether this pool has been initialized. + * + * @return whether this pool has been initialized + */ + public boolean isInitialized() + { + return initialized; + } + + + /** + * Used to determine whether {@link #initialize()} has been invoked for this pool. + * + * @throws IllegalStateException if this pool has not been initialized + */ + protected void throwIfNotInitialized() + { + if (!initialized) { + throw new IllegalStateException("Pool has not been initialized"); + } + } + + + /** + * Initialize this pool for use. Once invoked the pool config is made immutable. See {@link + * PoolConfig#makeImmutable()}. + * + * @throws IllegalStateException if this pool has already been initialized, the pooling configuration is + * inconsistent or the pool does not contain at least one connection and it's minimum + * size is greater than zero + */ + @Override + public void initialize() + { + if (initialized) { + throw new IllegalStateException("Pool has already been initialized"); + } + logger.debug("beginning pool initialization for {}", this); + + // sanity check the configuration + if ((getPoolConfig().isValidatePeriodically() || + getPoolConfig().isValidateOnCheckIn() || + getPoolConfig().isValidateOnCheckOut()) && getValidator() == null) { + throw new IllegalStateException("Validation is enabled, but no validator has been configured"); + } + if ((!getPoolConfig().isValidatePeriodically() && + !getPoolConfig().isValidateOnCheckIn() && + !getPoolConfig().isValidateOnCheckOut()) && getValidator() != null) { + throw new IllegalStateException("Validator configured, but no validate flag has been set"); + } + + getPoolConfig().makeImmutable(); + + if (getPruneStrategy() == null) { + setPruneStrategy(new IdlePruneStrategy()); + logger.debug("no prune strategy configured, using default prune strategy: {}", getPruneStrategy()); + } + + // sanity check the scheduler periods + if (getPruneStrategy().getPrunePeriod().toMillis() <= 0) { + throw new IllegalStateException( + "Prune period " + getPruneStrategy().getPrunePeriod() + " must be greater than zero"); + } + if (getPoolConfig().getValidatePeriod().toMillis() <= 0) { + throw new IllegalStateException( + "Validate period " + getPoolConfig().getValidatePeriod() + " must be greater than zero"); + } + if (getPoolConfig().getValidateTimeout() != null && getPoolConfig().getValidateTimeout().toMillis() <= 0) { + throw new IllegalStateException( + "Validate timeout " + getPoolConfig().getValidateTimeout() + " must be greater than zero"); + } + + available = new Queue<>(queueType); + active = new Queue<>(queueType); + + IllegalStateException growException = null; + try { + grow(getPoolConfig().getMinPoolSize(), true); + } catch (IllegalStateException e) { + growException = e; + } + if (available.isEmpty() && getPoolConfig().getMinPoolSize() > 0) { + if (failFastInitialize) { + throw new IllegalStateException( + "Could not initialize pool size", + growException != null ? growException.getCause() : null); + } else { + logger.warn("Could not initialize pool size, pool is empty"); + } + } + logger.debug("initialized available queue: {}", available); + + poolExecutor = Executors.newSingleThreadScheduledExecutor( + r -> { + final Thread t = new Thread(r); + t.setDaemon(true); + return t; + }); + + poolExecutor.scheduleAtFixedRate( + () -> { + logger.debug("begin prune task for {}", AbstractConnectionPool.this); + try { + prune(); + } catch (Exception e) { + logger.error("prune task failed for {}", AbstractConnectionPool.this); + } + logger.debug("end prune task for {}", AbstractConnectionPool.this); + }, + getPruneStrategy().getPrunePeriod().toMillis(), + getPruneStrategy().getPrunePeriod().toMillis(), + TimeUnit.MILLISECONDS); + logger.debug("prune pool task scheduled for {}", this); + + poolExecutor.scheduleAtFixedRate( + () -> { + logger.debug("begin validate task for {}", AbstractConnectionPool.this); + try { + validate(); + } catch (Exception e) { + logger.error("validation task failed for {}", AbstractConnectionPool.this); + } + logger.debug("end validate task for {}", AbstractConnectionPool.this); + }, + getPoolConfig().getValidatePeriod().toMillis(), + getPoolConfig().getValidatePeriod().toMillis(), + TimeUnit.MILLISECONDS); + logger.debug("validate pool task scheduled for {}", this); + + initialized = true; + logger.info("pool initialized {}", this); + } + + + /** + * Attempts to grow the pool to the supplied size. If the pool size is greater than or equal to the supplied size, + * this method is a no-op. + * + * @param size to grow the pool to + */ + protected void grow(final int size) + { + grow(size, false); + } + + + /** + * Attempts to grow the pool to the supplied size. If the pool size is greater than or equal to the supplied size, + * this method is a no-op. + * + * @param size to grow the pool to + * @param throwOnFailure whether to throw illegal state exception + * + * @throws IllegalStateException if the pool cannot grow to the supplied size and {@link + * #createAvailableConnection(boolean)} throws + */ + protected void grow(final int size, final boolean throwOnFailure) + { + logger.trace("waiting for pool lock to initialize pool {}", poolLock.getQueueLength()); + + int count = 0; + poolLock.lock(); + try { + IllegalStateException lastThrown = null; + int currentPoolSize = active.size() + available.size(); + logger.debug("checking connection pool size >= {} for {}", size, this); + while (currentPoolSize < size && count < size * 2) { + try { + final PooledConnectionProxy pc = createAvailableConnection(throwOnFailure); + if (pc != null && getPoolConfig().isValidateOnCheckIn()) { + if (validate(pc.getConnection())) { + logger.trace("connection passed initialize validation: {}", pc); + } else { + logger.warn("connection failed initialize validation: {}", pc); + removeAvailableConnection(pc); + } + } + } catch (IllegalStateException e) { + lastThrown = e; + } + currentPoolSize = active.size() + available.size(); + count++; + } + if (lastThrown != null && currentPoolSize < size) { + throw lastThrown; + } + } finally { + poolLock.unlock(); + } + } + + + /** + * Empty this pool, freeing any resources. + * + * @throws IllegalStateException if this pool has not been initialized + */ + @Override + public void close() + { + throwIfNotInitialized(); + logger.debug("closing connection pool of size {} for {}", available.size() + active.size(), this); + poolLock.lock(); + try { + while (!available.isEmpty()) { + final PooledConnectionProxy pc = available.remove(); + pc.getConnection().close(); + logger.trace("destroyed connection: {}", pc); + } + while (!active.isEmpty()) { + final PooledConnectionProxy pc = active.remove(); + pc.getConnection().close(); + logger.trace("destroyed connection: {}", pc); + } + logger.debug("pool closed"); + } finally { + poolLock.unlock(); + } + + logger.debug("shutting down executor"); + poolExecutor.shutdown(); + logger.debug("executor shutdown"); + logger.info("pool closed {}", this); + initialized = false; + } + + + /** + * Returns a connection from the pool. + * + * @return connection + * + * @throws PoolException if this operation fails + * @throws BlockingTimeoutException if this pool is configured with a block time and it occurs + * @throws PoolInterruptedException if this pool is configured with a block time and the current thread is + * interrupted + * @throws IllegalStateException if this pool has not been initialized + */ + @Override + public abstract Connection getConnection() + throws PoolException; + + + /** + * Returns a connection to the pool. + * + * @param c connection + * + * @throws IllegalStateException if this pool has not been initialized + */ + public abstract void putConnection(final Connection c); + + + /** + * Create a new connection. If {@link #connectOnCreate} is true, the connection will be opened. + * + * @return pooled connection + */ + protected PooledConnectionProxy createConnection() + { + return createConnection(false); + } + + + /** + * Create a new connection. If {@link #connectOnCreate} is true, the connection will be opened. + * + * @param throwOnFailure whether to throw illegal state exception + * + * @return pooled connection + * + * @throws IllegalStateException if {@link #connectOnCreate} is true and the connection cannot be opened + */ + protected PooledConnectionProxy createConnection(final boolean throwOnFailure) + { + Connection c = connectionFactory.getConnection(); + Response<Void> r = null; + if (connectOnCreate) { + try { + r = c.open(); + } catch (LdapException e) { + logger.error("{} unable to connect to the ldap", this, e); + c = null; + if (throwOnFailure) { + throw new IllegalStateException("unable to connect to the ldap", e); + } + } + } + if (c != null) { + return new DefaultPooledConnectionProxy(c, r); + } else { + return null; + } + } + + + /** + * Create a new connection and place it in the available pool. + * + * @return connection that was placed in the available pool + */ + protected PooledConnectionProxy createAvailableConnection() + { + return createAvailableConnection(false); + } + + + /** + * Create a new connection and place it in the available pool. + * + * @param throwOnFailure whether to throw illegal state exception + * + * @return connection that was placed in the available pool + * + * @throws IllegalStateException if {@link #createConnection(boolean)} throws + */ + protected PooledConnectionProxy createAvailableConnection(final boolean throwOnFailure) + { + final PooledConnectionProxy pc = createConnection(throwOnFailure); + if (pc != null) { + poolLock.lock(); + try { + available.add(pc); + pc.getPooledConnectionStatistics().addAvailableStat(); + logger.info("added available connection: {}", pc); + } finally { + poolLock.unlock(); + } + } else { + logger.warn("unable to create available connection"); + } + return pc; + } + + + /** + * Create a new connection and place it in the active pool. + * + * @return connection that was placed in the active pool + */ + protected PooledConnectionProxy createActiveConnection() + { + return createActiveConnection(false); + } + + + /** + * Create a new connection and place it in the active pool. + * + * @param throwOnFailure whether to throw illegal state exception + * + * @return connection that was placed in the active pool + * + * @throws IllegalStateException if {@link #createConnection(boolean)} throws + */ + protected PooledConnectionProxy createActiveConnection(final boolean throwOnFailure) + { + final PooledConnectionProxy pc = createConnection(throwOnFailure); + if (pc != null) { + poolLock.lock(); + try { + active.add(pc); + pc.getPooledConnectionStatistics().addActiveStat(); + logger.info("added active connection: {}", pc); + } finally { + poolLock.unlock(); + } + } else { + logger.warn("unable to create active connection"); + } + return pc; + } + + + /** + * Remove a connection from the available pool. + * + * @param pc connection that is in the available pool + */ + protected void removeAvailableConnection(final PooledConnectionProxy pc) + { + boolean destroy = false; + poolLock.lock(); + try { + if (available.remove(pc)) { + destroy = true; + } else { + logger.warn("attempt to remove unknown available connection: {}", pc); + } + } finally { + poolLock.unlock(); + } + if (destroy) { + pc.getConnection().close(); + logger.info("destroyed connection: {}", pc); + } + } + + + /** + * Remove a connection from the active pool. + * + * @param pc connection that is in the active pool + */ + protected void removeActiveConnection(final PooledConnectionProxy pc) + { + boolean destroy = false; + poolLock.lock(); + try { + if (active.remove(pc)) { + destroy = true; + } else { + logger.warn("attempt to remove unknown active connection: {}", pc); + } + } finally { + poolLock.unlock(); + } + if (destroy) { + pc.getConnection().close(); + logger.info("destroyed connection: {}", pc); + } + } + + + /** + * Remove a connection from both the available and active pools. + * + * @param pc connection that is in both the available and active pools + */ + protected void removeAvailableAndActiveConnection(final PooledConnectionProxy pc) + { + boolean destroy = false; + poolLock.lock(); + try { + if (available.remove(pc)) { + destroy = true; + } else { + logger.debug("attempt to remove unknown available connection: {}", pc); + } + if (active.remove(pc)) { + destroy = true; + } else { + logger.debug("attempt to remove unknown active connection: {}", pc); + } + } finally { + poolLock.unlock(); + } + if (destroy) { + pc.getConnection().close(); + logger.info("destroyed connection: {}", pc); + } + } + + + /** + * Attempts to activate and validate a connection. Performed before a connection is returned from {@link + * #getConnection()}. + * + * @param pc connection + * + * @throws PoolException if this method fails + * @throws ActivationException if the connection cannot be activated + * @throws ValidationException if the connection cannot be validated + */ + protected void activateAndValidateConnection(final PooledConnectionProxy pc) + throws PoolException + { + if (!activate(pc.getConnection())) { + logger.warn("connection failed activation: {}", pc); + removeAvailableAndActiveConnection(pc); + throw new ActivationException("Activation of connection failed"); + } + if (getPoolConfig().isValidateOnCheckOut() && !validate(pc.getConnection())) { + logger.warn("connection failed check out validation: {}", pc); + removeAvailableAndActiveConnection(pc); + throw new ValidationException("Validation of connection failed"); + } + } + + + /** + * Attempts to validate and passivate a connection. Performed when a connection is given to {@link + * #putConnection(Connection)}. + * + * @param pc connection + * + * @return whether both validate and passivation succeeded + */ + protected boolean validateAndPassivateConnection(final PooledConnectionProxy pc) + { + if (!pc.getConnection().isOpen()) { + logger.debug("connection not open: {}", pc); + return false; + } + + boolean valid = false; + if (getPoolConfig().isValidateOnCheckIn()) { + if (!validate(pc.getConnection())) { + logger.warn("connection failed check in validation: {}", pc); + } else { + valid = true; + } + } else { + valid = true; + } + if (valid && !passivate(pc.getConnection())) { + valid = false; + logger.warn("connection failed passivation: {}", pc); + } + return valid; + } + + + /** + * Attempts to reduce the size of the pool back to it's configured minimum. {@link PoolConfig#setMinPoolSize(int)}. + * + * @throws IllegalStateException if this pool has not been initialized + */ + public void prune() + { + throwIfNotInitialized(); + logger.trace("waiting for pool lock to prune {}", poolLock.getQueueLength()); + poolLock.lock(); + try { + if (!available.isEmpty()) { + final int minPoolSize = getPoolConfig().getMinPoolSize(); + int currentPoolSize = active.size() + available.size(); + if (currentPoolSize > minPoolSize) { + logger.debug("pruning available pool of size {} for {}", available.size(), this); + + final int numConnToPrune = available.size(); + final Iterator<PooledConnectionProxy> connIter = available.iterator(); + for (int i = 0; i < numConnToPrune && currentPoolSize > minPoolSize; i++) { + final PooledConnectionProxy pc = connIter.next(); + if (getPruneStrategy().prune(pc)) { + connIter.remove(); + pc.getConnection().close(); + logger.trace("destroyed connection: {}", pc); + currentPoolSize--; + } + } + if (numConnToPrune == available.size()) { + logger.debug("prune strategy did not remove any connections"); + } else { + logger.info("available pool size pruned to {}", available.size()); + } + } else { + logger.debug("pool size is {}, no connections pruned for {}", currentPoolSize, this); + } + } else { + logger.debug("no available connections, no connections pruned for {}", this); + } + } finally { + poolLock.unlock(); + } + } + + + /** + * Attempts to validate all objects in the pool. {@link PoolConfig#setValidatePeriodically(boolean)}. + * + * @throws IllegalStateException if this pool has not been initialized + */ + public void validate() + { + throwIfNotInitialized(); + poolLock.lock(); + try { + if (!available.isEmpty()) { + if (getPoolConfig().isValidatePeriodically()) { + logger.debug("validate available pool of size {} for {}", available.size(), this); + + final List<PooledConnectionProxy> remove = new ArrayList<>(); + if (getPoolConfig().getValidateTimeout() == null) { + for (PooledConnectionProxy pc : available) { + logger.trace("validating {}", pc); + if (validate(pc.getConnection())) { + logger.trace("{} passed validation", pc); + } else { + logger.warn("{} failed validation", pc); + remove.add(pc); + } + } + } else { + final ExecutorService es = Executors.newCachedThreadPool(); + try { + final Map<PooledConnectionProxy, Future<Boolean>> results = new HashMap<>(available.size()); + for (PooledConnectionProxy pc : available) { + logger.trace("validating {}", pc); + results.put(pc, es.submit(() -> validate(pc.getConnection()))); + } + for (Map.Entry<PooledConnectionProxy, Future<Boolean>> entry : results.entrySet()) { + final Future<Boolean> future = entry.getValue(); + boolean validateResult = false; + try { + validateResult = future.get(getPoolConfig().getValidateTimeout().toMillis(), TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + logger.debug("validating {} interrupted", entry.getKey(), e); + future.cancel(true); + } catch (ExecutionException e) { + logger.debug("validating {} threw unexpected exception", entry.getKey(), e); + future.cancel(true); + } catch (TimeoutException e) { + logger.debug("validating {} timed out", entry.getKey(), e); + future.cancel(true); + } + + if (validateResult) { + logger.trace("{} passed validation", entry.getKey()); + } else { + logger.warn("{} failed validation", entry.getKey()); + remove.add(entry.getKey()); + } + } + } finally { + es.shutdownNow(); + } + } + for (PooledConnectionProxy pc : remove) { + logger.trace("removing {} from the pool", pc); + available.remove(pc); + pc.getConnection().close(); + logger.trace("destroyed connection: {}", pc); + } + } + } else { + logger.debug("no available connections, no validation performed for {}", this); + } + grow(getPoolConfig().getMinPoolSize()); + logger.debug("pool size after validation is {}", available.size() + active.size()); + } finally { + poolLock.unlock(); + } + } + + + @Override + public int availableCount() + { + if (available == null) { + return 0; + } + return available.size(); + } + + + @Override + public int activeCount() + { + if (active == null) { + return 0; + } + return active.size(); + } + + + @Override + public Set<PooledConnectionStatistics> getPooledConnectionStatistics() + { + throwIfNotInitialized(); + + final Set<PooledConnectionStatistics> stats = Collections.unmodifiableSet( + new HashSet<>()); + poolLock.lock(); + try { + for (PooledConnectionProxy cp : available) { + stats.add(cp.getPooledConnectionStatistics()); + } + for (PooledConnectionProxy cp : active) { + stats.add(cp.getPooledConnectionStatistics()); + } + } finally { + poolLock.unlock(); + } + return stats; + } + + + /** + * Creates a connection proxy using the supplied pool connection. + * + * @param pc pool connection to create proxy with + * + * @return connection proxy + */ + protected Connection createConnectionProxy(final PooledConnectionProxy pc) + { + return (Connection) Proxy.newProxyInstance(Connection.class.getClassLoader(), new Class[] {Connection.class}, pc); + } + + + /** + * Retrieves the invocation handler from the supplied connection proxy. + * + * @param proxy connection proxy + * + * @return pooled connection proxy + */ + protected PooledConnectionProxy retrieveConnectionProxy(final Connection proxy) + { + return (PooledConnectionProxy) Proxy.getInvocationHandler(proxy); + } + + + /** + * Called by the garbage collector on an object when garbage collection determines that there are no more references + * to the object. + * + * @throws Throwable if an exception is thrown by this method + */ + @Override + protected void finalize() + throws Throwable + { + try { + close(); + } finally { + super.finalize(); + } + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::name=%s, poolConfig=%s, activator=%s, passivator=%s, " + + "validator=%s pruneStrategy=%s, connectOnCreate=%s, " + + "connectionFactory=%s, initialized=%s, availableCount=%s, " + + "activeCount=%s]", + getClass().getName(), + hashCode(), + getName(), + getPoolConfig(), + getActivator(), + getPassivator(), + getValidator(), + getPruneStrategy(), + connectOnCreate, + connectionFactory, + initialized, + availableCount(), + activeCount()); + } + + + /** + * Contains a connection that is participating in this pool. Used to track how long a connection has been in use and + * override certain method invocations. + */ + protected class DefaultPooledConnectionProxy implements PooledConnectionProxy + { + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 503; + + /** Underlying connection. */ + private final Connection conn; + + /** Response produced when the connection was opened. */ + private Response<Void> openResponse; + + /** Time this connection was created. */ + private final long createdTime = System.currentTimeMillis(); + + /** Statistics for this connection. */ + private final PooledConnectionStatistics statistics = new PooledConnectionStatistics( + getPruneStrategy().getStatisticsSize()); + + + /** + * Creates a new pooled connection. + * + * @param c connection to participate in this pool + * @param r response produced by opening the connection + */ + public DefaultPooledConnectionProxy(final Connection c, final Response<Void> r) + { + conn = c; + openResponse = r; + } + + + @Override + public ConnectionPool getConnectionPool() + { + return AbstractConnectionPool.this; + } + + + @Override + public Connection getConnection() + { + return conn; + } + + + @Override + public long getCreatedTime() + { + return createdTime; + } + + + @Override + public PooledConnectionStatistics getPooledConnectionStatistics() + { + return statistics; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof DefaultPooledConnectionProxy) { + final DefaultPooledConnectionProxy v = (DefaultPooledConnectionProxy) o; + return LdapUtils.areEqual(conn, v.conn); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, conn); + } + + + @Override + @SuppressWarnings("unchecked") + public Object invoke(final Object proxy, final Method method, final Object[] args) + throws Throwable + { + Object retValue = null; + if ("open".equals(method.getName())) { + // if the connection has been closed, invoke open + if (!conn.isOpen()) { + try { + openResponse = (Response<Void>) method.invoke(conn, args); + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } + } + retValue = openResponse; + } else if ("reopen".equals(method.getName())) { + try { + openResponse = (Response<Void>) method.invoke(conn, args); + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } + retValue = openResponse; + } else if ("close".equals(method.getName())) { + putConnection((Connection) proxy); + } else { + try { + retValue = method.invoke(conn, args); + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } + } + return retValue; + } + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/AbstractPool.java b/core/src/main/java/org/ldaptive/pool/AbstractPool.java new file mode 100644 index 0000000..f6060cd --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/AbstractPool.java
@@ -0,0 +1,238 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Contains functionality common to pool implementations. + * + * @param <T> type of object being pooled + * + * @author Middleware Services + */ +public abstract class AbstractPool<T> +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Pool name. */ + private String name; + + /** Pool config. */ + private PoolConfig poolConfig; + + /** For activating pooled objects. */ + private Activator<T> activator; + + /** For passivating pooled objects. */ + private Passivator<T> passivator; + + /** For validating pooled objects. */ + private Validator<T> validator; + + /** For removing pooled objects. */ + private PruneStrategy pruneStrategy; + + + /** + * Returns the name for this pool. + * + * @return pool name + */ + public String getName() + { + return name; + } + + + /** + * Sets the name for this pool. + * + * @param s pool name + */ + public void setName(final String s) + { + logger.trace("setting name: {}", s); + name = s; + } + + + /** + * Returns the configuration for this pool. + * + * @return pool config + */ + public PoolConfig getPoolConfig() + { + return poolConfig; + } + + + /** + * Sets the configuration for this pool. + * + * @param pc pool config + */ + public void setPoolConfig(final PoolConfig pc) + { + logger.trace("setting poolConfig: {}", pc); + poolConfig = pc; + } + + + /** + * Returns the activator for this pool. + * + * @return activator + */ + public Activator<T> getActivator() + { + return activator; + } + + + /** + * Sets the activator for this pool. + * + * @param a activator + */ + public void setActivator(final Activator<T> a) + { + logger.trace("setting activator: {}", a); + activator = a; + } + + + /** + * Prepare the object to exit the pool for use. + * + * @param t pooled object + * + * @return whether the object successfully activated + */ + public boolean activate(final T t) + { + boolean success; + if (activator == null) { + success = true; + logger.trace("no activator configured"); + } else { + success = activator.activate(t); + logger.trace("activation for {} = {}", t, success); + } + return success; + } + + + /** + * Returns the passivator for this pool. + * + * @return passivator + */ + public Passivator<T> getPassivator() + { + return passivator; + } + + + /** + * Sets the passivator for this pool. + * + * @param p passivator + */ + public void setPassivator(final Passivator<T> p) + { + logger.trace("setting passivator: {}", p); + passivator = p; + } + + + /** + * Prepare the object to enter the pool after use. + * + * @param t pooled object + * + * @return whether the object successfully passivated + */ + public boolean passivate(final T t) + { + boolean success; + if (passivator == null) { + success = true; + logger.trace("no passivator configured"); + } else { + success = passivator.passivate(t); + logger.trace("passivation for {} = {}", t, success); + } + return success; + } + + + /** + * Returns the validator for this pool. + * + * @return validator + */ + public Validator<T> getValidator() + { + return validator; + } + + + /** + * Sets the validator for this pool. + * + * @param v validator + */ + public void setValidator(final Validator<T> v) + { + logger.trace("setting validator: {}", v); + validator = v; + } + + + /** + * Verify the object is still viable for use in the pool. + * + * @param t pooled object + * + * @return whether the object is viable + */ + public boolean validate(final T t) + { + boolean success; + if (validator == null) { + success = true; + logger.warn("validate called, but no validator configured"); + } else { + success = validator.validate(t); + logger.trace("validation for {} = {}", t, success); + } + return success; + } + + + /** + * Returns the prune strategy for this pool. + * + * @return prune strategy + */ + public PruneStrategy getPruneStrategy() + { + return pruneStrategy; + } + + + /** + * Sets the prune strategy for this pool. + * + * @param ps prune strategy + */ + public void setPruneStrategy(final PruneStrategy ps) + { + logger.trace("setting pruneStrategy: {}", ps); + pruneStrategy = ps; + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/ActivationException.java b/core/src/main/java/org/ldaptive/pool/ActivationException.java new file mode 100644 index 0000000..f3281d7 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/ActivationException.java
@@ -0,0 +1,48 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +/** + * Thrown when an attempt to activate a pooled object fails. + * + * @author Middleware Services + */ +public class ActivationException extends PoolException +{ + + /** serialVersionUID. */ + private static final long serialVersionUID = 5547712224386623996L; + + + /** + * Creates a new activation exception. + * + * @param msg describing this exception + */ + public ActivationException(final String msg) + { + super(msg); + } + + + /** + * Creates a new activation exception. + * + * @param e pooling specific exception + */ + public ActivationException(final Exception e) + { + super(e); + } + + + /** + * Creates a new activation exception. + * + * @param msg describing this exception + * @param e pooling specific exception + */ + public ActivationException(final String msg, final Exception e) + { + super(msg, e); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/Activator.java b/core/src/main/java/org/ldaptive/pool/Activator.java new file mode 100644 index 0000000..8088e9d --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/Activator.java
@@ -0,0 +1,23 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +/** + * Provides an interface for activating objects when they enter the pool. + * + * @param <T> type of object being pooled + * + * @author Middleware Services + */ +public interface Activator<T> +{ + + + /** + * Activate the supplied object. + * + * @param t object + * + * @return whether activation was successful + */ + boolean activate(T t); +}
diff --git a/core/src/main/java/org/ldaptive/pool/BindPassivator.java b/core/src/main/java/org/ldaptive/pool/BindPassivator.java new file mode 100644 index 0000000..0b91093 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/BindPassivator.java
@@ -0,0 +1,89 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import org.ldaptive.BindOperation; +import org.ldaptive.BindRequest; +import org.ldaptive.Connection; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Passivates a connection by performing a bind operation on it. + * + * @author Middleware Services + */ +public class BindPassivator implements Passivator<Connection> +{ + + /** Logger for this class. */ + private final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Bind request to perform passivation with. */ + private BindRequest bindRequest; + + + /** Creates a new bind passivator. */ + public BindPassivator() + { + bindRequest = new BindRequest(); + } + + + /** + * Creates a new bind passivator. + * + * @param br to use for binds + */ + public BindPassivator(final BindRequest br) + { + bindRequest = br; + } + + + /** + * Returns the bind request. + * + * @return bind request + */ + public BindRequest getBindRequest() + { + return bindRequest; + } + + + /** + * Sets the bind request. + * + * @param br bind request + */ + public void setBindRequest(final BindRequest br) + { + bindRequest = br; + } + + + @Override + public boolean passivate(final Connection c) + { + boolean success = false; + if (c != null) { + try { + final BindOperation bind = new BindOperation(c); + final Response<Void> response = bind.execute(bindRequest); + success = ResultCode.SUCCESS == response.getResultCode(); + } catch (Exception e) { + logger.debug("passivation failed for bind request {}", bindRequest, e); + } + } + return success; + } + + + @Override + public String toString() + { + return String.format("[%s@%d::bindRequest=%s]", getClass().getName(), hashCode(), bindRequest); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/BlockingConnectionPool.java b/core/src/main/java/org/ldaptive/pool/BlockingConnectionPool.java new file mode 100644 index 0000000..8276232 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/BlockingConnectionPool.java
@@ -0,0 +1,254 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import java.time.Duration; +import java.util.NoSuchElementException; +import java.util.concurrent.TimeUnit; +import org.ldaptive.Connection; +import org.ldaptive.DefaultConnectionFactory; + +/** + * Implements a pool of connections that has a set minimum and maximum size. The pool will not grow beyond the maximum + * size and when the pool is exhausted, requests for new connections will block. The length of time the pool will block + * is determined by {@link #getBlockWaitTime()}. By default the pool will block indefinitely and there is no guarantee + * that waiting threads will be serviced in the order in which they made their request. This implementation should be + * used when you need to control the <em>exact</em> number of connections that can be created. See {@link + * AbstractConnectionPool}. + * + * @author Middleware Services + */ +public class BlockingConnectionPool extends AbstractConnectionPool +{ + + /** Duration to wait for an available connection. */ + private Duration blockWaitTime; + + + /** Creates a new blocking pool. */ + public BlockingConnectionPool() {} + + + /** + * Creates a new blocking pool. The pool config is initialized with the default values. + * + * @param cf connection factory + */ + public BlockingConnectionPool(final DefaultConnectionFactory cf) + { + this(new PoolConfig(), cf); + } + + + /** + * Creates a new blocking pool. + * + * @param pc pool configuration + * @param cf connection factory + */ + public BlockingConnectionPool(final PoolConfig pc, final DefaultConnectionFactory cf) + { + setPoolConfig(pc); + setConnectionFactory(cf); + } + + + /** + * Returns the block wait time. Default time is null, which will wait indefinitely. + * + * @return time to wait for available connections + */ + public Duration getBlockWaitTime() + { + return blockWaitTime; + } + + + /** + * Sets the block wait time. Default time is null, which will wait indefinitely. + * + * @param time to wait for available connections + */ + public void setBlockWaitTime(final Duration time) + { + if (time != null && time.isNegative()) { + throw new IllegalArgumentException("Block wait time cannot be negative"); + } + blockWaitTime = time; + } + + + @Override + public Connection getConnection() + throws PoolException + { + throwIfNotInitialized(); + + PooledConnectionProxy pc = null; + boolean create = false; + logger.trace("waiting on pool lock for check out {}", poolLock.getQueueLength()); + poolLock.lock(); + try { + // if an available connection exists, use it + // if no available connections and the pool can grow, attempt to create + // otherwise the pool is full, block until a connection is returned + if (!available.isEmpty()) { + try { + logger.trace("retrieve available connection from pool of size {}", available.size()); + pc = retrieveAvailableConnection(); + } catch (NoSuchElementException e) { + logger.error("could not remove connection from list", e); + throw new IllegalStateException("Pool is empty", e); + } + } else if (active.size() < getPoolConfig().getMaxPoolSize()) { + logger.trace("pool can grow, attempt to create active connection in pool of " + + "size {}", active.size()); + create = true; + } else { + logger.trace("pool is full, block until connection is available"); + pc = blockAvailableConnection(); + } + } finally { + poolLock.unlock(); + } + + if (create) { + // previous block determined a creation should occur + // block here until create occurs without locking the whole pool + // if the pool is already maxed or creates are failing, + // block until a connection is available + checkOutLock.lock(); + try { + boolean b = true; + poolLock.lock(); + try { + logger.trace("create connection in pool of size {}", available.size() + active.size()); + if (available.size() + active.size() == getPoolConfig().getMaxPoolSize()) { + logger.trace("pool at maximum size, create not allowed"); + b = false; + } + } finally { + poolLock.unlock(); + } + if (b) { + pc = createActiveConnection(); + } + } finally { + checkOutLock.unlock(); + } + if (pc == null) { + if (available.isEmpty() && active.isEmpty()) { + logger.error("Could not service check out request"); + throw new PoolExhaustedException("Pool is empty and connection creation failed"); + } + logger.debug("create failed, block until connection is available"); + pc = blockAvailableConnection(); + } else { + logger.trace("created new active connection: {}", pc); + } + } + + if (pc != null) { + activateAndValidateConnection(pc); + } else { + logger.error("Could not service check out request"); + throw new PoolExhaustedException("Pool is empty and connection creation failed"); + } + + return createConnectionProxy(pc); + } + + + /** + * Attempts to retrieve a connection from the available queue. + * + * @return connection from the pool + * + * @throws NoSuchElementException if the available queue is empty + */ + protected PooledConnectionProxy retrieveAvailableConnection() + { + PooledConnectionProxy pc = null; + logger.trace("waiting on pool lock for retrieve available {}", poolLock.getQueueLength()); + poolLock.lock(); + try { + pc = available.remove(); + active.add(pc); + pc.getPooledConnectionStatistics().addActiveStat(); + logger.trace("retrieved available connection: {}", pc); + } finally { + poolLock.unlock(); + } + return pc; + } + + + /** + * This blocks until a connection can be acquired. + * + * @return connection from the pool + * + * @throws PoolException if this method fails + * @throws BlockingTimeoutException if this pool is configured with a block time and it occurs + * @throws PoolInterruptedException if the current thread is interrupted + */ + protected PooledConnectionProxy blockAvailableConnection() + throws PoolException + { + PooledConnectionProxy pc = null; + logger.trace("waiting on pool lock for block available {}", poolLock.getQueueLength()); + poolLock.lock(); + try { + while (pc == null) { + logger.trace("available pool is empty, waiting..."); + if (blockWaitTime != null) { + if (!poolNotEmpty.await(blockWaitTime.toMillis(), TimeUnit.MILLISECONDS)) { + logger.debug("block time exceeded, throwing exception"); + throw new BlockingTimeoutException("Block time exceeded"); + } + } else { + poolNotEmpty.await(); + } + logger.trace("notified to continue..."); + try { + pc = retrieveAvailableConnection(); + } catch (NoSuchElementException e) { + logger.trace("notified to continue but pool was empty"); + } + } + } catch (InterruptedException e) { + logger.error("waiting for available connection interrupted", e); + throw new PoolInterruptedException("Interrupted while waiting for an available connection", e); + } finally { + poolLock.unlock(); + } + return pc; + } + + + @Override + public void putConnection(final Connection c) + { + throwIfNotInitialized(); + + final PooledConnectionProxy pc = retrieveConnectionProxy(c); + final boolean valid = validateAndPassivateConnection(pc); + logger.trace("waiting on pool lock for check in {}", poolLock.getQueueLength()); + poolLock.lock(); + try { + if (active.remove(pc)) { + if (valid) { + available.add(pc); + pc.getPooledConnectionStatistics().addAvailableStat(); + logger.trace("returned active connection: {}", pc); + poolNotEmpty.signal(); + } + } else if (available.contains(pc)) { + logger.warn("returned available connection: {}", pc); + } else { + logger.warn("attempt to return unknown connection: {}", pc); + } + } finally { + poolLock.unlock(); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/BlockingTimeoutException.java b/core/src/main/java/org/ldaptive/pool/BlockingTimeoutException.java new file mode 100644 index 0000000..ab9771d --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/BlockingTimeoutException.java
@@ -0,0 +1,48 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +/** + * Thrown when a blocking operation times out. See {@link ConnectionPool#getConnection()}. + * + * @author Middleware Services + */ +public class BlockingTimeoutException extends PoolException +{ + + /** serialVersionUID. */ + private static final long serialVersionUID = 6013765020562222482L; + + + /** + * Creates a new blocking timeout exception. + * + * @param msg describing this exception + */ + public BlockingTimeoutException(final String msg) + { + super(msg); + } + + + /** + * Creates a new blocking timeout exception. + * + * @param e pooling specific exception + */ + public BlockingTimeoutException(final Exception e) + { + super(e); + } + + + /** + * Creates a new blocking timeout exception. + * + * @param msg describing this exception + * @param e pooling specific exception + */ + public BlockingTimeoutException(final String msg, final Exception e) + { + super(msg, e); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/ClosePassivator.java b/core/src/main/java/org/ldaptive/pool/ClosePassivator.java new file mode 100644 index 0000000..46e136e --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/ClosePassivator.java
@@ -0,0 +1,25 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import org.ldaptive.Connection; + +/** + * Passivates a connection by attempting to close it. + * + * @author Middleware Services + */ +public class ClosePassivator implements Passivator<Connection> +{ + + + @Override + public boolean passivate(final Connection c) + { + boolean success = false; + if (c != null) { + c.close(); + success = true; + } + return success; + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/CompareValidator.java b/core/src/main/java/org/ldaptive/pool/CompareValidator.java new file mode 100644 index 0000000..d76702b --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/CompareValidator.java
@@ -0,0 +1,89 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import org.ldaptive.CompareOperation; +import org.ldaptive.CompareRequest; +import org.ldaptive.Connection; +import org.ldaptive.LdapAttribute; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Validates a connection is healthy by performing a compare operation. + * + * @author Middleware Services + */ +public class CompareValidator implements Validator<Connection> +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Compare request to perform validation with. */ + private CompareRequest compareRequest; + + + /** Creates a new compare validator. */ + public CompareValidator() + { + compareRequest = new CompareRequest(); + compareRequest.setDn(""); + compareRequest.setAttribute(new LdapAttribute("objectClass", "top")); + } + + + /** + * Creates a new compare validator. + * + * @param cr to use for compares + */ + public CompareValidator(final CompareRequest cr) + { + compareRequest = cr; + } + + + /** + * Returns the compare request. + * + * @return compare request + */ + public CompareRequest getCompareRequest() + { + return compareRequest; + } + + + /** + * Sets the compare request. + * + * @param cr compare request + */ + public void setCompareRequest(final CompareRequest cr) + { + compareRequest = cr; + } + + + @Override + public boolean validate(final Connection c) + { + boolean success = false; + if (c != null) { + try { + final CompareOperation compare = new CompareOperation(c); + success = compare.execute(compareRequest).getResult(); + } catch (Exception e) { + logger.debug("validation failed for compare request {}", compareRequest, e); + } + } + return success; + } + + + @Override + public String toString() + { + return String.format("[%s@%d::compareRequest=%s]", getClass().getName(), hashCode(), compareRequest); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/ConnectActivator.java b/core/src/main/java/org/ldaptive/pool/ConnectActivator.java new file mode 100644 index 0000000..b1aaee9 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/ConnectActivator.java
@@ -0,0 +1,34 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import org.ldaptive.Connection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Activates a connection by attempting to open it. + * + * @author Middleware Services + */ +public class ConnectActivator implements Activator<Connection> +{ + + /** Logger for this class. */ + private final Logger logger = LoggerFactory.getLogger(getClass()); + + + @Override + public boolean activate(final Connection c) + { + boolean success = false; + if (c != null) { + try { + c.open(); + success = true; + } catch (Exception e) { + logger.error("unable to connect to the ldap", e); + } + } + return success; + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/ConnectionPool.java b/core/src/main/java/org/ldaptive/pool/ConnectionPool.java new file mode 100644 index 0000000..b557063 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/ConnectionPool.java
@@ -0,0 +1,108 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import java.util.Set; +import org.ldaptive.Connection; + +/** + * Provides an interface for connection pooling. + * + * @author Middleware Services + */ +public interface ConnectionPool +{ + + + /** + * Returns the activator for this pool. + * + * @return activator + */ + Activator<Connection> getActivator(); + + + /** + * Sets the activator for this pool. + * + * @param a activator + */ + void setActivator(Activator<Connection> a); + + + /** + * Returns the passivator for this pool. + * + * @return passivator + */ + Passivator<Connection> getPassivator(); + + + /** + * Sets the passivator for this pool. + * + * @param p passivator + */ + void setPassivator(Passivator<Connection> p); + + + /** + * Returns the validator for this pool. + * + * @return validator + */ + Validator<Connection> getValidator(); + + + /** + * Sets the validator for this pool. + * + * @param v validator + */ + void setValidator(Validator<Connection> v); + + + /** Initialize this pool for use. */ + void initialize(); + + + /** + * Returns an object from the pool. + * + * @return pooled object + * + * @throws PoolException if this operation fails + * @throws BlockingTimeoutException if this pool is configured with a block time and it occurs + * @throws PoolInterruptedException if this pool is configured with a block time and the current thread is + * interrupted + */ + Connection getConnection() + throws PoolException; + + + /** + * Returns the number of connections available for use. + * + * @return count + */ + int availableCount(); + + + /** + * Returns the number of connections in use. + * + * @return count + */ + int activeCount(); + + + /** + * Returns the statistics for each connection in the pool. + * + * @return connection statistics + */ + Set<PooledConnectionStatistics> getPooledConnectionStatistics(); + + + /** Empty this pool, freeing any resources. */ + void close(); +}
diff --git a/core/src/main/java/org/ldaptive/pool/ConnectionPoolType.java b/core/src/main/java/org/ldaptive/pool/ConnectionPoolType.java new file mode 100644 index 0000000..15fdfa6 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/ConnectionPoolType.java
@@ -0,0 +1,16 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +/** + * Enum to define connection pool types. + * + * @author Middleware Services + */ +public enum ConnectionPoolType { + + /** blocking. */ + BLOCKING, + + /** soft limit. */ + SOFTLIMIT +}
diff --git a/core/src/main/java/org/ldaptive/pool/IdlePruneStrategy.java b/core/src/main/java/org/ldaptive/pool/IdlePruneStrategy.java new file mode 100644 index 0000000..cb4b80c --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/IdlePruneStrategy.java
@@ -0,0 +1,125 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import java.time.Duration; +import java.time.Instant; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Removes connections from the pool based on how long they have been idle in the available queue. By default this + * implementation executes every 5 minutes and prunes connections that have been idle for more than 10 minutes. + * + * @author Middleware Services + */ +public class IdlePruneStrategy implements PruneStrategy +{ + + /** Default number of statistics to store. Value is {@value}. */ + private static final int DEFAULT_STATISTICS_SIZE = 1; + + /** Default prune period in seconds. Value is 5 minutes. */ + private static final Duration DEFAULT_PRUNE_PERIOD = Duration.ofMinutes(5); + + /** Default idle time. Value is 10 minutes. */ + private static final Duration DEFAULT_IDLE_TIME = Duration.ofMinutes(10); + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Prune period. */ + private Duration prunePeriod; + + /** Idle time. */ + private Duration idleTime; + + + /** Creates a new idle prune strategy. */ + public IdlePruneStrategy() + { + this(DEFAULT_PRUNE_PERIOD, DEFAULT_IDLE_TIME); + } + + + /** + * Creates a new idle prune strategy. + * + * @param period to execute the prune task + * @param idle time at which a connection should be pruned + */ + public IdlePruneStrategy(final Duration period, final Duration idle) + { + setPrunePeriod(period); + setIdleTime(idle); + } + + + @Override + public boolean prune(final PooledConnectionProxy conn) + { + final Instant timeAvailable = conn.getPooledConnectionStatistics().getLastAvailableState(); + logger.trace("evaluating timestamp {} for connection {}", timeAvailable, conn); + return timeAvailable.plus(idleTime).isBefore(Instant.now()); + } + + + @Override + public int getStatisticsSize() + { + return DEFAULT_STATISTICS_SIZE; + } + + + @Override + public Duration getPrunePeriod() + { + return prunePeriod; + } + + + /** + * Sets the prune period. + * + * @param period to set + */ + public void setPrunePeriod(final Duration period) + { + if (period == null || period.isNegative()) { + throw new IllegalArgumentException("Prune period cannot be null or negative"); + } + prunePeriod = period; + } + + + /** + * Returns the idle time. + * + * @return idle time + */ + public Duration getIdleTime() + { + return idleTime; + } + + + /** + * Sets the idle time. + * + * @param time that a connection has been idle and should be pruned + */ + public void setIdleTime(final Duration time) + { + if (time == null || time.isNegative()) { + throw new IllegalArgumentException("Idle time cannot be null or negative"); + } + idleTime = time; + } + + + @Override + public String toString() + { + return + String.format("[%s@%d::prunePeriod=%s, idleTime=%s]", getClass().getName(), hashCode(), prunePeriod, idleTime); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/Passivator.java b/core/src/main/java/org/ldaptive/pool/Passivator.java new file mode 100644 index 0000000..c943402 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/Passivator.java
@@ -0,0 +1,23 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +/** + * Provides an interface for passivating objects when they are checked back into the pool. + * + * @param <T> type of object being pooled + * + * @author Middleware Services + */ +public interface Passivator<T> +{ + + + /** + * Passivate the supplied object. + * + * @param t object + * + * @return whether passivation was successful + */ + boolean passivate(T t); +}
diff --git a/core/src/main/java/org/ldaptive/pool/PoolConfig.java b/core/src/main/java/org/ldaptive/pool/PoolConfig.java new file mode 100644 index 0000000..b866705 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/PoolConfig.java
@@ -0,0 +1,255 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import java.time.Duration; +import org.ldaptive.AbstractConfig; + +/** + * Contains all the configuration data that the pooling implementations need to control the pool. + * + * @author Middleware Services + */ +public class PoolConfig extends AbstractConfig +{ + + /** Default min pool size, value is {@value}. */ + public static final int DEFAULT_MIN_POOL_SIZE = 3; + + /** Default max pool size, value is {@value}. */ + public static final int DEFAULT_MAX_POOL_SIZE = 10; + + /** Default validate on check in, value is {@value}. */ + public static final boolean DEFAULT_VALIDATE_ON_CHECKIN = false; + + /** Default validate on check out, value is {@value}. */ + public static final boolean DEFAULT_VALIDATE_ON_CHECKOUT = false; + + /** Default validate periodically, value is {@value}. */ + public static final boolean DEFAULT_VALIDATE_PERIODICALLY = false; + + /** Default validate period, value is 30 minutes. */ + public static final Duration DEFAULT_VALIDATE_PERIOD = Duration.ofMinutes(30); + + /** Default per connection validate timeout, value is 5 seconds. */ + public static final Duration DEFAULT_VALIDATE_TIMEOUT = Duration.ofSeconds(5); + + /** Minimum pool size. */ + private int minPoolSize = DEFAULT_MIN_POOL_SIZE; + + /** Maximum pool size. */ + private int maxPoolSize = DEFAULT_MAX_POOL_SIZE; + + /** Whether the ldap object should be validated when returned to the pool. */ + private boolean validateOnCheckIn = DEFAULT_VALIDATE_ON_CHECKIN; + + /** Whether the ldap object should be validated when given from the pool. */ + private boolean validateOnCheckOut = DEFAULT_VALIDATE_ON_CHECKOUT; + + /** Whether the pool should be validated periodically. */ + private boolean validatePeriodically = DEFAULT_VALIDATE_PERIODICALLY; + + /** Time that the pool validation should repeat. */ + private Duration validatePeriod = DEFAULT_VALIDATE_PERIOD; + + /** Maximum length of time a connection validation should block. */ + private Duration validateTimeout = DEFAULT_VALIDATE_TIMEOUT; + + + /** + * Returns the min pool size. Default value is {@link #DEFAULT_MIN_POOL_SIZE}. This value represents the size of the + * pool after a prune has occurred. + * + * @return min pool size + */ + public int getMinPoolSize() + { + return minPoolSize; + } + + + /** + * Sets the min pool size. + * + * @param size min pool size + */ + public void setMinPoolSize(final int size) + { + checkImmutable(); + if (size >= 0) { + logger.trace("setting minPoolSize: {}", size); + minPoolSize = size; + } + } + + + /** + * Returns the max pool size. Default value is {@link #DEFAULT_MAX_POOL_SIZE}. This value may or may not be strictly + * enforced depending on the pooling implementation. + * + * @return max pool size + */ + public int getMaxPoolSize() + { + return maxPoolSize; + } + + + /** + * Sets the max pool size. + * + * @param size max pool size + */ + public void setMaxPoolSize(final int size) + { + checkImmutable(); + if (size >= 0) { + logger.trace("setting maxPoolSize: {}", size); + maxPoolSize = size; + } + } + + + /** + * Returns the validate on check in flag. Default value is {@link #DEFAULT_VALIDATE_ON_CHECKIN}. + * + * @return validate on check in + */ + public boolean isValidateOnCheckIn() + { + return validateOnCheckIn; + } + + + /** + * Sets the validate on check in flag. + * + * @param b validate on check in + */ + public void setValidateOnCheckIn(final boolean b) + { + checkImmutable(); + logger.trace("setting validateOnCheckIn: {}", b); + validateOnCheckIn = b; + } + + + /** + * Returns the validate on check out flag. Default value is {@link #DEFAULT_VALIDATE_ON_CHECKOUT}. + * + * @return validate on check in + */ + public boolean isValidateOnCheckOut() + { + return validateOnCheckOut; + } + + + /** + * Sets the validate on check out flag. + * + * @param b validate on check out + */ + public void setValidateOnCheckOut(final boolean b) + { + checkImmutable(); + logger.trace("setting validateOnCheckOut: {}", b); + validateOnCheckOut = b; + } + + + /** + * Returns the validate periodically flag. Default value is {@link #DEFAULT_VALIDATE_PERIODICALLY}. + * + * @return validate periodically + */ + public boolean isValidatePeriodically() + { + return validatePeriodically; + } + + + /** + * Sets the validate periodically flag. + * + * @param b validate periodically + */ + public void setValidatePeriodically(final boolean b) + { + checkImmutable(); + logger.trace("setting validatePeriodically: {}", b); + validatePeriodically = b; + } + + + /** + * Returns the validate period. Default value is {@link #DEFAULT_VALIDATE_PERIOD}. + * + * @return validate period + */ + public Duration getValidatePeriod() + { + return validatePeriod; + } + + + /** + * Sets the period for which the pool will be validated. + * + * @param time in seconds + */ + public void setValidatePeriod(final Duration time) + { + checkImmutable(); + if (time == null || time.isNegative()) { + throw new IllegalArgumentException("Validate period cannot be null or negative"); + } + logger.trace("setting validatePeriod: {}", time); + validatePeriod = time; + } + + + /** + * Returns the timeout imposed when validating a single connection. + * + * @return validate timeout + */ + public Duration getValidateTimeout() + { + return validateTimeout; + } + + + /** + * Sets the timeout imposed when validating a single connection. + * + * @param time for a connection validation + */ + public void setValidateTimeout(final Duration time) + { + checkImmutable(); + if (time != null && time.isNegative()) { + throw new IllegalArgumentException("Validate timeout cannot be negative"); + } + logger.trace("setting validateTimeout: {}", time); + validateTimeout = time; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::minPoolSize=%s, maxPoolSize=%s, validateOnCheckIn=%s, validateOnCheckOut=%s, " + + "validatePeriodically=%s, validatePeriod=%s, validateTimeout=%s]", + getClass().getName(), + hashCode(), + minPoolSize, + maxPoolSize, + validateOnCheckIn, + validateOnCheckOut, + validatePeriodically, + validatePeriod, + validateTimeout); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/PoolException.java b/core/src/main/java/org/ldaptive/pool/PoolException.java new file mode 100644 index 0000000..0752e06 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/PoolException.java
@@ -0,0 +1,50 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import org.ldaptive.LdapException; + +/** + * Base exception thrown when a pool operation fails. + * + * @author Middleware Services + */ +public class PoolException extends LdapException +{ + + /** serialVersionUID. */ + private static final long serialVersionUID = 6320399208563015506L; + + + /** + * Creates a new pool exception. + * + * @param msg describing this exception + */ + public PoolException(final String msg) + { + super(msg); + } + + + /** + * Creates a new pool exception. + * + * @param e pooling specific exception + */ + public PoolException(final Exception e) + { + super(e); + } + + + /** + * Creates a new pool exception. + * + * @param msg describing this exception + * @param e pooling specific exception + */ + public PoolException(final String msg, final Exception e) + { + super(msg, e); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/PoolExhaustedException.java b/core/src/main/java/org/ldaptive/pool/PoolExhaustedException.java new file mode 100644 index 0000000..458e840 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/PoolExhaustedException.java
@@ -0,0 +1,48 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +/** + * Thrown when the pool is empty and no new requests can be serviced. + * + * @author Middleware Services + */ +public class PoolExhaustedException extends PoolException +{ + + /** serialVersionUID. */ + private static final long serialVersionUID = -2092251274513447389L; + + + /** + * Creates a new pool exhausted exception. + * + * @param msg describing this exception + */ + public PoolExhaustedException(final String msg) + { + super(msg); + } + + + /** + * Creates a new pool exhausted exception. + * + * @param e pooling specific exception + */ + public PoolExhaustedException(final Exception e) + { + super(e); + } + + + /** + * Creates a new pool exhausted exception. + * + * @param msg describing this exception + * @param e pooling specific exception + */ + public PoolExhaustedException(final String msg, final Exception e) + { + super(msg, e); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/PoolInterruptedException.java b/core/src/main/java/org/ldaptive/pool/PoolInterruptedException.java new file mode 100644 index 0000000..d10d37f --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/PoolInterruptedException.java
@@ -0,0 +1,48 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +/** + * Thrown when a pool thread is unexpectedly interrupted while blocking. + * + * @author Middleware Services + */ +public class PoolInterruptedException extends PoolException +{ + + /** serialVersionUID. */ + private static final long serialVersionUID = -1427225156311025280L; + + + /** + * Creates a new pool interrupted exception. + * + * @param msg describing this exception + */ + public PoolInterruptedException(final String msg) + { + super(msg); + } + + + /** + * Creates a new pool interrupted exception. + * + * @param e pooling specific exception + */ + public PoolInterruptedException(final Exception e) + { + super(e); + } + + + /** + * Creates a new pool interrupted exception. + * + * @param msg describing this exception + * @param e pooling specific exception + */ + public PoolInterruptedException(final String msg, final Exception e) + { + super(msg, e); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/PooledConnectionFactory.java b/core/src/main/java/org/ldaptive/pool/PooledConnectionFactory.java new file mode 100644 index 0000000..3878cdf --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/PooledConnectionFactory.java
@@ -0,0 +1,77 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import org.ldaptive.Connection; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.LdapException; + +/** + * Leverages a pool to obtain connections for performing ldap operations. + * + * @author Middleware Services + */ +public class PooledConnectionFactory implements ConnectionFactory +{ + + /** Connection pool. */ + private ConnectionPool pool; + + + /** Default constructor. */ + public PooledConnectionFactory() {} + + + /** + * Creates a new pooled connection factory. + * + * @param cp connection pool + */ + public PooledConnectionFactory(final ConnectionPool cp) + { + pool = cp; + } + + + /** + * Returns the connection pool. + * + * @return connection pool + */ + public ConnectionPool getConnectionPool() + { + return pool; + } + + + /** + * Sets the connection pool. + * + * @param cp connection pool + */ + public void setConnectionPool(final ConnectionPool cp) + { + pool = cp; + } + + + /** + * Returns a connection from the pool. Connections returned from this method are ready to perform ldap operations. + * + * @return connection + * + * @throws LdapException if a connection cannot be retrieved from the pool + */ + @Override + public Connection getConnection() + throws LdapException + { + return pool.getConnection(); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::pool=%s]", getClass().getName(), hashCode(), pool); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/PooledConnectionFactoryManager.java b/core/src/main/java/org/ldaptive/pool/PooledConnectionFactoryManager.java new file mode 100644 index 0000000..86417e8 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/PooledConnectionFactoryManager.java
@@ -0,0 +1,27 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +/** + * Interface for objects that manage an instance of pooled connection factory. + * + * @author Middleware Services + */ +public interface PooledConnectionFactoryManager +{ + + + /** + * Returns the connection factory. + * + * @return connection factory + */ + PooledConnectionFactory getConnectionFactory(); + + + /** + * Sets the connection factory. + * + * @param cf connection factory + */ + void setConnectionFactory(PooledConnectionFactory cf); +}
diff --git a/core/src/main/java/org/ldaptive/pool/PooledConnectionProxy.java b/core/src/main/java/org/ldaptive/pool/PooledConnectionProxy.java new file mode 100644 index 0000000..96dddf6 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/PooledConnectionProxy.java
@@ -0,0 +1,46 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import java.lang.reflect.InvocationHandler; +import org.ldaptive.Connection; + +/** + * Provides an interface for metadata surrounding a connection that is participating in the connection pool. + * + * @author Middleware Services + */ +public interface PooledConnectionProxy extends InvocationHandler +{ + + + /** + * Returns the connection pool that this proxy is participating in. + * + * @return connection pool + */ + ConnectionPool getConnectionPool(); + + + /** + * Returns the connection that is being proxied. + * + * @return underlying connection + */ + Connection getConnection(); + + + /** + * Returns the time this proxy was created. + * + * @return creation timestamp in milliseconds + */ + long getCreatedTime(); + + + /** + * Returns the statistics associated with this connection's activity in the pool. + * + * @return pooled connection statistics + */ + PooledConnectionStatistics getPooledConnectionStatistics(); +}
diff --git a/core/src/main/java/org/ldaptive/pool/PooledConnectionStatistics.java b/core/src/main/java/org/ldaptive/pool/PooledConnectionStatistics.java new file mode 100644 index 0000000..20315df --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/PooledConnectionStatistics.java
@@ -0,0 +1,135 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import java.time.Instant; +import java.util.Deque; +import java.util.LinkedList; + +/** + * Statistics associated with a connection's activity in the pool. Exposes the timestamps when this connection entered + * both the available pool and the active pool. A size of 512 uses approximately 50 kilobytes of memory per connection. + * + * @author Middleware Services + */ +public class PooledConnectionStatistics +{ + + /** Number of available and active timestamps to store. */ + private final int size; + + /** Available stats. */ + private final Deque<Instant> availableStats; + + /** Active stats. */ + private final Deque<Instant> activeStats; + + + /** + * Creates a new pooled connection statistics. + * + * @param i number of timestamps to store + */ + public PooledConnectionStatistics(final int i) + { + size = i; + availableStats = new LinkedList<Instant>() { + + + @Override + public boolean add(final Instant e) + { + if (size < 1) { + return false; + } + + final boolean b = super.add(e); + while (size() > size) { + remove(); + } + return b; + } + }; + activeStats = new LinkedList<Instant>() { + + + @Override + public boolean add(final Instant e) + { + if (size < 1) { + return false; + } + + final boolean b = super.add(e); + while (size() > size) { + remove(); + } + return b; + } + }; + } + + + /** + * Returns all the available timestamp statistics. + * + * @return available timestamp statistics + */ + public Deque<Instant> getAvailableStats() + { + return availableStats; + } + + + /** + * Returns the last timestamp at which this connection was made available. + * + * @return millisecond timestamp + */ + public Instant getLastAvailableState() + { + return availableStats.peekLast(); + } + + + /** Inserts the current timestamp into the available statistics. */ + public synchronized void addAvailableStat() + { + availableStats.add(Instant.now()); + } + + + /** + * Returns all the active timestamp statistics. + * + * @return active timestamp statistics + */ + public Deque<Instant> getActiveStats() + { + return activeStats; + } + + + /** + * Returns the last timestamp at which this connection was made active. + * + * @return millisecond timestamp + */ + public Instant getLastActiveStat() + { + return activeStats.peekLast(); + } + + + /** Inserts the current timestamp into the active statistics. */ + public synchronized void addActiveStat() + { + activeStats.add(Instant.now()); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::size=%s]", getClass().getName(), hashCode(), size); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/PruneStrategy.java b/core/src/main/java/org/ldaptive/pool/PruneStrategy.java new file mode 100644 index 0000000..f385988 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/PruneStrategy.java
@@ -0,0 +1,39 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import java.time.Duration; + +/** + * Provides an interface for pruning connections from the pool. + * + * @author Middleware Services + */ +public interface PruneStrategy +{ + + + /** + * Invoked to determine whether a connection should be pruned from the pool. + * + * @param conn that is available for pruning + * + * @return whether the connection should be pruned + */ + boolean prune(PooledConnectionProxy conn); + + + /** + * Returns the number of statistics to store for this prune strategy. See {@link PooledConnectionStatistics}. + * + * @return number of statistics to store + */ + int getStatisticsSize(); + + + /** + * Returns the interval at which the prune task will be executed. + * + * @return prune period + */ + Duration getPrunePeriod(); +}
diff --git a/core/src/main/java/org/ldaptive/pool/Queue.java b/core/src/main/java/org/ldaptive/pool/Queue.java new file mode 100644 index 0000000..e01d21f --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/Queue.java
@@ -0,0 +1,137 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import java.util.Deque; +import java.util.Iterator; +import java.util.LinkedList; + +/** + * Provides a wrapper around a {@link Deque} to support LIFO and FIFO operations. + * + * @param <T> type of object in the queue + * + * @author Middleware Services + */ +public class Queue<T> implements Iterable<T> +{ + + /** How will objects be inserted into the queue. */ + private final QueueType queueType; + + /** Underlying queue. */ + private final Deque<T> queue; + + + /** + * Creates a new queue. + * + * @param type how will objects be inserted into the queue + */ + public Queue(final QueueType type) + { + queueType = type; + queue = new LinkedList<>(); + } + + + /** + * Adds an object to the queue based on the queue type. See {@link Deque#offerFirst(Object)} and {@link + * Deque#offerLast(Object)}. + * + * @param t to add + */ + public void add(final T t) + { + if (QueueType.LIFO == queueType) { + queue.addFirst(t); + } else if (QueueType.FIFO == queueType) { + queue.addLast(t); + } else { + throw new IllegalStateException("Unknown queue type: " + queueType); + } + } + + + /** + * Removes the first element in the queue. See {@link Deque#removeFirst()}. + * + * @return first element in the queue + */ + public T remove() + { + return queue.removeFirst(); + } + + + /** + * Removes the supplied element from the queue. See {@link Deque#remove(Object)}. + * + * @param t to remove + * + * @return whether t was removed + */ + public boolean remove(final T t) + { + return queue.remove(t); + } + + + /** + * Retrieves, but does not remove, the first element in the queue. See {@link Deque#getFirst()}. + * + * @return first element in the queue + */ + public T element() + { + return queue.getFirst(); + } + + + /** + * Returns whether t is in the queue. See {@link Deque#contains(Object)}. + * + * @param t that may be in the queue + * + * @return whether t is in the queue + */ + public boolean contains(final T t) + { + return queue.contains(t); + } + + + /** + * Returns whether or not the queue is empty. See {@link Deque#isEmpty()}}. + * + * @return whether the queue is empty + */ + public boolean isEmpty() + { + return queue.isEmpty(); + } + + + /** + * Returns the number of elements in the queue. See {@link Deque#size()}. + * + * @return number of elements in the queue + */ + public int size() + { + return queue.size(); + } + + + @Override + public Iterator<T> iterator() + { + return queue.iterator(); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::queueType=%s, queue=%s]", getClass().getName(), hashCode(), queueType, queue); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/QueueType.java b/core/src/main/java/org/ldaptive/pool/QueueType.java new file mode 100644 index 0000000..c07f1ab --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/QueueType.java
@@ -0,0 +1,16 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +/** + * Enum to define queue type. + * + * @author Middleware Services + */ +public enum QueueType { + + /** first in, first out ordering. */ + FIFO, + + /** last in, first out ordering. */ + LIFO +}
diff --git a/core/src/main/java/org/ldaptive/pool/SearchValidator.java b/core/src/main/java/org/ldaptive/pool/SearchValidator.java new file mode 100644 index 0000000..7c46231 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/SearchValidator.java
@@ -0,0 +1,97 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import org.ldaptive.Connection; +import org.ldaptive.ReturnAttributes; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.SearchScope; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Validates a connection is healthy by performing a search operation. Validation is considered successful if the search + * result size is greater than zero. + * + * @author Middleware Services + */ +public class SearchValidator implements Validator<Connection> +{ + + /** Logger for this class. */ + private final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Search request to perform validation with. */ + private SearchRequest searchRequest; + + + /** Creates a new search validator. */ + public SearchValidator() + { + searchRequest = new SearchRequest(); + searchRequest.setBaseDn(""); + searchRequest.setSearchFilter(new SearchFilter("(objectClass=*)")); + searchRequest.setReturnAttributes(ReturnAttributes.NONE.value()); + searchRequest.setSearchScope(SearchScope.OBJECT); + searchRequest.setSizeLimit(1); + } + + + /** + * Creates a new search validator. + * + * @param sr to use for searches + */ + public SearchValidator(final SearchRequest sr) + { + searchRequest = sr; + } + + + /** + * Returns the search request. + * + * @return search request + */ + public SearchRequest getSearchRequest() + { + return searchRequest; + } + + + /** + * Sets the search request. + * + * @param sr search request + */ + public void setSearchRequest(final SearchRequest sr) + { + searchRequest = sr; + } + + + @Override + public boolean validate(final Connection c) + { + boolean success = false; + if (c != null) { + try { + final SearchOperation search = new SearchOperation(c); + final SearchResult result = search.execute(searchRequest).getResult(); + success = result.size() > 0; + } catch (Exception e) { + logger.debug("validation failed for search request {}", searchRequest, e); + } + } + return success; + } + + + @Override + public String toString() + { + return String.format("[%s@%d::searchRequest=%s]", getClass().getName(), hashCode(), searchRequest); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/SoftLimitConnectionPool.java b/core/src/main/java/org/ldaptive/pool/SoftLimitConnectionPool.java new file mode 100644 index 0000000..1531c04 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/SoftLimitConnectionPool.java
@@ -0,0 +1,97 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import java.util.NoSuchElementException; +import org.ldaptive.Connection; +import org.ldaptive.DefaultConnectionFactory; + +/** + * Implements a pool of connections that has a set minimum and maximum size. The pool will grow beyond it's maximum size + * as necessary based on it's current load. Pool size will return to it's minimum based on the configuration of the + * prune strategy. See {@link PruneStrategy}. This implementation should be used when you have some flexibility in the + * number of connections that can be created to handle spikes in load. See {@link AbstractConnectionPool}. Note that + * this pool will begin blocking if it cannot create new connections. + * + * @author Middleware Services + */ +public class SoftLimitConnectionPool extends BlockingConnectionPool +{ + + + /** Creates a new soft limit pool. */ + public SoftLimitConnectionPool() {} + + + /** + * Creates a new soft limit pool. + * + * @param cf connection factory + */ + public SoftLimitConnectionPool(final DefaultConnectionFactory cf) + { + super(new PoolConfig(), cf); + } + + + /** + * Creates a new soft limit pool. + * + * @param pc pool configuration + * @param cf connection factory + */ + public SoftLimitConnectionPool(final PoolConfig pc, final DefaultConnectionFactory cf) + { + super(pc, cf); + } + + + @Override + public Connection getConnection() + throws PoolException + { + throwIfNotInitialized(); + + PooledConnectionProxy pc = null; + logger.trace("waiting on pool lock for check out {}", poolLock.getQueueLength()); + poolLock.lock(); + try { + // if an available connection exists, use it + // if no available connections, attempt to create + if (!available.isEmpty()) { + try { + logger.trace("retrieve available connection"); + pc = retrieveAvailableConnection(); + } catch (NoSuchElementException e) { + logger.error("could not remove connection from list", e); + throw new IllegalStateException("Pool is empty", e); + } + } + } finally { + poolLock.unlock(); + } + + if (pc == null) { + // no connection was available, create a new one + pc = createActiveConnection(); + if (pc == null) { + if (available.isEmpty() && active.isEmpty()) { + logger.error("Could not service check out request"); + throw new PoolExhaustedException("Pool is empty and connection creation failed"); + } + logger.debug("create failed, block until a connection is available"); + pc = blockAvailableConnection(); + } else { + logger.trace("created new active connection: {}", pc); + } + } + + if (pc != null) { + activateAndValidateConnection(pc); + } else { + logger.error("Could not service check out request"); + throw new PoolExhaustedException("Pool is empty and connection creation failed"); + } + + return createConnectionProxy(pc); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/ValidationException.java b/core/src/main/java/org/ldaptive/pool/ValidationException.java new file mode 100644 index 0000000..5fdc0be --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/ValidationException.java
@@ -0,0 +1,48 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +/** + * Thrown when an attempt to validate a pooled object fails. + * + * @author Middleware Services + */ +public class ValidationException extends PoolException +{ + + /** serialVersionUID. */ + private static final long serialVersionUID = -5043560632396467010L; + + + /** + * Creates a new validation exception. + * + * @param msg describing this exception + */ + public ValidationException(final String msg) + { + super(msg); + } + + + /** + * Creates a new validation exception. + * + * @param e pooling specific exception + */ + public ValidationException(final Exception e) + { + super(e); + } + + + /** + * Creates a new validation exception. + * + * @param msg describing this exception + * @param e pooling specific exception + */ + public ValidationException(final String msg, final Exception e) + { + super(msg, e); + } +}
diff --git a/core/src/main/java/org/ldaptive/pool/Validator.java b/core/src/main/java/org/ldaptive/pool/Validator.java new file mode 100644 index 0000000..f0cfe12 --- /dev/null +++ b/core/src/main/java/org/ldaptive/pool/Validator.java
@@ -0,0 +1,23 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +/** + * Provides an interface for validating objects when they are in the pool. + * + * @param <T> type of object being pooled + * + * @author Middleware Services + */ +public interface Validator<T> +{ + + + /** + * Validate the supplied object. + * + * @param t object + * + * @return whether validation was successful + */ + boolean validate(T t); +}
diff --git a/core/src/main/java/org/ldaptive/props/AbstractPropertyInvoker.java b/core/src/main/java/org/ldaptive/props/AbstractPropertyInvoker.java new file mode 100644 index 0000000..6411c96 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/AbstractPropertyInvoker.java
@@ -0,0 +1,414 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.time.Duration; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides methods common to property invokers. + * + * @author Middleware Services + */ +public abstract class AbstractPropertyInvoker implements PropertyInvoker +{ + + /** Cache of properties. */ + private static final Map<String, Map<String, Method[]>> PROPERTIES_CACHE = new HashMap<>(); + + /** Class to invoke methods on. */ + private Class<?> clazz; + + /** Map of all properties to their getter and setter methods. */ + private Map<String, Method[]> properties; + + + /** + * Initializes the properties cache with the supplied class. The cache contains a map of properties to an array of the + * setter and getter methods. If a method named 'initialize' is found, it is also cached. + * + * @param c to read methods from + */ + protected synchronized void initialize(final Class<?> c) + { + final String cacheKey = c.getName(); + if (PROPERTIES_CACHE.containsKey(cacheKey)) { + properties = PROPERTIES_CACHE.get(cacheKey); + } else { + properties = new HashMap<>(); + for (Method method : c.getMethods()) { + if (!method.isBridge()) { + if (method.getName().startsWith("set") && method.getParameterTypes().length == 1) { + final String mName = method.getName().substring(3); + final String pName = mName.substring(0, 1).toLowerCase() + mName.substring(1, mName.length()); + if (properties.containsKey(pName)) { + final Method[] m = properties.get(pName); + m[1] = method; + properties.put(pName, m); + } else { + properties.put(pName, new Method[] {null, method}); + } + } else if (method.getName().startsWith("get") && method.getParameterTypes().length == 0) { + final String mName = method.getName().substring(3); + final String pName = mName.substring(0, 1).toLowerCase() + mName.substring(1, mName.length()); + if (properties.containsKey(pName)) { + final Method[] m = properties.get(pName); + m[0] = method; + properties.put(pName, m); + } else { + properties.put(pName, new Method[] {method, null}); + } + } else if (method.getName().startsWith("is") && method.getParameterTypes().length == 0) { + final String mName = method.getName().substring(2); + final String pName = mName.substring(0, 1).toLowerCase() + mName.substring(1, mName.length()); + if (properties.containsKey(pName)) { + final Method[] m = properties.get(pName); + // prefer any get method that may exist + if (m[0] == null) { + m[0] = method; + properties.put(pName, m); + } + } else { + properties.put(pName, new Method[] {method, null}); + } + } else if ("initialize".equals(method.getName()) && method.getParameterTypes().length == 0) { + final String pName = method.getName(); + properties.put(pName, new Method[] {method, method}); + } + } + } + + // remove any properties that don't have both getters and setters + final Iterator<Method[]> i = properties.values().iterator(); + while (i.hasNext()) { + final Method[] m = i.next(); + if (m[0] == null || m[1] == null) { + i.remove(); + } + } + + PROPERTIES_CACHE.put(cacheKey, Collections.unmodifiableMap(properties)); + } + clazz = c; + } + + + /** + * This invokes the setter method for the supplied property name with the supplied value. + * + * @param object to invoke method on + * @param name of the property + * @param value of the property + * + * @throws IllegalArgumentException if an invocation exception occurs + */ + @Override + public void setProperty(final Object object, final String name, final String value) + { + if (!clazz.isInstance(object)) { + throw new IllegalArgumentException( + "Illegal attempt to set property for class " + clazz.getName() + " on object of type " + + object.getClass().getName()); + } + + final Method getter = properties.get(name) != null ? properties.get(name)[0] : null; + if (getter == null) { + throw new IllegalArgumentException("No getter method found for " + name + " on object " + clazz.getName()); + } + + final Method setter = properties.get(name) != null ? properties.get(name)[1] : null; + if (setter == null) { + throw new IllegalArgumentException("No setter method found for " + name + " on object " + clazz.getName()); + } + + invokeMethod(setter, object, convertValue(getter.getReturnType(), value)); + } + + + /** + * Converts the supplied string value into an Object of the supplied type. If value cannot be converted it is returned + * as is. + * + * @param type of object to convert value into + * @param value to parse + * + * @return object of the supplied type + */ + protected abstract Object convertValue(final Class<?> type, final String value); + + + /** + * Returns whether the supplied property exists for this invoker. + * + * @param name to check + * + * @return whether the supplied property exists + */ + @Override + public boolean hasProperty(final String name) + { + return properties.containsKey(name); + } + + + /** + * Returns the property keys for this invoker. + * + * @return set of property names + */ + @Override + public Set<String> getProperties() + { + return Collections.unmodifiableSet(properties.keySet()); + } + + + /** + * Creates an instance of the supplied type. + * + * @param <T> type of class returned + * @param type of class to create + * @param className to create + * + * @return class of type T + * + * @throws IllegalArgumentException if the supplied class name cannot create a new instance of T + */ + public static <T> T instantiateType(final T type, final String className) + { + try { + try { + final Class<?> clazz = createClass(className); + final Constructor<?> con = clazz.getDeclaredConstructor((Class[]) null); + @SuppressWarnings("unchecked") + final T t = (T) con.newInstance(); + return t; + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) { + throw new IllegalArgumentException(e); + } + } catch (RuntimeException e) { + final Logger l = LoggerFactory.getLogger(AbstractPropertyInvoker.class); + l.error("Error instantiating type {}, with {}", type, className); + throw e; + } + } + + + /** + * Creates the class with the supplied name. + * + * @param className to create + * + * @return class + * + * @throws IllegalArgumentException if the supplied class name cannot be created + */ + public static Class<?> createClass(final String className) + { + try { + return Class.forName(className); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException(String.format("Could not find class '%s'", className), e); + } + } + + + /** + * Converts simple types that are common to all property invokers. If value cannot be converted it is returned as is. + * + * @param type of object to convert value into + * @param value to parse + * + * @return object of the supplied type + */ + protected Object convertSimpleType(final Class<?> type, final String value) + { + Object newValue = value; + if (Class.class.isAssignableFrom(type)) { + newValue = createTypeFromPropertyValue(Class.class, value); + } else if (Class[].class.isAssignableFrom(type)) { + newValue = createArrayTypeFromPropertyValue(Class.class, value); + } else if (type.isEnum()) { + newValue = getEnum(type, value); + } else if (String[].class == type) { + newValue = value.split(","); + } else if (Object[].class == type) { + newValue = value.split(","); + } else if (float.class == type) { + newValue = Float.parseFloat(value); + } else if (int.class == type) { + newValue = Integer.parseInt(value); + } else if (long.class == type) { + newValue = Long.parseLong(value); + } else if (short.class == type) { + newValue = Short.parseShort(value); + } else if (double.class == type) { + newValue = Double.parseDouble(value); + } else if (boolean.class == type) { + newValue = Boolean.valueOf(value); + } else if (Duration.class == type) { + newValue = Duration.parse(value); + } + return newValue; + } + + + /** + * Returns the enum for the supplied type and value. + * + * @param clazz of the enum + * @param value of the enum + * + * @return enum that matches the supplied value + */ + protected static Enum<?> getEnum(final Class<?> clazz, final String value) + { + for (Object o : clazz.getEnumConstants()) { + final Enum<?> e = (Enum<?>) o; + if (e.name().equals(value)) { + return e; + } + } + throw new IllegalArgumentException(String.format("Unknown enum value %s for %s", value, clazz)); + } + + + /** + * Returns the object which represents the supplied class given the supplied string representation. + * + * @param c type to instantiate + * @param s property value to parse + * + * @return the supplied type or null + */ + protected Object createTypeFromPropertyValue(final Class<?> c, final String s) + { + Object newObject; + if ("null".equals(s)) { + newObject = null; + } else { + if (PropertyValueParser.isConfig(s)) { + final PropertyValueParser configParser = new PropertyValueParser(s); + newObject = configParser.initializeType(); + } else { + if (Class.class == c) { + newObject = createClass(s); + } else { + newObject = instantiateType(c, s); + } + } + } + return newObject; + } + + + /** + * Returns the object which represents an array of the supplied class given the supplied string representation. + * + * @param c type to instantiate + * @param s property value to parse + * + * @return an array or null + */ + protected Object createArrayTypeFromPropertyValue(final Class<?> c, final String s) + { + Object newObject; + if ("null".equals(s)) { + newObject = null; + } else { + if (s.contains("},")) { + final String[] classes = s.split("\\},"); + newObject = Array.newInstance(c, classes.length); + for (int i = 0; i < classes.length; i++) { + classes[i] = classes[i] + "}"; + if (PropertyValueParser.isConfig(classes[i])) { + final PropertyValueParser configParser = new PropertyValueParser(classes[i]); + Array.set(newObject, i, configParser.initializeType()); + } else { + throw new IllegalArgumentException(String.format("Could not parse property string: %s", classes[i])); + } + } + } else { + final String[] classes = s.split(","); + newObject = Array.newInstance(c, classes.length); + for (int i = 0; i < classes.length; i++) { + if (PropertyValueParser.isConfig(classes[i])) { + final PropertyValueParser configParser = new PropertyValueParser(classes[i]); + Array.set(newObject, i, configParser.initializeType()); + } else { + if (Class.class == c) { + Array.set(newObject, i, createClass(classes[i])); + } else { + Array.set(newObject, i, instantiateType(c, classes[i])); + } + } + } + } + } + return newObject; + } + + + /** + * Returns the enum array which represents the supplied class given the supplied string representation. + * + * @param c type to instantiate + * @param s property value to parse + * + * @return Enum[] of the supplied type or null + */ + protected Object createArrayEnumFromPropertyValue(final Class<?> c, final String s) + { + Object newObject; + if ("null".equals(s)) { + newObject = null; + } else { + final String[] values = s.split(","); + newObject = Array.newInstance(c, values.length); + for (int i = 0; i < values.length; i++) { + Array.set(newObject, i, getEnum(c, values[i])); + } + } + return newObject; + } + + + /** + * Invokes the supplied method on the supplied object with the supplied argument. + * + * @param method to invoke + * @param object to invoke method on + * @param arg to invoke method with + * + * @return object produced by the invocation + * + * @throws IllegalArgumentException if an error occurs invoking the method + */ + public static Object invokeMethod(final Method method, final Object object, final Object arg) + { + try { + try { + Object[] params = new Object[] {arg}; + if (arg == null && method.getParameterTypes().length == 0) { + params = null; + } + return method.invoke(object, params); + } catch (InvocationTargetException | IllegalAccessException e) { + throw new IllegalArgumentException(e); + } + } catch (RuntimeException e) { + final Logger l = LoggerFactory.getLogger(AbstractPropertyInvoker.class); + l.error("Error invoking {}, on {}, with params {}", method, object, arg); + throw e; + } + } +}
diff --git a/core/src/main/java/org/ldaptive/props/AbstractPropertySource.java b/core/src/main/java/org/ldaptive/props/AbstractPropertySource.java new file mode 100644 index 0000000..a41c685 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/AbstractPropertySource.java
@@ -0,0 +1,147 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import org.ldaptive.LdapUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides methods common to property source implementations. + * + * @param <T> type of object to invoke properties on + * + * @author Middleware Services + */ +public abstract class AbstractPropertySource<T> implements PropertySource<T> +{ + + /** Default file to read properties from, value is {@value}. */ + public static final String PROPERTIES_FILE = "classpath:/org/ldaptive/ldap.properties"; + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Object to initialize with properties. */ + protected final T object; + + /** Domain that properties are in. */ + protected final PropertyDomain propertiesDomain; + + /** Properties to set. */ + protected final Properties properties; + + /** Properties that are not in the ldaptive domain. */ + protected final Map<String, Object> extraProps = new HashMap<>(); + + + /** + * Creates a new abstract property source. + * + * @param t to set properties on + * @param pd domain that properties reside in + * @param p properties to set + */ + public AbstractPropertySource(final T t, final PropertyDomain pd, final Properties p) + { + object = t; + propertiesDomain = pd; + properties = p; + } + + + /** + * Creates properties from the supplied file paths. See {@link #loadProperties(Reader...)}. + * + * @param paths to read properties from + * + * @return initialized properties object. + */ + protected static Properties loadProperties(final String... paths) + { + try { + final Reader[] readers = new Reader[paths.length]; + for (int i = 0; i < paths.length; i++) { + readers[i] = new InputStreamReader(LdapUtils.getResource(paths[i])); + } + return loadProperties(readers); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + + + /** + * Creates properties from the supplied reader. See {@link Properties#load(Reader)}. Readers supplied to this method + * will be closed. + * + * @param readers to read properties from + * + * @return initialized properties object. + */ + protected static Properties loadProperties(final Reader... readers) + { + try { + final Properties properties = new Properties(); + for (Reader r : readers) { + try { + properties.load(r); + } finally { + r.close(); + } + } + return properties; + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + + + /** + * Iterates over the properties and uses the invoker to set those properties on the object. Any properties that do not + * belong to the object are set in the extraProps map. + * + * @param invoker to set properties on the object + */ + protected void initializeObject(final PropertyInvoker invoker) + { + final Map<String, String> props = new HashMap<>(); + final Enumeration<?> en = properties.keys(); + if (en != null) { + while (en.hasMoreElements()) { + final String name = (String) en.nextElement(); + final String value = (String) properties.get(name); + // add to provider specific properties if it isn't an ldaptive property + if (!name.startsWith(PropertyDomain.LDAP.value())) { + extraProps.put(name, value); + } else { + // strip out the method name + final int split = name.lastIndexOf('.') + 1; + final String propName = name.substring(split); + final String propDomain = name.substring(0, split); + // if we have this property, set it last + if (propertiesDomain.value().equals(propDomain)) { + if (invoker.hasProperty(propName)) { + props.put(propName, value); + } + // check if this is a super class property + // if it is, set it now, it may be overridden with the props map + } else if (propertiesDomain.value().startsWith(propDomain)) { + if (invoker.hasProperty(propName)) { + invoker.setProperty(object, propName, value); + } + } + } + } + for (Map.Entry<String, String> entry : props.entrySet()) { + invoker.setProperty(object, entry.getKey(), entry.getValue()); + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/props/AuthenticationRequestPropertyInvoker.java b/core/src/main/java/org/ldaptive/props/AuthenticationRequestPropertyInvoker.java new file mode 100644 index 0000000..89a54c7 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/AuthenticationRequestPropertyInvoker.java
@@ -0,0 +1,49 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.IOException; +import org.ldaptive.Credential; +import org.ldaptive.LdapUtils; + +/** + * Handles properties for {@link org.ldaptive.auth.AuthenticationRequest}. + * + * @author Middleware Services + */ +public class AuthenticationRequestPropertyInvoker extends AbstractPropertyInvoker +{ + + + /** + * Creates a new authentication request property invoker for the supplied class. + * + * @param c class that has setter methods + */ + public AuthenticationRequestPropertyInvoker(final Class<?> c) + { + initialize(c); + } + + + @Override + protected Object convertValue(final Class<?> type, final String value) + { + Object newValue = value; + if (type != String.class) { + if (Credential.class.isAssignableFrom(type)) { + if (LdapUtils.isResource(value)) { + try { + newValue = new Credential(LdapUtils.readInputStream(LdapUtils.getResource(value))); + } catch (IOException e) { + throw new IllegalArgumentException("Could not read resource: " + value, e); + } + } else { + newValue = new Credential(value); + } + } else { + newValue = convertSimpleType(type, value); + } + } + return newValue; + } +}
diff --git a/core/src/main/java/org/ldaptive/props/AuthenticationRequestPropertySource.java b/core/src/main/java/org/ldaptive/props/AuthenticationRequestPropertySource.java new file mode 100644 index 0000000..b85942b --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/AuthenticationRequestPropertySource.java
@@ -0,0 +1,102 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.Reader; +import java.util.Properties; +import java.util.Set; +import org.ldaptive.auth.AuthenticationRequest; + +/** + * Reads properties specific to {@link org.ldaptive.auth.AuthenticationRequest} and returns an initialized object of + * that type. + * + * @author Middleware Services + */ +public final class AuthenticationRequestPropertySource extends AbstractPropertySource<AuthenticationRequest> +{ + + /** Invoker for authentication request. */ + private static final AuthenticationRequestPropertyInvoker INVOKER = new AuthenticationRequestPropertyInvoker( + AuthenticationRequest.class); + + + /** + * Creates a new authentication request property source using the default properties file. + * + * @param request authentication request to set properties on + */ + public AuthenticationRequestPropertySource(final AuthenticationRequest request) + { + this(request, PROPERTIES_FILE); + } + + + /** + * Creates a new authentication request property source. + * + * @param request authentication request to set properties on + * @param paths to read properties from + */ + public AuthenticationRequestPropertySource(final AuthenticationRequest request, final String... paths) + { + this(request, loadProperties(paths)); + } + + + /** + * Creates a new authentication request property source. + * + * @param request authentication request to set properties on + * @param readers to read properties from + */ + public AuthenticationRequestPropertySource(final AuthenticationRequest request, final Reader... readers) + { + this(request, loadProperties(readers)); + } + + + /** + * Creates a new authentication request property source. + * + * @param request authentication request to set properties on + * @param props to read properties from + */ + public AuthenticationRequestPropertySource(final AuthenticationRequest request, final Properties props) + { + this(request, PropertyDomain.AUTH, props); + } + + + /** + * Creates a new authentication request property source. + * + * @param request authentication request to set properties on + * @param domain that properties are in + * @param props to read properties from + */ + public AuthenticationRequestPropertySource( + final AuthenticationRequest request, + final PropertyDomain domain, + final Properties props) + { + super(request, domain, props); + } + + + @Override + public void initialize() + { + initializeObject(INVOKER); + } + + + /** + * Returns the property names for this property source. + * + * @return all property names + */ + public static Set<String> getProperties() + { + return INVOKER.getProperties(); + } +}
diff --git a/core/src/main/java/org/ldaptive/props/AuthenticatorPropertyInvoker.java b/core/src/main/java/org/ldaptive/props/AuthenticatorPropertyInvoker.java new file mode 100644 index 0000000..b6777ba --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/AuthenticatorPropertyInvoker.java
@@ -0,0 +1,48 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import org.ldaptive.auth.AuthenticationHandler; +import org.ldaptive.auth.AuthenticationResponseHandler; +import org.ldaptive.auth.DnResolver; +import org.ldaptive.auth.EntryResolver; + +/** + * Handles properties for {@link org.ldaptive.auth.Authenticator}. + * + * @author Middleware Services + */ +public class AuthenticatorPropertyInvoker extends AbstractPropertyInvoker +{ + + + /** + * Creates a new authenticator property invoker for the supplied class. + * + * @param c class that has setter methods + */ + public AuthenticatorPropertyInvoker(final Class<?> c) + { + initialize(c); + } + + + @Override + protected Object convertValue(final Class<?> type, final String value) + { + Object newValue = value; + if (type != String.class) { + if (DnResolver.class.isAssignableFrom(type)) { + newValue = createTypeFromPropertyValue(DnResolver.class, value); + } else if (AuthenticationHandler.class.isAssignableFrom(type)) { + newValue = createTypeFromPropertyValue(AuthenticationHandler.class, value); + } else if (AuthenticationResponseHandler[].class.isAssignableFrom(type)) { + newValue = createArrayTypeFromPropertyValue(AuthenticationResponseHandler.class, value); + } else if (EntryResolver.class.isAssignableFrom(type)) { + newValue = createTypeFromPropertyValue(EntryResolver.class, value); + } else { + newValue = convertSimpleType(type, value); + } + } + return newValue; + } +}
diff --git a/core/src/main/java/org/ldaptive/props/AuthenticatorPropertySource.java b/core/src/main/java/org/ldaptive/props/AuthenticatorPropertySource.java new file mode 100644 index 0000000..7ab847e --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/AuthenticatorPropertySource.java
@@ -0,0 +1,201 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.Reader; +import java.util.Properties; +import java.util.Set; +import org.ldaptive.ConnectionFactoryManager; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.auth.AuthenticationHandler; +import org.ldaptive.auth.Authenticator; +import org.ldaptive.auth.BindAuthenticationHandler; +import org.ldaptive.auth.DnResolver; +import org.ldaptive.auth.SearchDnResolver; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.pool.PooledConnectionFactoryManager; + +/** + * Reads properties specific to {@link org.ldaptive.auth.Authenticator} and returns an initialized object of that type. + * + * @author Middleware Services + */ +public final class AuthenticatorPropertySource extends AbstractPropertySource<Authenticator> +{ + + /** Invoker for authenticator. */ + private static final AuthenticatorPropertyInvoker INVOKER = new AuthenticatorPropertyInvoker(Authenticator.class); + + + /** + * Creates a new authenticator property source using the default properties file. + * + * @param a authenticator to set properties on + */ + public AuthenticatorPropertySource(final Authenticator a) + { + this(a, PROPERTIES_FILE); + } + + + /** + * Creates a new authenticator property source. + * + * @param a authenticator to set properties on + * @param paths to read properties from + */ + public AuthenticatorPropertySource(final Authenticator a, final String... paths) + { + this(a, loadProperties(paths)); + } + + + /** + * Creates a new authenticator property source. + * + * @param a authenticator to set properties on + * @param readers to read properties from + */ + public AuthenticatorPropertySource(final Authenticator a, final Reader... readers) + { + this(a, loadProperties(readers)); + } + + + /** + * Creates a new authenticator property source. + * + * @param a authenticator to set properties on + * @param props to read properties from + */ + public AuthenticatorPropertySource(final Authenticator a, final Properties props) + { + this(a, PropertyDomain.AUTH, props); + } + + + /** + * Creates a new authenticator property source. + * + * @param a authenticator to set properties on + * @param domain that properties are in + * @param props to read properties from + */ + public AuthenticatorPropertySource(final Authenticator a, final PropertyDomain domain, final Properties props) + { + super(a, domain, props); + } + + + @Override + public void initialize() + { + initializeObject(INVOKER); + + // initialize a SearchDnResolver by default + DnResolver dnResolver = object.getDnResolver(); + if (dnResolver == null) { + dnResolver = new SearchDnResolver(); + + final SearchDnResolverPropertySource dnPropSource = new SearchDnResolverPropertySource( + (SearchDnResolver) dnResolver, + propertiesDomain, + properties); + dnPropSource.initialize(); + object.setDnResolver(dnResolver); + } else { + final SimplePropertySource<DnResolver> sPropSource = new SimplePropertySource<>( + dnResolver, + propertiesDomain, + properties); + sPropSource.initialize(); + } + if (dnResolver instanceof PooledConnectionFactoryManager) { + final PooledConnectionFactoryManager cfm = (PooledConnectionFactoryManager) dnResolver; + if (cfm.getConnectionFactory() == null) { + initPooledConnectionFactoryManager(cfm); + } + } + if (dnResolver instanceof ConnectionFactoryManager) { + final ConnectionFactoryManager cfm = (ConnectionFactoryManager) dnResolver; + if (cfm.getConnectionFactory() == null) { + initConnectionFactoryManager(cfm); + } + } + + // initialize a BindAuthenticationHandler by default + AuthenticationHandler authHandler = object.getAuthenticationHandler(); + if (authHandler == null) { + authHandler = new BindAuthenticationHandler(); + + final BindAuthenticationHandlerPropertySource ahPropSource = new BindAuthenticationHandlerPropertySource( + (BindAuthenticationHandler) authHandler, + propertiesDomain, + properties); + ahPropSource.initialize(); + object.setAuthenticationHandler(authHandler); + } else { + final SimplePropertySource<AuthenticationHandler> sPropSource = new SimplePropertySource<>( + authHandler, + propertiesDomain, + properties); + sPropSource.initialize(); + } + if (authHandler instanceof PooledConnectionFactoryManager) { + final PooledConnectionFactoryManager cfm = (PooledConnectionFactoryManager) authHandler; + if (cfm.getConnectionFactory() == null) { + initPooledConnectionFactoryManager(cfm); + } + } + if (authHandler instanceof ConnectionFactoryManager) { + final ConnectionFactoryManager cfm = (ConnectionFactoryManager) authHandler; + if (cfm.getConnectionFactory() == null) { + initConnectionFactoryManager(cfm); + } + } + } + + + /** + * Initializes the supplied connection factory manager using the properties in this property source. + * + * @param cfm to initialize + */ + private void initConnectionFactoryManager(final ConnectionFactoryManager cfm) + { + final DefaultConnectionFactory cf = new DefaultConnectionFactory(); + final DefaultConnectionFactoryPropertySource cfPropSource = new DefaultConnectionFactoryPropertySource( + cf, + propertiesDomain, + properties); + cfPropSource.initialize(); + cfm.setConnectionFactory(cf); + } + + + /** + * Initializes the supplied connection factory manager using the properties in this property source. + * + * @param cfm to initialize + */ + private void initPooledConnectionFactoryManager(final PooledConnectionFactoryManager cfm) + { + final PooledConnectionFactory cf = new PooledConnectionFactory(); + final PooledConnectionFactoryPropertySource cfPropSource = new PooledConnectionFactoryPropertySource( + cf, + propertiesDomain, + properties); + cfPropSource.initialize(); + cfm.setConnectionFactory(cf); + } + + + /** + * Returns the property names for this property source. + * + * @return all property names + */ + public static Set<String> getProperties() + { + return INVOKER.getProperties(); + } +}
diff --git a/core/src/main/java/org/ldaptive/props/BindAuthenticationHandlerPropertyInvoker.java b/core/src/main/java/org/ldaptive/props/BindAuthenticationHandlerPropertyInvoker.java new file mode 100644 index 0000000..f0a64c5 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/BindAuthenticationHandlerPropertyInvoker.java
@@ -0,0 +1,54 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import org.ldaptive.control.RequestControl; +import org.ldaptive.sasl.SaslConfig; + +/** + * Handles properties for {@link org.ldaptive.auth.BindAuthenticationHandler}. + * + * @author Middleware Services + */ +public class BindAuthenticationHandlerPropertyInvoker extends AbstractPropertyInvoker +{ + + + /** + * Creates a new bind authentication handler property invoker for the supplied class. + * + * @param c class that has setter methods + */ + public BindAuthenticationHandlerPropertyInvoker(final Class<?> c) + { + initialize(c); + } + + + @Override + protected Object convertValue(final Class<?> type, final String value) + { + Object newValue = value; + if (type != String.class) { + if (SaslConfig.class.isAssignableFrom(type)) { + if ("null".equals(value)) { + newValue = null; + } else { + if (PropertyValueParser.isParamsOnlyConfig(value)) { + final PropertyValueParser configParser = new PropertyValueParser(value, "org.ldaptive.sasl.SaslConfig"); + newValue = configParser.initializeType(); + } else if (PropertyValueParser.isConfig(value)) { + final PropertyValueParser configParser = new PropertyValueParser(value); + newValue = configParser.initializeType(); + } else { + newValue = instantiateType(SaslConfig.class, value); + } + } + } else if (RequestControl[].class.isAssignableFrom(type)) { + newValue = createArrayTypeFromPropertyValue(RequestControl.class, value); + } else { + newValue = convertSimpleType(type, value); + } + } + return newValue; + } +}
diff --git a/core/src/main/java/org/ldaptive/props/BindAuthenticationHandlerPropertySource.java b/core/src/main/java/org/ldaptive/props/BindAuthenticationHandlerPropertySource.java new file mode 100644 index 0000000..3a717df --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/BindAuthenticationHandlerPropertySource.java
@@ -0,0 +1,101 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.Reader; +import java.util.Properties; +import java.util.Set; +import org.ldaptive.auth.BindAuthenticationHandler; + +/** + * Reads properties specific to {@link BindAuthenticationHandler} and returns an initialized object of that type. + * + * @author Middleware Services + */ +public final class BindAuthenticationHandlerPropertySource extends AbstractPropertySource<BindAuthenticationHandler> +{ + + /** Invoker for bind authentication handler. */ + private static final BindAuthenticationHandlerPropertyInvoker INVOKER = new BindAuthenticationHandlerPropertyInvoker( + BindAuthenticationHandler.class); + + + /** + * Creates a new bind authentication handler property source using the default properties file. + * + * @param handler bind authentication handler to invoke properties on + */ + public BindAuthenticationHandlerPropertySource(final BindAuthenticationHandler handler) + { + this(handler, PROPERTIES_FILE); + } + + + /** + * Creates a new bind authentication handler property source. + * + * @param handler bind authentication handler to invoke properties on + * @param paths to read properties from + */ + public BindAuthenticationHandlerPropertySource(final BindAuthenticationHandler handler, final String... paths) + { + this(handler, loadProperties(paths)); + } + + + /** + * Creates a new bind authentication handler property source. + * + * @param handler bind authentication handler to invoke properties on + * @param readers to read properties from + */ + public BindAuthenticationHandlerPropertySource(final BindAuthenticationHandler handler, final Reader... readers) + { + this(handler, loadProperties(readers)); + } + + + /** + * Creates a new bind authentication handler property source. + * + * @param handler bind authentication handler to invoke properties on + * @param props to read properties from + */ + public BindAuthenticationHandlerPropertySource(final BindAuthenticationHandler handler, final Properties props) + { + this(handler, PropertyDomain.AUTH, props); + } + + + /** + * Creates a new bind authentication handler property source. + * + * @param handler bind authentication handler to invoke properties on + * @param domain that properties are in + * @param props to read properties from + */ + public BindAuthenticationHandlerPropertySource( + final BindAuthenticationHandler handler, + final PropertyDomain domain, + final Properties props) + { + super(handler, domain, props); + } + + + @Override + public void initialize() + { + initializeObject(INVOKER); + } + + + /** + * Returns the property names for this property source. + * + * @return all property names + */ + public static Set<String> getProperties() + { + return INVOKER.getProperties(); + } +}
diff --git a/core/src/main/java/org/ldaptive/props/BindConnectionInitializerPropertyInvoker.java b/core/src/main/java/org/ldaptive/props/BindConnectionInitializerPropertyInvoker.java new file mode 100644 index 0000000..0df1e1d --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/BindConnectionInitializerPropertyInvoker.java
@@ -0,0 +1,67 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.IOException; +import org.ldaptive.Credential; +import org.ldaptive.LdapUtils; +import org.ldaptive.control.RequestControl; +import org.ldaptive.sasl.SaslConfig; + +/** + * Handles properties for {@link org.ldaptive.BindConnectionInitializer}. + * + * @author Middleware Services + */ +public class BindConnectionInitializerPropertyInvoker extends AbstractPropertyInvoker +{ + + + /** + * Creates a new bind connection initializer property invoker for the supplied class. + * + * @param c class that has setter methods + */ + public BindConnectionInitializerPropertyInvoker(final Class<?> c) + { + initialize(c); + } + + + @Override + protected Object convertValue(final Class<?> type, final String value) + { + Object newValue = value; + if (type != String.class) { + if (SaslConfig.class.isAssignableFrom(type)) { + if ("null".equals(value)) { + newValue = null; + } else { + if (PropertyValueParser.isParamsOnlyConfig(value)) { + final PropertyValueParser configParser = new PropertyValueParser(value, "org.ldaptive.sasl.SaslConfig"); + newValue = configParser.initializeType(); + } else if (PropertyValueParser.isConfig(value)) { + final PropertyValueParser configParser = new PropertyValueParser(value); + newValue = configParser.initializeType(); + } else { + newValue = instantiateType(SaslConfig.class, value); + } + } + } else if (RequestControl[].class.isAssignableFrom(type)) { + newValue = createArrayTypeFromPropertyValue(RequestControl.class, value); + } else if (Credential.class.isAssignableFrom(type)) { + if (LdapUtils.isResource(value)) { + try { + newValue = new Credential(LdapUtils.readInputStream(LdapUtils.getResource(value))); + } catch (IOException e) { + throw new IllegalArgumentException("Could not read resource: " + value, e); + } + } else { + newValue = new Credential(value); + } + } else { + newValue = convertSimpleType(type, value); + } + } + return newValue; + } +}
diff --git a/core/src/main/java/org/ldaptive/props/BindConnectionInitializerPropertySource.java b/core/src/main/java/org/ldaptive/props/BindConnectionInitializerPropertySource.java new file mode 100644 index 0000000..9cd7f8e --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/BindConnectionInitializerPropertySource.java
@@ -0,0 +1,101 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.Reader; +import java.util.Properties; +import java.util.Set; +import org.ldaptive.BindConnectionInitializer; + +/** + * Reads properties specific to {@link BindConnectionInitializer} and returns an initialized object of that type. + * + * @author Middleware Services + */ +public final class BindConnectionInitializerPropertySource extends AbstractPropertySource<BindConnectionInitializer> +{ + + /** Invoker for bind connection initializer. */ + private static final BindConnectionInitializerPropertyInvoker INVOKER = new BindConnectionInitializerPropertyInvoker( + BindConnectionInitializer.class); + + + /** + * Creates a new bind connection initializer property source using the default properties file. + * + * @param initializer bind connection initializer to invoke properties on + */ + public BindConnectionInitializerPropertySource(final BindConnectionInitializer initializer) + { + this(initializer, PROPERTIES_FILE); + } + + + /** + * Creates a new bind connection initializer property source. + * + * @param initializer bind connection initializer to invoke properties on + * @param paths to read properties from + */ + public BindConnectionInitializerPropertySource(final BindConnectionInitializer initializer, final String... paths) + { + this(initializer, loadProperties(paths)); + } + + + /** + * Creates a new bind connection initializer property source. + * + * @param initializer bind connection initializer to invoke properties on + * @param readers to read properties from + */ + public BindConnectionInitializerPropertySource(final BindConnectionInitializer initializer, final Reader... readers) + { + this(initializer, loadProperties(readers)); + } + + + /** + * Creates a new bind connection initializer property source. + * + * @param initializer bind connection initializer to invoke properties on + * @param props to read properties from + */ + public BindConnectionInitializerPropertySource(final BindConnectionInitializer initializer, final Properties props) + { + this(initializer, PropertyDomain.LDAP, props); + } + + + /** + * Creates a new bind connection initializer property source. + * + * @param initializer bind connection initializer to invoke properties on + * @param domain that properties are in + * @param props to read properties from + */ + public BindConnectionInitializerPropertySource( + final BindConnectionInitializer initializer, + final PropertyDomain domain, + final Properties props) + { + super(initializer, domain, props); + } + + + @Override + public void initialize() + { + initializeObject(INVOKER); + } + + + /** + * Returns the property names for this property source. + * + * @return all property names + */ + public static Set<String> getProperties() + { + return INVOKER.getProperties(); + } +}
diff --git a/core/src/main/java/org/ldaptive/props/BlockingConnectionPoolPropertyInvoker.java b/core/src/main/java/org/ldaptive/props/BlockingConnectionPoolPropertyInvoker.java new file mode 100644 index 0000000..96f074f --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/BlockingConnectionPoolPropertyInvoker.java
@@ -0,0 +1,48 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import org.ldaptive.pool.Activator; +import org.ldaptive.pool.Passivator; +import org.ldaptive.pool.PruneStrategy; +import org.ldaptive.pool.Validator; + +/** + * Handles properties for {@link org.ldaptive.pool.BlockingConnectionPool}. + * + * @author Middleware Services + */ +public class BlockingConnectionPoolPropertyInvoker extends AbstractPropertyInvoker +{ + + + /** + * Creates a new blocking connection pool property invoker for the supplied class. + * + * @param c class that has setter methods + */ + public BlockingConnectionPoolPropertyInvoker(final Class<?> c) + { + initialize(c); + } + + + @Override + protected Object convertValue(final Class<?> type, final String value) + { + Object newValue = value; + if (type != String.class) { + if (Activator.class.isAssignableFrom(type)) { + newValue = createTypeFromPropertyValue(Activator.class, value); + } else if (Passivator.class.isAssignableFrom(type)) { + newValue = createTypeFromPropertyValue(Passivator.class, value); + } else if (PruneStrategy.class.isAssignableFrom(type)) { + newValue = createTypeFromPropertyValue(PruneStrategy.class, value); + } else if (Validator.class.isAssignableFrom(type)) { + newValue = createTypeFromPropertyValue(Validator.class, value); + } else { + newValue = convertSimpleType(type, value); + } + } + return newValue; + } +}
diff --git a/core/src/main/java/org/ldaptive/props/BlockingConnectionPoolPropertySource.java b/core/src/main/java/org/ldaptive/props/BlockingConnectionPoolPropertySource.java new file mode 100644 index 0000000..c35cfb9 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/BlockingConnectionPoolPropertySource.java
@@ -0,0 +1,127 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.Reader; +import java.util.Properties; +import java.util.Set; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.pool.BlockingConnectionPool; +import org.ldaptive.pool.PoolConfig; + +/** + * Reads properties specific to {@link BlockingConnectionPool} and returns an initialized object of that type. + * + * @author Middleware Services + */ +public final class BlockingConnectionPoolPropertySource extends AbstractPropertySource<BlockingConnectionPool> +{ + + /** Invoker for connection factory. */ + private static final BlockingConnectionPoolPropertyInvoker INVOKER = new BlockingConnectionPoolPropertyInvoker( + BlockingConnectionPool.class); + + + /** + * Creates a new blocking connection pool property source using the default properties file. + * + * @param cp connection pool to invoke properties on + */ + public BlockingConnectionPoolPropertySource(final BlockingConnectionPool cp) + { + this(cp, PROPERTIES_FILE); + } + + + /** + * Creates a new blocking connection pool property source. + * + * @param cp connection pool to invoke properties on + * @param paths to read properties from + */ + public BlockingConnectionPoolPropertySource(final BlockingConnectionPool cp, final String... paths) + { + this(cp, loadProperties(paths)); + } + + + /** + * Creates a new blocking connection pool property source. + * + * @param cp connection pool to invoke properties on + * @param readers to read properties from + */ + public BlockingConnectionPoolPropertySource(final BlockingConnectionPool cp, final Reader... readers) + { + this(cp, loadProperties(readers)); + } + + + /** + * Creates a new blocking connection pool property source. + * + * @param cp connection pool to invoke properties on + * @param props to read properties from + */ + public BlockingConnectionPoolPropertySource(final BlockingConnectionPool cp, final Properties props) + { + this(cp, PropertyDomain.POOL, props); + } + + + /** + * Creates a new blocking connection pool property source. + * + * @param cp connection pool to invoke properties on + * @param domain that properties are in + * @param props to read properties from + */ + public BlockingConnectionPoolPropertySource( + final BlockingConnectionPool cp, + final PropertyDomain domain, + final Properties props) + { + super(cp, domain, props); + } + + + @Override + public void initialize() + { + initializeObject(INVOKER); + + DefaultConnectionFactory cf = object.getConnectionFactory(); + if (cf == null) { + cf = new DefaultConnectionFactory(); + + final DefaultConnectionFactoryPropertySource cfPropSource = new DefaultConnectionFactoryPropertySource( + cf, + propertiesDomain, + properties); + cfPropSource.initialize(); + object.setConnectionFactory(cf); + } + + PoolConfig pc = object.getPoolConfig(); + if (pc == null) { + pc = new PoolConfig(); + + final PoolConfigPropertySource pcPropSource = new PoolConfigPropertySource(pc, propertiesDomain, properties); + pcPropSource.initialize(); + object.setPoolConfig(pc); + } else { + final SimplePropertySource<PoolConfig> sPropSource = new SimplePropertySource<>(pc, propertiesDomain, properties); + sPropSource.initialize(); + } + } + + + /** + * Returns the property names for this property source. + * + * @return all property names + */ + public static Set<String> getProperties() + { + return INVOKER.getProperties(); + } +}
diff --git a/core/src/main/java/org/ldaptive/props/ConnectionConfigPropertyInvoker.java b/core/src/main/java/org/ldaptive/props/ConnectionConfigPropertyInvoker.java new file mode 100644 index 0000000..8701670 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/ConnectionConfigPropertyInvoker.java
@@ -0,0 +1,56 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import org.ldaptive.ActivePassiveConnectionStrategy; +import org.ldaptive.ConnectionInitializer; +import org.ldaptive.ConnectionStrategy; +import org.ldaptive.DefaultConnectionStrategy; +import org.ldaptive.RandomConnectionStrategy; +import org.ldaptive.RoundRobinConnectionStrategy; + +/** + * Handles properties for {@link org.ldaptive.ConnectionConfig}. + * + * @author Middleware Services + */ +public class ConnectionConfigPropertyInvoker extends AbstractPropertyInvoker +{ + + + /** + * Creates a new connection config property invoker for the supplied class. + * + * @param c class that has setter methods + */ + public ConnectionConfigPropertyInvoker(final Class<?> c) + { + initialize(c); + } + + + @Override + protected Object convertValue(final Class<?> type, final String value) + { + Object newValue = value; + if (type != String.class) { + if (ConnectionInitializer.class.isAssignableFrom(type)) { + newValue = createTypeFromPropertyValue(ConnectionInitializer.class, value); + } else if (ConnectionStrategy.class.isAssignableFrom(type)) { + if ("DEFAULT".equals(value)) { + newValue = new DefaultConnectionStrategy(); + } else if ("ACTIVE_PASSIVE".equals(value)) { + newValue = new ActivePassiveConnectionStrategy(); + } else if ("ROUND_ROBIN".equals(value)) { + newValue = new RoundRobinConnectionStrategy(); + } else if ("RANDOM".equals(value)) { + newValue = new RandomConnectionStrategy(); + } else { + newValue = createTypeFromPropertyValue(ConnectionStrategy.class, value); + } + } else { + newValue = convertSimpleType(type, value); + } + } + return newValue; + } +}
diff --git a/core/src/main/java/org/ldaptive/props/ConnectionConfigPropertySource.java b/core/src/main/java/org/ldaptive/props/ConnectionConfigPropertySource.java new file mode 100644 index 0000000..d325be6 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/ConnectionConfigPropertySource.java
@@ -0,0 +1,137 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.Reader; +import java.util.Properties; +import java.util.Set; +import org.ldaptive.BindConnectionInitializer; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.ConnectionInitializer; +import org.ldaptive.ssl.SslConfig; + +/** + * Reads properties specific to {@link ConnectionConfig} and returns an initialized object of that type. + * + * @author Middleware Services + */ +public final class ConnectionConfigPropertySource extends AbstractPropertySource<ConnectionConfig> +{ + + /** Invoker for connection config. */ + private static final ConnectionConfigPropertyInvoker INVOKER = new ConnectionConfigPropertyInvoker( + ConnectionConfig.class); + + + /** + * Creates a new connection config property source using the default properties file. + * + * @param cc connection config to invoke properties on + */ + public ConnectionConfigPropertySource(final ConnectionConfig cc) + { + this(cc, PROPERTIES_FILE); + } + + + /** + * Creates a new connection config property source. + * + * @param cc connection config to invoke properties on + * @param paths to read properties from + */ + public ConnectionConfigPropertySource(final ConnectionConfig cc, final String... paths) + { + this(cc, loadProperties(paths)); + } + + + /** + * Creates a new connection config property source. + * + * @param cc connection config to invoke properties on + * @param readers to read properties from + */ + public ConnectionConfigPropertySource(final ConnectionConfig cc, final Reader... readers) + { + this(cc, loadProperties(readers)); + } + + + /** + * Creates a new connection config property source. + * + * @param cc connection config to invoke properties on + * @param props to read properties from + */ + public ConnectionConfigPropertySource(final ConnectionConfig cc, final Properties props) + { + this(cc, PropertyDomain.LDAP, props); + } + + + /** + * Creates a new connection config property source. + * + * @param cc connection config to invoke properties on + * @param domain that properties are in + * @param props to read properties from + */ + public ConnectionConfigPropertySource(final ConnectionConfig cc, final PropertyDomain domain, final Properties props) + { + super(cc, domain, props); + } + + + @Override + public void initialize() + { + initializeObject(INVOKER); + + SslConfig sc = object.getSslConfig(); + if (sc == null) { + sc = new SslConfig(); + + final SslConfigPropertySource scSource = new SslConfigPropertySource(sc, propertiesDomain, properties); + scSource.initialize(); + if (!sc.isEmpty()) { + object.setSslConfig(sc); + } + } else { + final SimplePropertySource<SslConfig> sPropSource = new SimplePropertySource<>(sc, propertiesDomain, properties); + sPropSource.initialize(); + } + + + final ConnectionInitializer ci = object.getConnectionInitializer(); + // configure a bind connection initializer if bind properties are found + if (ci == null) { + final BindConnectionInitializer bci = new BindConnectionInitializer(); + + final BindConnectionInitializerPropertySource bciSource = new BindConnectionInitializerPropertySource( + bci, + propertiesDomain, + properties); + bciSource.initialize(); + if (!bci.isEmpty()) { + object.setConnectionInitializer(bci); + } + } else { + final SimplePropertySource<ConnectionInitializer> sPropSource = new SimplePropertySource<>( + ci, + propertiesDomain, + properties); + sPropSource.initialize(); + } + } + + + /** + * Returns the property names for this property source. + * + * @return all property names + */ + public static Set<String> getProperties() + { + return INVOKER.getProperties(); + } +}
diff --git a/core/src/main/java/org/ldaptive/props/CredentialConfigParser.java b/core/src/main/java/org/ldaptive/props/CredentialConfigParser.java new file mode 100644 index 0000000..dfc74fb --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/CredentialConfigParser.java
@@ -0,0 +1,57 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.util.regex.Matcher; + +/** + * Parses the configuration data associated with credential configs. The format of the property string should be like: + * + * <pre> + KeyStoreCredentialConfig + {{trustStore=file:/tmp/my.truststore}{trustStoreType=JKS}} + * </pre> + * + * <p>or</p> + * + * <pre> + {{trustCertificates=file:/tmp/my.crt}} + * </pre> + * + * @author Middleware Services + */ +public class CredentialConfigParser extends PropertyValueParser +{ + + /** Credential config class found in the config. */ + protected static final String DEFAULT_CREDENTIAL_CONFIG_CLASS = "org.ldaptive.ssl.X509CredentialConfig"; + + + /** + * Creates a new credential config parser. + * + * @param config containing configuration data + */ + public CredentialConfigParser(final String config) + { + final Matcher credentialOnlyMatcher = CONFIG_PATTERN.matcher(config); + final Matcher paramsOnlyMatcher = PARAMS_ONLY_CONFIG_PATTERN.matcher(config); + if (credentialOnlyMatcher.matches()) { + initialize(credentialOnlyMatcher.group(1).trim(), credentialOnlyMatcher.group(2).trim()); + } else if (paramsOnlyMatcher.matches()) { + initialize(DEFAULT_CREDENTIAL_CONFIG_CLASS, paramsOnlyMatcher.group(1).trim()); + } + } + + + /** + * Returns whether the supplied configuration data contains a credential config. + * + * @param config containing configuration data + * + * @return whether the supplied configuration data contains a credential config + */ + public static boolean isCredentialConfig(final String config) + { + return isConfig(config) || isParamsOnlyConfig(config); + } +}
diff --git a/core/src/main/java/org/ldaptive/props/DefaultConnectionFactoryPropertyInvoker.java b/core/src/main/java/org/ldaptive/props/DefaultConnectionFactoryPropertyInvoker.java new file mode 100644 index 0000000..ce5def6 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/DefaultConnectionFactoryPropertyInvoker.java
@@ -0,0 +1,39 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import org.ldaptive.provider.Provider; + +/** + * Handles properties for {@link org.ldaptive.DefaultConnectionFactory}. + * + * @author Middleware Services + */ +public class DefaultConnectionFactoryPropertyInvoker extends AbstractPropertyInvoker +{ + + + /** + * Creates a new default connection factory property invoker for the supplied class. + * + * @param c class that has setter methods + */ + public DefaultConnectionFactoryPropertyInvoker(final Class<?> c) + { + initialize(c); + } + + + @Override + protected Object convertValue(final Class<?> type, final String value) + { + Object newValue = value; + if (type != String.class) { + if (Provider.class.isAssignableFrom(type)) { + newValue = createTypeFromPropertyValue(Provider.class, value); + } else { + newValue = convertSimpleType(type, value); + } + } + return newValue; + } +}
diff --git a/core/src/main/java/org/ldaptive/props/DefaultConnectionFactoryPropertySource.java b/core/src/main/java/org/ldaptive/props/DefaultConnectionFactoryPropertySource.java new file mode 100644 index 0000000..fc1563e --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/DefaultConnectionFactoryPropertySource.java
@@ -0,0 +1,129 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.Reader; +import java.util.Properties; +import java.util.Set; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.provider.ProviderConfig; + +/** + * Reads properties specific to {@link org.ldaptive.DefaultConnectionFactory} and returns an initialized object of that + * type. + * + * @author Middleware Services + */ +public final class DefaultConnectionFactoryPropertySource extends AbstractPropertySource<DefaultConnectionFactory> +{ + + /** Invoker for connection factory. */ + private static final DefaultConnectionFactoryPropertyInvoker INVOKER = new DefaultConnectionFactoryPropertyInvoker( + DefaultConnectionFactory.class); + + + /** + * Creates a new default connection factory property source using the default properties file. + * + * @param cf connection factory to invoke properties on + */ + public DefaultConnectionFactoryPropertySource(final DefaultConnectionFactory cf) + { + this(cf, PROPERTIES_FILE); + } + + + /** + * Creates a new default connection factory property source. + * + * @param cf connection factory to invoke properties on + * @param paths to read properties from + */ + public DefaultConnectionFactoryPropertySource(final DefaultConnectionFactory cf, final String... paths) + { + this(cf, loadProperties(paths)); + } + + + /** + * Creates a new default connection factory property source. + * + * @param cf connection factory to invoke properties on + * @param readers to read properties from + */ + public DefaultConnectionFactoryPropertySource(final DefaultConnectionFactory cf, final Reader... readers) + { + this(cf, loadProperties(readers)); + } + + + /** + * Creates a new default connection factory property source. + * + * @param cf connection factory to invoke properties on + * @param props to read properties from + */ + public DefaultConnectionFactoryPropertySource(final DefaultConnectionFactory cf, final Properties props) + { + this(cf, PropertyDomain.LDAP, props); + } + + + /** + * Creates a new default connection factory property source. + * + * @param cf connection factory to invoke properties on + * @param domain that properties are in + * @param props to read properties from + */ + public DefaultConnectionFactoryPropertySource( + final DefaultConnectionFactory cf, + final PropertyDomain domain, + final Properties props) + { + super(cf, domain, props); + } + + + @Override + @SuppressWarnings("unchecked") + public void initialize() + { + initializeObject(INVOKER); + + final ConnectionConfig cc = new ConnectionConfig(); + final ConnectionConfigPropertySource ccPropSource = new ConnectionConfigPropertySource( + cc, + propertiesDomain, + properties); + ccPropSource.initialize(); + object.setConnectionConfig(cc); + + final ProviderConfig pc = new ProviderConfig(); + final ProviderConfigPropertySource pcPropSource = new ProviderConfigPropertySource( + pc, + propertiesDomain, + properties); + pcPropSource.initialize(); + if (pc.getOperationExceptionResultCodes() != null) { + object.getProvider().getProviderConfig().setOperationExceptionResultCodes(pc.getOperationExceptionResultCodes()); + } + if (pc.getControlProcessor() != null) { + object.getProvider().getProviderConfig().setControlProcessor(pc.getControlProcessor()); + } + if (!extraProps.isEmpty()) { + object.getProvider().getProviderConfig().setProperties(extraProps); + } + } + + + /** + * Returns the property names for this property source. + * + * @return all property names + */ + public static Set<String> getProperties() + { + return INVOKER.getProperties(); + } +}
diff --git a/core/src/main/java/org/ldaptive/props/PoolConfigPropertySource.java b/core/src/main/java/org/ldaptive/props/PoolConfigPropertySource.java new file mode 100644 index 0000000..86192b3 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/PoolConfigPropertySource.java
@@ -0,0 +1,97 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.Reader; +import java.util.Properties; +import java.util.Set; +import org.ldaptive.pool.PoolConfig; + +/** + * Reads properties specific to {@link PoolConfig} and returns an initialized object of that type. + * + * @author Middleware Services + */ +public final class PoolConfigPropertySource extends AbstractPropertySource<PoolConfig> +{ + + /** Invoker for ldap pool config. */ + private static final SimplePropertyInvoker INVOKER = new SimplePropertyInvoker(PoolConfig.class); + + + /** + * Creates a new ldap pool config property source using the default properties file. + * + * @param pc pool config to invoke properties on + */ + public PoolConfigPropertySource(final PoolConfig pc) + { + this(pc, PROPERTIES_FILE); + } + + + /** + * Creates a new ldap pool config property source. + * + * @param pc pool config to invoke properties on + * @param paths to read properties from + */ + public PoolConfigPropertySource(final PoolConfig pc, final String... paths) + { + this(pc, loadProperties(paths)); + } + + + /** + * Creates a new ldap pool config property source. + * + * @param pc pool config to invoke properties on + * @param readers to read properties from + */ + public PoolConfigPropertySource(final PoolConfig pc, final Reader... readers) + { + this(pc, loadProperties(readers)); + } + + + /** + * Creates a new ldap pool config property source. + * + * @param pc pool config to invoke properties on + * @param props to read properties from + */ + public PoolConfigPropertySource(final PoolConfig pc, final Properties props) + { + this(pc, PropertyDomain.POOL, props); + } + + + /** + * Creates a new ldap pool config property source. + * + * @param pc pool config to invoke properties on + * @param domain that properties are in + * @param props to read properties from + */ + public PoolConfigPropertySource(final PoolConfig pc, final PropertyDomain domain, final Properties props) + { + super(pc, domain, props); + } + + + @Override + public void initialize() + { + initializeObject(INVOKER); + } + + + /** + * Returns the property names for this property source. + * + * @return all property names + */ + public static Set<String> getProperties() + { + return INVOKER.getProperties(); + } +}
diff --git a/core/src/main/java/org/ldaptive/props/PooledConnectionFactoryPropertySource.java b/core/src/main/java/org/ldaptive/props/PooledConnectionFactoryPropertySource.java new file mode 100644 index 0000000..92efcd0 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/PooledConnectionFactoryPropertySource.java
@@ -0,0 +1,145 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.Reader; +import java.util.Collections; +import java.util.Properties; +import java.util.Set; +import org.ldaptive.pool.BlockingConnectionPool; +import org.ldaptive.pool.ConnectionPool; +import org.ldaptive.pool.ConnectionPoolType; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.pool.SoftLimitConnectionPool; + +/** + * Reads properties specific to {@link PooledConnectionFactory} and returns an initialized object of that type. + * + * @author Middleware Services + */ +public final class PooledConnectionFactoryPropertySource extends AbstractPropertySource<PooledConnectionFactory> +{ + + /** Connection pool type. */ + private ConnectionPoolType poolType = ConnectionPoolType.BLOCKING; + + + /** + * Creates a new pooled connection factory property source using the default properties file. + * + * @param cf connection factory to invoke properties on + */ + public PooledConnectionFactoryPropertySource(final PooledConnectionFactory cf) + { + this(cf, PROPERTIES_FILE); + } + + + /** + * Creates a new pooled connection factory property source. + * + * @param cf connection factory to invoke properties on + * @param paths to read properties from + */ + public PooledConnectionFactoryPropertySource(final PooledConnectionFactory cf, final String... paths) + { + this(cf, loadProperties(paths)); + } + + + /** + * Creates a new pooled connection factory property source. + * + * @param cf connection factory to invoke properties on + * @param readers to read properties from + */ + public PooledConnectionFactoryPropertySource(final PooledConnectionFactory cf, final Reader... readers) + { + this(cf, loadProperties(readers)); + } + + + /** + * Creates a new pooled connection factory property source. + * + * @param cf connection factory to invoke properties on + * @param props to read properties from + */ + public PooledConnectionFactoryPropertySource(final PooledConnectionFactory cf, final Properties props) + { + this(cf, PropertyDomain.POOL, props); + } + + + /** + * Creates a new pooled connection factory property source. + * + * @param cf connection factory to invoke properties on + * @param domain that properties are in + * @param props to read properties from + */ + public PooledConnectionFactoryPropertySource( + final PooledConnectionFactory cf, + final PropertyDomain domain, + final Properties props) + { + super(cf, domain, props); + } + + + /** + * Returns the pool type. + * + * @return pool type + */ + public ConnectionPoolType getPoolType() + { + return poolType; + } + + + /** @param pt pool type */ + public void setPoolType(final ConnectionPoolType pt) + { + poolType = pt; + } + + + @Override + public void initialize() + { + ConnectionPool cp; + if (poolType == ConnectionPoolType.BLOCKING) { + cp = new BlockingConnectionPool(); + + final BlockingConnectionPoolPropertySource cpPropSource = new BlockingConnectionPoolPropertySource( + (BlockingConnectionPool) cp, + propertiesDomain, + properties); + cpPropSource.initialize(); + } else if (poolType == ConnectionPoolType.SOFTLIMIT) { + cp = new SoftLimitConnectionPool(); + + final BlockingConnectionPoolPropertySource cpPropSource = new BlockingConnectionPoolPropertySource( + (SoftLimitConnectionPool) cp, + propertiesDomain, + properties); + cpPropSource.initialize(); + } else { + throw new IllegalStateException("Unknown pool type: " + poolType); + } + + cp.initialize(); + object.setConnectionPool(cp); + } + + + /** + * Returns the property names for this property source. + * + * @return all property names + */ + public static Set<String> getProperties() + { + return Collections.emptySet(); + } +}
diff --git a/core/src/main/java/org/ldaptive/props/PropertyInvoker.java b/core/src/main/java/org/ldaptive/props/PropertyInvoker.java new file mode 100644 index 0000000..e660249 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/PropertyInvoker.java
@@ -0,0 +1,41 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.util.Set; + +/** + * Interface for property driven object method invocation. + * + * @author Middleware Services + */ +public interface PropertyInvoker +{ + + + /** + * Invokes the setter method on the supplied object for the supplied property name and value. + * + * @param object to invoke property setter on + * @param name of the property to invoke + * @param value of the property to set + */ + void setProperty(Object object, String name, String value); + + + /** + * Returns whether a property with the supplied name exists on this invoker. + * + * @param name of the property to check + * + * @return whether a property with the supplied name exists on this invoker + */ + boolean hasProperty(String name); + + + /** + * Returns the property names for this invoker. + * + * @return set of property names + */ + Set<String> getProperties(); +}
diff --git a/core/src/main/java/org/ldaptive/props/PropertySource.java b/core/src/main/java/org/ldaptive/props/PropertySource.java new file mode 100644 index 0000000..ae79033 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/PropertySource.java
@@ -0,0 +1,55 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +/** + * Interface for property driven object initialization. + * + * @param <T> type of object to invoke properties on + * + * @author Middleware Services + */ +public interface PropertySource<T> +{ + + /** Enum to define the domain for properties. */ + enum PropertyDomain { + + /** ldap property domain. */ + LDAP("org.ldaptive."), + + /** auth property domain. */ + AUTH("org.ldaptive.auth."), + + /** pool property domain. */ + POOL("org.ldaptive.pool."); + + /** properties domain. */ + private final String domain; + + + /** + * Creates a new property domain. + * + * @param s properties domain + */ + PropertyDomain(final String s) + { + domain = s; + } + + + /** + * Returns the properties domain value. + * + * @return properties domain + */ + public String value() + { + return domain; + } + } + + + /** Initializes the object for this property source. */ + void initialize(); +}
diff --git a/core/src/main/java/org/ldaptive/props/PropertyValueParser.java b/core/src/main/java/org/ldaptive/props/PropertyValueParser.java new file mode 100644 index 0000000..0791c6f --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/PropertyValueParser.java
@@ -0,0 +1,206 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Parses the configuration data associated with classes that contain setter properties. The format of the property + * string should be like: + * + * <pre> + MyClass{{propertyOne=foo}{propertyTwo=bar}} + * </pre> + * + * <p>If the class name is supplied to the constructor, the property string need not contain the class declaration.</p> + * + * @author Middleware Services + */ +public class PropertyValueParser +{ + + /** Property string containing configuration. */ + protected static final Pattern CONFIG_PATTERN = Pattern.compile("([^\\{]+)\\s*\\{(.*)\\}\\s*"); + + /** Property string for configuring a config where the class is known. */ + protected static final Pattern PARAMS_ONLY_CONFIG_PATTERN = Pattern.compile("\\s*\\{\\s*(.*)\\s*\\}\\s*"); + + /** Pattern for finding properties. */ + protected static final Pattern PROPERTY_PATTERN = Pattern.compile("([^\\}\\{])+"); + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Class found in the config. */ + private String className; + + /** Properties found in the config to set on the class. */ + private final Map<String, String> properties = new HashMap<>(); + + + /** Default constructor. */ + protected PropertyValueParser() {} + + + /** + * Creates a new config parser. + * + * @param config containing configuration data + */ + public PropertyValueParser(final String config) + { + final Matcher matcher = CONFIG_PATTERN.matcher(config); + if (matcher.matches()) { + initialize(matcher.group(1).trim(), matcher.group(2).trim()); + } + } + + + /** + * Creates a new config parser. + * + * @param config containing configuration data + * @param clazz fully qualified class name + */ + public PropertyValueParser(final String config, final String clazz) + { + final Matcher matcher = PARAMS_ONLY_CONFIG_PATTERN.matcher(config); + if (matcher.matches()) { + initialize(clazz, matcher.group(1).trim()); + } + } + + + /** + * Invokes {@link #setClassName(String)} and {@link #initializeProperties(Matcher)}. + * + * @param clazz type to create and initialize + * @param props to set on the class + */ + protected void initialize(final String clazz, final String props) + { + setClassName(clazz); + if (!"".equals(props)) { + initializeProperties(PROPERTY_PATTERN.matcher(props)); + } + } + + + /** + * Finds all the matches in the supplied matcher puts them into the properties map. Properties are split on '='. + * + * @param matcher to find matches + */ + protected void initializeProperties(final Matcher matcher) + { + while (matcher.find()) { + final String input = matcher.group().trim(); + if (input != null && !"".equals(input)) { + final String[] s = input.split("=", 2); + if (s.length < 2) { + throw new IllegalArgumentException("Invalid property syntax: " + input); + } + properties.put(s[0].trim(), s[1].trim()); + } + } + } + + + /** + * Returns the class name of the object to initialize. + * + * @return class name + */ + public String getClassName() + { + return className; + } + + + /** + * Sets the class name of the object to initialize. + * + * @param name of the object class type + */ + protected void setClassName(final String name) + { + className = name; + } + + + /** + * Returns the properties from the configuration. + * + * @return map of property name to value + */ + public Map<String, String> getProperties() + { + return properties; + } + + + /** + * Returns whether the supplied configuration data contains a config. + * + * @param config containing configuration data + * + * @return whether the supplied configuration data contains a config + */ + public static boolean isConfig(final String config) + { + return CONFIG_PATTERN.matcher(config).matches(); + } + + + /** + * Returns whether the supplied configuration data contains a params only config. + * + * @param config containing configuration data + * + * @return whether the supplied configuration data contains a params only config + */ + public static boolean isParamsOnlyConfig(final String config) + { + return PARAMS_ONLY_CONFIG_PATTERN.matcher(config).matches(); + } + + + /** + * Initialize an instance of the class type with the properties contained in this config. + * + * @return object of the type the config parsed + */ + public Object initializeType() + { + final Class<?> c = SimplePropertyInvoker.createClass(getClassName()); + final Object o = SimplePropertyInvoker.instantiateType(c, getClassName()); + setProperties(c, o); + return o; + } + + + /** + * Sets the properties on the supplied object. + * + * @param c type of the supplied object + * @param o to invoke properties on + */ + protected void setProperties(final Class<?> c, final Object o) + { + final SimplePropertyInvoker invoker = new SimplePropertyInvoker(c); + for (Map.Entry<String, String> entry : getProperties().entrySet()) { + invoker.setProperty(o, entry.getKey(), entry.getValue()); + } + if (invoker.getProperties().contains("initialize")) { + try { + invoker.setProperty(o, "initialize", null); + } catch (Throwable t) { + logger.debug("Error invoking initialize method", t); + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/props/ProviderConfigPropertyInvoker.java b/core/src/main/java/org/ldaptive/props/ProviderConfigPropertyInvoker.java new file mode 100644 index 0000000..5aadc0d --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/ProviderConfigPropertyInvoker.java
@@ -0,0 +1,39 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import org.ldaptive.provider.ControlProcessor; + +/** + * Handles properties for {@link org.ldaptive.provider.ProviderConfig}. + * + * @author Middleware Services + */ +public class ProviderConfigPropertyInvoker extends AbstractPropertyInvoker +{ + + + /** + * Creates a new provider config property invoker for the supplied class. + * + * @param c class that has setter methods + */ + public ProviderConfigPropertyInvoker(final Class<?> c) + { + initialize(c); + } + + + @Override + protected Object convertValue(final Class<?> type, final String value) + { + Object newValue = value; + if (type != String.class) { + if (ControlProcessor.class.isAssignableFrom(type)) { + newValue = createTypeFromPropertyValue(ControlProcessor.class, value); + } else { + newValue = convertSimpleType(type, value); + } + } + return newValue; + } +}
diff --git a/core/src/main/java/org/ldaptive/props/ProviderConfigPropertySource.java b/core/src/main/java/org/ldaptive/props/ProviderConfigPropertySource.java new file mode 100644 index 0000000..387b6ef --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/ProviderConfigPropertySource.java
@@ -0,0 +1,98 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.Reader; +import java.util.Properties; +import java.util.Set; +import org.ldaptive.provider.ProviderConfig; + +/** + * Reads properties specific to {@link ProviderConfig} and returns an initialized object of that type. + * + * @author Middleware Services + */ +public final class ProviderConfigPropertySource extends AbstractPropertySource<ProviderConfig<?>> +{ + + /** Invoker for provider config. */ + private static final ProviderConfigPropertyInvoker INVOKER = new ProviderConfigPropertyInvoker(ProviderConfig.class); + + + /** + * Creates a new provider config property source using the default properties file. + * + * @param pc provider config to invoke properties on + */ + public ProviderConfigPropertySource(final ProviderConfig pc) + { + this(pc, PROPERTIES_FILE); + } + + + /** + * Creates a new provider config property source. + * + * @param pc provider config to invoke properties on + * @param paths to read properties from + */ + public ProviderConfigPropertySource(final ProviderConfig pc, final String... paths) + { + this(pc, loadProperties(paths)); + } + + + /** + * Creates a new provider config property source. + * + * @param pc provider config to invoke properties on + * @param readers to read properties from + */ + public ProviderConfigPropertySource(final ProviderConfig pc, final Reader... readers) + { + this(pc, loadProperties(readers)); + } + + + /** + * Creates a new provider config property source. + * + * @param pc provider config to invoke properties on + * @param props to read properties from + */ + public ProviderConfigPropertySource(final ProviderConfig pc, final Properties props) + { + this(pc, PropertyDomain.LDAP, props); + } + + + /** + * Creates a new provider config property source. + * + * @param pc provider config to invoke properties on + * @param domain that properties are in + * @param props to read properties from + */ + public ProviderConfigPropertySource(final ProviderConfig pc, final PropertyDomain domain, final Properties props) + { + super(pc, domain, props); + } + + + @Override + public void initialize() + { + initializeObject(INVOKER); + object.setProperties(extraProps); + } + + + /** + * Returns the property names for this property source. + * + * @return all property names + */ + public static Set<String> getProperties() + { + return INVOKER.getProperties(); + } +}
diff --git a/core/src/main/java/org/ldaptive/props/SearchDnResolverPropertySource.java b/core/src/main/java/org/ldaptive/props/SearchDnResolverPropertySource.java new file mode 100644 index 0000000..5879f18 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/SearchDnResolverPropertySource.java
@@ -0,0 +1,100 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.Reader; +import java.util.Properties; +import java.util.Set; +import org.ldaptive.auth.SearchDnResolver; + +/** + * Reads properties specific to {@link SearchDnResolver} and returns an initialized object of that type. + * + * @author Middleware Services + */ +public final class SearchDnResolverPropertySource extends AbstractPropertySource<SearchDnResolver> +{ + + /** Invoker for search dn resolver. */ + private static final SimplePropertyInvoker INVOKER = new SimplePropertyInvoker(SearchDnResolver.class); + + + /** + * Creates a new search dn resolver property source using the default properties file. + * + * @param resolver search dn resolver to invoke properties on + */ + public SearchDnResolverPropertySource(final SearchDnResolver resolver) + { + this(resolver, PROPERTIES_FILE); + } + + + /** + * Creates a new search dn resolver property source. + * + * @param resolver search dn resolver to invoke properties on + * @param paths to read properties from + */ + public SearchDnResolverPropertySource(final SearchDnResolver resolver, final String... paths) + { + this(resolver, loadProperties(paths)); + } + + + /** + * Creates a new search dn resolver property source. + * + * @param resolver search dn resolver to invoke properties on + * @param readers to read properties from + */ + public SearchDnResolverPropertySource(final SearchDnResolver resolver, final Reader... readers) + { + this(resolver, loadProperties(readers)); + } + + + /** + * Creates a new search dn resolver property source. + * + * @param resolver search dn resolver to invoke properties on + * @param props to read properties from + */ + public SearchDnResolverPropertySource(final SearchDnResolver resolver, final Properties props) + { + this(resolver, PropertyDomain.AUTH, props); + } + + + /** + * Creates a new search dn resolver property source. + * + * @param resolver search dn resolver to invoke properties on + * @param domain that properties are in + * @param props to read properties from + */ + public SearchDnResolverPropertySource( + final SearchDnResolver resolver, + final PropertyDomain domain, + final Properties props) + { + super(resolver, domain, props); + } + + + @Override + public void initialize() + { + initializeObject(INVOKER); + } + + + /** + * Returns the property names for this property source. + * + * @return all property names + */ + public static Set<String> getProperties() + { + return INVOKER.getProperties(); + } +}
diff --git a/core/src/main/java/org/ldaptive/props/SearchRequestPropertyInvoker.java b/core/src/main/java/org/ldaptive/props/SearchRequestPropertyInvoker.java new file mode 100644 index 0000000..6bfffca --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/SearchRequestPropertyInvoker.java
@@ -0,0 +1,54 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import org.ldaptive.SearchFilter; +import org.ldaptive.control.RequestControl; +import org.ldaptive.handler.IntermediateResponseHandler; +import org.ldaptive.handler.SearchEntryHandler; +import org.ldaptive.handler.SearchReferenceHandler; +import org.ldaptive.referral.ReferralHandler; + +/** + * Handles properties for {@link org.ldaptive.SearchRequest}. + * + * @author Middleware Services + */ +public class SearchRequestPropertyInvoker extends AbstractPropertyInvoker +{ + + + /** + * Creates a new search request property invoker for the supplied class. + * + * @param c class that has setter methods + */ + public SearchRequestPropertyInvoker(final Class<?> c) + { + initialize(c); + } + + + @Override + protected Object convertValue(final Class<?> type, final String value) + { + Object newValue = value; + if (type != String.class) { + if (SearchFilter.class.isAssignableFrom(type)) { + newValue = new SearchFilter(value); + } else if (RequestControl[].class.isAssignableFrom(type)) { + newValue = createArrayTypeFromPropertyValue(RequestControl.class, value); + } else if (ReferralHandler.class.isAssignableFrom(type)) { + newValue = createTypeFromPropertyValue(ReferralHandler.class, value); + } else if (SearchEntryHandler[].class.isAssignableFrom(type)) { + newValue = createArrayTypeFromPropertyValue(SearchEntryHandler.class, value); + } else if (SearchReferenceHandler[].class.isAssignableFrom(type)) { + newValue = createArrayTypeFromPropertyValue(SearchReferenceHandler.class, value); + } else if (IntermediateResponseHandler[].class.isAssignableFrom(type)) { + newValue = createArrayTypeFromPropertyValue(IntermediateResponseHandler.class, value); + } else { + newValue = convertSimpleType(type, value); + } + } + return newValue; + } +}
diff --git a/core/src/main/java/org/ldaptive/props/SearchRequestPropertySource.java b/core/src/main/java/org/ldaptive/props/SearchRequestPropertySource.java new file mode 100644 index 0000000..a1b3258 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/SearchRequestPropertySource.java
@@ -0,0 +1,97 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.Reader; +import java.util.Properties; +import java.util.Set; +import org.ldaptive.SearchRequest; + +/** + * Reads properties specific to {@link SearchRequest} and returns an initialized object of that type. + * + * @author Middleware Services + */ +public final class SearchRequestPropertySource extends AbstractPropertySource<SearchRequest> +{ + + /** Invoker for search request. */ + private static final SearchRequestPropertyInvoker INVOKER = new SearchRequestPropertyInvoker(SearchRequest.class); + + + /** + * Creates a new search request property source using the default properties file. + * + * @param request search request to invoke properties on + */ + public SearchRequestPropertySource(final SearchRequest request) + { + this(request, PROPERTIES_FILE); + } + + + /** + * Creates a new search request property source. + * + * @param request search request to invoke properties on + * @param paths to read properties from + */ + public SearchRequestPropertySource(final SearchRequest request, final String... paths) + { + this(request, loadProperties(paths)); + } + + + /** + * Creates a new search request property source. + * + * @param request search request to invoke properties on + * @param readers to read properties from + */ + public SearchRequestPropertySource(final SearchRequest request, final Reader... readers) + { + this(request, loadProperties(readers)); + } + + + /** + * Creates a new search request property source. + * + * @param request search request to invoke properties on + * @param props to read properties from + */ + public SearchRequestPropertySource(final SearchRequest request, final Properties props) + { + this(request, PropertyDomain.LDAP, props); + } + + + /** + * Creates a new search request property source. + * + * @param request search request to invoke properties on + * @param domain that properties are in + * @param props to read properties from + */ + public SearchRequestPropertySource(final SearchRequest request, final PropertyDomain domain, final Properties props) + { + super(request, domain, props); + } + + + @Override + public void initialize() + { + initializeObject(INVOKER); + } + + + /** + * Returns the property names for this property source. + * + * @return all property names + */ + public static Set<String> getProperties() + { + return INVOKER.getProperties(); + } +}
diff --git a/core/src/main/java/org/ldaptive/props/SimplePropertyInvoker.java b/core/src/main/java/org/ldaptive/props/SimplePropertyInvoker.java new file mode 100644 index 0000000..aaeda11 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/SimplePropertyInvoker.java
@@ -0,0 +1,29 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +/** + * Handles simple properties common to all objects. + * + * @author Middleware Services + */ +public class SimplePropertyInvoker extends AbstractPropertyInvoker +{ + + + /** + * Creates a new simple property invoker for the supplied class. + * + * @param c class that has setter methods + */ + public SimplePropertyInvoker(final Class<?> c) + { + initialize(c); + } + + + @Override + protected Object convertValue(final Class<?> type, final String value) + { + return convertSimpleType(type, value); + } +}
diff --git a/core/src/main/java/org/ldaptive/props/SimplePropertySource.java b/core/src/main/java/org/ldaptive/props/SimplePropertySource.java new file mode 100644 index 0000000..3165d9a --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/SimplePropertySource.java
@@ -0,0 +1,87 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.Reader; +import java.util.Properties; + +/** + * Reads simple properties and returns an initialized object of the supplied type. + * + * @param <T> type of object to invoke properties on + * + * @author Middleware Services + */ +public final class SimplePropertySource<T> extends AbstractPropertySource<T> +{ + + /** Invoker for simple properties. */ + private final SimplePropertyInvoker invoker; + + + /** + * Creates a new simple property source using the default properties file. + * + * @param t object to invoke properties on + */ + public SimplePropertySource(final T t) + { + this(t, PROPERTIES_FILE); + } + + + /** + * Creates a new simple property source. + * + * @param t object to invoke properties on + * @param paths to read properties from + */ + public SimplePropertySource(final T t, final String... paths) + { + this(t, loadProperties(paths)); + } + + + /** + * Creates a new simple property source. + * + * @param t object to invoke properties on + * @param readers to read properties from + */ + public SimplePropertySource(final T t, final Reader... readers) + { + this(t, loadProperties(readers)); + } + + + /** + * Creates a new simple property source. + * + * @param t object to invoke properties on + * @param props to read properties from + */ + public SimplePropertySource(final T t, final Properties props) + { + this(t, PropertyDomain.LDAP, props); + } + + + /** + * Creates a new simple property source. + * + * @param t object to invoke properties on + * @param domain that properties are in + * @param props to read properties from + */ + public SimplePropertySource(final T t, final PropertyDomain domain, final Properties props) + { + super(t, domain, props); + invoker = new SimplePropertyInvoker(t.getClass()); + } + + + @Override + public void initialize() + { + initializeObject(invoker); + } +}
diff --git a/core/src/main/java/org/ldaptive/props/SslConfigPropertyInvoker.java b/core/src/main/java/org/ldaptive/props/SslConfigPropertyInvoker.java new file mode 100644 index 0000000..1c0c094 --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/SslConfigPropertyInvoker.java
@@ -0,0 +1,61 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.TrustManager; +import org.ldaptive.ssl.CertificateHostnameVerifier; +import org.ldaptive.ssl.CredentialConfig; +import org.ldaptive.ssl.SslConfig; + +/** + * Handles properties for {@link SslConfig}. + * + * @author Middleware Services + */ +public class SslConfigPropertyInvoker extends AbstractPropertyInvoker +{ + + + /** + * Creates a new ssl config property invoker for the supplied class. + * + * @param c class that has setter methods + */ + public SslConfigPropertyInvoker(final Class<?> c) + { + initialize(c); + } + + + @Override + protected Object convertValue(final Class<?> type, final String value) + { + Object newValue = value; + if (type != String.class) { + if (CredentialConfig.class.isAssignableFrom(type)) { + if ("null".equals(value)) { + newValue = null; + } else { + if (CredentialConfigParser.isCredentialConfig(value)) { + final CredentialConfigParser configParser = new CredentialConfigParser(value); + newValue = configParser.initializeType(); + } else if (PropertyValueParser.isConfig(value)) { + final PropertyValueParser configParser = new PropertyValueParser(value); + newValue = configParser.initializeType(); + } else { + newValue = instantiateType(SslConfig.class, value); + } + } + } else if (TrustManager[].class.isAssignableFrom(type)) { + newValue = createArrayTypeFromPropertyValue(TrustManager.class, value); + } else if (CertificateHostnameVerifier.class.isAssignableFrom(type)) { + newValue = createTypeFromPropertyValue(CertificateHostnameVerifier.class, value); + } else if (HandshakeCompletedListener[].class.isAssignableFrom(type)) { + newValue = createArrayTypeFromPropertyValue(HandshakeCompletedListener.class, value); + } else { + newValue = convertSimpleType(type, value); + } + } + return newValue; + } +}
diff --git a/core/src/main/java/org/ldaptive/props/SslConfigPropertySource.java b/core/src/main/java/org/ldaptive/props/SslConfigPropertySource.java new file mode 100644 index 0000000..1d6ba4a --- /dev/null +++ b/core/src/main/java/org/ldaptive/props/SslConfigPropertySource.java
@@ -0,0 +1,97 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.io.Reader; +import java.util.Properties; +import java.util.Set; +import org.ldaptive.ssl.SslConfig; + +/** + * Reads properties specific to {@link SslConfig} and returns an initialized object of that type. + * + * @author Middleware Services + */ +public final class SslConfigPropertySource extends AbstractPropertySource<SslConfig> +{ + + /** Invoker for ssl config. */ + private static final SslConfigPropertyInvoker INVOKER = new SslConfigPropertyInvoker(SslConfig.class); + + + /** + * Creates a new ssl config property source using the default properties file. + * + * @param config ssl config to invoke properties on + */ + public SslConfigPropertySource(final SslConfig config) + { + this(config, PROPERTIES_FILE); + } + + + /** + * Creates a new ssl config property source. + * + * @param config ssl config to invoke properties on + * @param paths to read properties from + */ + public SslConfigPropertySource(final SslConfig config, final String... paths) + { + this(config, loadProperties(paths)); + } + + + /** + * Creates a new ssl config property source. + * + * @param config ssl config to invoke properties on + * @param readers to read properties from + */ + public SslConfigPropertySource(final SslConfig config, final Reader... readers) + { + this(config, loadProperties(readers)); + } + + + /** + * Creates a new ssl config property source. + * + * @param config ssl config to invoke properties on + * @param props to read properties from + */ + public SslConfigPropertySource(final SslConfig config, final Properties props) + { + this(config, PropertyDomain.LDAP, props); + } + + + /** + * Creates a new sssl config property source. + * + * @param config ssl config to invoke properties on + * @param domain that properties are in + * @param props to read properties from + */ + public SslConfigPropertySource(final SslConfig config, final PropertyDomain domain, final Properties props) + { + super(config, domain, props); + } + + + @Override + public void initialize() + { + initializeObject(INVOKER); + } + + + /** + * Returns the property names for this property source. + * + * @return all property names + */ + public static Set<String> getProperties() + { + return INVOKER.getProperties(); + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/AbstractProviderConnectionFactory.java b/core/src/main/java/org/ldaptive/provider/AbstractProviderConnectionFactory.java new file mode 100644 index 0000000..91eae9f --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/AbstractProviderConnectionFactory.java
@@ -0,0 +1,179 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider; + +import org.ldaptive.ConnectionFactoryMetadata; +import org.ldaptive.ConnectionStrategy; +import org.ldaptive.LdapException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides a basic implementation for other connection factories to inherit. + * + * @param <T> type of provider config for this connection factory + * + * @author Middleware Services + */ +public abstract class AbstractProviderConnectionFactory<T extends ProviderConfig> + implements ProviderConnectionFactory<T> +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Provider configuration. */ + private final T providerConfig; + + /** Factory metadata. */ + private final DefaultConnectionFactoryMetadata metadata; + + /** Connection strategy. */ + private final ConnectionStrategy connectionStrategy; + + + /** + * Creates a new abstract connection factory. Once invoked the supplied provider config is made immutable. See {@link + * ProviderConfig#makeImmutable()}. + * + * @param url of the ldap to connect to + * @param strategy connection strategy + * @param config provider configuration + */ + public AbstractProviderConnectionFactory(final String url, final ConnectionStrategy strategy, final T config) + { + metadata = new DefaultConnectionFactoryMetadata(url); + connectionStrategy = strategy; + providerConfig = config; + providerConfig.makeImmutable(); + } + + + @Override + public T getProviderConfig() + { + return providerConfig; + } + + + /** + * Returns the connection factory metadata. + * + * @return metadata + */ + protected ConnectionFactoryMetadata getMetadata() + { + return metadata; + } + + + @Override + public ProviderConnection create() + throws LdapException + { + LdapException lastThrown = null; + final String[] urls = connectionStrategy.getLdapUrls(metadata); + if (urls == null || urls.length == 0) { + throw new ConnectionException( + "Connection strategy " + connectionStrategy + " did not produce any LDAP URLs for " + metadata); + } + + ProviderConnection conn = null; + for (String url : urls) { + try { + logger.trace("[{}] Attempting connection to {} for strategy {}", metadata, url, connectionStrategy); + conn = createInternal(url); + metadata.incrementCount(); + lastThrown = null; + break; + } catch (ConnectionException e) { + lastThrown = e; + logger.debug("Error connecting to LDAP URL: {}", url, e); + } + } + if (lastThrown != null) { + throw lastThrown; + } + return conn; + } + + + /** + * Create the provider connection and prepare the connection for use. + * + * @param url to connect to + * + * @return provider connection + * + * @throws LdapException if a connection cannot be established + */ + protected abstract ProviderConnection createInternal(final String url) + throws LdapException; + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::metadata=%s, providerConfig=%s]", + getClass().getName(), + hashCode(), + metadata, + providerConfig); + } + + + /** Provides an object to track the connection count. */ + private class DefaultConnectionFactoryMetadata implements ConnectionFactoryMetadata + { + + /** ldap url. */ + private final String ldapUrl; + + /** connection count. */ + private int count; + + + /** + * Creates a new default connection factory metadata. + * + * @param s ldap url + */ + DefaultConnectionFactoryMetadata(final String s) + { + ldapUrl = s; + } + + + @Override + public String getLdapUrl() + { + return ldapUrl; + } + + + @Override + public int getConnectionCount() + { + return count; + } + + + /** Increments the connection count. */ + private void incrementCount() + { + count++; + // reset the count if it exceeds the size of an integer + if (count < 0) { + count = 0; + } + } + + + @Override + public String toString() + { + return String.format("[ldapUrl=%s, count=%s]", ldapUrl, count); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/ConnectionException.java b/core/src/main/java/org/ldaptive/provider/ConnectionException.java new file mode 100644 index 0000000..dcff1ba --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/ConnectionException.java
@@ -0,0 +1,239 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider; + +import org.ldaptive.LdapException; +import org.ldaptive.ResultCode; +import org.ldaptive.control.ResponseControl; + +/** + * Exception thrown when a connection attempt fails. + * + * @author Middleware Services + */ +public class ConnectionException extends LdapException +{ + + /** serialVersionUID. */ + private static final long serialVersionUID = -1902801031167384619L; + + + /** + * Creates a new connection exception. + * + * @param msg describing this exception + */ + public ConnectionException(final String msg) + { + super(msg); + } + + + /** + * Creates a new connection exception. + * + * @param msg describing this exception + * @param code result code + */ + public ConnectionException(final String msg, final ResultCode code) + { + super(msg, code); + } + + + /** + * Creates a new connection exception. + * + * @param msg describing this exception + * @param code result code + * @param dn matched dn + */ + public ConnectionException(final String msg, final ResultCode code, final String dn) + { + super(msg, code, dn); + } + + + /** + * Creates a new connection exception. + * + * @param msg describing this exception + * @param code result code + * @param dn matched dn + * @param c response controls + */ + public ConnectionException(final String msg, final ResultCode code, final String dn, final ResponseControl[] c) + { + super(msg, code, dn, c); + } + + + /** + * Creates a new connection exception. + * + * @param msg describing this exception + * @param code result code + * @param dn matched dn + * @param c response controls + * @param urls referral urls + */ + public ConnectionException( + final String msg, + final ResultCode code, + final String dn, + final ResponseControl[] c, + final String[] urls) + { + super(msg, code, dn, c, urls); + } + + + /** + * Creates a new connection exception. + * + * @param e provider specific exception + */ + public ConnectionException(final Exception e) + { + super(e); + } + + + /** + * Creates a new connection exception. + * + * @param e provider specific exception + * @param code result code + */ + public ConnectionException(final Exception e, final ResultCode code) + { + super(e, code); + } + + + /** + * Creates a new connection exception. + * + * @param e provider specific exception + * @param code result code + * @param dn matched dn + */ + public ConnectionException(final Exception e, final ResultCode code, final String dn) + { + super(e, code, dn); + } + + + /** + * Creates a new connection exception. + * + * @param e provider specific exception + * @param code result code + * @param dn matched dn + * @param c response controls + */ + public ConnectionException(final Exception e, final ResultCode code, final String dn, final ResponseControl[] c) + { + super(e, code, dn, c); + } + + + /** + * Creates a new connection exception. + * + * @param e provider specific exception + * @param code result code + * @param dn matched dn + * @param c response controls + * @param urls referral urls + */ + public ConnectionException( + final Exception e, + final ResultCode code, + final String dn, + final ResponseControl[] c, + final String[] urls) + { + super(e, code, dn, c, urls); + } + + + /** + * Creates a new connection exception. + * + * @param msg describing this exception + * @param e provider specific exception + */ + public ConnectionException(final String msg, final Exception e) + { + super(msg, e); + } + + + /** + * Creates a new connection exception. + * + * @param msg describing this exception + * @param e provider specific exception + * @param code result code + */ + public ConnectionException(final String msg, final Exception e, final ResultCode code) + { + super(msg, e, code); + } + + + /** + * Creates a new connection exception. + * + * @param msg describing this exception + * @param e provider specific exception + * @param code result code + * @param dn matched dn + */ + public ConnectionException(final String msg, final Exception e, final ResultCode code, final String dn) + { + super(msg, e, code, dn); + } + + + /** + * Creates a new connection exception. + * + * @param msg describing this exception + * @param e provider specific exception + * @param code result code + * @param dn matched dn + * @param c response controls + */ + public ConnectionException( + final String msg, + final Exception e, + final ResultCode code, + final String dn, + final ResponseControl[] c) + { + super(msg, e, code, dn, c); + } + + + /** + * Creates a new connection exception. + * + * @param msg describing this exception + * @param e provider specific exception + * @param code result code + * @param dn matched dn + * @param c response controls + * @param urls referral urls + */ + public ConnectionException( + final String msg, + final Exception e, + final ResultCode code, + final String dn, + final ResponseControl[] c, + final String[] urls) + { + super(msg, e, code, dn, c, urls); + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/ControlHandler.java b/core/src/main/java/org/ldaptive/provider/ControlHandler.java new file mode 100644 index 0000000..f3d49b6 --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/ControlHandler.java
@@ -0,0 +1,54 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider; + +import org.ldaptive.control.RequestControl; +import org.ldaptive.control.ResponseControl; + +/** + * Handles provider specific request and response controls. + * + * @param <T> type of provider control + * + * @author Middleware Services + */ +public interface ControlHandler<T> +{ + + + /** + * Returns the type of control that is handled. + * + * @return type of control + */ + Class<T> getControlType(); + + + /** + * Returns the OID of the supplied control. + * + * @param control to return oid for + * + * @return control oid + */ + String getOID(T control); + + + /** + * Converts the supplied control to a provider specific request control. + * + * @param requestControl to convert + * + * @return provider specific controls + */ + T handleRequest(RequestControl requestControl); + + + /** + * Converts the supplied provider control to a response control. + * + * @param responseControl to convert + * + * @return control + */ + ResponseControl handleResponse(T responseControl); +}
diff --git a/core/src/main/java/org/ldaptive/provider/ControlProcessor.java b/core/src/main/java/org/ldaptive/provider/ControlProcessor.java new file mode 100644 index 0000000..d6b0b4a --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/ControlProcessor.java
@@ -0,0 +1,137 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.List; +import org.ldaptive.control.RequestControl; +import org.ldaptive.control.ResponseControl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class for invoking provider specific control processors. + * + * @param <T> type of provider specific control + * + * @author Middleware Services + */ +public class ControlProcessor<T> +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Control handler. */ + private final ControlHandler<T> controlHandler; + + + /** + * Creates a new control processor. + * + * @param handler to handle controls with + */ + public ControlProcessor(final ControlHandler<T> handler) + { + controlHandler = handler; + } + + + /** + * Converts the supplied request controls to a provider specific request controls. + * + * @param requestControls to convert + * + * @return provider specific controls + */ + @SuppressWarnings("unchecked") + public T[] processRequestControls(final RequestControl[] requestControls) + { + if (requestControls == null || requestControls.length == 0) { + return null; + } + logger.trace("processing request controls: {}", new Object[] {requestControls}); + + final List<T> providerCtls = new ArrayList<>(requestControls.length); + for (RequestControl c : requestControls) { + final T providerCtl = processRequest(c); + if (providerCtl != null) { + providerCtls.add(providerCtl); + } + } + logger.trace("produced provider request controls: {}", providerCtls); + return + !providerCtls.isEmpty() + ? providerCtls.toArray((T[]) Array.newInstance(controlHandler.getControlType(), providerCtls.size())) + : null; + } + + + /** + * Converts the supplied control to a provider control. + * + * @param ctl to convert + * + * @return provider control + */ + protected T processRequest(final RequestControl ctl) + { + if (ctl == null) { + return null; + } + + final T providerCtl = controlHandler.handleRequest(ctl); + if (providerCtl == null) { + logger.info("Unsupported request control {}", ctl); + } + return providerCtl; + } + + + /** + * Converts the supplied provider controls to a response controls. The supplied request controls were used to produce + * the response. + * + * @param responseControls to convert + * + * @return controls + */ + public ResponseControl[] processResponseControls(final T[] responseControls) + { + if (responseControls == null || responseControls.length == 0) { + return null; + } + logger.trace("processing provider response controls: {}", responseControls); + + final List<ResponseControl> ctls = new ArrayList<>(responseControls.length); + for (T c : responseControls) { + final ResponseControl ctl = processResponse(c); + if (ctl != null) { + ctls.add(ctl); + } + } + logger.trace("produced response controls: {}", ctls); + return ctls.toArray(new ResponseControl[ctls.size()]); + } + + + /** + * Converts the supplied provider control to a control. + * + * @param providerCtl to convert + * + * @return control + */ + protected ResponseControl processResponse(final T providerCtl) + { + if (providerCtl == null) { + return null; + } + + final ResponseControl ctl = controlHandler.handleResponse(providerCtl); + if (ctl == null) { + logger.info("Unsupported response control {}", providerCtl); + } + return ctl; + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/Provider.java b/core/src/main/java/org/ldaptive/provider/Provider.java new file mode 100644 index 0000000..8af4ed6 --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/Provider.java
@@ -0,0 +1,49 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider; + +import org.ldaptive.ConnectionConfig; + +/** + * Provides access to a provider specific connection factory. + * + * @param <T> type of provider config for this provider + * + * @author Middleware Services + */ +public interface Provider<T extends ProviderConfig> +{ + + + /** + * Returns the provider configuration. + * + * @return provider configuration + */ + T getProviderConfig(); + + + /** + * Sets the provider configuration. + * + * @param pc provider configuration + */ + void setProviderConfig(T pc); + + + /** + * Returns the connection factory for this provider. + * + * @param cc connection configuration + * + * @return connection factory + */ + ProviderConnectionFactory<T> getConnectionFactory(ConnectionConfig cc); + + + /** + * Creates a new instance of this provider. + * + * @return new instance of this provider + */ + Provider<T> newInstance(); +}
diff --git a/core/src/main/java/org/ldaptive/provider/ProviderConfig.java b/core/src/main/java/org/ldaptive/provider/ProviderConfig.java new file mode 100644 index 0000000..5cfa0f8 --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/ProviderConfig.java
@@ -0,0 +1,119 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import org.ldaptive.AbstractConfig; +import org.ldaptive.ResultCode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Contains configuration data common to providers. + * + * @param <C> type of control produced by the control processor + * + * @author Middleware Services + */ +public class ProviderConfig<C> extends AbstractConfig +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Result codes indicating that an operation exception should be thrown. */ + private ResultCode[] operationExceptionResultCodes; + + /** Additional provider properties. */ + private Map<String, Object> properties = new HashMap<>(); + + /** Control processor. */ + private ControlProcessor<C> controlProcessor; + + + /** + * Returns the result codes that trigger an operation exception. + * + * @return ldap result codes + */ + public ResultCode[] getOperationExceptionResultCodes() + { + return operationExceptionResultCodes; + } + + + /** + * Sets the result codes that trigger an operation exception. + * + * @param codes ldap result codes + */ + public void setOperationExceptionResultCodes(final ResultCode... codes) + { + checkImmutable(); + logger.trace("setting operationExceptionResultCodes: {}", Arrays.toString(codes)); + operationExceptionResultCodes = codes; + } + + + /** + * Returns provider specific properties. + * + * @return map of additional provider properties + */ + public Map<String, Object> getProperties() + { + return properties; + } + + + /** + * Sets provider specific properties. + * + * @param props map of additional provider properties + */ + public void setProperties(final Map<String, Object> props) + { + checkImmutable(); + logger.trace("setting properties: {}", props); + properties = props; + } + + + /** + * Returns the control processor. + * + * @return control processor + */ + public ControlProcessor<C> getControlProcessor() + { + return controlProcessor; + } + + + /** + * Sets the control processor. + * + * @param processor control processor + */ + public void setControlProcessor(final ControlProcessor<C> processor) + { + checkImmutable(); + logger.trace("setting controlProcessor: {}", processor); + controlProcessor = processor; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::operationExceptionResultCodes=%s, properties=%s, controlProcessor=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(operationExceptionResultCodes), + properties, + controlProcessor); + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/ProviderConnection.java b/core/src/main/java/org/ldaptive/provider/ProviderConnection.java new file mode 100644 index 0000000..51b5db8 --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/ProviderConnection.java
@@ -0,0 +1,179 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider; + +import org.ldaptive.AddRequest; +import org.ldaptive.BindRequest; +import org.ldaptive.CompareRequest; +import org.ldaptive.DeleteRequest; +import org.ldaptive.LdapException; +import org.ldaptive.ModifyDnRequest; +import org.ldaptive.ModifyRequest; +import org.ldaptive.Response; +import org.ldaptive.SearchRequest; +import org.ldaptive.control.RequestControl; +import org.ldaptive.extended.ExtendedRequest; +import org.ldaptive.extended.UnsolicitedNotificationListener; + +/** + * Interface for a provider specific implementation of ldap operations. + * + * @author Middleware Services + */ +public interface ProviderConnection +{ + + + /** + * Bind to the ldap. + * + * @param request containing the data necessary to perform the operation + * + * @return response associated with the bind operation + * + * @throws LdapException if an error occurs + */ + Response<Void> bind(BindRequest request) + throws LdapException; + + + /** + * Add an entry to an ldap. + * + * @param request containing the data necessary to perform the operation + * + * @return response associated with the add operation + * + * @throws LdapException if an error occurs + */ + Response<Void> add(AddRequest request) + throws LdapException; + + + /** + * Compare an entry in the ldap. + * + * @param request containing the data necessary to perform the operation + * + * @return response associated with the compare operation + * + * @throws LdapException if an error occurs + */ + Response<Boolean> compare(CompareRequest request) + throws LdapException; + + + /** + * Delete an entry in the ldap. + * + * @param request containing the data necessary to perform the operation + * + * @return response associated with the delete operation + * + * @throws LdapException if an error occurs + */ + Response<Void> delete(DeleteRequest request) + throws LdapException; + + + /** + * Modify an entry in the ldap. + * + * @param request containing the data necessary to perform the operation + * + * @return response associated with the modify operation + * + * @throws LdapException if an error occurs + */ + Response<Void> modify(ModifyRequest request) + throws LdapException; + + + /** + * Modify the DN of an entry in the ldap. + * + * @param request containing the data necessary to perform the operation + * + * @return response associated with the modify dn operation + * + * @throws LdapException if an error occurs + */ + Response<Void> modifyDn(ModifyDnRequest request) + throws LdapException; + + + /** + * Search the ldap. + * + * @param request containing the data necessary to perform the operation + * + * @return search iterator + * + * @throws LdapException if an error occurs + */ + SearchIterator search(SearchRequest request) + throws LdapException; + + + /** + * Search the ldap asynchronously. + * + * @param request containing the data necessary to perform the operation + * @param listener to be notified as results arrive + * + * @throws LdapException if an error occurs + */ + void searchAsync(SearchRequest request, SearchListener listener) + throws LdapException; + + + /** + * Abandon an operation. + * + * @param messageId of the operation to abandon + * @param controls request controls + * + * @throws LdapException if an error occurs + */ + void abandon(int messageId, RequestControl[] controls) + throws LdapException; + + + /** + * Perform an extended operation in the ldap. + * + * @param request containing the data necessary to perform the operation + * + * @return response associated with the extended operation + * + * @throws LdapException if an error occurs + */ + Response<?> extendedOperation(ExtendedRequest request) + throws LdapException; + + + /** + * Adds a listener to receive unsolicited notifications. + * + * @param listener to receive unsolicited notifications + */ + void addUnsolicitedNotificationListener(UnsolicitedNotificationListener listener); + + + /** + * Removes a listener from receiving unsolicited notifications. + * + * @param listener that was registered to receive unsolicited notifications + */ + void removeUnsolicitedNotificationListener(UnsolicitedNotificationListener listener); + + + /** + * Tear down this connection to an LDAP. + * + * @param controls request controls + * + * @throws LdapException if an LDAP error occurs + */ + void close(RequestControl[] controls) + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/provider/ProviderConnectionFactory.java b/core/src/main/java/org/ldaptive/provider/ProviderConnectionFactory.java new file mode 100644 index 0000000..4aec824 --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/ProviderConnectionFactory.java
@@ -0,0 +1,34 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider; + +import org.ldaptive.LdapException; + +/** + * Provides an interface for creating provider connections. + * + * @param <T> type of provider config for this connection factory + * + * @author Middleware Services + */ +public interface ProviderConnectionFactory<T extends ProviderConfig> +{ + + + /** + * Returns the provider configuration. + * + * @return provider configuration + */ + T getProviderConfig(); + + + /** + * Create a connection to an LDAP. + * + * @return provider connection + * + * @throws LdapException if an LDAP error occurs + */ + ProviderConnection create() + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/provider/ProviderUtils.java b/core/src/main/java/org/ldaptive/provider/ProviderUtils.java new file mode 100644 index 0000000..7ece9bc --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/ProviderUtils.java
@@ -0,0 +1,96 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider; + +import org.ldaptive.LdapException; +import org.ldaptive.OperationException; +import org.ldaptive.ResultCode; +import org.ldaptive.control.ResponseControl; + +/** + * Provides utility methods for this package. + * + * @author Middleware Services + */ +public final class ProviderUtils +{ + + + /** Default constructor. */ + private ProviderUtils() {} + + + /** + * Determines whether to throw operation exception or ldap exception. If operation exception is thrown, the operation + * will be retried. Otherwise the exception is propagated out. + * + * @param operationRetryResultCodes to compare result code against + * @param e provider exception to wrap + * @param resultCode provider result code + * @param matchedDn response matched dn + * @param respControls response controls + * @param referralUrls response referral urls + * @param throwLdapException throw an ldap exception if an operation exception is not thrown + * + * @throws OperationException if the operation should be retried + * @throws LdapException to propagate the exception out + */ + public static void throwOperationException( + final ResultCode[] operationRetryResultCodes, + final Exception e, + final int resultCode, + final String matchedDn, + final ResponseControl[] respControls, + final String[] referralUrls, + final boolean throwLdapException) + throws LdapException + { + if (operationRetryResultCodes != null && operationRetryResultCodes.length > 0) { + for (ResultCode rc : operationRetryResultCodes) { + if (rc.value() == resultCode) { + throw new OperationException(e, rc, matchedDn, respControls, referralUrls); + } + } + } + if (throwLdapException) { + throw new LdapException(e, ResultCode.valueOf(resultCode), matchedDn, respControls, referralUrls); + } + } + + + /** + * Determines whether to throw operation exception or ldap exception. If operation exception is thrown, the operation + * will be retried. Otherwise the exception is propagated out. + * + * @param operationRetryResultCodes to compare result code against + * @param msg provider message + * @param resultCode provider result code + * @param matchedDn response matched dn + * @param respControls response controls + * @param referralUrls response referral urls + * @param throwLdapException throw an ldap exception if an operation exception is not thrown + * + * @throws OperationException if the operation should be retried + * @throws LdapException to propagate the exception out + */ + public static void throwOperationException( + final ResultCode[] operationRetryResultCodes, + final String msg, + final int resultCode, + final String matchedDn, + final ResponseControl[] respControls, + final String[] referralUrls, + final boolean throwLdapException) + throws LdapException + { + if (operationRetryResultCodes != null && operationRetryResultCodes.length > 0) { + for (ResultCode rc : operationRetryResultCodes) { + if (rc.value() == resultCode) { + throw new OperationException(msg, rc, matchedDn, respControls, referralUrls); + } + } + } + if (throwLdapException) { + throw new LdapException(msg, ResultCode.valueOf(resultCode), matchedDn, respControls, referralUrls); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/ResponseListener.java b/core/src/main/java/org/ldaptive/provider/ResponseListener.java new file mode 100644 index 0000000..a5ffa6b --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/ResponseListener.java
@@ -0,0 +1,38 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider; + +import org.ldaptive.Response; +import org.ldaptive.async.AsyncRequest; + +/** + * Response listener. + * + * @author Middleware Services + */ +public interface ResponseListener +{ + + + /** + * Invoked when an asynchronous operation has begun. + * + * @param request to abandon this operation + */ + void asyncRequestReceived(AsyncRequest request); + + + /** + * Invoked when a response is received from a provider indicating the operation has completed. + * + * @param response containing the result + */ + void responseReceived(Response<Void> response); + + + /** + * Invoked when an exception is thrown from a provider indicating the operation cannot be completed. + * + * @param exception thrown from the async operation + */ + void exceptionReceived(Exception exception); +}
diff --git a/core/src/main/java/org/ldaptive/provider/SearchItem.java b/core/src/main/java/org/ldaptive/provider/SearchItem.java new file mode 100644 index 0000000..6f9cf31 --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/SearchItem.java
@@ -0,0 +1,147 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider; + +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchReference; +import org.ldaptive.intermediate.IntermediateResponse; + +/** + * Contains the data returned from a search request. + * + * @author Middleware Services + */ +public class SearchItem +{ + + /** search entry. */ + private final SearchEntry searchEntry; + + /** search reference. */ + private final SearchReference searchReference; + + /** intermediate response. */ + private final IntermediateResponse intermediateResponse; + + + /** + * Creates a new search item. + * + * @param se ldap entry + */ + public SearchItem(final SearchEntry se) + { + searchEntry = se; + searchReference = null; + intermediateResponse = null; + } + + + /** + * Creates a new search item. + * + * @param sr searchReference + */ + public SearchItem(final SearchReference sr) + { + searchEntry = null; + searchReference = sr; + intermediateResponse = null; + } + + + /** + * Creates a new search item. + * + * @param ir intermediate response + */ + public SearchItem(final IntermediateResponse ir) + { + searchEntry = null; + searchReference = null; + intermediateResponse = ir; + } + + + /** + * Returns whether this search item contains a search entry. + * + * @return whether this search item contains a search entry + */ + public boolean isSearchEntry() + { + return searchEntry != null; + } + + + /** + * Returns the search entry in this search item or null if this search item does not contain a search entry. + * + * @return search entry + */ + public SearchEntry getSearchEntry() + { + return searchEntry; + } + + + /** + * Returns whether this search item contains a search reference. + * + * @return whether this search item contains a search reference + */ + public boolean isSearchReference() + { + return searchReference != null; + } + + + /** + * Returns the search reference in this search item or null if this search item does not contain a search reference. + * + * @return searchReference + */ + public SearchReference getSearchReference() + { + return searchReference; + } + + + /** + * Returns whether this search item contains an intermediate response. + * + * @return whether this search item contains an intermediate response + */ + public boolean isIntermediateResponse() + { + return intermediateResponse != null; + } + + + /** + * Returns the intermediate response in this search item or null if this search item does not contain an intermediate + * response. + * + * @return intermediate response + */ + public IntermediateResponse getIntermediateResponse() + { + return intermediateResponse; + } + + + @Override + public String toString() + { + String s; + if (isSearchEntry()) { + s = String.format("[%s@%d::searchEntry=%s]", getClass().getName(), hashCode(), searchEntry); + } else if (isSearchReference()) { + s = String.format("[%s@%d::searchReference=%s]", getClass().getName(), hashCode(), searchReference); + } else if (isIntermediateResponse()) { + s = String.format("[%s@%d::intermediateResponse=%s]", getClass().getName(), hashCode(), intermediateResponse); + } else { + s = String.format("[%s@%d]", getClass().getName(), hashCode()); + } + return s; + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/SearchIterator.java b/core/src/main/java/org/ldaptive/provider/SearchIterator.java new file mode 100644 index 0000000..19fca64 --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/SearchIterator.java
@@ -0,0 +1,53 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider; + +import org.ldaptive.LdapException; +import org.ldaptive.Response; + +/** + * Search results iterator. + * + * @author Middleware Services + */ +public interface SearchIterator +{ + + + /** + * Returns true if the iteration has more elements. + * + * @return true if the iterator has more elements + * + * @throws LdapException if an error occurs + */ + boolean hasNext() + throws LdapException; + + + /** + * Returns the next element in the iteration. + * + * @return the next element in the iteration + * + * @throws LdapException if an error occurs + */ + SearchItem next() + throws LdapException; + + + /** + * Returns the response data associated with this search or null if this iterator has more ldap entries to return. + * + * @return response data + */ + Response<Void> getResponse(); + + + /** + * Close any resources associated with this iterator. + * + * @throws LdapException if an error occurs + */ + void close() + throws LdapException; +}
diff --git a/core/src/main/java/org/ldaptive/provider/SearchListener.java b/core/src/main/java/org/ldaptive/provider/SearchListener.java new file mode 100644 index 0000000..50340d1 --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/SearchListener.java
@@ -0,0 +1,19 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider; + +/** + * Search results listener. + * + * @author Middleware Services + */ +public interface SearchListener extends ResponseListener +{ + + + /** + * Invoked when a search item is received from a provider. + * + * @param item containing a search result entry, reference, or intermediate response + */ + void searchItemReceived(SearchItem item); +}
diff --git a/core/src/main/java/org/ldaptive/provider/jndi/AttributesFactory.java b/core/src/main/java/org/ldaptive/provider/jndi/AttributesFactory.java new file mode 100644 index 0000000..f6b02f8 --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/jndi/AttributesFactory.java
@@ -0,0 +1,165 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jndi; + +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttribute; +import javax.naming.directory.BasicAttributes; + +/** + * Provides convenience methods for creating jndi attributes and attribute objects. + * + * @author Middleware Services + */ +public final class AttributesFactory +{ + + /** Default ignore case value, value of this constant is {@value}. */ + public static final boolean DEFAULT_IGNORE_CASE = true; + + + /** Default constructor. */ + private AttributesFactory() {} + + + /** + * Creates a new attributes. Attributes will be case-insensitive. + * + * @param name of the attribute + * + * @return attributes + */ + public static Attributes createAttributes(final String name) + { + return createAttributes(name, DEFAULT_IGNORE_CASE); + } + + + /** + * Creates a new attributes. + * + * @param name of the attribute + * @param ignoreCase whether to ignore the case of attribute values + * + * @return attributes + */ + public static Attributes createAttributes(final String name, final boolean ignoreCase) + { + return createAttributes(name, null, ignoreCase); + } + + + /** + * Creates a new attributes. Attributes will be case-insensitive. + * + * @param name of the attribute + * @param value of the attribute + * + * @return attributes + */ + public static Attributes createAttributes(final String name, final Object value) + { + return createAttributes(name, value, DEFAULT_IGNORE_CASE); + } + + + /** + * Creates a new attributes. + * + * @param name of the attribute + * @param value of the attribute + * @param ignoreCase whether to ignore the case of attribute values + * + * @return attributes + */ + public static Attributes createAttributes(final String name, final Object value, final boolean ignoreCase) + { + if (value == null) { + return createAttributes(name, null, ignoreCase); + } else { + return createAttributes(name, new Object[] {value}, ignoreCase); + } + } + + + /** + * Creates a new attributes. Attributes will be case-insensitive. + * + * @param name of the attribute + * @param values of the attribute + * + * @return attributes + */ + public static Attributes createAttributes(final String name, final Object[] values) + { + return createAttributes(name, values, DEFAULT_IGNORE_CASE); + } + + + /** + * Creates a new attributes. + * + * @param name of the attribute + * @param values of the attribute + * @param ignoreCase whether to ignore the case of attribute values + * + * @return attributes + */ + public static Attributes createAttributes(final String name, final Object[] values, final boolean ignoreCase) + { + final Attributes attrs = new BasicAttributes(ignoreCase); + attrs.put(createAttribute(name, values)); + return attrs; + } + + + /** + * Creates a new attribute. + * + * @param name of the attribute + * + * @return attribute + */ + public static Attribute createAttribute(final String name) + { + return createAttribute(name, null); + } + + + /** + * Creates a new attribute. + * + * @param name of the attribute + * @param value of the attribute + * + * @return attribute + */ + public static Attribute createAttribute(final String name, final Object value) + { + if (value == null) { + return createAttribute(name, null); + } else { + return createAttribute(name, new Object[] {value}); + } + } + + + /** + * Creates a new attribute. + * + * @param name of the attribute + * @param values of the attribute + * + * @return attribute + */ + public static Attribute createAttribute(final String name, final Object[] values) + { + final Attribute attr = new BasicAttribute(name); + if (values != null) { + for (Object o : values) { + attr.add(o); + } + } + return attr; + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/jndi/JndiConnection.java b/core/src/main/java/org/ldaptive/provider/jndi/JndiConnection.java new file mode 100644 index 0000000..7e2c639 --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/jndi/JndiConnection.java
@@ -0,0 +1,1196 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jndi; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.naming.CompositeName; +import javax.naming.InvalidNameException; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.ReferralException; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; +import javax.naming.ldap.Control; +import javax.naming.ldap.LdapContext; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.LdapReferralException; +import org.ldaptive.AddRequest; +import org.ldaptive.BindRequest; +import org.ldaptive.CompareRequest; +import org.ldaptive.DeleteRequest; +import org.ldaptive.DerefAliases; +import org.ldaptive.LdapException; +import org.ldaptive.ModifyDnRequest; +import org.ldaptive.ModifyRequest; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.ReturnAttributes; +import org.ldaptive.SearchReference; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchScope; +import org.ldaptive.control.RequestControl; +import org.ldaptive.control.ResponseControl; +import org.ldaptive.extended.ExtendedRequest; +import org.ldaptive.extended.ExtendedResponse; +import org.ldaptive.extended.ExtendedResponseFactory; +import org.ldaptive.extended.UnsolicitedNotificationListener; +import org.ldaptive.provider.ControlProcessor; +import org.ldaptive.provider.ProviderConnection; +import org.ldaptive.provider.ProviderUtils; +import org.ldaptive.provider.SearchItem; +import org.ldaptive.provider.SearchIterator; +import org.ldaptive.provider.SearchListener; +import org.ldaptive.sasl.DigestMd5Config; +import org.ldaptive.sasl.SaslConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * JNDI provider implementation of ldap operations. + * + * @author Middleware Services + */ +public class JndiConnection implements ProviderConnection +{ + + /** + * The value of this property is a string that specifies the authentication mechanism(s) for the provider to use. The + * value of this constant is {@value}. + */ + public static final String AUTHENTICATION = "java.naming.security.authentication"; + + /** + * The value of this property is an object that specifies the credentials of the principal to be authenticated. The + * value of this constant is {@value}. + */ + public static final String CREDENTIALS = "java.naming.security.credentials"; + + /** + * The value of this property is a string that specifies the identity of the principal to be authenticated. The value + * of this constant is {@value}. + */ + public static final String PRINCIPAL = "java.naming.security.principal"; + + /** + * The value of this property is a string that specifies the sasl authorization id. The value of this constant is + * {@value}. + */ + public static final String SASL_AUTHZ_ID = "java.naming.security.sasl.authorizationId"; + + /** + * The value of this property is a string that specifies the sasl quality of protection. The value of this constant is + * {@value}. + */ + public static final String SASL_QOP = "javax.security.sasl.qop"; + + /** + * The value of this property is a string that specifies the sasl security strength. The value of this constant is + * {@value}. + */ + public static final String SASL_STRENGTH = "javax.security.sasl.strength"; + + /** + * The value of this property is a string that specifies the sasl mutual authentication flag. The value of this + * constant is {@value}. + */ + public static final String SASL_MUTUAL_AUTH = "javax.security.sasl.server.authentication"; + + /** The value of this property is a string that specifies the sasl realm. The value of this constant is {@value}. */ + public static final String SASL_REALM = "java.naming.security.sasl.realm"; + + /** + * The value of this property is a string that specifies whether the RDN attribute should be deleted for a modify dn + * operation. The value of this constant is {@value}. + */ + public static final String DELETE_RDN = "java.naming.ldap.deleteRDN"; + + /** + * The value of this property is a string that specifies additional binary attributes. The value of this constant is + * {@value}. + */ + public static final String BINARY_ATTRIBUTES = "java.naming.ldap.attributes.binary"; + + /** + * The value of this property is a string that specifies how aliases shall be handled by the provider. The value of + * this constant is {@value}. + */ + public static final String DEREF_ALIASES = "java.naming.ldap.derefAliases"; + + /** + * The value of this property is a string that specifies how referrals shall be handled by the provider. The value of + * this constant is {@value}. + */ + public static final String REFERRAL = "java.naming.referral"; + + /** + * The value of this property is a string that specifies to only return attribute type names, no values. The value of + * this constant is {@value}. + */ + public static final String TYPES_ONLY = "java.naming.ldap.typesOnly"; + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Ldap context. */ + private LdapContext context; + + /** Provider configuration. */ + private final JndiProviderConfig config; + + + /** + * Creates a new jndi connection. + * + * @param lc ldap context + * @param pc provider configuration + */ + public JndiConnection(final LdapContext lc, final JndiProviderConfig pc) + { + context = lc; + config = pc; + } + + + /** + * Returns the underlying ldap context. + * + * @return ldap context + */ + public LdapContext getLdapContext() + { + return context; + } + + + @Override + public void close(final RequestControl[] controls) + throws LdapException + { + if (controls != null) { + throw new UnsupportedOperationException("Provider does not support unbind with controls"); + } + try { + if (context != null) { + context.close(); + } + } catch (NamingException e) { + ResultCode rc = NamingExceptionUtils.getResultCode(e.getClass()); + if (rc == null) { + rc = NamingExceptionUtils.getResultCode(e.getMessage()); + } + throw new LdapException(e, rc); + } finally { + context = null; + } + } + + + @Override + public Response<Void> bind(final BindRequest request) + throws LdapException + { + Response<Void> response; + if (request.getSaslConfig() != null) { + response = saslBind(request); + } else if (request.getDn() == null && request.getCredential() == null) { + response = anonymousBind(request); + } else { + response = simpleBind(request); + } + return response; + } + + + /** + * Performs an anonymous bind. + * + * @param request to bind with + * + * @return bind response + * + * @throws LdapException if an error occurs + */ + protected Response<Void> anonymousBind(final BindRequest request) + throws LdapException + { + Response<Void> response = null; + try { + context.addToEnvironment(AUTHENTICATION, "none"); + context.removeFromEnvironment(PRINCIPAL); + context.removeFromEnvironment(CREDENTIALS); + context.reconnect(config.getControlProcessor().processRequestControls(request.getControls())); + response = createResponse(request, null, ResultCode.SUCCESS, null, context); + } catch (ReferralException e) { + final String[] refUrls = e.getReferralInfo() != null ? new String[] {(String) e.getReferralInfo()} : null; + response = createResponse(request, null, ResultCode.REFERRAL, refUrls, context); + } catch (NamingException e) { + processNamingException(request, e, null, context); + } + return response; + } + + + /** + * Performs a simple bind. + * + * @param request to bind with + * + * @return bind response + * + * @throws LdapException if an error occurs + */ + protected Response<Void> simpleBind(final BindRequest request) + throws LdapException + { + Response<Void> response = null; + try { + context.addToEnvironment(AUTHENTICATION, "simple"); + context.addToEnvironment(PRINCIPAL, request.getDn()); + context.addToEnvironment(CREDENTIALS, request.getCredential().getBytes()); + context.reconnect(config.getControlProcessor().processRequestControls(request.getControls())); + response = createResponse(request, null, ResultCode.SUCCESS, null, context); + } catch (ReferralException e) { + final String[] refUrls = e.getReferralInfo() != null ? new String[] {(String) e.getReferralInfo()} : null; + response = createResponse(request, null, ResultCode.REFERRAL, refUrls, context); + } catch (NamingException e) { + processNamingException(request, e, null, context); + } + return response; + } + + + /** + * Performs a sasl bind. + * + * @param request to bind with + * + * @return bind response + * + * @throws LdapException if an error occurs + */ + protected Response<Void> saslBind(final BindRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final String authenticationType = JndiUtils.getAuthenticationType(request.getSaslConfig().getMechanism()); + for (Map.Entry<String, Object> entry : getSaslProperties(request.getSaslConfig()).entrySet()) { + context.addToEnvironment(entry.getKey(), entry.getValue()); + } + context.addToEnvironment(AUTHENTICATION, authenticationType); + if (request.getDn() != null) { + context.addToEnvironment(PRINCIPAL, request.getDn()); + if (request.getCredential() != null) { + context.addToEnvironment(CREDENTIALS, request.getCredential().getBytes()); + } + } + context.reconnect(config.getControlProcessor().processRequestControls(request.getControls())); + response = createResponse(request, null, ResultCode.SUCCESS, null, context); + } catch (ReferralException e) { + final String[] refUrls = e.getReferralInfo() != null ? new String[] {(String) e.getReferralInfo()} : null; + response = createResponse(request, null, ResultCode.REFERRAL, refUrls, context); + } catch (NamingException e) { + processNamingException(request, e, null, context); + } + return response; + } + + + @Override + public Response<Void> add(final AddRequest request) + throws LdapException + { + Response<Void> response = null; + LdapContext ctx = null; + try { + try { + ctx = initializeContext(request); + + final JndiUtils bu = new JndiUtils(); + ctx.createSubcontext(new LdapName(request.getDn()), bu.fromLdapAttributes(request.getLdapAttributes())).close(); + response = createResponse(request, null, ResultCode.SUCCESS, null, ctx); + } finally { + if (ctx != null) { + ctx.close(); + } + } + } catch (ReferralException e) { + final String[] refUrls = e.getReferralInfo() != null ? new String[] {(String) e.getReferralInfo()} : null; + response = createResponse(request, null, ResultCode.REFERRAL, refUrls, ctx); + } catch (NamingException e) { + processNamingException(request, e, null, ctx); + } + return response; + } + + + @Override + public Response<Boolean> compare(final CompareRequest request) + throws LdapException + { + Response<Boolean> response = null; + LdapContext ctx = null; + try { + NamingEnumeration<SearchResult> en = null; + try { + ctx = initializeContext(request); + en = ctx.search( + new LdapName(request.getDn()), + String.format("(%s={0})", request.getAttribute().getName()), + request.getAttribute().isBinary() ? new Object[] {request.getAttribute().getBinaryValue()} : new Object[] { + request.getAttribute().getStringValue(), + }, + getCompareSearchControls()); + + final boolean success = en.hasMore(); + response = createResponse( + request, + success, + success ? ResultCode.COMPARE_TRUE : ResultCode.COMPARE_FALSE, + null, + ctx); + } finally { + if (en != null) { + en.close(); + } + if (ctx != null) { + ctx.close(); + } + } + } catch (ReferralException e) { + final String[] refUrls = e.getReferralInfo() != null ? new String[] {(String) e.getReferralInfo()} : null; + response = createResponse(request, null, ResultCode.REFERRAL, refUrls, ctx); + } catch (NamingException e) { + processNamingException(request, e, null, ctx); + } + return response; + } + + + @Override + public Response<Void> delete(final DeleteRequest request) + throws LdapException + { + Response<Void> response = null; + LdapContext ctx = null; + try { + try { + ctx = initializeContext(request); + ctx.destroySubcontext(new LdapName(request.getDn())); + response = createResponse(request, null, ResultCode.SUCCESS, null, ctx); + } finally { + if (ctx != null) { + ctx.close(); + } + } + } catch (ReferralException e) { + final String[] refUrls = e.getReferralInfo() != null ? new String[] {(String) e.getReferralInfo()} : null; + response = createResponse(request, null, ResultCode.REFERRAL, refUrls, ctx); + } catch (NamingException e) { + processNamingException(request, e, null, ctx); + } + return response; + } + + + @Override + public Response<Void> modify(final ModifyRequest request) + throws LdapException + { + Response<Void> response = null; + LdapContext ctx = null; + try { + try { + ctx = initializeContext(request); + + final JndiUtils bu = new JndiUtils(); + ctx.modifyAttributes( + new LdapName(request.getDn()), + bu.fromAttributeModification(request.getAttributeModifications())); + response = createResponse(request, null, ResultCode.SUCCESS, null, ctx); + } finally { + if (ctx != null) { + ctx.close(); + } + } + } catch (ReferralException e) { + final String[] refUrls = e.getReferralInfo() != null ? new String[] {(String) e.getReferralInfo()} : null; + response = createResponse(request, null, ResultCode.REFERRAL, refUrls, ctx); + } catch (NamingException e) { + processNamingException(request, e, null, ctx); + } + return response; + } + + + @Override + public Response<Void> modifyDn(final ModifyDnRequest request) + throws LdapException + { + Response<Void> response = null; + LdapContext ctx = null; + try { + try { + ctx = initializeContext(request); + ctx.addToEnvironment("java.naming.ldap.deleteRDN", Boolean.valueOf(request.getDeleteOldRDn()).toString()); + ctx.rename(new LdapName(request.getDn()), new LdapName(request.getNewDn())); + response = createResponse(request, null, ResultCode.SUCCESS, null, ctx); + } finally { + if (ctx != null) { + ctx.close(); + } + } + } catch (ReferralException e) { + final String[] refUrls = e.getReferralInfo() != null ? new String[] {(String) e.getReferralInfo()} : null; + response = createResponse(request, null, ResultCode.REFERRAL, refUrls, ctx); + } catch (NamingException e) { + processNamingException(request, e, null, ctx); + } + return response; + } + + + @Override + public SearchIterator search(final SearchRequest request) + throws LdapException + { + final JndiSearchIterator i = new JndiSearchIterator(request); + i.initialize(); + return i; + } + + + @Override + public void searchAsync(final SearchRequest request, final SearchListener listener) + throws LdapException + { + throw new UnsupportedOperationException("Asynchronous searches not supported"); + } + + + @Override + public void abandon(final int messageId, final RequestControl[] controls) + throws LdapException + { + throw new UnsupportedOperationException("Abandons not supported"); + } + + + @Override + public Response<?> extendedOperation(final ExtendedRequest request) + throws LdapException + { + Response<?> response = null; + LdapContext ctx = null; + try { + try { + ctx = initializeContext(request); + + final JndiExtendedResponse jndiExtRes = (JndiExtendedResponse) ctx.extendedOperation( + new JndiExtendedRequest(request.getOID(), request.encode())); + final ExtendedResponse<?> extRes = ExtendedResponseFactory.createExtendedResponse( + request.getOID(), + jndiExtRes.getID(), + jndiExtRes.getEncodedValue()); + response = createResponse(request, extRes.getValue(), ResultCode.SUCCESS, null, ctx); + } finally { + if (ctx != null) { + ctx.close(); + } + } + } catch (ReferralException e) { + final String[] refUrls = e.getReferralInfo() != null ? new String[] {(String) e.getReferralInfo()} : null; + response = createResponse(request, null, ResultCode.REFERRAL, refUrls, ctx); + } catch (NamingException e) { + processNamingException(request, e, null, ctx); + } + return response; + } + + + @Override + public void addUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + throw new UnsupportedOperationException("Unsolicited notifications not supported"); + } + + + @Override + public void removeUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + throw new UnsupportedOperationException("Unsolicited notifications not supported"); + } + + + /** + * Returns a search controls object configured to perform an LDAP compare operation. + * + * @return search controls + */ + public static SearchControls getCompareSearchControls() + { + final SearchControls ctls = new SearchControls(); + ctls.setReturningAttributes(new String[0]); + ctls.setSearchScope(SearchScope.OBJECT.ordinal()); + return ctls; + } + + + /** + * Creates a new ldap context using {@link LdapContext#newInstance(Control[])}. Adds any additional environment + * properties found in the supplied request to the context. + * + * @param request to read properties from + * + * @return ldap context + * + * @throws NamingException if a property cannot be added to the context + */ + protected LdapContext initializeContext(final Request request) + throws NamingException + { + final LdapContext ctx = context.newInstance( + config.getControlProcessor().processRequestControls(request.getControls())); + + // by default set referral behavior to throw, otherwise jndi will send the + // ManageDsaIT control + ctx.addToEnvironment(REFERRAL, "throw"); + return ctx; + } + + + /** + * Creates an operation response with the supplied response data. + * + * @param <T> type of response + * @param request containing controls + * @param result of the operation + * @param code operation result code + * @param urls referral urls + * @param ctx ldap context + * + * @return operation response + */ + protected <T> Response<T> createResponse( + final Request request, + final T result, + final ResultCode code, + final String[] urls, + final LdapContext ctx) + { + return + new Response<>( + result, + code, + null, + null, + processResponseControls(config.getControlProcessor(), request.getControls(), ctx), + urls, + -1); + } + + + /** + * Determines if the supplied naming exception should result in an operation retry. + * + * @param request that produced the exception + * @param e that was produced + * @param urls referral urls + * @param ctx that the exception occurred on + * + * @throws LdapException wrapping the naming exception + */ + protected void processNamingException( + final Request request, + final NamingException e, + final String[] urls, + final LdapContext ctx) + throws LdapException + { + ResultCode rc = NamingExceptionUtils.getResultCode(e.getClass()); + if (rc == null) { + rc = NamingExceptionUtils.getResultCode(e.getMessage()); + } + ProviderUtils.throwOperationException( + config.getOperationExceptionResultCodes(), + e, + rc != null ? rc.value() : -1, + null, + processResponseControls(config.getControlProcessor(), request.getControls(), ctx), + urls, + true); + } + + + /** + * Retrieves the response controls from the supplied context and processes them with the supplied control processor. + * Logs a warning if controls cannot be retrieved. + * + * @param processor control processor + * @param requestControls that produced this response + * @param ctx to get controls from + * + * @return response controls + */ + protected ResponseControl[] processResponseControls( + final ControlProcessor<Control> processor, + final RequestControl[] requestControls, + final LdapContext ctx) + { + ResponseControl[] ctls = null; + if (ctx != null) { + try { + ctls = processor.processResponseControls(ctx.getResponseControls()); + } catch (NamingException e) { + final Logger l = LoggerFactory.getLogger(JndiUtils.class); + l.warn("Error retrieving response controls.", e); + } + } + return ctls; + } + + + /** + * Returns the JNDI properties for the supplied sasl configuration. + * + * @param config sasl configuration + * + * @return JNDI properties for use in a context environment + */ + protected static Map<String, Object> getSaslProperties(final SaslConfig config) + { + final Map<String, Object> env = new HashMap<>(); + if (config.getAuthorizationId() != null && !"".equals(config.getAuthorizationId())) { + env.put(SASL_AUTHZ_ID, config.getAuthorizationId()); + } + if (config.getQualityOfProtection() != null) { + env.put(SASL_QOP, JndiUtils.getQualityOfProtection(config.getQualityOfProtection())); + } + if (config.getSecurityStrength() != null) { + env.put(SASL_STRENGTH, JndiUtils.getSecurityStrength(config.getSecurityStrength())); + } + if (config.getMutualAuthentication() != null) { + env.put(SASL_MUTUAL_AUTH, config.getMutualAuthentication().toString()); + } + if (config instanceof DigestMd5Config) { + if (((DigestMd5Config) config).getRealm() != null) { + env.put(SASL_REALM, ((DigestMd5Config) config).getRealm()); + } + } + return env; + } + + + /** Search iterator for JNDI naming enumeration. */ + protected class JndiSearchIterator implements SearchIterator + { + + /** Search request. */ + private final SearchRequest request; + + /** Response data. */ + private Response<Void> response; + + /** Response result code. */ + private ResultCode responseResultCode; + + /** Search reference URLs. */ + private List<String> searchReferences; + + /** Ldap context to search with. */ + private LdapContext searchContext; + + /** Results read from the search operation. */ + private NamingEnumeration<SearchResult> results; + + + /** + * Creates a new jndi search iterator. + * + * @param sr search request + */ + public JndiSearchIterator(final SearchRequest sr) + { + request = sr; + } + + + /** + * Initializes this jndi search iterator. + * + * @throws LdapException if an error occurs + */ + public void initialize() + throws LdapException + { + boolean closeContext = false; + try { + searchContext = context.newInstance(config.getControlProcessor().processRequestControls(request.getControls())); + initializeSearchContext(searchContext, request); + results = search(searchContext, request); + } catch (LdapReferralException e) { + closeContext = true; + response = createResponse(request, null, ResultCode.REFERRAL, readReferralUrls(e), searchContext); + } catch (NamingException e) { + closeContext = true; + processNamingException(request, e, null, searchContext); + } finally { + if (closeContext) { + try { + if (searchContext != null) { + searchContext.close(); + } + } catch (NamingException e) { + logger.debug("Problem closing context", e); + } + } + } + } + + + /** + * Adds any additional environment properties found in the supplied request to the supplied context. + * + * @param ctx to initialize for searching + * @param sr to read properties from + * + * @throws NamingException if a property cannot be added to the context + */ + protected void initializeSearchContext(final LdapContext ctx, final SearchRequest sr) + throws NamingException + { + // by default set referral behavior to throw, otherwise jndi will send the + // ManageDsaIT control + ctx.addToEnvironment(REFERRAL, "throw"); + // by default set dereferencing aliases to never, jndi default is always + if (sr.getDerefAliases() != null) { + ctx.addToEnvironment(DEREF_ALIASES, sr.getDerefAliases().name().toLowerCase()); + } else { + ctx.addToEnvironment(DEREF_ALIASES, DerefAliases.NEVER.name().toLowerCase()); + } + if (sr.getBinaryAttributes() != null) { + final String[] a = sr.getBinaryAttributes(); + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < a.length; i++) { + sb.append(a[i]); + if (i < a.length - 1) { + sb.append(" "); + } + } + ctx.addToEnvironment(BINARY_ATTRIBUTES, sb.toString()); + } + if (sr.getTypesOnly()) { + ctx.addToEnvironment(TYPES_ONLY, Boolean.valueOf(sr.getTypesOnly()).toString()); + } + } + + + /** + * Executes {@link LdapContext#search( javax.naming.Name, String, Object[], SearchControls)}. + * + * @param ctx to search + * @param sr to read properties from + * + * @return naming enumeration of search results + * + * @throws NamingException if an error occurs + */ + protected NamingEnumeration<SearchResult> search(final LdapContext ctx, final SearchRequest sr) + throws NamingException + { + return + ctx.search( + sr.getBaseDn(), + sr.getSearchFilter() != null ? request.getSearchFilter().format() : null, + getSearchControls(sr)); + } + + + /** + * Returns a search controls object configured with the supplied search request. + * + * @param sr search request containing configuration to create search controls + * + * @return search controls + */ + protected SearchControls getSearchControls(final SearchRequest sr) + { + final SearchControls ctls = new SearchControls(); + if (ReturnAttributes.DEFAULT.equalsAttributes(sr.getReturnAttributes())) { + ctls.setReturningAttributes(null); + } else { + ctls.setReturningAttributes(sr.getReturnAttributes()); + } + + final int searchScope = getSearchScope(sr.getSearchScope()); + if (searchScope != -1) { + ctls.setSearchScope(searchScope); + } + ctls.setTimeLimit((int) sr.getTimeLimit().toMillis()); + ctls.setCountLimit(sr.getSizeLimit()); + ctls.setDerefLinkFlag(false); + // note that if returning obj flag is set to true, object contexts on the + // SearchResult must the explicitly closed: + // ctx = (Context) SearchResult#getObject(); ctx.close(); + ctls.setReturningObjFlag(false); + return ctls; + } + + + /** + * Returns the jndi integer constant for the supplied search scope. + * + * @param ss search scope + * + * @return integer constant + */ + protected int getSearchScope(final SearchScope ss) + { + int scope = -1; + if (ss == SearchScope.OBJECT) { + scope = SearchControls.OBJECT_SCOPE; + } else if (ss == SearchScope.ONELEVEL) { + scope = SearchControls.ONELEVEL_SCOPE; + } else if (ss == SearchScope.SUBTREE) { + scope = SearchControls.SUBTREE_SCOPE; + } + return scope; + } + + + @Override + public boolean hasNext() + throws LdapException + { + if (results == null || response != null) { + return false; + } + + boolean more = false; + if (searchReferences != null) { + more = true; + } else { + try { + more = results.hasMore(); + if (!more) { + response = createResponse( + request, + null, + responseResultCode != null ? responseResultCode : ResultCode.SUCCESS, + null, + searchContext); + } + } catch (LdapReferralException e) { + searchReferences = new ArrayList<>(Arrays.asList(readReferralUrls(e))); + more = true; + } catch (NamingException e) { + final ResultCode ignoreRc = ignoreSearchException(config.getSearchIgnoreResultCodes(), e); + if (ignoreRc == null) { + processNamingException(request, e, null, searchContext); + } + response = createResponse(request, null, ignoreRc, null, searchContext); + } + } + return more; + } + + + @Override + public SearchItem next() + throws LdapException + { + SearchItem item = null; + if (searchReferences != null) { + if (!searchReferences.isEmpty()) { + item = new SearchItem(new SearchReference(-1, null, searchReferences.remove(0))); + } + if (searchReferences.isEmpty()) { + response = createResponse(request, null, ResultCode.SUCCESS, null, searchContext); + } + } else { + final JndiUtils bu = new JndiUtils(request.getSortBehavior()); + try { + final SearchResult result = results.next(); + logger.trace("reading search result: {}", result); + result.setName(formatDn(result, getSearchDn(searchContext, request))); + item = new SearchItem(bu.toSearchEntry(result)); + } catch (LdapReferralException e) { + item = new SearchItem(new SearchReference(-1, null, readReferralUrls(e))); + } catch (NamingException e) { + final ResultCode ignoreRc = ignoreSearchException(config.getSearchIgnoreResultCodes(), e); + if (ignoreRc == null) { + processNamingException(request, e, null, searchContext); + } + responseResultCode = ignoreRc; + } + } + return item; + } + + + /** + * Determines whether the supplied naming exception should be ignored. + * + * @param ignoreResultCodes to match against the exception + * @param e naming exception to match + * + * @return result code that should be ignored or null + */ + protected ResultCode ignoreSearchException(final ResultCode[] ignoreResultCodes, final NamingException e) + { + ResultCode ignore = null; + if (ignoreResultCodes != null && ignoreResultCodes.length > 0) { + for (ResultCode rc : ignoreResultCodes) { + if (NamingExceptionUtils.matches(e.getClass(), rc)) { + logger.debug("Ignoring naming exception", e); + ignore = rc; + break; + } + } + } + return ignore; + } + + + /** + * Reads all referral URLs associated with this exception by invoking the search operation on the referral context + * until all referrals have been read. JNDI does not distinguish the URLs contained in specific references. So each + * URL must be treated as a separate search reference. + * + * @param refEx to read URLs from + * + * @return referral urls + */ + protected String[] readReferralUrls(final LdapReferralException refEx) + { + final List<String> urls = new ArrayList<>(); + LdapReferralException loopEx = refEx; + urls.add((String) loopEx.getReferralInfo()); + while (loopEx.skipReferral()) { + try { + final LdapContext ctx = (LdapContext) loopEx.getReferralContext( + searchContext.getEnvironment(), + config.getControlProcessor().processRequestControls(request.getControls())); + search(ctx, request); + } catch (LdapReferralException e) { + if (e.getReferralInfo() != null && e.getReferralInfo() instanceof String) { + urls.add((String) e.getReferralInfo()); + } + loopEx = e; + } catch (NamingException namingEx) { + logger.warn("Error reading search references", namingEx); + break; + } + } + logger.trace("read search references: {}", urls); + return urls.toArray(new String[urls.size()]); + } + + + @Override + public Response<Void> getResponse() + { + return response; + } + + + /** + * Determines the DN of the supplied search request. Returns {@link LdapContext#getNameInNamespace()} if it is + * available, otherwise returns {@link SearchRequest#getBaseDn()}. + * + * @param ctx ldap context the search was performed on + * @param sr search request + * + * @return DN + * + * @throws NamingException if an error occurs + */ + protected String getSearchDn(final LdapContext ctx, final SearchRequest sr) + throws NamingException + { + if (ctx != null && !"".equals(ctx.getNameInNamespace())) { + return ctx.getNameInNamespace(); + } else { + return sr.getBaseDn(); + } + } + + + /** + * Returns a fully-qualified DN for the supplied search result. If search result is relative, the DN is created with + * {@link SearchResult#getNameInNamespace()}. Otherwise the behavior is controlled by {@link + * JndiProviderConfig#getRemoveDnUrls()}. + * + * @param sr to determine DN for + * @param baseDn that search was performed on + * + * @return fully qualified DN + * + * @throws NamingException if search result name cannot be formatted as a DN + */ + protected String formatDn(final SearchResult sr, final String baseDn) + throws NamingException + { + String fqName; + if (sr.isRelative()) { + logger.trace("formatting relative dn '{}'", sr.getNameInNamespace()); + final LdapName lname = new LdapName(sr.getNameInNamespace()); + fqName = lname.toString(); + } else { + logger.trace("formatting non-relative dn '{}'", sr.getName()); + if (config.getRemoveDnUrls()) { + fqName = readCompositeName(URI.create(sr.getName()).getPath().substring(1)); + } else { + fqName = readCompositeName(sr.getName()); + } + } + logger.trace("formatted dn '{}'", fqName); + return fqName; + } + + + /** + * Uses a composite name to parse the supplied string. + * + * @param s composite name to read + * + * @return ldap name + * + * @throws InvalidNameException if the supplied string is not a valid composite name + */ + protected String readCompositeName(final String s) + throws InvalidNameException + { + final StringBuilder name = new StringBuilder(); + final CompositeName cName = new CompositeName(s); + for (int i = 0; i < cName.size(); i++) { + name.append(cName.get(i)); + if (i + 1 < cName.size()) { + name.append("/"); + } + } + return name.toString(); + } + + + @Override + public void close() + throws LdapException + { + try { + if (results != null) { + results.close(); + } + } catch (NamingException e) { + logger.error("Error closing naming enumeration", e); + } + try { + if (searchContext != null) { + searchContext.close(); + } + } catch (NamingException e) { + logger.error("Error closing ldap context", e); + } + } + } + + + /** Class for exposing extended request properties. */ + protected static class JndiExtendedRequest implements javax.naming.ldap.ExtendedRequest + { + + /** OID of the extended request. */ + private final String oid; + + /** BER encoded request data. */ + private final byte[] encoded; + + + /** + * Creates a new jndi extended request. + * + * @param id request oid + * @param berValue BER encoded request + */ + public JndiExtendedRequest(final String id, final byte[] berValue) + { + oid = id; + encoded = berValue; + } + + + @Override + public String getID() + { + return oid; + } + + + @Override + public byte[] getEncodedValue() + { + return encoded; + } + + + @Override + public javax.naming.ldap.ExtendedResponse createExtendedResponse( + final String id, + final byte[] berValue, + final int offset, + final int length) + throws NamingException + { + byte[] b = null; + if (berValue != null) { + b = new byte[length]; + System.arraycopy(berValue, offset, b, 0, length); + } + return new JndiExtendedResponse(id, b); + } + } + + + /** Class for exposing extended response properties. */ + protected static class JndiExtendedResponse implements javax.naming.ldap.ExtendedResponse + { + + /** OID of the extended response. */ + private final String oid; + + /** BER encoded response data. */ + private final byte[] encoded; + + + /** + * Creates a new jndi extended response. + * + * @param id response oid + * @param berValue BER encoded response + */ + public JndiExtendedResponse(final String id, final byte[] berValue) + { + oid = id; + encoded = berValue; + } + + + @Override + public String getID() + { + return oid; + } + + + @Override + public byte[] getEncodedValue() + { + return encoded; + } + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/jndi/JndiConnectionFactory.java b/core/src/main/java/org/ldaptive/provider/jndi/JndiConnectionFactory.java new file mode 100644 index 0000000..c969076 --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/jndi/JndiConnectionFactory.java
@@ -0,0 +1,109 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jndi; + +import java.util.Collections; +import java.util.Hashtable; +import java.util.Map; +import javax.naming.NamingException; +import javax.naming.ldap.InitialLdapContext; +import org.ldaptive.ConnectionStrategy; +import org.ldaptive.LdapException; +import org.ldaptive.provider.AbstractProviderConnectionFactory; +import org.ldaptive.provider.ConnectionException; +import org.ldaptive.ssl.SslConfig; +import org.ldaptive.ssl.ThreadLocalTLSSocketFactory; + +/** + * Creates connections using the JNDI {@link InitialLdapContext} class. + * + * @author Middleware Services + */ +public class JndiConnectionFactory extends AbstractProviderConnectionFactory<JndiProviderConfig> +{ + + /** Environment properties. */ + private final Map<String, Object> environment; + + /** Context class loader to use when instantiating {@link InitialLdapContext}. */ + private final ClassLoader classLoader; + + /** Thread local SslConfig, if one exists. */ + private SslConfig threadLocalSslConfig; + + + /** + * Creates a new jndi connection factory. + * + * @param url of the ldap to connect to + * @param strategy connection strategy + * @param config provider configuration + * @param env jndi context environment + * @param cl class loader + */ + public JndiConnectionFactory( + final String url, + final ConnectionStrategy strategy, + final JndiProviderConfig config, + final Map<String, Object> env, + final ClassLoader cl) + { + super(url, strategy, config); + environment = Collections.unmodifiableMap(env); + classLoader = cl; + if (ThreadLocalTLSSocketFactory.class.getName().equals(environment.get(JndiProvider.SOCKET_FACTORY))) { + threadLocalSslConfig = new ThreadLocalTLSSocketFactory().getSslConfig(); + } + } + + + @Override + protected JndiConnection createInternal(final String url) + throws LdapException + { + if ( + threadLocalSslConfig != null && + ThreadLocalTLSSocketFactory.class.getName().equals(environment.get(JndiProvider.SOCKET_FACTORY))) { + final ThreadLocalTLSSocketFactory sf = new ThreadLocalTLSSocketFactory(); + sf.setSslConfig(threadLocalSslConfig); + } + + // CheckStyle:IllegalType OFF + // the JNDI API requires the Hashtable type + final Hashtable<String, Object> env = new Hashtable<>(environment); + // CheckStyle:IllegalType ON + env.put(JndiProvider.PROVIDER_URL, url); + + JndiConnection conn; + try { + if (classLoader != null) { + final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(classLoader); + conn = new JndiConnection(new InitialLdapContext(env, null), getProviderConfig()); + } finally { + Thread.currentThread().setContextClassLoader(currentClassLoader); + } + } else { + conn = new JndiConnection(new InitialLdapContext(env, null), getProviderConfig()); + } + } catch (NamingException e) { + throw new ConnectionException(e, NamingExceptionUtils.getResultCode(e.getClass())); + } + return conn; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::metadata=%s, environment=%s, classLoader=%s, providerConfig=%s]", + getClass().getName(), + hashCode(), + getMetadata(), + environment, + classLoader, + getProviderConfig()); + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/jndi/JndiControlHandler.java b/core/src/main/java/org/ldaptive/provider/jndi/JndiControlHandler.java new file mode 100644 index 0000000..7810c24 --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/jndi/JndiControlHandler.java
@@ -0,0 +1,52 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jndi; + +import org.ldaptive.control.ControlFactory; +import org.ldaptive.control.RequestControl; +import org.ldaptive.control.ResponseControl; +import org.ldaptive.provider.ControlHandler; + +/** + * JNDI request control handler. + * + * @author Middleware Services + */ +public class JndiControlHandler implements ControlHandler<javax.naming.ldap.Control> +{ + + + @Override + public Class<javax.naming.ldap.Control> getControlType() + { + return javax.naming.ldap.Control.class; + } + + + @Override + public String getOID(final javax.naming.ldap.Control control) + { + return control.getID(); + } + + + @Override + public javax.naming.ldap.Control handleRequest(final RequestControl requestControl) + { + return + new javax.naming.ldap.BasicControl( + requestControl.getOID(), + requestControl.getCriticality(), + requestControl.encode()); + } + + + @Override + public ResponseControl handleResponse(final javax.naming.ldap.Control responseControl) + { + return + ControlFactory.createResponseControl( + responseControl.getID(), + responseControl.isCritical(), + responseControl.getEncodedValue()); + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/jndi/JndiProvider.java b/core/src/main/java/org/ldaptive/provider/jndi/JndiProvider.java new file mode 100644 index 0000000..3385627 --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/jndi/JndiProvider.java
@@ -0,0 +1,233 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jndi; + +import java.security.GeneralSecurityException; +import java.util.HashMap; +import java.util.Map; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSocketFactory; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.LdapURL; +import org.ldaptive.provider.Provider; +import org.ldaptive.provider.ProviderConnectionFactory; +import org.ldaptive.ssl.HostnameVerifierAdapter; +import org.ldaptive.ssl.SslConfig; +import org.ldaptive.ssl.TLSSocketFactory; +import org.ldaptive.ssl.ThreadLocalTLSSocketFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Exposes a connection factory for creating connections with JNDI. + * + * @author Middleware Services + */ +public class JndiProvider implements Provider<JndiProviderConfig> +{ + + /** + * The value of this property is a fully qualified class name of the factory class which creates the initial context + * for the LDAP service provider. The value of this constant is {@value}. + */ + public static final String CONTEXT_FACTORY = "java.naming.factory.initial"; + + /** + * The value of this property is a string that specifies the protocol version for the provider. The value of this + * constant is {@value}. + */ + public static final String VERSION = "java.naming.ldap.version"; + + /** + * The value of this property is a URL string that specifies the hostname and port number of the LDAP server, and the + * root distinguished name of the naming context to use. The value of this constant is {@value}. + */ + public static final String PROVIDER_URL = "java.naming.provider.url"; + + /** + * The value of this property is a string that specifies the security protocol for the provider to use. The value of + * this constant is {@value}. + */ + public static final String PROTOCOL = "java.naming.security.protocol"; + + /** + * The value of this property is a string identifying the class name of a socket factory. The value of this constant + * is {@value}. + */ + public static final String SOCKET_FACTORY = "java.naming.ldap.factory.socket"; + + /** + * The value of this property is a string that specifies the time in milliseconds that a connection attempt will abort + * if the connection cannot be made. The value of this constant is {@value}. + */ + public static final String CONNECT_TIMEOUT = "com.sun.jndi.ldap.connect.timeout"; + + /** + * The value of this property is a string that specifies the time in milliseconds that an operation will abort if a + * response is not received. The value of this constant is {@value}. + */ + public static final String READ_TIMEOUT = "com.sun.jndi.ldap.read.timeout"; + + /** + * The value of this property is a java.io.OutputStream object into which a hexadecimal dump of the incoming and + * outgoing LDAP ASN.1 BER packets is written. The value of this constant is {@value}. + */ + public static final String TRACE = "com.sun.jndi.ldap.trace.ber"; + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Provider configuration. */ + private JndiProviderConfig config = new JndiProviderConfig(); + + + @Override + public ProviderConnectionFactory<JndiProviderConfig> getConnectionFactory(final ConnectionConfig cc) + { + ProviderConnectionFactory<JndiProviderConfig> cf; + if (cc.getUseStartTLS()) { + cf = getJndiStartTLSConnectionFactory(cc, config.getEnvironment()); + } else { + cf = getJndiConnectionFactory(cc, config.getEnvironment()); + } + return cf; + } + + + @Override + public JndiProviderConfig getProviderConfig() + { + return config; + } + + + @Override + public void setProviderConfig(final JndiProviderConfig jpc) + { + config = jpc; + } + + + @Override + public JndiProvider newInstance() + { + return new JndiProvider(); + } + + + /** + * Returns a jndi startTLS connection factory using the properties found in the supplied connection config. If the + * supplied env is null, the environment is retrieved from {@link #getDefaultEnvironment(ConnectionConfig, String)}. + * + * @param cc connection config + * @param env context environment or null to use the default + * + * @return jndi startTLS connection factory + */ + protected JndiStartTLSConnectionFactory getJndiStartTLSConnectionFactory( + final ConnectionConfig cc, + final Map<String, Object> env) + { + // hostname verification always occurs for startTLS after the handshake + SSLSocketFactory factory = config.getSslSocketFactory(); + if (factory == null && cc.getSslConfig() != null && !cc.getSslConfig().isEmpty()) { + final TLSSocketFactory sf = new TLSSocketFactory(); + sf.setSslConfig(SslConfig.newSslConfig(cc.getSslConfig())); + try { + sf.initialize(); + } catch (GeneralSecurityException e) { + throw new IllegalArgumentException(e); + } + factory = sf; + } + HostnameVerifier verifier = config.getHostnameVerifier(); + if (verifier == null && cc.getSslConfig() != null && !cc.getSslConfig().isEmpty()) { + if (cc.getSslConfig().getHostnameVerifier() != null) { + verifier = new HostnameVerifierAdapter(cc.getSslConfig().getHostnameVerifier()); + } + } + return + new JndiStartTLSConnectionFactory( + cc.getLdapUrl(), + cc.getConnectionStrategy(), + config, + env != null ? env : getDefaultEnvironment(cc, null), + config.getClassLoader(), + factory, + verifier); + } + + + /** + * Returns a jndi connection factory using the properties found in the supplied connection config. If the supplied env + * is null, the environment is retrieved from {@link #getDefaultEnvironment(ConnectionConfig, String)}. + * + * @param cc connection config + * @param env context environment or null to use the default + * + * @return jndi connection factory + */ + protected JndiConnectionFactory getJndiConnectionFactory(final ConnectionConfig cc, final Map<String, Object> env) + { + SSLSocketFactory factory = config.getSslSocketFactory(); + if (factory == null && (cc.getUseSSL() || cc.getLdapUrl().toLowerCase().contains("ldaps://"))) { + // LDAPS hostname verification does not occur by default + // set a default hostname verifier + final LdapURL ldapUrl = new LdapURL(cc.getLdapUrl()); + factory = ThreadLocalTLSSocketFactory.getHostnameVerifierFactory(cc.getSslConfig(), ldapUrl.getHostnames()); + } + ClassLoader classLoader = config.getClassLoader(); + if (classLoader == null && factory != null) { + try { + Thread.currentThread().getContextClassLoader().loadClass(factory.getClass().getName()); + } catch (ClassNotFoundException e) { + classLoader = factory.getClass().getClassLoader(); + logger.debug("Could not find {}, using class loader {}", factory.getClass(), classLoader); + } + } + return + new JndiConnectionFactory( + cc.getLdapUrl(), + cc.getConnectionStrategy(), + config, + env != null ? env : getDefaultEnvironment(cc, factory != null ? factory.getClass().getName() : null), + classLoader); + } + + + /** + * Returns the configuration environment for a JNDI ldap context using the properties found in the supplied connection + * config. + * + * @param cc connection config + * @param factory class name of the socket factory to use for LDAPS + * + * @return JNDI ldap context environment + */ + protected Map<String, Object> getDefaultEnvironment(final ConnectionConfig cc, final String factory) + { + final Map<String, Object> env = new HashMap<>(); + env.put(CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + env.put(VERSION, "3"); + if (cc.getUseSSL()) { + env.put(PROTOCOL, "ssl"); + } + if (factory != null && (cc.getUseSSL() || cc.getLdapUrl().toLowerCase().contains("ldaps://"))) { + env.put(JndiProvider.SOCKET_FACTORY, factory); + } + if (cc.getConnectTimeout() != null) { + env.put(CONNECT_TIMEOUT, Long.toString(cc.getConnectTimeout().toMillis())); + } + if (cc.getResponseTimeout() != null) { + env.put(READ_TIMEOUT, Long.toString(cc.getResponseTimeout().toMillis())); + } + if (config.getTracePackets() != null) { + env.put(JndiProvider.TRACE, config.getTracePackets()); + } + if (!config.getProperties().isEmpty()) { + for (Map.Entry<String, Object> entry : config.getProperties().entrySet()) { + env.put(entry.getKey(), entry.getValue()); + } + } + return env; + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/jndi/JndiProviderConfig.java b/core/src/main/java/org/ldaptive/provider/jndi/JndiProviderConfig.java new file mode 100644 index 0000000..7edd4db --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/jndi/JndiProviderConfig.java
@@ -0,0 +1,266 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jndi; + +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Map; +import javax.naming.ldap.Control; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSocketFactory; +import org.ldaptive.ResultCode; +import org.ldaptive.provider.ControlProcessor; +import org.ldaptive.provider.ProviderConfig; +import org.ldaptive.ssl.AllowAnyHostnameVerifier; + +/** + * Contains configuration data for the JNDI provider. + * + * @author Middleware Services + */ +public class JndiProviderConfig extends ProviderConfig<Control> +{ + + /** + * Boolean property that indicates whether hostname verification should be disabled for StartTLS connections. The + * value of this constant is {@value}. + */ + protected static final String ALLOW_ANY_HOSTNAME = "jndi.starttls.allowAnyHostname"; + + /** Context environment. */ + private Map<String, Object> environment; + + /** Stream to print LDAP ASN.1 BER packets. */ + private OutputStream tracePackets; + + /** Whether to remove the URL from any DNs which are not relative. */ + private boolean removeDnUrls = true; + + /** Search result codes to ignore. */ + private ResultCode[] searchIgnoreResultCodes; + + /** Context class loader. */ + private ClassLoader classLoader; + + /** ldap socket factory used for SSL and startTLS. */ + private SSLSocketFactory sslSocketFactory; + + /** hostname verifier for startTLS connections. */ + private HostnameVerifier hostnameVerifier; + + + /** Default constructor. */ + public JndiProviderConfig() + { + setOperationExceptionResultCodes(ResultCode.PROTOCOL_ERROR, ResultCode.SERVER_DOWN); + searchIgnoreResultCodes = new ResultCode[] { + ResultCode.TIME_LIMIT_EXCEEDED, + ResultCode.SIZE_LIMIT_EXCEEDED, + ResultCode.PARTIAL_RESULTS, + }; + setControlProcessor(new ControlProcessor<>(new JndiControlHandler())); + } + + + /** + * Returns the context environment. + * + * @return ldap context environment + */ + public Map<String, Object> getEnvironment() + { + return environment; + } + + + /** + * Sets the context environment. + * + * @param env ldap context environment + */ + public void setEnvironment(final Map<String, Object> env) + { + checkImmutable(); + logger.trace("setting environment: {}", env); + environment = env; + } + + + /** + * Returns the output stream used to print ASN.1 BER packets. + * + * @return output stream + */ + public OutputStream getTracePackets() + { + return tracePackets; + } + + + /** + * Sets the output stream to print ASN.1 BER packets to. + * + * @param stream to output to + */ + public void setTracePackets(final OutputStream stream) + { + checkImmutable(); + logger.trace("setting tracePackets: {}", stream); + tracePackets = stream; + } + + + /** + * Returns whether the URL will be removed from any DNs which are not relative. The default value is true. + * + * @return whether the URL will be removed from DNs + */ + public boolean getRemoveDnUrls() + { + return removeDnUrls; + } + + + /** + * Sets whether the URL will be removed from any DNs which are not relative The default value is true. + * + * @param b whether the URL will be removed from DNs + */ + public void setRemoveDnUrls(final boolean b) + { + checkImmutable(); + logger.trace("setting removeDnUrls: {}", b); + removeDnUrls = b; + } + + + /** + * Returns the search ignore result codes. + * + * @return result codes to ignore + */ + public ResultCode[] getSearchIgnoreResultCodes() + { + return searchIgnoreResultCodes; + } + + + /** + * Sets the search ignore result codes. + * + * @param codes to ignore + */ + public void setSearchIgnoreResultCodes(final ResultCode... codes) + { + checkImmutable(); + logger.trace("setting searchIgnoreResultCodes: {}", Arrays.toString(codes)); + searchIgnoreResultCodes = codes; + } + + + /** + * Returns the class loader to use when creating JNDI contexts. + * + * @return class loader + */ + public ClassLoader getClassLoader() + { + return classLoader; + } + + + /** + * Sets the class loader to use when creating JNDI contexts. + * + * @param cl class loader + */ + public void setClassLoader(final ClassLoader cl) + { + checkImmutable(); + logger.trace("setting classLoader: {}", cl); + classLoader = cl; + } + + + /** + * Returns the SSL socket factory to use for SSL and startTLS connections. + * + * @return SSL socket factory + */ + public SSLSocketFactory getSslSocketFactory() + { + return sslSocketFactory; + } + + + /** + * Sets the SSL socket factory to use for SSL and startTLS connections. + * + * @param sf SSL socket factory + */ + public void setSslSocketFactory(final SSLSocketFactory sf) + { + checkImmutable(); + logger.trace("setting sslSocketFactory: {}", sf); + sslSocketFactory = sf; + } + + + /** + * Returns the hostname verifier to use for startTLS connections. + * + * @return hostname verifier + */ + public HostnameVerifier getHostnameVerifier() + { + return hostnameVerifier; + } + + + /** + * Sets the hostname verifier to use for startTLS connections. + * + * @param verifier for hostnames + */ + public void setHostnameVerifier(final HostnameVerifier verifier) + { + checkImmutable(); + logger.trace("setting hostnameVerifier: {}", verifier); + hostnameVerifier = verifier; + } + + + @Override + public void setProperties(final Map<String, Object> props) + { + checkImmutable(); + + final boolean allowAnyHostname = Boolean.valueOf((String) props.get(ALLOW_ANY_HOSTNAME)); + if (allowAnyHostname) { + setHostnameVerifier(new AllowAnyHostnameVerifier()); + } + super.setProperties(props); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::operationExceptionResultCodes=%s, properties=%s, controlProcessor=%s, environment=%s, " + + "tracePackets=%s, removeDnUrls=%s, searchIgnoreResultCodes=%s, classLoader=%s, sslSocketFactory=%s, " + + "hostnameVerifier=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(getOperationExceptionResultCodes()), + getProperties(), + getControlProcessor(), + environment, + tracePackets, + removeDnUrls, + Arrays.toString(searchIgnoreResultCodes), + classLoader, + sslSocketFactory, + hostnameVerifier); + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/jndi/JndiStartTLSConnection.java b/core/src/main/java/org/ldaptive/provider/jndi/JndiStartTLSConnection.java new file mode 100644 index 0000000..a6ec0b4 --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/jndi/JndiStartTLSConnection.java
@@ -0,0 +1,113 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jndi; + +import java.io.IOException; +import javax.naming.ldap.LdapContext; +import javax.naming.ldap.StartTlsResponse; +import org.ldaptive.LdapException; +import org.ldaptive.control.RequestControl; + +/** + * JNDI provider implementation of ldap operations using startTLS. + * + * @author Middleware Services + */ +public class JndiStartTLSConnection extends JndiConnection +{ + + /** Start TLS response. */ + private StartTlsResponse startTlsResponse; + + /** Whether to call {@link StartTlsResponse#close()} when {@link #close(RequestControl[])} is called. */ + private boolean stopTLSOnClose; + + + /** + * Creates a new jndi startTLS connection. + * + * @param lc ldap context + * @param pc provider configuration + */ + public JndiStartTLSConnection(final LdapContext lc, final JndiProviderConfig pc) + { + super(lc, pc); + } + + + /** + * Creates a new jndi startTLS connection. + * + * @param lc ldap context + * @param pc provider configuration + * @param tlsResponse of successful TLS handshake + */ + public JndiStartTLSConnection(final LdapContext lc, final JndiProviderConfig pc, final StartTlsResponse tlsResponse) + { + super(lc, pc); + startTlsResponse = tlsResponse; + } + + + /** + * Returns whether to call {@link StartTlsResponse#close()} when {@link #close(RequestControl[])} is called. + * + * @return stop TLS on close + */ + public boolean getStopTLSOnClose() + { + return stopTLSOnClose; + } + + + /** + * Sets whether to call {@link StartTlsResponse#close()} when {@link #close(RequestControl[])} is called. + * + * @param b stop TLS on close + */ + public void setStopTLSOnClose(final boolean b) + { + logger.trace("setting stopTLSOnClose: {}", b); + stopTLSOnClose = b; + } + + + /** + * Returns the start tls response used by this connection. + * + * @return start tls response + */ + public StartTlsResponse getStartTlsResponse() + { + return startTlsResponse; + } + + + /** + * Sets the start tls response. + * + * @param str start tls response + */ + public void setStartTlsResponse(final StartTlsResponse str) + { + startTlsResponse = str; + } + + + @Override + public void close(final RequestControl[] controls) + throws LdapException + { + try { + if (stopTLSOnClose) { + if (startTlsResponse != null) { + startTlsResponse.close(); + } + } + } catch (IOException e) { + logger.error("Error stopping TLS", e); + } finally { + startTlsResponse = null; + super.close(controls); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/jndi/JndiStartTLSConnectionFactory.java b/core/src/main/java/org/ldaptive/provider/jndi/JndiStartTLSConnectionFactory.java new file mode 100644 index 0000000..bda3d56 --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/jndi/JndiStartTLSConnectionFactory.java
@@ -0,0 +1,162 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jndi; + +import java.io.IOException; +import java.util.Collections; +import java.util.Hashtable; +import java.util.Map; +import javax.naming.NamingException; +import javax.naming.ldap.InitialLdapContext; +import javax.naming.ldap.LdapContext; +import javax.naming.ldap.StartTlsRequest; +import javax.naming.ldap.StartTlsResponse; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSocketFactory; +import org.ldaptive.ConnectionStrategy; +import org.ldaptive.LdapException; +import org.ldaptive.provider.AbstractProviderConnectionFactory; +import org.ldaptive.provider.ConnectionException; + +/** + * Creates connections using the JNDI {@link InitialLdapContext} class with the startTLS extended operation. + * + * @author Middleware Services + */ +public class JndiStartTLSConnectionFactory extends AbstractProviderConnectionFactory<JndiProviderConfig> +{ + + /** Environment properties. */ + private final Map<String, Object> environment; + + /** Context class loader to use when instantiating {@link InitialLdapContext}. */ + private final ClassLoader classLoader; + + /** SSL socket factory to use for startTLS negotiation. */ + private final SSLSocketFactory sslSocketFactory; + + /** Hostname verifier to use for startTLS negotiation. */ + private final HostnameVerifier hostnameVerifier; + + + /** + * Creates a new jndi startTLS connection factory. + * + * @param url of the ldap to connect to + * @param strategy connection strategy + * @param config provider configuration + * @param env jndi context environment + * @param cl class loader + * @param factory SSL socket factory + * @param verifier hostname verifier + */ + public JndiStartTLSConnectionFactory( + final String url, + final ConnectionStrategy strategy, + final JndiProviderConfig config, + final Map<String, Object> env, + final ClassLoader cl, + final SSLSocketFactory factory, + final HostnameVerifier verifier) + { + super(url, strategy, config); + environment = Collections.unmodifiableMap(env); + classLoader = cl; + sslSocketFactory = factory; + hostnameVerifier = verifier; + } + + + @Override + protected JndiStartTLSConnection createInternal(final String url) + throws LdapException + { + // CheckStyle:IllegalType OFF + // the JNDI API requires the Hashtable type + final Hashtable<String, Object> env = new Hashtable<>(environment); + // CheckStyle:IllegalType ON + env.put(JndiProvider.PROVIDER_URL, url); + + JndiStartTLSConnection conn = null; + boolean closeConn = false; + try { + if (classLoader != null) { + final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(classLoader); + conn = new JndiStartTLSConnection(new InitialLdapContext(env, null), getProviderConfig()); + } finally { + Thread.currentThread().setContextClassLoader(currentClassLoader); + } + } else { + conn = new JndiStartTLSConnection(new InitialLdapContext(env, null), getProviderConfig()); + } + conn.setStartTlsResponse(startTLS(conn.getLdapContext())); + } catch (NamingException e) { + closeConn = true; + throw new ConnectionException(e, NamingExceptionUtils.getResultCode(e.getClass())); + } catch (IOException e) { + closeConn = true; + throw new ConnectionException(e); + } catch (RuntimeException e) { + closeConn = true; + throw e; + } finally { + if (closeConn) { + try { + if (conn != null) { + conn.close(null); + } + } catch (LdapException e) { + logger.debug("Problem tearing down connection", e); + } + } + } + return conn; + } + + + /** + * This will attempt the startTLS extended operation on the supplied ldap context. + * + * @param ctx ldap context + * + * @return start tls response + * + * @throws NamingException if an error occurs while requesting an extended operation + * @throws IOException if an error occurs while negotiating TLS + */ + protected StartTlsResponse startTLS(final LdapContext ctx) + throws NamingException, IOException + { + final StartTlsResponse tls = (StartTlsResponse) ctx.extendedOperation(new StartTlsRequest()); + if (hostnameVerifier != null) { + logger.trace("startTLS hostnameVerifier = {}", hostnameVerifier); + tls.setHostnameVerifier(hostnameVerifier); + } + if (sslSocketFactory != null) { + logger.trace("startTLS sslSocketFactory = {}", sslSocketFactory); + tls.negotiate(sslSocketFactory); + } else { + tls.negotiate(); + } + return tls; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::metadata=%s, environment=%s, classLoader=%s, providerConfig=%s, sslSocketFactory=%s, " + + "hostnameVerifier=%s]", + getClass().getName(), + hashCode(), + getMetadata(), + environment, + classLoader, + getProviderConfig(), + sslSocketFactory, + hostnameVerifier); + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/jndi/JndiUtils.java b/core/src/main/java/org/ldaptive/provider/jndi/JndiUtils.java new file mode 100644 index 0000000..a2f13be --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/jndi/JndiUtils.java
@@ -0,0 +1,311 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jndi; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttribute; +import javax.naming.directory.BasicAttributes; +import javax.naming.directory.ModificationItem; +import javax.naming.directory.SearchResult; +import javax.naming.ldap.LdapContext; +import org.ldaptive.AttributeModification; +import org.ldaptive.AttributeModificationType; +import org.ldaptive.LdapAttribute; +import org.ldaptive.SearchEntry; +import org.ldaptive.SortBehavior; +import org.ldaptive.control.SortKey; +import org.ldaptive.sasl.Mechanism; +import org.ldaptive.sasl.QualityOfProtection; +import org.ldaptive.sasl.SecurityStrength; + +/** + * Provides methods for converting between JNDI specific objects and ldaptive specific objects. + * + * @author Middleware Services + */ +public class JndiUtils +{ + + /** Whether to ignore case when creating basic attributes. */ + public static final boolean DEFAULT_IGNORE_CASE = true; + + /** Ldap result sort behavior. */ + private final SortBehavior sortBehavior; + + + /** Default constructor. */ + public JndiUtils() + { + sortBehavior = SortBehavior.getDefaultSortBehavior(); + } + + + /** + * Creates a new jndi util. + * + * @param sb sort behavior + */ + public JndiUtils(final SortBehavior sb) + { + sortBehavior = sb; + } + + + /** + * Returns a jndi attribute that represents the values in the supplied ldap attribute. + * + * @param attr ldap attribute + * + * @return jndi attribute + */ + public Attribute fromLdapAttribute(final LdapAttribute attr) + { + final Attribute attribute = new BasicAttribute(attr.getName()); + if (attr.isBinary()) { + attr.getBinaryValues().forEach(attribute::add); + } else { + attr.getStringValues().forEach(attribute::add); + } + return attribute; + } + + + /** + * Returns an ldap attribute using the supplied jndi attribute. + * + * @param attr jndi attribute + * + * @return ldap attribute + * + * @throws NamingException if the attribute values cannot be read + */ + public LdapAttribute toLdapAttribute(final Attribute attr) + throws NamingException + { + final Set<Object> values = new HashSet<>(); + final NamingEnumeration<?> ne = attr.getAll(); + while (ne.hasMore()) { + values.add(ne.next()); + } + return LdapAttribute.createLdapAttribute(sortBehavior, attr.getID(), values); + } + + + /** + * Returns a jndi attributes that represents the values in the supplied ldap attributes. + * + * @param attrs ldap attributes + * + * @return jndi attributes + */ + public Attributes fromLdapAttributes(final Collection<LdapAttribute> attrs) + { + final Attributes attributes = new BasicAttributes(DEFAULT_IGNORE_CASE); + for (LdapAttribute a : attrs) { + attributes.put(fromLdapAttribute(a)); + } + return attributes; + } + + + /** + * Returns a jndi search result that represents the supplied search entry. + * + * @param entry search entry + * + * @return jndi search result + */ + public SearchResult fromSearchEntry(final SearchEntry entry) + { + return new SearchResult(entry.getDn(), null, fromLdapAttributes(entry.getAttributes())); + } + + + /** + * Returns a search entry using the supplied jndi search result. + * + * @param result jndi search result + * + * @return search entry + * + * @throws NamingException if the search result cannot be read + */ + public SearchEntry toSearchEntry(final SearchResult result) + throws NamingException + { + final SearchEntry se = new SearchEntry(-1, null, sortBehavior); + se.setDn(result.getName()); + + final Attributes a = result.getAttributes(); + final NamingEnumeration<? extends Attribute> ne = a.getAll(); + while (ne.hasMore()) { + se.addAttribute(toLdapAttribute(ne.next())); + } + return se; + } + + + /** + * Returns jndi modification items using the supplied attribute modifications. + * + * @param mods attribute modifications + * + * @return jndi modification items + */ + public ModificationItem[] fromAttributeModification(final AttributeModification[] mods) + { + final ModificationItem[] mi = new ModificationItem[mods.length]; + for (int i = 0; i < mods.length; i++) { + mi[i] = new ModificationItem( + getAttributeModification(mods[i].getAttributeModificationType()), + fromLdapAttribute(mods[i].getAttribute())); + } + return mi; + } + + + /** + * Returns jndi sort keys using the supplied sort keys. + * + * @param keys sort keys + * + * @return jndi sort keys + */ + public static javax.naming.ldap.SortKey[] fromSortKey(final SortKey[] keys) + { + javax.naming.ldap.SortKey[] sk = null; + if (keys != null) { + sk = new javax.naming.ldap.SortKey[keys.length]; + for (int i = 0; i < keys.length; i++) { + sk[i] = new javax.naming.ldap.SortKey( + keys[i].getAttributeDescription(), + !keys[i].getReverseOrder(), + keys[i].getMatchingRuleId()); + } + } + return sk; + } + + + /** + * Returns the jndi modification integer constant for the supplied attribute modification type. + * + * @param type attribute modification type + * + * @return integer constant + */ + protected static int getAttributeModification(final AttributeModificationType type) + { + int op = -1; + if (type == AttributeModificationType.ADD) { + op = LdapContext.ADD_ATTRIBUTE; + } else if (type == AttributeModificationType.REMOVE) { + op = LdapContext.REMOVE_ATTRIBUTE; + } else if (type == AttributeModificationType.REPLACE) { + op = LdapContext.REPLACE_ATTRIBUTE; + } + return op; + } + + + /** + * Returns the SASL quality of protection string for the supplied enum. + * + * @param qop quality of protection enum + * + * @return SASL quality of protection string + */ + public static String getQualityOfProtection(final QualityOfProtection qop) + { + String s; + switch (qop) { + + case AUTH: + s = "auth"; + break; + + case AUTH_INT: + s = "auth-int"; + break; + + case AUTH_CONF: + s = "auth-conf"; + break; + + default: + throw new IllegalArgumentException("Unknown SASL quality of protection: " + qop); + } + return s; + } + + + /** + * Returns the SASL security strength string for the supplied enum. + * + * @param ss security strength enum + * + * @return SASL security strength string + */ + public static String getSecurityStrength(final SecurityStrength ss) + { + String s; + switch (ss) { + + case HIGH: + s = "high"; + break; + + case MEDIUM: + s = "medium"; + break; + + case LOW: + s = "low"; + break; + + default: + throw new IllegalArgumentException("Unknown SASL security strength: " + ss); + } + return s; + } + + + /** + * Returns the JNDI authentication string for the supplied authentication type. + * + * @param m sasl mechanism + * + * @return JNDI authentication string + */ + public static String getAuthenticationType(final Mechanism m) + { + String s; + switch (m) { + + case EXTERNAL: + s = "EXTERNAL"; + break; + + case DIGEST_MD5: + s = "DIGEST-MD5"; + break; + + case CRAM_MD5: + s = "CRAM-MD5"; + break; + + case GSSAPI: + s = "GSSAPI"; + break; + + default: + throw new IllegalArgumentException("Unknown SASL authentication mechanism: " + m); + } + return s; + } +}
diff --git a/core/src/main/java/org/ldaptive/provider/jndi/NamingExceptionUtils.java b/core/src/main/java/org/ldaptive/provider/jndi/NamingExceptionUtils.java new file mode 100644 index 0000000..ed96f3a --- /dev/null +++ b/core/src/main/java/org/ldaptive/provider/jndi/NamingExceptionUtils.java
@@ -0,0 +1,336 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jndi; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.naming.AuthenticationException; +import javax.naming.AuthenticationNotSupportedException; +import javax.naming.CommunicationException; +import javax.naming.ContextNotEmptyException; +import javax.naming.InvalidNameException; +import javax.naming.LimitExceededException; +import javax.naming.NameAlreadyBoundException; +import javax.naming.NameNotFoundException; +import javax.naming.NamingException; +import javax.naming.NoPermissionException; +import javax.naming.OperationNotSupportedException; +import javax.naming.PartialResultException; +import javax.naming.ReferralException; +import javax.naming.ServiceUnavailableException; +import javax.naming.SizeLimitExceededException; +import javax.naming.TimeLimitExceededException; +import javax.naming.directory.AttributeInUseException; +import javax.naming.directory.InvalidAttributeIdentifierException; +import javax.naming.directory.InvalidAttributeValueException; +import javax.naming.directory.InvalidSearchFilterException; +import javax.naming.directory.NoSuchAttributeException; +import javax.naming.directory.SchemaViolationException; +import org.ldaptive.ResultCode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utility class that provides a bridge between JNDI naming exceptions and ldap result codes. See + * http://docs.oracle.com/javase/tutorial/jndi/ldap/exceptions.html + * + * @author Middleware Services + */ +public final class NamingExceptionUtils +{ + + /** Map of naming exceptions to ldap result codes. */ + private static final Map<Class<? extends NamingException>, ResultCode[]> EXCEPTIONS_TO_RESULT_CODES; + + /** Map of ldap result codes to naming exceptions. */ + private static final Map<ResultCode, Class<? extends NamingException>> RESULT_CODES_TO_EXCEPTION; + + /** Pattern to find error code in exception messages. */ + private static final Pattern PATTERN = Pattern.compile("LDAP: error code (\\d+)"); + + /** + * initialize map of exceptions to result codes. + */ + static { + EXCEPTIONS_TO_RESULT_CODES = new HashMap<>(); + EXCEPTIONS_TO_RESULT_CODES.put( + NamingException.class, + new ResultCode[] { + ResultCode.OPERATIONS_ERROR, + ResultCode.ALIAS_PROBLEM, + ResultCode.ALIAS_DEREFERENCING_PROBLEM, + ResultCode.LOOP_DETECT, + ResultCode.AFFECTS_MULTIPLE_DSAS, + ResultCode.OTHER, + }); + EXCEPTIONS_TO_RESULT_CODES.put(CommunicationException.class, new ResultCode[] {ResultCode.PROTOCOL_ERROR, }); + EXCEPTIONS_TO_RESULT_CODES.put( + TimeLimitExceededException.class, + new ResultCode[] {ResultCode.TIME_LIMIT_EXCEEDED, }); + EXCEPTIONS_TO_RESULT_CODES.put( + SizeLimitExceededException.class, + new ResultCode[] {ResultCode.SIZE_LIMIT_EXCEEDED, }); + EXCEPTIONS_TO_RESULT_CODES.put( + AuthenticationNotSupportedException.class, + new ResultCode[] { + ResultCode.AUTH_METHOD_NOT_SUPPORTED, + ResultCode.STRONG_AUTH_REQUIRED, + ResultCode.CONFIDENTIALITY_REQUIRED, + ResultCode.INAPPROPRIATE_AUTHENTICATION, + }); + EXCEPTIONS_TO_RESULT_CODES.put(PartialResultException.class, new ResultCode[] {ResultCode.PARTIAL_RESULTS, }); + EXCEPTIONS_TO_RESULT_CODES.put(ReferralException.class, new ResultCode[] {ResultCode.REFERRAL, }); + EXCEPTIONS_TO_RESULT_CODES.put( + LimitExceededException.class, + new ResultCode[] { + ResultCode.REFERRAL, + ResultCode.ADMIN_LIMIT_EXCEEDED, + }); + EXCEPTIONS_TO_RESULT_CODES.put( + OperationNotSupportedException.class, + new ResultCode[] { + ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, + ResultCode.UNWILLING_TO_PERFORM, + }); + EXCEPTIONS_TO_RESULT_CODES.put(NoSuchAttributeException.class, new ResultCode[] {ResultCode.NO_SUCH_ATTRIBUTE, }); + EXCEPTIONS_TO_RESULT_CODES.put( + InvalidAttributeIdentifierException.class, + new ResultCode[] {ResultCode.UNDEFINED_ATTRIBUTE_TYPE, }); + EXCEPTIONS_TO_RESULT_CODES.put( + InvalidSearchFilterException.class, + new ResultCode[] {ResultCode.INAPPROPRIATE_MATCHING, }); + EXCEPTIONS_TO_RESULT_CODES.put( + InvalidAttributeValueException.class, + new ResultCode[] { + ResultCode.CONSTRAINT_VIOLATION, + ResultCode.INVALID_ATTRIBUTE_SYNTAX, + }); + EXCEPTIONS_TO_RESULT_CODES.put( + AttributeInUseException.class, + new ResultCode[] {ResultCode.ATTRIBUTE_OR_VALUE_EXISTS, }); + EXCEPTIONS_TO_RESULT_CODES.put(NameNotFoundException.class, new ResultCode[] {ResultCode.NO_SUCH_OBJECT, }); + EXCEPTIONS_TO_RESULT_CODES.put( + InvalidNameException.class, + new ResultCode[] { + ResultCode.INVALID_DN_SYNTAX, + ResultCode.NAMING_VIOLATION, + }); + EXCEPTIONS_TO_RESULT_CODES.put(AuthenticationException.class, new ResultCode[] {ResultCode.INVALID_CREDENTIALS, }); + EXCEPTIONS_TO_RESULT_CODES.put( + NoPermissionException.class, + new ResultCode[] {ResultCode.INSUFFICIENT_ACCESS_RIGHTS, }); + EXCEPTIONS_TO_RESULT_CODES.put( + ServiceUnavailableException.class, + new ResultCode[] { + ResultCode.BUSY, + ResultCode.UNAVAILABLE, + }); + EXCEPTIONS_TO_RESULT_CODES.put( + SchemaViolationException.class, + new ResultCode[] { + ResultCode.OBJECT_CLASS_VIOLATION, + ResultCode.NOT_ALLOWED_ON_RDN, + ResultCode.OBJECT_CLASS_MODS_PROHIBITED, + }); + EXCEPTIONS_TO_RESULT_CODES.put( + ContextNotEmptyException.class, + new ResultCode[] {ResultCode.NOT_ALLOWED_ON_NONLEAF, }); + EXCEPTIONS_TO_RESULT_CODES.put( + NameAlreadyBoundException.class, + new ResultCode[] {ResultCode.ENTRY_ALREADY_EXISTS, }); + } + + + /** + * initialize map of result codes to exceptions. + */ + static { + RESULT_CODES_TO_EXCEPTION = new HashMap<>(); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.SUCCESS, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.OPERATIONS_ERROR, NamingException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.PROTOCOL_ERROR, CommunicationException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.TIME_LIMIT_EXCEEDED, TimeLimitExceededException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.SIZE_LIMIT_EXCEEDED, SizeLimitExceededException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.COMPARE_FALSE, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.COMPARE_TRUE, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.AUTH_METHOD_NOT_SUPPORTED, AuthenticationNotSupportedException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.STRONG_AUTH_REQUIRED, AuthenticationNotSupportedException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.PARTIAL_RESULTS, PartialResultException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.REFERRAL, ReferralException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.ADMIN_LIMIT_EXCEEDED, LimitExceededException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, OperationNotSupportedException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.CONFIDENTIALITY_REQUIRED, AuthenticationNotSupportedException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.SASL_BIND_IN_PROGRESS, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.NO_SUCH_ATTRIBUTE, NoSuchAttributeException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.UNDEFINED_ATTRIBUTE_TYPE, InvalidAttributeIdentifierException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.INAPPROPRIATE_MATCHING, InvalidSearchFilterException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.CONSTRAINT_VIOLATION, InvalidAttributeValueException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.ATTRIBUTE_OR_VALUE_EXISTS, AttributeInUseException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.INVALID_ATTRIBUTE_SYNTAX, InvalidAttributeValueException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.NO_SUCH_OBJECT, NameNotFoundException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.ALIAS_PROBLEM, NamingException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.INVALID_DN_SYNTAX, InvalidNameException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.IS_LEAF, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.ALIAS_DEREFERENCING_PROBLEM, NamingException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.INAPPROPRIATE_AUTHENTICATION, AuthenticationNotSupportedException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.INVALID_CREDENTIALS, AuthenticationException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.INSUFFICIENT_ACCESS_RIGHTS, NoPermissionException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.BUSY, ServiceUnavailableException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.UNAVAILABLE, ServiceUnavailableException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.UNWILLING_TO_PERFORM, OperationNotSupportedException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.LOOP_DETECT, NamingException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.NAMING_VIOLATION, InvalidNameException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.OBJECT_CLASS_VIOLATION, SchemaViolationException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.NOT_ALLOWED_ON_NONLEAF, ContextNotEmptyException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.NOT_ALLOWED_ON_RDN, SchemaViolationException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.ENTRY_ALREADY_EXISTS, NameAlreadyBoundException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.OBJECT_CLASS_MODS_PROHIBITED, SchemaViolationException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.AFFECTS_MULTIPLE_DSAS, NamingException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.OTHER, NamingException.class); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.SERVER_DOWN, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.LOCAL_ERROR, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.ENCODING_ERROR, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.DECODING_ERROR, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.LDAP_TIMEOUT, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.AUTH_UNKNOWN, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.FILTER_ERROR, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.USER_CANCELLED, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.PARAM_ERROR, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.NO_MEMORY, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.CONNECT_ERROR, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.LDAP_NOT_SUPPORTED, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.CONTROL_NOT_FOUND, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.NO_RESULTS_RETURNED, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.MORE_RESULTS_TO_RETURN, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.CLIENT_LOOP, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.REFERRAL_LIMIT_EXCEEDED, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.INVALID_RESPONSE, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.AMBIGUOUS_RESPONSE, null); + RESULT_CODES_TO_EXCEPTION.put(ResultCode.TLS_NOT_SUPPORTED, null); + } + + + /** Default constructor. */ + private NamingExceptionUtils() {} + + + /** + * Returns the result codes that map to the supplied naming exception. + * + * @param clazz naming exception + * + * @return ldap result codes + */ + public static ResultCode[] getResultCodes(final Class<? extends NamingException> clazz) + { + Class<?> c = clazz; + do { + final ResultCode[] codes = EXCEPTIONS_TO_RESULT_CODES.get(c); + if (codes != null) { + return codes; + } + c = c.getSuperclass(); + } while (!c.equals(NamingException.class)); + return null; + } + + + /** + * Returns the result code that map to the supplied naming exception. If the exception maps to multiple result codes, + * null is returned. + * + * @param clazz naming exception + * + * @return ldap result code or null + */ + public static ResultCode getResultCode(final Class<? extends NamingException> clazz) + { + final ResultCode[] codes = getResultCodes(clazz); + if (codes != null) { + if (codes.length == 1) { + return codes[0]; + } + + final Logger l = LoggerFactory.getLogger(NamingExceptionUtils.class); + l.debug("naming exception {} is ambiguous, maps to multiple result codes: {}", clazz, Arrays.toString(codes)); + } + return null; + } + + + /** + * Returns the result code contained in the supplied naming exception message. JNDI displays the error code in the + * form "[LDAP: error code {code} - {message}" and this method attempts to parse that numeric code from the message. + * + * @param message naming exception message + * + * @return ldap result code or null + */ + public static ResultCode getResultCode(final String message) + { + ResultCode code = null; + if (message != null) { + final Matcher matcher = PATTERN.matcher(message); + if (matcher.find()) { + try { + code = ResultCode.valueOf(Integer.parseInt(matcher.group(1))); + } catch (NumberFormatException e) { + final Logger l = LoggerFactory.getLogger(NamingExceptionUtils.class); + l.debug("Error parsing LDAP error code", e); + } + } else if (message.contains("socket closed")) { + // jndi does not return an error code for a closed socket + code = ResultCode.SERVER_DOWN; + } else if (message.contains("LDAP response read timed out")) { + // jndi does not return an error code for a response timeout + code = ResultCode.LDAP_TIMEOUT; + } + + if (code == null) { + final Logger l = LoggerFactory.getLogger(NamingExceptionUtils.class); + l.debug("could not find result code in naming exception {}", message); + } + } + return code; + } + + + /** + * Returns whether the supplied naming exception maps to the supplied result code. + * + * @param clazz naming exception + * @param code ldap result code + * + * @return whether the naming exception matches the result code + */ + public static boolean matches(final Class<? extends NamingException> clazz, final ResultCode code) + { + boolean match = false; + final ResultCode[] matchingCodes = getResultCodes(clazz); + if (matchingCodes != null) { + for (ResultCode rc : matchingCodes) { + if (rc == code) { + match = true; + break; + } + } + } + return match; + } + + + /** + * Returns the naming exception that maps to the supplied result code. If the result code does not map to an + * exception, null is returned + * + * @param code ldap result code + * + * @return array of naming exception classes + */ + public static Class<? extends NamingException> getNamingException(final ResultCode code) + { + return RESULT_CODES_TO_EXCEPTION.get(code); + } +}
diff --git a/core/src/main/java/org/ldaptive/referral/AbstractReferralHandler.java b/core/src/main/java/org/ldaptive/referral/AbstractReferralHandler.java new file mode 100644 index 0000000..2edb436 --- /dev/null +++ b/core/src/main/java/org/ldaptive/referral/AbstractReferralHandler.java
@@ -0,0 +1,234 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.referral; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.LdapException; +import org.ldaptive.LdapURL; +import org.ldaptive.Operation; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.handler.HandlerResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Common implementation of referral handling. + * + * @param <Q> type of ldap request + * @param <S> type of ldap response + * + * @author Middleware Services + */ +public abstract class AbstractReferralHandler<Q extends Request, S> implements ReferralHandler<Q, S> +{ + + /** Default referral limit. Value is {@value}. */ + protected static final int DEFAULT_REFERRAL_LIMIT = 10; + + + /** Default referral connection factory. Uses {@link DefaultConnectionFactory}. */ + // CheckStyle:JavadocVariable OFF + protected static final ReferralConnectionFactory DEFAULT_CONNECTION_FACTORY = (config, ldapUrl) -> { + final ConnectionConfig cc = ConnectionConfig.newConnectionConfig(config); + cc.setLdapUrl(ldapUrl); + return new DefaultConnectionFactory(cc); + }; + // CheckStyle:JavadocVariable ON + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Referral limit. */ + private final int referralLimit; + + /** Referral depth. */ + private final int referralDepth; + + /** Referral connection factory. */ + private final ReferralConnectionFactory connectionFactory; + + + /** + * Creates a new abstract referral handler. + * + * @param limit number of referrals to follow + * @param depth number of referrals followed + * @param factory referral connection factory + */ + public AbstractReferralHandler(final int limit, final int depth, final ReferralConnectionFactory factory) + { + referralLimit = limit; + referralDepth = depth; + connectionFactory = factory; + } + + + /** + * Returns the maximum number of referrals to follow. + * + * @return referral limit + */ + public int getReferralLimit() + { + return referralLimit; + } + + + /** + * Returns the referral depth of this handler. + * + * @return referral depth + */ + public int getReferralDepth() + { + return referralDepth; + } + + + /** + * Returns the referral connection factory. + * + * @return referral connection factory + */ + public ReferralConnectionFactory getReferralConnectionFactory() + { + return connectionFactory; + } + + + /** + * Creates a new request for this type of referral. + * + * @param request of the original operation + * @param url of the referral + * + * @return new request + */ + protected abstract Q createReferralRequest(final Q request, final LdapURL url); + + + /** + * Creates an operation for this type of referral. + * + * @param conn to execute the operation on + * + * @return new operation + */ + protected abstract Operation<Q, S> createReferralOperation(final Connection conn); + + + /** + * Follows the supplied referral URLs in order until a SUCCESS or REFERRAL_LIMIT_EXCEEDED occurs. If neither of those + * conditions occurs this method returns null. + * + * @param conn the original operation occurred on + * @param request of the operation that produced a referral + * @param referralUrls produced by the request + * + * @return referral response + * + * @throws LdapException if a REFERRAL_LIMIT_EXCEEDED in encountered + */ + protected Response<S> followReferral(final Connection conn, final Q request, final String[] referralUrls) + throws LdapException + { + Response<S> referralResponse = null; + final List<String> urls = Arrays.asList(referralUrls); + Collections.shuffle(urls); + logger.debug("Following referral with URLs: {}", urls); + for (String url : urls) { + final LdapURL ldapUrl = new LdapURL(url); + if (ldapUrl.getEntry().getHostname() == null) { + continue; + } + + final ConnectionFactory cf = connectionFactory.getConnectionFactory( + conn.getConnectionConfig(), + ldapUrl.getEntry().getHostnameWithSchemeAndPort()); + try (Connection referralConn = cf.getConnection()) { + referralConn.open(); + + final Q referralRequest = createReferralRequest(request, ldapUrl); + final Operation<Q, S> op = createReferralOperation(referralConn); + referralResponse = op.execute(referralRequest); + } catch (LdapException e) { + logger.warn("Could not follow referral to " + url, e); + if (e.getResultCode() == ResultCode.REFERRAL_LIMIT_EXCEEDED) { + throw e; + } + } + if (referralResponse != null && referralResponse.getResultCode() == ResultCode.SUCCESS) { + break; + } + } + return referralResponse; + } + + + @Override + public HandlerResult<Response<S>> handle(final Connection conn, final Q request, final Response<S> response) + throws LdapException + { + HandlerResult<Response<S>> result; + if (referralDepth > referralLimit) { + result = new HandlerResult<>( + new Response<>( + response.getResult(), + ResultCode.REFERRAL_LIMIT_EXCEEDED, + response.getMessage(), + response.getMatchedDn(), + response.getControls(), + response.getReferralURLs(), + response.getMessageId())); + } else { + final Response<S> referralResponse = followReferral(conn, request, response.getReferralURLs()); + if (referralResponse != null) { + result = new HandlerResult<>(referralResponse); + } else { + result = new HandlerResult<>(response); + } + } + return result; + } + + + /** + * Implementation that does not require the response. + * + * @param conn the operation occurred on + * @param request the operation executed + * @param referralUrls encountered in the operation + * + * @return handler result + * + * @throws LdapException if an error occurs following referrals + */ + public HandlerResult<Response<S>> handle(final Connection conn, final Q request, final String[] referralUrls) + throws LdapException + { + HandlerResult<Response<S>> result; + if (referralDepth > referralLimit) { + result = new HandlerResult<>( + new Response<>((S) null, ResultCode.REFERRAL_LIMIT_EXCEEDED, null, null, null, null, -1)); + } else { + final Response<S> referralResponse = followReferral(conn, request, referralUrls); + if (referralResponse != null) { + result = new HandlerResult<>(referralResponse); + } else { + result = new HandlerResult<>(null); + } + } + return result; + } + + + @Override + public void initializeRequest(final Q request) {} +}
diff --git a/core/src/main/java/org/ldaptive/referral/AddReferralHandler.java b/core/src/main/java/org/ldaptive/referral/AddReferralHandler.java new file mode 100644 index 0000000..b98779f --- /dev/null +++ b/core/src/main/java/org/ldaptive/referral/AddReferralHandler.java
@@ -0,0 +1,96 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.referral; + +import org.ldaptive.AddOperation; +import org.ldaptive.AddRequest; +import org.ldaptive.Connection; +import org.ldaptive.LdapURL; +import org.ldaptive.Operation; + +/** + * Provides handling of an ldap referral for add operations. + * + * @author Middleware Services + */ +public class AddReferralHandler extends AbstractReferralHandler<AddRequest, Void> +{ + + + /** Creates a new add referral handler. */ + public AddReferralHandler() + { + this(DEFAULT_REFERRAL_LIMIT, 0, DEFAULT_CONNECTION_FACTORY); + } + + + /** + * Creates a new add referral handler. + * + * @param factory referral connection factory + */ + public AddReferralHandler(final ReferralConnectionFactory factory) + { + this(DEFAULT_REFERRAL_LIMIT, 0, factory); + } + + + /** + * Creates a new add referral handler. + * + * @param limit number of referrals to follow + */ + public AddReferralHandler(final int limit) + { + this(limit, 0, DEFAULT_CONNECTION_FACTORY); + } + + + /** + * Creates a new add referral handler. + * + * @param limit number of referrals to follow + * @param factory referral connection factory + */ + public AddReferralHandler(final int limit, final ReferralConnectionFactory factory) + { + this(limit, 0, factory); + } + + + /** + * Creates a new add referral handler. + * + * @param limit number of referrals to follow + * @param depth number of referrals followed + * @param factory referral connection factory + */ + private AddReferralHandler(final int limit, final int depth, final ReferralConnectionFactory factory) + { + super(limit, depth, factory); + } + + + @Override + protected AddRequest createReferralRequest(final AddRequest request, final LdapURL url) + { + final AddRequest referralRequest = new AddRequest(); + referralRequest.setControls(request.getControls()); + referralRequest.setIntermediateResponseHandlers(request.getIntermediateResponseHandlers()); + referralRequest.setReferralHandler( + new AddReferralHandler(getReferralLimit(), getReferralDepth() + 1, getReferralConnectionFactory())); + if (!url.getEntry().isDefaultBaseDn()) { + referralRequest.setDn(url.getEntry().getBaseDn()); + } else { + referralRequest.setDn(request.getDn()); + } + referralRequest.setLdapAttributes(request.getLdapAttributes()); + return referralRequest; + } + + + @Override + protected Operation<AddRequest, Void> createReferralOperation(final Connection conn) + { + return new AddOperation(conn); + } +}
diff --git a/core/src/main/java/org/ldaptive/referral/CompareReferralHandler.java b/core/src/main/java/org/ldaptive/referral/CompareReferralHandler.java new file mode 100644 index 0000000..d257b09 --- /dev/null +++ b/core/src/main/java/org/ldaptive/referral/CompareReferralHandler.java
@@ -0,0 +1,96 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.referral; + +import org.ldaptive.CompareOperation; +import org.ldaptive.CompareRequest; +import org.ldaptive.Connection; +import org.ldaptive.LdapURL; +import org.ldaptive.Operation; + +/** + * Provides handling of an ldap referral for compare operations. + * + * @author Middleware Services + */ +public class CompareReferralHandler extends AbstractReferralHandler<CompareRequest, Boolean> +{ + + + /** Creates a compare add referral handler. */ + public CompareReferralHandler() + { + this(DEFAULT_REFERRAL_LIMIT, 0, DEFAULT_CONNECTION_FACTORY); + } + + + /** + * Creates a new compare referral handler. + * + * @param factory referral connection factory + */ + public CompareReferralHandler(final ReferralConnectionFactory factory) + { + this(DEFAULT_REFERRAL_LIMIT, 0, factory); + } + + + /** + * Creates a new compare referral handler. + * + * @param limit number of referrals to follow + */ + public CompareReferralHandler(final int limit) + { + this(limit, 0, DEFAULT_CONNECTION_FACTORY); + } + + + /** + * Creates a new compare referral handler. + * + * @param limit number of referrals to follow + * @param factory referral connection factory + */ + public CompareReferralHandler(final int limit, final ReferralConnectionFactory factory) + { + this(limit, 0, factory); + } + + + /** + * Creates a new compare referral handler. + * + * @param limit number of referrals to follow + * @param depth number of referrals followed + * @param factory referral connection factory + */ + private CompareReferralHandler(final int limit, final int depth, final ReferralConnectionFactory factory) + { + super(limit, depth, factory); + } + + + @Override + protected CompareRequest createReferralRequest(final CompareRequest request, final LdapURL url) + { + final CompareRequest referralRequest = new CompareRequest(); + referralRequest.setControls(request.getControls()); + referralRequest.setIntermediateResponseHandlers(request.getIntermediateResponseHandlers()); + referralRequest.setReferralHandler( + new CompareReferralHandler(getReferralLimit(), getReferralDepth() + 1, getReferralConnectionFactory())); + if (!url.getEntry().isDefaultBaseDn()) { + referralRequest.setDn(url.getEntry().getBaseDn()); + } else { + referralRequest.setDn(request.getDn()); + } + referralRequest.setAttribute(request.getAttribute()); + return referralRequest; + } + + + @Override + protected Operation<CompareRequest, Boolean> createReferralOperation(final Connection conn) + { + return new CompareOperation(conn); + } +}
diff --git a/core/src/main/java/org/ldaptive/referral/DeleteReferralHandler.java b/core/src/main/java/org/ldaptive/referral/DeleteReferralHandler.java new file mode 100644 index 0000000..9d8dfbd --- /dev/null +++ b/core/src/main/java/org/ldaptive/referral/DeleteReferralHandler.java
@@ -0,0 +1,95 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.referral; + +import org.ldaptive.Connection; +import org.ldaptive.DeleteOperation; +import org.ldaptive.DeleteRequest; +import org.ldaptive.LdapURL; +import org.ldaptive.Operation; + +/** + * Provides handling of an ldap referral for delete operations. + * + * @author Middleware Services + */ +public class DeleteReferralHandler extends AbstractReferralHandler<DeleteRequest, Void> +{ + + + /** Creates a new delete referral handler. */ + public DeleteReferralHandler() + { + this(DEFAULT_REFERRAL_LIMIT, 0, DEFAULT_CONNECTION_FACTORY); + } + + + /** + * Creates a new delete referral handler. + * + * @param factory referral connection factory + */ + public DeleteReferralHandler(final ReferralConnectionFactory factory) + { + this(DEFAULT_REFERRAL_LIMIT, 0, factory); + } + + + /** + * Creates a new delete referral handler. + * + * @param limit number of referrals to follow + */ + public DeleteReferralHandler(final int limit) + { + this(limit, 0, DEFAULT_CONNECTION_FACTORY); + } + + + /** + * Creates a new delete referral handler. + * + * @param limit number of referrals to follow + * @param factory referral connection factory + */ + public DeleteReferralHandler(final int limit, final ReferralConnectionFactory factory) + { + this(limit, 0, factory); + } + + + /** + * Creates a new delete referral handler. + * + * @param limit number of referrals to follow + * @param depth number of referrals followed + * @param factory referral connection factory + */ + private DeleteReferralHandler(final int limit, final int depth, final ReferralConnectionFactory factory) + { + super(limit, depth, factory); + } + + + @Override + protected DeleteRequest createReferralRequest(final DeleteRequest request, final LdapURL url) + { + final DeleteRequest referralRequest = new DeleteRequest(); + referralRequest.setControls(request.getControls()); + referralRequest.setIntermediateResponseHandlers(request.getIntermediateResponseHandlers()); + referralRequest.setReferralHandler( + new DeleteReferralHandler(getReferralLimit(), getReferralDepth() + 1, getReferralConnectionFactory())); + if (!url.getEntry().isDefaultBaseDn()) { + referralRequest.setDn(url.getEntry().getBaseDn()); + } else { + referralRequest.setDn(request.getDn()); + } + return referralRequest; + } + + + @Override + protected Operation<DeleteRequest, Void> createReferralOperation(final Connection conn) + { + return new DeleteOperation(conn); + } +}
diff --git a/core/src/main/java/org/ldaptive/referral/ModifyDnReferralHandler.java b/core/src/main/java/org/ldaptive/referral/ModifyDnReferralHandler.java new file mode 100644 index 0000000..d1b071c --- /dev/null +++ b/core/src/main/java/org/ldaptive/referral/ModifyDnReferralHandler.java
@@ -0,0 +1,97 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.referral; + +import org.ldaptive.Connection; +import org.ldaptive.LdapURL; +import org.ldaptive.ModifyDnOperation; +import org.ldaptive.ModifyDnRequest; +import org.ldaptive.Operation; + +/** + * Provides handling of an ldap referral for modify dn operations. + * + * @author Middleware Services + */ +public class ModifyDnReferralHandler extends AbstractReferralHandler<ModifyDnRequest, Void> +{ + + + /** Creates a new modify dn referral handler. */ + public ModifyDnReferralHandler() + { + this(DEFAULT_REFERRAL_LIMIT, 0, DEFAULT_CONNECTION_FACTORY); + } + + + /** + * Creates a new modify dn referral handler. + * + * @param factory referral connection factory + */ + public ModifyDnReferralHandler(final ReferralConnectionFactory factory) + { + this(DEFAULT_REFERRAL_LIMIT, 0, factory); + } + + + /** + * Creates a new modify dn referral handler. + * + * @param limit number of referrals to follow + */ + public ModifyDnReferralHandler(final int limit) + { + this(limit, 0, DEFAULT_CONNECTION_FACTORY); + } + + + /** + * Creates a new modify dn referral handler. + * + * @param limit number of referrals to follow + * @param factory referral connection factory + */ + public ModifyDnReferralHandler(final int limit, final ReferralConnectionFactory factory) + { + this(limit, 0, factory); + } + + + /** + * Creates a new modify dn referral handler. + * + * @param limit number of referrals to follow + * @param depth number of referrals followed + * @param factory referral connection factory + */ + private ModifyDnReferralHandler(final int limit, final int depth, final ReferralConnectionFactory factory) + { + super(limit, depth, factory); + } + + + @Override + protected ModifyDnRequest createReferralRequest(final ModifyDnRequest request, final LdapURL url) + { + final ModifyDnRequest referralRequest = new ModifyDnRequest(); + referralRequest.setControls(request.getControls()); + referralRequest.setIntermediateResponseHandlers(request.getIntermediateResponseHandlers()); + referralRequest.setReferralHandler( + new ModifyDnReferralHandler(getReferralLimit(), getReferralDepth() + 1, getReferralConnectionFactory())); + if (!url.getEntry().isDefaultBaseDn()) { + referralRequest.setDn(url.getEntry().getBaseDn()); + } else { + referralRequest.setDn(request.getDn()); + } + referralRequest.setDeleteOldRDn(request.getDeleteOldRDn()); + referralRequest.setNewDn(request.getNewDn()); + return referralRequest; + } + + + @Override + protected Operation<ModifyDnRequest, Void> createReferralOperation(final Connection conn) + { + return new ModifyDnOperation(conn); + } +}
diff --git a/core/src/main/java/org/ldaptive/referral/ModifyReferralHandler.java b/core/src/main/java/org/ldaptive/referral/ModifyReferralHandler.java new file mode 100644 index 0000000..cf049da --- /dev/null +++ b/core/src/main/java/org/ldaptive/referral/ModifyReferralHandler.java
@@ -0,0 +1,96 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.referral; + +import org.ldaptive.Connection; +import org.ldaptive.LdapURL; +import org.ldaptive.ModifyOperation; +import org.ldaptive.ModifyRequest; +import org.ldaptive.Operation; + +/** + * Provides handling of an ldap referral for modify operations. + * + * @author Middleware Services + */ +public class ModifyReferralHandler extends AbstractReferralHandler<ModifyRequest, Void> +{ + + + /** Creates a new modify referral handler. */ + public ModifyReferralHandler() + { + this(DEFAULT_REFERRAL_LIMIT, 0, DEFAULT_CONNECTION_FACTORY); + } + + + /** + * Creates a new modify referral handler. + * + * @param factory referral connection factory + */ + public ModifyReferralHandler(final ReferralConnectionFactory factory) + { + this(DEFAULT_REFERRAL_LIMIT, 0, factory); + } + + + /** + * Creates a new modify referral handler. + * + * @param limit number of referrals to follow + */ + public ModifyReferralHandler(final int limit) + { + this(limit, 0, DEFAULT_CONNECTION_FACTORY); + } + + + /** + * Creates a new modify referral handler. + * + * @param limit number of referrals to follow + * @param factory referral connection factory + */ + public ModifyReferralHandler(final int limit, final ReferralConnectionFactory factory) + { + this(limit, 0, factory); + } + + + /** + * Creates a new modify referral handler. + * + * @param limit number of referrals to follow + * @param depth number of referrals followed + * @param factory referral connection factory + */ + private ModifyReferralHandler(final int limit, final int depth, final ReferralConnectionFactory factory) + { + super(limit, depth, factory); + } + + + @Override + protected ModifyRequest createReferralRequest(final ModifyRequest request, final LdapURL url) + { + final ModifyRequest referralRequest = new ModifyRequest(); + referralRequest.setControls(request.getControls()); + referralRequest.setIntermediateResponseHandlers(request.getIntermediateResponseHandlers()); + referralRequest.setReferralHandler( + new ModifyReferralHandler(getReferralLimit(), getReferralDepth() + 1, getReferralConnectionFactory())); + if (!url.getEntry().isDefaultBaseDn()) { + referralRequest.setDn(url.getEntry().getBaseDn()); + } else { + referralRequest.setDn(request.getDn()); + } + referralRequest.setAttributeModifications(request.getAttributeModifications()); + return referralRequest; + } + + + @Override + protected Operation<ModifyRequest, Void> createReferralOperation(final Connection conn) + { + return new ModifyOperation(conn); + } +}
diff --git a/core/src/main/java/org/ldaptive/referral/ReferralConnectionFactory.java b/core/src/main/java/org/ldaptive/referral/ReferralConnectionFactory.java new file mode 100644 index 0000000..1005e8c --- /dev/null +++ b/core/src/main/java/org/ldaptive/referral/ReferralConnectionFactory.java
@@ -0,0 +1,25 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.referral; + +import org.ldaptive.ConnectionConfig; +import org.ldaptive.ConnectionFactory; + +/** + * Factory for creating connections used by referrals. + * + * @author Middleware Services + */ +public interface ReferralConnectionFactory +{ + + + /** + * Returns a connection factory for use with a referral. + * + * @param config for the connection factory + * @param ldapUrl of the referred host + * + * @return connection factory + */ + ConnectionFactory getConnectionFactory(ConnectionConfig config, String ldapUrl); +}
diff --git a/core/src/main/java/org/ldaptive/referral/ReferralHandler.java b/core/src/main/java/org/ldaptive/referral/ReferralHandler.java new file mode 100644 index 0000000..e8004e2 --- /dev/null +++ b/core/src/main/java/org/ldaptive/referral/ReferralHandler.java
@@ -0,0 +1,34 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.referral; + +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.ldaptive.handler.Handler; +import org.ldaptive.handler.HandlerResult; + +/** + * Provides handling of an ldap referral. + * + * @param <Q> type of ldap request + * @param <S> type of ldap response + * + * @author Middleware Services + */ +public interface ReferralHandler<Q extends Request, S> extends Handler<Q, Response<S>> +{ + + + @Override + HandlerResult<Response<S>> handle(Connection conn, Q request, Response<S> response) + throws LdapException; + + + /** + * Initialize the request for use with this referral handler. + * + * @param request to initialize for this referral handler + */ + void initializeRequest(Q request); +}
diff --git a/core/src/main/java/org/ldaptive/referral/SearchReferralHandler.java b/core/src/main/java/org/ldaptive/referral/SearchReferralHandler.java new file mode 100644 index 0000000..9314ad5 --- /dev/null +++ b/core/src/main/java/org/ldaptive/referral/SearchReferralHandler.java
@@ -0,0 +1,280 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.referral; + +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.LdapURL; +import org.ldaptive.LdapUtils; +import org.ldaptive.Operation; +import org.ldaptive.Response; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchReference; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.handler.HandlerResult; + +/** + * Provides handling of an ldap referral for search operations. Injects a {@link + * org.ldaptive.handler.SearchReferenceHandler} so that both referrals and search references will be followed. + * + * @author Middleware Services + */ +public class SearchReferralHandler extends AbstractReferralHandler<SearchRequest, SearchResult> +{ + + + /** Creates a new search referral handler. */ + public SearchReferralHandler() + { + this(DEFAULT_REFERRAL_LIMIT, 0, DEFAULT_CONNECTION_FACTORY); + } + + + /** + * Creates a new search referral handler. + * + * @param factory referral connection factory + */ + public SearchReferralHandler(final ReferralConnectionFactory factory) + { + this(DEFAULT_REFERRAL_LIMIT, 0, factory); + } + + + /** + * Creates a new search referral handler. + * + * @param limit number of referrals to follow + */ + public SearchReferralHandler(final int limit) + { + this(limit, 0, DEFAULT_CONNECTION_FACTORY); + } + + + /** + * Creates a new search referral handler. + * + * @param limit number of referrals to follow + * @param factory referral connection factory + */ + public SearchReferralHandler(final int limit, final ReferralConnectionFactory factory) + { + this(limit, 0, factory); + } + + + /** + * Creates a new search referral handler. + * + * @param limit number of referrals to follow + * @param depth number of referrals followed + * @param factory referral connection factory + */ + private SearchReferralHandler(final int limit, final int depth, final ReferralConnectionFactory factory) + { + super(limit, depth, factory); + } + + + @Override + protected SearchRequest createReferralRequest(final SearchRequest request, final LdapURL url) + { + final SearchRequest referralRequest = new SearchRequest(); + referralRequest.setControls(request.getControls()); + referralRequest.setIntermediateResponseHandlers(request.getIntermediateResponseHandlers()); + referralRequest.setReferralHandler( + new SearchReferralHandler(getReferralLimit(), getReferralDepth() + 1, getReferralConnectionFactory())); + + if (!url.getEntry().isDefaultBaseDn()) { + referralRequest.setBaseDn(url.getEntry().getBaseDn()); + } else { + referralRequest.setBaseDn(request.getBaseDn()); + } + referralRequest.setBinaryAttributes(request.getBinaryAttributes()); + referralRequest.setDerefAliases(request.getDerefAliases()); + referralRequest.setSearchEntryHandlers(request.getSearchEntryHandlers()); + + final org.ldaptive.handler.SearchReferenceHandler[] searchReferenceHandlers = request.getSearchReferenceHandlers(); + if (searchReferenceHandlers != null) { + for (int i = 0; i < searchReferenceHandlers.length; i++) { + if (searchReferenceHandlers[i] instanceof SearchReferenceHandler) { + final SearchReferenceHandler handler = (SearchReferenceHandler) searchReferenceHandlers[i]; + searchReferenceHandlers[i] = new SearchReferenceHandler( + handler.getReferralLimit(), + handler.getReferralDepth() + 1, + handler.getReferralConnectionFactory()); + } + } + } + referralRequest.setReturnAttributes(request.getReturnAttributes()); + if (!url.getEntry().isDefaultFilter()) { + referralRequest.setSearchFilter(url.getEntry().getFilter()); + } else { + referralRequest.setSearchFilter(request.getSearchFilter()); + } + if (!url.getEntry().isDefaultScope()) { + referralRequest.setSearchScope(url.getEntry().getScope()); + } else { + referralRequest.setSearchScope(request.getSearchScope()); + } + referralRequest.setSizeLimit(request.getSizeLimit()); + referralRequest.setSortBehavior(request.getSortBehavior()); + referralRequest.setTimeLimit(request.getTimeLimit()); + referralRequest.setTypesOnly(request.getTypesOnly()); + + return referralRequest; + } + + + @Override + protected Operation<SearchRequest, SearchResult> createReferralOperation(final Connection conn) + { + return new SearchOperation(conn); + } + + + @Override + public void initializeRequest(final SearchRequest request) + { + if (request.getSearchReferenceHandlers() != null) { + request.setSearchReferenceHandlers( + LdapUtils.concatArrays( + request.getSearchReferenceHandlers(), + new org.ldaptive.handler.SearchReferenceHandler[] {new SearchReferenceHandler(), })); + } else { + request.setSearchReferenceHandlers(new SearchReferenceHandler()); + } + } + + + /** + * Implementation of {@link org.ldaptive.handler.SearchReferenceHandler} that delegates to {@link + * SearchReferralHandler}. + */ + public static class SearchReferenceHandler implements org.ldaptive.handler.SearchReferenceHandler + { + + /** Referral limit. */ + private final int referralLimit; + + /** Referral depth. */ + private final int referralDepth; + + /** Referral connection factory. */ + private final ReferralConnectionFactory connectionFactory; + + + /** Creates a new search reference handler. */ + public SearchReferenceHandler() + { + this(DEFAULT_REFERRAL_LIMIT, 0, DEFAULT_CONNECTION_FACTORY); + } + + + /** + * Creates a new search reference handler. + * + * @param factory referral connection factory + */ + public SearchReferenceHandler(final ReferralConnectionFactory factory) + { + this(DEFAULT_REFERRAL_LIMIT, 0, factory); + } + + + /** + * Creates a new search reference handler. + * + * @param limit number of referrals to follow + */ + public SearchReferenceHandler(final int limit) + { + this(limit, 0, DEFAULT_CONNECTION_FACTORY); + } + + + /** + * Creates a new search reference handler. + * + * @param limit number of referrals to follow + * @param factory referral connection factory + */ + public SearchReferenceHandler(final int limit, final ReferralConnectionFactory factory) + { + this(limit, 0, factory); + } + + + /** + * Creates a new search reference handler. + * + * @param limit number of referrals to follow + * @param depth number of referrals followed + * @param factory referral connection factory + */ + private SearchReferenceHandler(final int limit, final int depth, final ReferralConnectionFactory factory) + { + referralLimit = limit; + referralDepth = depth; + connectionFactory = factory; + } + + + /** + * Returns the maximum number of referrals to follow. + * + * @return referral limit + */ + public int getReferralLimit() + { + return referralLimit; + } + + + /** + * Returns the referral depth of this handler. + * + * @return referral depth + */ + public int getReferralDepth() + { + return referralDepth; + } + + + /** + * Returns the referral connection factory. + * + * @return referral connection factory + */ + public ReferralConnectionFactory getReferralConnectionFactory() + { + return connectionFactory; + } + + + @Override + public HandlerResult<SearchReference> handle( + final Connection conn, + final SearchRequest request, + final SearchReference reference) + throws LdapException + { + if (reference == null) { + return new HandlerResult<>(null); + } + final SearchReferralHandler handler = new SearchReferralHandler(referralLimit, referralDepth, connectionFactory); + final HandlerResult<Response<SearchResult>> result = handler.handle(conn, request, reference.getReferralUrls()); + final Response<SearchResult> response = result.getResult(); + if (response != null) { + reference.setReferenceResponse(response); + } + return new HandlerResult<>(reference); + } + + + @Override + public void initializeRequest(final SearchRequest request) {} + } +}
diff --git a/core/src/main/java/org/ldaptive/sasl/CramMd5Config.java b/core/src/main/java/org/ldaptive/sasl/CramMd5Config.java new file mode 100644 index 0000000..f80695a --- /dev/null +++ b/core/src/main/java/org/ldaptive/sasl/CramMd5Config.java
@@ -0,0 +1,35 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.sasl; + +/** + * Contains all the configuration data for SASL Cram-MD5 authentication. + * + * @author Middleware Services + */ +public class CramMd5Config extends SaslConfig +{ + + + /** Default constructor. */ + public CramMd5Config() + { + setMechanism(Mechanism.CRAM_MD5); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::mechanism=%s, authorizationId=%s, mutualAuthentication=%s, " + + "qualityOfProtection=%s, securityStrength=%s]", + getClass().getName(), + hashCode(), + getMechanism(), + getAuthorizationId(), + getMutualAuthentication(), + getQualityOfProtection(), + getSecurityStrength()); + } +}
diff --git a/core/src/main/java/org/ldaptive/sasl/DigestMd5Config.java b/core/src/main/java/org/ldaptive/sasl/DigestMd5Config.java new file mode 100644 index 0000000..74cb1ba --- /dev/null +++ b/core/src/main/java/org/ldaptive/sasl/DigestMd5Config.java
@@ -0,0 +1,63 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.sasl; + +/** + * Contains all the configuration data for SASL Digest-MD5 authentication. + * + * @author Middleware Services + */ +public class DigestMd5Config extends SaslConfig +{ + + /** sasl realm. */ + private String saslRealm; + + + /** Default constructor. */ + public DigestMd5Config() + { + setMechanism(Mechanism.DIGEST_MD5); + } + + + /** + * Returns the sasl realm. + * + * @return realm + */ + public String getRealm() + { + return saslRealm; + } + + + /** + * Sets the sasl realm. + * + * @param realm to set + */ + public void setRealm(final String realm) + { + checkImmutable(); + logger.trace("setting realm: {}", realm); + saslRealm = realm; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::mechanism=%s, authorizationId=%s, mutualAuthentication=%s, " + + "qualityOfProtection=%s, securityStrength=%s, realm=%s]", + getClass().getName(), + hashCode(), + getMechanism(), + getAuthorizationId(), + getMutualAuthentication(), + getQualityOfProtection(), + getSecurityStrength(), + saslRealm); + } +}
diff --git a/core/src/main/java/org/ldaptive/sasl/ExternalConfig.java b/core/src/main/java/org/ldaptive/sasl/ExternalConfig.java new file mode 100644 index 0000000..fcf0f5f --- /dev/null +++ b/core/src/main/java/org/ldaptive/sasl/ExternalConfig.java
@@ -0,0 +1,35 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.sasl; + +/** + * Contains all the configuration data for SASL EXTERNAL authentication. + * + * @author Middleware Services + */ +public class ExternalConfig extends SaslConfig +{ + + + /** Default constructor. */ + public ExternalConfig() + { + setMechanism(Mechanism.EXTERNAL); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::mechanism=%s, authorizationId=%s, mutualAuthentication=%s, " + + "qualityOfProtection=%s, securityStrength=%s]", + getClass().getName(), + hashCode(), + getMechanism(), + getAuthorizationId(), + getMutualAuthentication(), + getQualityOfProtection(), + getSecurityStrength()); + } +}
diff --git a/core/src/main/java/org/ldaptive/sasl/GssApiConfig.java b/core/src/main/java/org/ldaptive/sasl/GssApiConfig.java new file mode 100644 index 0000000..4d8beb5 --- /dev/null +++ b/core/src/main/java/org/ldaptive/sasl/GssApiConfig.java
@@ -0,0 +1,63 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.sasl; + +/** + * Contains all the configuration data for SASL GSSAPI authentication. + * + * @author Middleware Services + */ +public class GssApiConfig extends SaslConfig +{ + + /** sasl realm. */ + private String saslRealm; + + + /** Default constructor. */ + public GssApiConfig() + { + setMechanism(Mechanism.GSSAPI); + } + + + /** + * Returns the sasl realm. + * + * @return realm + */ + public String getRealm() + { + return saslRealm; + } + + + /** + * Sets the sasl realm. + * + * @param realm realm + */ + public void setRealm(final String realm) + { + checkImmutable(); + logger.trace("setting realm: {}", realm); + saslRealm = realm; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::mechanism=%s, authorizationId=%s, mutualAuthentication=%s, " + + "qualityOfProtection=%s, securityStrength=%s, realm=%s]", + getClass().getName(), + hashCode(), + getMechanism(), + getAuthorizationId(), + getMutualAuthentication(), + getQualityOfProtection(), + getSecurityStrength(), + saslRealm); + } +}
diff --git a/core/src/main/java/org/ldaptive/sasl/Mechanism.java b/core/src/main/java/org/ldaptive/sasl/Mechanism.java new file mode 100644 index 0000000..9093bfd --- /dev/null +++ b/core/src/main/java/org/ldaptive/sasl/Mechanism.java
@@ -0,0 +1,22 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.sasl; + +/** + * Enum to define SASL mechanisms. + * + * @author Middleware Services + */ +public enum Mechanism { + + /** External authentication type. */ + EXTERNAL, + + /** Digest MD5 authentication type. */ + DIGEST_MD5, + + /** Cram MD5 authentication type. */ + CRAM_MD5, + + /** Kerberos authentication type. */ + GSSAPI +}
diff --git a/core/src/main/java/org/ldaptive/sasl/QualityOfProtection.java b/core/src/main/java/org/ldaptive/sasl/QualityOfProtection.java new file mode 100644 index 0000000..27bdc38 --- /dev/null +++ b/core/src/main/java/org/ldaptive/sasl/QualityOfProtection.java
@@ -0,0 +1,19 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.sasl; + +/** + * Enum to define SASL quality of protection. + * + * @author Middleware Services + */ +public enum QualityOfProtection { + + /** Authentication only. */ + AUTH, + + /** Authentication with integrity protection. */ + AUTH_INT, + + /** Authentication with integrity and privacy protection. */ + AUTH_CONF +}
diff --git a/core/src/main/java/org/ldaptive/sasl/SaslConfig.java b/core/src/main/java/org/ldaptive/sasl/SaslConfig.java new file mode 100644 index 0000000..cd3bebe --- /dev/null +++ b/core/src/main/java/org/ldaptive/sasl/SaslConfig.java
@@ -0,0 +1,165 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.sasl; + +import org.ldaptive.AbstractConfig; + +/** + * Contains all the configuration data for SASL authentication. + * + * @author Middleware Services + */ +public class SaslConfig extends AbstractConfig +{ + + /** sasl mechanism. */ + private Mechanism mechanism; + + /** sasl authorization id. */ + private String authorizationId = ""; + + /** perform mutual authentication. */ + private Boolean mutualAuthentication; + + /** sasl quality of protection. */ + private QualityOfProtection qualityOfProtection; + + /** sasl security strength. */ + private SecurityStrength securityStrength; + + + /** + * Returns the sasl mechanism. + * + * @return mechanism + */ + public Mechanism getMechanism() + { + return mechanism; + } + + + /** + * Sets the sasl mechanism. + * + * @param m mechanism + */ + public void setMechanism(final Mechanism m) + { + checkImmutable(); + logger.trace("setting mechanism: {}", m); + mechanism = m; + } + + + /** + * Returns the sasl authorization id. + * + * @return authorization id + */ + public String getAuthorizationId() + { + return authorizationId; + } + + + /** + * Sets the sasl authorization id. + * + * @param id authorization id + */ + public void setAuthorizationId(final String id) + { + checkImmutable(); + logger.trace("setting authorizationId: {}", id); + authorizationId = id; + } + + + /** + * Returns whether mutual authentication should occur. + * + * @return whether mutual authentication should occur + */ + public Boolean getMutualAuthentication() + { + return mutualAuthentication; + } + + + /** + * Sets whether mutual authentication should occur. + * + * @param b whether mutual authentication should occur + */ + public void setMutualAuthentication(final Boolean b) + { + checkImmutable(); + logger.trace("setting mutualAuthentication: {}", b); + mutualAuthentication = b; + } + + + /** + * Returns the sasl quality of protection. + * + * @return quality of protection + */ + public QualityOfProtection getQualityOfProtection() + { + return qualityOfProtection; + } + + + /** + * Sets the sasl quality of protection. + * + * @param qop quality of protection + */ + public void setQualityOfProtection(final QualityOfProtection qop) + { + checkImmutable(); + logger.trace("setting qualityOfProtection: {}", qop); + qualityOfProtection = qop; + } + + + /** + * Returns the sasl security strength. + * + * @return security strength + */ + public SecurityStrength getSecurityStrength() + { + return securityStrength; + } + + + /** + * Sets the sasl security strength. + * + * @param ss security strength + */ + public void setSecurityStrength(final SecurityStrength ss) + { + checkImmutable(); + logger.trace("setting securityStrength: {}", ss); + securityStrength = ss; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::mechanism=%s, authorizationId=%s, mutualAuthentication=%s, qualityOfProtection=%s, " + + "securityStrength=%s]", + getClass().getName(), + hashCode(), + mechanism, + authorizationId, + mutualAuthentication, + qualityOfProtection, + securityStrength); + } +}
diff --git a/core/src/main/java/org/ldaptive/sasl/SecurityStrength.java b/core/src/main/java/org/ldaptive/sasl/SecurityStrength.java new file mode 100644 index 0000000..53846ff --- /dev/null +++ b/core/src/main/java/org/ldaptive/sasl/SecurityStrength.java
@@ -0,0 +1,19 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.sasl; + +/** + * Enum to define SASL security strength. + * + * @author Middleware Services + */ +public enum SecurityStrength { + + /** High security strength. */ + HIGH, + + /** Medium security strength. */ + MEDIUM, + + /** Low security strength. */ + LOW +}
diff --git a/core/src/main/java/org/ldaptive/schema/AbstractNamedSchemaElement.java b/core/src/main/java/org/ldaptive/schema/AbstractNamedSchemaElement.java new file mode 100644 index 0000000..1196045 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/AbstractNamedSchemaElement.java
@@ -0,0 +1,95 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +/** + * Base schema bean for named schema elements. + * + * @author Middleware Services + */ +public abstract class AbstractNamedSchemaElement extends AbstractSchemaElement +{ + + /** Names. */ + private String[] names; + + /** Obsolete. */ + private boolean obsolete; + + + /** + * Returns the first name defined or null if no names are defined. + * + * @return first name in the list + */ + public String getName() + { + if (names != null && names.length > 0) { + return names[0]; + } + return null; + } + + + /** + * Returns the names. + * + * @return names + */ + public String[] getNames() + { + return names; + } + + + /** + * Sets the names. + * + * @param s names + */ + public void setNames(final String[] s) + { + names = s; + } + + + /** + * Returns whether the supplied string matches, ignoring case, any of the names for this schema element. + * + * @param s to match + * + * @return whether the supplied string matches a name + */ + public boolean hasName(final String s) + { + if (names != null) { + for (String name : names) { + if (name.equalsIgnoreCase(s)) { + return true; + } + } + } + return false; + } + + + /** + * Returns whether this attribute type definition is obsolete. + * + * @return whether this attribute type definition is obsolete + */ + public boolean isObsolete() + { + return obsolete; + } + + + /** + * Sets whether this attribute type definition is obsolete. + * + * @param b whether this attribute type definition is obsolete + */ + public void setObsolete(final boolean b) + { + obsolete = b; + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/AbstractSchemaElement.java b/core/src/main/java/org/ldaptive/schema/AbstractSchemaElement.java new file mode 100644 index 0000000..77f1fe7 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/AbstractSchemaElement.java
@@ -0,0 +1,101 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +/** + * Base class for schema elements. + * + * @author Middleware Services + */ +public abstract class AbstractSchemaElement implements SchemaElement +{ + + /** Regex to match zero or more spaces. */ + protected static final String WSP_REGEX = "[ ]*"; + + /** Regex to match one or more non spaces. */ + protected static final String NO_WSP_REGEX = "[^ ]+"; + + /** Description. */ + private String description; + + /** Extensions. */ + private Extensions extensions; + + + /** + * Returns the description. + * + * @return description + */ + public String getDescription() + { + return description; + } + + + /** + * Sets the description. + * + * @param s description + */ + public void setDescription(final String s) + { + description = s; + } + + + /** + * Returns the extensions. + * + * @return extensions + */ + public Extensions getExtensions() + { + return extensions; + } + + + /** + * Sets the extensions. + * + * @param e extensions + */ + public void setExtensions(final Extensions e) + { + extensions = e; + } + + + /** + * Returns whether the supplied schema element has an extension name with a value of 'true'. + * + * @param <T> type of schema element + * @param schemaElement to inspect + * @param extensionName to read boolean from + * + * @return whether syntax has this boolean extension + */ + public static <T extends AbstractSchemaElement> boolean containsBooleanExtension( + final T schemaElement, + final String extensionName) + { + if (schemaElement != null) { + final Extensions exts = schemaElement.getExtensions(); + if (exts != null && Boolean.parseBoolean(exts.getValue(extensionName))) { + return true; + } + } + return false; + } + + + @Override + public boolean equals(final Object o) + { + return super.equals(o); + } + + + @Override + public abstract int hashCode(); +}
diff --git a/core/src/main/java/org/ldaptive/schema/AttributeType.java b/core/src/main/java/org/ldaptive/schema/AttributeType.java new file mode 100644 index 0000000..ed74eb5 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/AttributeType.java
@@ -0,0 +1,575 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.text.ParseException; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.ldaptive.LdapUtils; + +/** + * Bean for an attribute type schema element. + * + * <pre> + AttributeTypeDescription = LPAREN WSP + numericoid ; object identifier + [ SP "NAME" SP qdescrs ] ; short names (descriptors) + [ SP "DESC" SP qdstring ] ; description + [ SP "OBSOLETE" ] ; not active + [ SP "SUP" SP oid ] ; supertype + [ SP "EQUALITY" SP oid ] ; equality matching rule + [ SP "ORDERING" SP oid ] ; ordering matching rule + [ SP "SUBSTR" SP oid ] ; substrings matching rule + [ SP "SYNTAX" SP noidlen ] ; value syntax + [ SP "SINGLE-VALUE" ] ; single-value + [ SP "COLLECTIVE" ] ; collective + [ SP "NO-USER-MODIFICATION" ] ; not user modifiable + [ SP "USAGE" SP usage ] ; usage + extensions WSP RPAREN ; extensions + * </pre> + * + * @author Middleware Services + */ +public class AttributeType extends AbstractNamedSchemaElement +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1103; + + /** Pattern to match definitions. */ + private static final Pattern DEFINITION_PATTERN = Pattern.compile( + WSP_REGEX + "\\(" + + WSP_REGEX + "(" + NO_WSP_REGEX + ")" + + WSP_REGEX + "(?:NAME (?:'([^']+)'|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:DESC '([^']*)')?" + + WSP_REGEX + "(OBSOLETE)?" + + WSP_REGEX + "(?:SUP (" + NO_WSP_REGEX + "))?" + + WSP_REGEX + "(?:EQUALITY (" + NO_WSP_REGEX + "))?" + + WSP_REGEX + "(?:ORDERING (" + NO_WSP_REGEX + "))?" + + WSP_REGEX + "(?:SUBSTR (" + NO_WSP_REGEX + "))?" + + WSP_REGEX + "(?:SYNTAX (" + NO_WSP_REGEX + "))?" + + WSP_REGEX + "(SINGLE-VALUE)?" + + WSP_REGEX + "(COLLECTIVE)?" + + WSP_REGEX + "(NO-USER-MODIFICATION)?" + + WSP_REGEX + "(?:USAGE (\\p{Alpha}+))?" + + WSP_REGEX + "(?:(X-[^ ]+.*))?" + + WSP_REGEX + "\\)" + WSP_REGEX); + + /** OID. */ + private final String oid; + + /** Superior type. */ + private String superiorType; + + /** Equality matching rule. */ + private String equalityMatchingRule; + + /** Ordering matching rule. */ + private String orderingMatchingRule; + + /** Substring matching rule. */ + private String substringMatchingRule; + + /** Syntax OID. */ + private String syntaxOID; + + /** Single valued. */ + private boolean singleValued; + + /** Collective. */ + private boolean collective; + + /** No user modification. */ + private boolean noUserModification; + + /** Usage. */ + private AttributeUsage usage; + + + /** + * Creates a new attribute type. + * + * @param s oid + */ + public AttributeType(final String s) + { + oid = s; + } + + + /** + * Creates a new attribute type. + * + * @param oid oid + * @param names names + * @param description description + * @param obsolete obsolete + * @param superiorType superior type + * @param equalityMatchingRule equality matching rule + * @param orderingMatchingRule ordering matching rule + * @param substringMatchingRule substring matching rule + * @param syntaxOID syntax OID + * @param singleValued single valued + * @param collective collective + * @param noUserModification no user modification + * @param usage usage + * @param extensions extensions + */ + // CheckStyle:ParameterNumber|HiddenField OFF + public AttributeType( + final String oid, + final String[] names, + final String description, + final boolean obsolete, + final String superiorType, + final String equalityMatchingRule, + final String orderingMatchingRule, + final String substringMatchingRule, + final String syntaxOID, + final boolean singleValued, + final boolean collective, + final boolean noUserModification, + final AttributeUsage usage, + final Extensions extensions) + { + this(oid); + setNames(names); + setDescription(description); + setObsolete(obsolete); + setSuperiorType(superiorType); + setEqualityMatchingRule(equalityMatchingRule); + setOrderingMatchingRule(orderingMatchingRule); + setSubstringMatchingRule(substringMatchingRule); + setSyntaxOID(syntaxOID); + setSingleValued(singleValued); + setCollective(collective); + setNoUserModification(noUserModification); + setUsage(usage); + setExtensions(extensions); + } + // CheckStyle:ParameterNumber|HiddenField ON + + + /** + * Returns the oid. + * + * @return oid + */ + public String getOID() + { + return oid; + } + + + /** + * Returns the superior type. + * + * @return superior type + */ + public String getSuperiorType() + { + return superiorType; + } + + + /** + * Sets the superior type. + * + * @param s superior type + */ + public void setSuperiorType(final String s) + { + superiorType = s; + } + + + /** + * Returns the equality matching rule. + * + * @return equality matching rule + */ + public String getEqualityMatchingRule() + { + return equalityMatchingRule; + } + + + /** + * Sets the equality matching rule. + * + * @param s equality matching rule + */ + public void setEqualityMatchingRule(final String s) + { + equalityMatchingRule = s; + } + + + /** + * Returns the ordering matching rule. + * + * @return ordering matching rule + */ + public String getOrderingMatchingRule() + { + return orderingMatchingRule; + } + + + /** + * Sets the ordering matching rule. + * + * @param s ordering matching rule + */ + public void setOrderingMatchingRule(final String s) + { + orderingMatchingRule = s; + } + + + /** + * Returns the substring matching rule. + * + * @return substring matching rule + */ + public String getSubstringMatchingRule() + { + return substringMatchingRule; + } + + + /** + * Sets the substring matching rule. + * + * @param s substring matching rule + */ + public void setSubstringMatchingRule(final String s) + { + substringMatchingRule = s; + } + + + /** + * Returns the syntax oid. + * + * @return syntax oid + */ + public String getSyntaxOID() + { + return syntaxOID; + } + + + /** + * Returns the syntax oid. + * + * @param withBoundCount whether the bound count should be included + * + * @return syntax oid + */ + public String getSyntaxOID(final boolean withBoundCount) + { + if (!withBoundCount && syntaxOID != null) { + if (syntaxOID.contains("{") && syntaxOID.endsWith("}")) { + return syntaxOID.substring(0, syntaxOID.indexOf('{')); + } + } + return syntaxOID; + } + + + /** + * Returns the syntax oid bound count. + * + * @return syntax oid bound count + */ + public int getSyntaxOIDBoundCount() + { + if (syntaxOID != null) { + if (syntaxOID.contains("{") && syntaxOID.endsWith("}")) { + final String count = syntaxOID.substring(syntaxOID.indexOf('{') + 1, syntaxOID.length() - 1); + return Integer.parseInt(count); + } + } + return -1; + } + + + /** + * Sets the syntax oid. + * + * @param s syntax oid + */ + public void setSyntaxOID(final String s) + { + syntaxOID = s; + } + + + /** + * Returns whether this attribute type is single valued. + * + * @return whether this attribute type is single valued + */ + public boolean isSingleValued() + { + return singleValued; + } + + + /** + * Sets whether this attribute type is single valued. + * + * @param b whether this attribute type is single valued + */ + public void setSingleValued(final boolean b) + { + singleValued = b; + } + + + /** + * Returns whether this attribute type is collective. + * + * @return whether this attribute type is collective + */ + public boolean isCollective() + { + return collective; + } + + + /** + * Sets whether this attribute type is collective. + * + * @param b whether this attribute type is collective + */ + public void setCollective(final boolean b) + { + collective = b; + } + + + /** + * Returns whether this attribute type allows user modification. + * + * @return whether this attribute type allows user modification + */ + public boolean isNoUserModification() + { + return noUserModification; + } + + + /** + * Sets whether this attribute type allows user modification. + * + * @param b whether this attribute type allows user modification + */ + public void setNoUserModification(final boolean b) + { + noUserModification = b; + } + + + /** + * Returns the usage. + * + * @return usage + */ + public AttributeUsage getUsage() + { + return usage != null ? usage : AttributeUsage.USER_APPLICATIONS; + } + + + /** + * Sets the usage. + * + * @param u attribute usage + */ + public void setUsage(final AttributeUsage u) + { + usage = u; + } + + + /** + * Parses the supplied definition string and creates an initialized attribute type. + * + * @param definition to parse + * + * @return attribute type + * + * @throws ParseException if the supplied definition is invalid + */ + public static AttributeType parse(final String definition) + throws ParseException + { + final Matcher m = DEFINITION_PATTERN.matcher(definition); + if (!m.matches()) { + throw new ParseException("Invalid attribute type definition: " + definition, definition.length()); + } + + final AttributeType atd = new AttributeType(m.group(1).trim()); + + // CheckStyle:MagicNumber OFF + // parse names + if (m.group(2) != null) { + atd.setNames(SchemaUtils.parseDescriptors(m.group(2).trim())); + } else if (m.group(3) != null) { + atd.setNames(SchemaUtils.parseDescriptors(m.group(3).trim())); + } + + atd.setDescription(m.group(4) != null ? m.group(4).trim() : null); + atd.setObsolete(m.group(5) != null); + atd.setSuperiorType(m.group(6) != null ? m.group(6).trim() : null); + atd.setEqualityMatchingRule(m.group(7) != null ? m.group(7).trim() : null); + atd.setOrderingMatchingRule(m.group(8) != null ? m.group(8).trim() : null); + atd.setSubstringMatchingRule(m.group(9) != null ? m.group(9).trim() : null); + atd.setSyntaxOID(m.group(10) != null ? m.group(10).trim() : null); + atd.setSingleValued(m.group(11) != null); + atd.setCollective(m.group(12) != null); + atd.setNoUserModification(m.group(13) != null); + if (m.group(14) != null) { + atd.setUsage(AttributeUsage.parse(m.group(14).trim())); + } + + // parse extensions + if (m.group(15) != null) { + atd.setExtensions(Extensions.parse(m.group(15).trim())); + } + return atd; + // CheckStyle:MagicNumber ON + } + + + @Override + public String format() + { + final StringBuilder sb = new StringBuilder("( "); + sb.append(oid).append(" "); + if (getNames() != null && getNames().length > 0) { + sb.append("NAME "); + sb.append(SchemaUtils.formatDescriptors(getNames())); + } + if (getDescription() != null) { + sb.append("DESC "); + sb.append(SchemaUtils.formatDescriptors(getDescription())); + } + if (isObsolete()) { + sb.append("OBSOLETE "); + } + if (superiorType != null) { + sb.append("SUP ").append(superiorType).append(" "); + } + if (equalityMatchingRule != null) { + sb.append("EQUALITY ").append(equalityMatchingRule).append(" "); + } + if (orderingMatchingRule != null) { + sb.append("ORDERING ").append(orderingMatchingRule).append(" "); + } + if (substringMatchingRule != null) { + sb.append("SUBSTR ").append(substringMatchingRule).append(" "); + } + if (syntaxOID != null) { + sb.append("SYNTAX ").append(syntaxOID).append(" "); + } + if (singleValued) { + sb.append("SINGLE-VALUE "); + } + if (collective) { + sb.append("COLLECTIVE "); + } + if (noUserModification) { + sb.append("NO-USER-MODIFICATION "); + } + if (usage != null) { + sb.append("USAGE ").append(usage.getName()).append(" "); + } + if (getExtensions() != null) { + sb.append(getExtensions().format()); + } + sb.append(")"); + return sb.toString(); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof AttributeType) { + final AttributeType v = (AttributeType) o; + return LdapUtils.areEqual(oid, v.oid) && + LdapUtils.areEqual(getNames(), v.getNames()) && + LdapUtils.areEqual(getDescription(), v.getDescription()) && + LdapUtils.areEqual(isObsolete(), v.isObsolete()) && + LdapUtils.areEqual(superiorType, v.superiorType) && + LdapUtils.areEqual(equalityMatchingRule, v.equalityMatchingRule) && + LdapUtils.areEqual(orderingMatchingRule, v.orderingMatchingRule) && + LdapUtils.areEqual(substringMatchingRule, v.substringMatchingRule) && + LdapUtils.areEqual(syntaxOID, v.syntaxOID) && + LdapUtils.areEqual(singleValued, v.singleValued) && + LdapUtils.areEqual(collective, v.collective) && + LdapUtils.areEqual(noUserModification, v.noUserModification) && + LdapUtils.areEqual(usage, v.usage) && + LdapUtils.areEqual(getExtensions(), v.getExtensions()); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + oid, + getNames(), + getDescription(), + isObsolete(), + superiorType, + equalityMatchingRule, + orderingMatchingRule, + substringMatchingRule, + syntaxOID, + singleValued, + collective, + noUserModification, + usage, + getExtensions()); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::oid=%s, names=%s, description=%s, obsolete=%s, " + + "superiorType=%s, equalityMatchingRule=%s, " + + "orderingMatchingRule=%s, substringMatchingRule=%s, syntaxOID=%s, " + + "singleValued=%s, collective=%s, noUserModification=%s, usage=%s, " + + "extensions=%s]", + getClass().getName(), + hashCode(), + oid, + Arrays.toString(getNames()), + getDescription(), + isObsolete(), + superiorType, + equalityMatchingRule, + orderingMatchingRule, + substringMatchingRule, + syntaxOID, + singleValued, + collective, + noUserModification, + usage, + getExtensions()); + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/AttributeUsage.java b/core/src/main/java/org/ldaptive/schema/AttributeUsage.java new file mode 100644 index 0000000..f032e1b --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/AttributeUsage.java
@@ -0,0 +1,89 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +/** + * Enum for an attribute usage schema element. + * + * <pre> + AttributeUsage = + "userApplications" / + "directoryOperation" / + "distributedOperation" / ; DSA-shared + "dSAOperation" ; DSA-specific, value depends on server + * </pre> + * + * @author Middleware Services + */ +public enum AttributeUsage { + + /** user applications. */ + USER_APPLICATIONS("userApplications", false), + + /** directory operation. */ + DIRECTORY_OPERATION("directoryOperation", true), + + /** distributed operation. */ + DISTRIBUTED_OPERATION("distributedOperation", true), + + /** dSA operation. */ + DSA_OPERATION("dSAOperation", true); + + /** Name of this attribute usage. */ + private final String name; + + /** Whether this attribute usage is operational. */ + private final boolean operational; + + + /** + * Creates a new attribute usage. + * + * @param s name of this usage + * @param b whether this usage is operational + */ + AttributeUsage(final String s, final boolean b) + { + name = s; + operational = b; + } + + + /** + * Returns the name. + * + * @return attribute usage name + */ + public String getName() + { + return name; + } + + + /** + * Whether this attribute usage is operational. + * + * @return whether this attribute usage is operational + */ + public boolean isOperational() + { + return operational; + } + + + /** + * Returns the attribute usage for the supplied string name. + * + * @param s case insensitive name to find attribute usage for + * + * @return attribute usage or null if name cannot be found + */ + public static AttributeUsage parse(final String s) + { + for (AttributeUsage usage : AttributeUsage.values()) { + if (usage.getName().equalsIgnoreCase(s)) { + return usage; + } + } + return null; + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/DITContentRule.java b/core/src/main/java/org/ldaptive/schema/DITContentRule.java new file mode 100644 index 0000000..eeff8f9 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/DITContentRule.java
@@ -0,0 +1,379 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.text.ParseException; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.ldaptive.LdapUtils; + +/** + * Bean for a DIT content rule schema element. + * + * <pre> + DITContentRuleDescription = LPAREN WSP + numericoid ; object identifier + [ SP "NAME" SP qdescrs ] ; short names (descriptors) + [ SP "DESC" SP qdstring ] ; description + [ SP "OBSOLETE" ] ; not active + [ SP "AUX" SP oids ] ; auxiliary object classes + [ SP "MUST" SP oids ] ; attribute types + [ SP "MAY" SP oids ] ; attribute types + [ SP "NOT" SP oids ] ; attribute types + extensions WSP RPAREN ; extensions + * </pre> + * + * @author Middleware Services + */ +public class DITContentRule extends AbstractNamedSchemaElement +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1151; + + /** Pattern to match definitions. */ + private static final Pattern DEFINITION_PATTERN = Pattern.compile( + WSP_REGEX + "\\(" + + WSP_REGEX + "(" + NO_WSP_REGEX + ")" + + WSP_REGEX + "(?:NAME (?:'([^']+)'|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:DESC '([^']*)')?" + + WSP_REGEX + "(OBSOLETE)?" + + WSP_REGEX + "(?:AUX (?:(" + NO_WSP_REGEX + ")|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:MUST (?:(" + NO_WSP_REGEX + ")|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:MAY (?:(" + NO_WSP_REGEX + ")|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:NOT (?:(" + NO_WSP_REGEX + ")|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:(X-[^ ]+.*))?" + + WSP_REGEX + "\\)" + WSP_REGEX); + + /** OID. */ + private final String oid; + + /** Auxiliary classes. */ + private String[] auxiliaryClasses; + + /** Required attributes. */ + private String[] requiredAttributes; + + /** Optional attributes. */ + private String[] optionalAttributes; + + /** Restricted attributes. */ + private String[] restrictedAttributes; + + + /** + * Creates a new DIT content rule. + * + * @param s oid + */ + public DITContentRule(final String s) + { + oid = s; + } + + + /** + * Creates a new DIT content rule. + * + * @param oid oid + * @param names names + * @param description description + * @param obsolete obsolete + * @param auxiliaryClasses auxiliary classes + * @param requiredAttributes required attributes + * @param optionalAttributes optional attributes + * @param restrictedAttributes restricted attributes + * @param extensions extensions + */ + // CheckStyle:ParameterNumber|HiddenField OFF + public DITContentRule( + final String oid, + final String[] names, + final String description, + final boolean obsolete, + final String[] auxiliaryClasses, + final String[] requiredAttributes, + final String[] optionalAttributes, + final String[] restrictedAttributes, + final Extensions extensions) + { + this(oid); + setNames(names); + setDescription(description); + setObsolete(obsolete); + setAuxiliaryClasses(auxiliaryClasses); + setRequiredAttributes(requiredAttributes); + setOptionalAttributes(optionalAttributes); + setRestrictedAttributes(restrictedAttributes); + setExtensions(extensions); + } + // CheckStyle:ParameterNumber|HiddenField ON + + + /** + * Returns the oid. + * + * @return oid + */ + public String getOID() + { + return oid; + } + + + /** + * Returns the auxiliary classes. + * + * @return auxiliary classes + */ + public String[] getAuxiliaryClasses() + { + return auxiliaryClasses; + } + + + /** + * Sets the auxiliary classes. + * + * @param s auxiliary classes + */ + public void setAuxiliaryClasses(final String[] s) + { + auxiliaryClasses = s; + } + + + /** + * Returns the required attributes. + * + * @return required attributes + */ + public String[] getRequiredAttributes() + { + return requiredAttributes; + } + + + /** + * Sets the required attributes. + * + * @param s required attributes + */ + public void setRequiredAttributes(final String[] s) + { + requiredAttributes = s; + } + + + /** + * Returns the optional attributes. + * + * @return optional attributes + */ + public String[] getOptionalAttributes() + { + return optionalAttributes; + } + + + /** + * Sets the optional attributes. + * + * @param s optional attributes + */ + public void setOptionalAttributes(final String[] s) + { + optionalAttributes = s; + } + + + /** + * Returns the restricted attributes. + * + * @return restricted attributes + */ + public String[] getRestrictedAttributes() + { + return restrictedAttributes; + } + + + /** + * Sets the restricted attributes. + * + * @param s restricted attributes + */ + public void setRestrictedAttributes(final String[] s) + { + restrictedAttributes = s; + } + + + /** + * Parses the supplied definition string and creates an initialized DIT content rule. + * + * @param definition to parse + * + * @return DIT content rule + * + * @throws ParseException if the supplied definition is invalid + */ + public static DITContentRule parse(final String definition) + throws ParseException + { + final Matcher m = DEFINITION_PATTERN.matcher(definition); + if (!m.matches()) { + throw new ParseException("Invalid DIT content rule definition: " + definition, definition.length()); + } + + final DITContentRule dcrd = new DITContentRule(m.group(1).trim()); + + // CheckStyle:MagicNumber OFF + // parse names + if (m.group(2) != null) { + dcrd.setNames(SchemaUtils.parseDescriptors(m.group(2).trim())); + } else if (m.group(3) != null) { + dcrd.setNames(SchemaUtils.parseDescriptors(m.group(3).trim())); + } + + dcrd.setDescription(m.group(4) != null ? m.group(4).trim() : null); + dcrd.setObsolete(m.group(5) != null); + + // parse auxiliary classes + if (m.group(6) != null) { + dcrd.setAuxiliaryClasses(SchemaUtils.parseOIDs(m.group(6).trim())); + } else if (m.group(7) != null) { + dcrd.setAuxiliaryClasses(SchemaUtils.parseOIDs(m.group(7).trim())); + } + + // parse required attributes + if (m.group(9) != null) { + dcrd.setRequiredAttributes(SchemaUtils.parseOIDs(m.group(9).trim())); + } else if (m.group(10) != null) { + dcrd.setRequiredAttributes(SchemaUtils.parseOIDs(m.group(10).trim())); + } + + // parse optional attributes + if (m.group(11) != null) { + dcrd.setOptionalAttributes(SchemaUtils.parseOIDs(m.group(11).trim())); + } else if (m.group(12) != null) { + dcrd.setOptionalAttributes(SchemaUtils.parseOIDs(m.group(12).trim())); + } + + // parse restricted attributes + if (m.group(11) != null) { + dcrd.setRestrictedAttributes(SchemaUtils.parseOIDs(m.group(11).trim())); + } else if (m.group(12) != null) { + dcrd.setRestrictedAttributes(SchemaUtils.parseOIDs(m.group(12).trim())); + } + + // parse extensions + if (m.group(13) != null) { + dcrd.setExtensions(Extensions.parse(m.group(13).trim())); + } + return dcrd; + // CheckStyle:MagicNumber ON + } + + + @Override + public String format() + { + final StringBuilder sb = new StringBuilder("( "); + sb.append(oid).append(" "); + if (getNames() != null && getNames().length > 0) { + sb.append("NAME "); + sb.append(SchemaUtils.formatDescriptors(getNames())); + } + if (getDescription() != null) { + sb.append("DESC "); + sb.append(SchemaUtils.formatDescriptors(getDescription())); + } + if (isObsolete()) { + sb.append("OBSOLETE "); + } + if (auxiliaryClasses != null && auxiliaryClasses.length > 0) { + sb.append("AUX "); + sb.append(SchemaUtils.formatOids(auxiliaryClasses)); + } + if (requiredAttributes != null && requiredAttributes.length > 0) { + sb.append("MUST "); + sb.append(SchemaUtils.formatOids(requiredAttributes)); + } + if (optionalAttributes != null && optionalAttributes.length > 0) { + sb.append("MAY "); + sb.append(SchemaUtils.formatOids(optionalAttributes)); + } + if (restrictedAttributes != null && restrictedAttributes.length > 0) { + sb.append("NOT "); + sb.append(SchemaUtils.formatOids(restrictedAttributes)); + } + if (getExtensions() != null) { + sb.append(getExtensions().format()); + } + sb.append(")"); + return sb.toString(); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof DITContentRule) { + final DITContentRule v = (DITContentRule) o; + return LdapUtils.areEqual(oid, v.oid) && + LdapUtils.areEqual(getNames(), v.getNames()) && + LdapUtils.areEqual(getDescription(), v.getDescription()) && + LdapUtils.areEqual(isObsolete(), v.isObsolete()) && + LdapUtils.areEqual(auxiliaryClasses, v.auxiliaryClasses) && + LdapUtils.areEqual(requiredAttributes, v.requiredAttributes) && + LdapUtils.areEqual(optionalAttributes, v.optionalAttributes) && + LdapUtils.areEqual(restrictedAttributes, v.restrictedAttributes) && + LdapUtils.areEqual(getExtensions(), v.getExtensions()); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + oid, + getNames(), + getDescription(), + isObsolete(), + auxiliaryClasses, + requiredAttributes, + optionalAttributes, + restrictedAttributes, + getExtensions()); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::oid=%s, names=%s, description=%s, obsolete=%s, " + + "auxiliaryClasses=%s, requiredAttributes=%s, " + + "optionalAttributes=%s, restrictedAttributes=%s, extensions=%s]", + getClass().getName(), + hashCode(), + oid, + Arrays.toString(getNames()), + getDescription(), + isObsolete(), + Arrays.toString(auxiliaryClasses), + Arrays.toString(requiredAttributes), + Arrays.toString(optionalAttributes), + Arrays.toString(restrictedAttributes), + getExtensions()); + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/DITStructureRule.java b/core/src/main/java/org/ldaptive/schema/DITStructureRule.java new file mode 100644 index 0000000..5fa8bd5 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/DITStructureRule.java
@@ -0,0 +1,282 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.text.ParseException; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.ldaptive.LdapUtils; + +/** + * Bean for a DIT content rule schema element. + * + * <pre> + DITStructureRuleDescription = LPAREN WSP + ruleid ; rule identifier + [ SP "NAME" SP qdescrs ] ; short names (descriptors) + [ SP "DESC" SP qdstring ] ; description + [ SP "OBSOLETE" ] ; not active + SP "FORM" SP oid ; NameForm + [ SP "SUP" ruleids ] ; superior rules + extensions WSP RPAREN ; extensions + * </pre> + * + * @author Middleware Services + */ +public class DITStructureRule extends AbstractNamedSchemaElement +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1153; + + /** Pattern to match definitions. */ + private static final Pattern DEFINITION_PATTERN = Pattern.compile( + WSP_REGEX + "\\(" + + WSP_REGEX + "(\\p{Digit}+)" + + WSP_REGEX + "(?:NAME (?:'([^']+)'|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:DESC '([^']*)')?" + + WSP_REGEX + "(OBSOLETE)?" + + WSP_REGEX + "(?:FORM (" + NO_WSP_REGEX + "))?" + + WSP_REGEX + "(?:SUP (?:(" + NO_WSP_REGEX + ")|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:(X-[^ ]+.*))?" + + WSP_REGEX + "\\)" + WSP_REGEX); + + /** ID. */ + private final int id; + + /** Name form. */ + private String nameForm; + + /** Superior rules. */ + private int[] superiorRules; + + + /** + * Creates a new DIT structure rule. + * + * @param i id + */ + public DITStructureRule(final int i) + { + id = i; + } + + + /** + * Creates a new DIT structure rule. + * + * @param id id + * @param names names + * @param description description + * @param obsolete obsolete + * @param nameForm name form + * @param superiorRules superior rules + * @param extensions extensions + */ + // CheckStyle:ParameterNumber|HiddenField OFF + public DITStructureRule( + final int id, + final String[] names, + final String description, + final boolean obsolete, + final String nameForm, + final int[] superiorRules, + final Extensions extensions) + { + this(id); + setNames(names); + setDescription(description); + setObsolete(obsolete); + setNameForm(nameForm); + setSuperiorRules(superiorRules); + setExtensions(extensions); + } + // CheckStyle:ParameterNumber|HiddenField ON + + + /** + * Returns the id. + * + * @return id + */ + public int getID() + { + return id; + } + + + /** + * Returns the name form. + * + * @return name form + */ + public String getNameForm() + { + return nameForm; + } + + + /** + * Sets the name form. + * + * @param s name form + */ + public void setNameForm(final String s) + { + nameForm = s; + } + + + /** + * Returns the superior rules. + * + * @return superior rules + */ + public int[] getSuperiorRules() + { + return superiorRules; + } + + + /** + * Sets the superior rules. + * + * @param i superior rules + */ + public void setSuperiorRules(final int[] i) + { + superiorRules = i; + } + + + /** + * Parses the supplied definition string and creates an initialized DIT structure rule. + * + * @param definition to parse + * + * @return DIT structure rule + * + * @throws ParseException if the supplied definition is invalid + */ + public static DITStructureRule parse(final String definition) + throws ParseException + { + final Matcher m = DEFINITION_PATTERN.matcher(definition); + if (!m.matches()) { + throw new ParseException("Invalid DIT structure rule definition: " + definition, definition.length()); + } + + final DITStructureRule dsrd = new DITStructureRule(Integer.parseInt(m.group(1).trim())); + + // CheckStyle:MagicNumber OFF + // parse names + if (m.group(2) != null) { + dsrd.setNames(SchemaUtils.parseDescriptors(m.group(2).trim())); + } else if (m.group(3) != null) { + dsrd.setNames(SchemaUtils.parseDescriptors(m.group(3).trim())); + } + + dsrd.setDescription(m.group(4) != null ? m.group(4).trim() : null); + dsrd.setObsolete(m.group(5) != null); + dsrd.setNameForm(m.group(6) != null ? m.group(6).trim() : null); + + // parse superior rules + if (m.group(7) != null) { + dsrd.setSuperiorRules(SchemaUtils.parseNumbers(m.group(7).trim())); + } else if (m.group(8) != null) { + dsrd.setSuperiorRules(SchemaUtils.parseNumbers(m.group(8).trim())); + } + + // parse extensions + if (m.group(9) != null) { + dsrd.setExtensions(Extensions.parse(m.group(9).trim())); + } + return dsrd; + // CheckStyle:MagicNumber ON + } + + + @Override + public String format() + { + final StringBuilder sb = new StringBuilder("( "); + sb.append(id).append(" "); + if (getNames() != null && getNames().length > 0) { + sb.append("NAME "); + sb.append(SchemaUtils.formatDescriptors(getNames())); + } + if (getDescription() != null) { + sb.append("DESC "); + sb.append(SchemaUtils.formatDescriptors(getDescription())); + } + if (isObsolete()) { + sb.append("OBSOLETE "); + } + if (nameForm != null) { + sb.append("FORM ").append(nameForm).append(" "); + } + if (superiorRules != null && superiorRules.length > 0) { + sb.append("SUP "); + sb.append(SchemaUtils.formatNumbers(superiorRules)); + } + if (getExtensions() != null) { + sb.append(getExtensions().format()); + } + sb.append(")"); + return sb.toString(); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof DITStructureRule) { + final DITStructureRule v = (DITStructureRule) o; + return LdapUtils.areEqual(id, v.id) && + LdapUtils.areEqual(getNames(), v.getNames()) && + LdapUtils.areEqual(getDescription(), v.getDescription()) && + LdapUtils.areEqual(isObsolete(), v.isObsolete()) && + LdapUtils.areEqual(nameForm, v.nameForm) && + LdapUtils.areEqual(superiorRules, v.superiorRules) && + LdapUtils.areEqual(getExtensions(), v.getExtensions()); + } + return false; + } + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + id, + getNames(), + getDescription(), + isObsolete(), + nameForm, + superiorRules, + getExtensions()); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::id=%s, names=%s, description=%s, obsolete=%s, " + + "nameForm=%s, superiorRules=%s, extensions=%s]", + getClass().getName(), + hashCode(), + id, + Arrays.toString(getNames()), + getDescription(), + isObsolete(), + nameForm, + Arrays.toString(superiorRules), + getExtensions()); + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/Extensions.java b/core/src/main/java/org/ldaptive/schema/Extensions.java new file mode 100644 index 0000000..a4682a3 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/Extensions.java
@@ -0,0 +1,198 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.ldaptive.LdapUtils; + +/** + * Bean for an extension found in a schema element. + * + * @author Middleware Services + */ +public class Extensions +{ + + /** Pattern to match attribute type definitions. */ + protected static final Pattern DEFINITION_PATTERN = Pattern.compile( + "(?:(X-[^ ]+)[ ]*(?:'([^']+)'|\\(([^\\)]+)\\))?)+"); + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1171; + + /** Extensions. */ + private final Map<String, List<String>> extensions = new LinkedHashMap<>(); + + + /** Creates a new extensions. */ + public Extensions() {} + + + /** + * Creates a new extensions. + * + * @param name of a single extension + * @param values for that extension + */ + public Extensions(final String name, final List<String> values) + { + addExtension(name, values); + } + + + /** + * Returns the name. + * + * @return name + */ + public Set<String> getNames() + { + return extensions.keySet(); + } + + + /** + * Returns the values for the extension with the supplied name. + * + * @param name of the extension + * + * @return values + */ + public List<String> getValues(final String name) + { + return extensions.get(name); + } + + + /** + * Returns a single string value for the extension with the supplied name. See {@link #getValues(String)}. + * + * @param name of the extension + * + * @return single string extension value + */ + public String getValue(final String name) + { + final List<String> values = getValues(name); + if (values == null || values.isEmpty()) { + return null; + } + return values.iterator().next(); + } + + + /** + * Returns all the values in this extensions. + * + * @return map of name to values for every extension + */ + public Map<String, List<String>> getAllValues() + { + return Collections.unmodifiableMap(extensions); + } + + + /** + * Adds an extension. + * + * @param name of the extension + */ + public void addExtension(final String name) + { + extensions.put(name, new ArrayList<>(0)); + } + + + /** + * Adds an extension. + * + * @param name of the extension + * @param values in the extension + */ + public void addExtension(final String name, final List<String> values) + { + extensions.put(name, values); + } + + + /** + * Parses the supplied definition string and creates an initialized extension. + * + * @param definition to parse + * + * @return extension + */ + public static Extensions parse(final String definition) + { + final Matcher m = DEFINITION_PATTERN.matcher(definition); + final Extensions exts = new Extensions(); + while (m.find()) { + final String name = m.group(1).trim(); + final List<String> values = new ArrayList<>(1); + + // CheckStyle:MagicNumber OFF + if (m.group(2) != null) { + values.add(m.group(2).trim()); + } else if (m.group(3) != null) { + values.addAll(Arrays.asList(SchemaUtils.parseDescriptors(m.group(3).trim()))); + } + // CheckStyle:MagicNumber ON + exts.addExtension(name, values); + } + + return exts; + } + + + /** + * Returns this extension as formatted string per RFC 4512. + * + * @return formatted string + */ + public String format() + { + final StringBuilder sb = new StringBuilder(); + for (Map.Entry<String, List<String>> entry : extensions.entrySet()) { + sb.append(entry.getKey()).append(" "); + if (entry.getValue() != null && !entry.getValue().isEmpty()) { + sb.append(SchemaUtils.formatDescriptors(entry.getValue().toArray(new String[entry.getValue().size()]))); + } + } + return sb.toString(); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof Extensions) { + final Extensions v = (Extensions) o; + return LdapUtils.areEqual(extensions, v.extensions); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, extensions); + } + + + @Override + public String toString() + { + return String.format("[%s@%d::extensions=%s]", getClass().getName(), hashCode(), extensions); + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/MatchingRule.java b/core/src/main/java/org/ldaptive/schema/MatchingRule.java new file mode 100644 index 0000000..b1999f5 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/MatchingRule.java
@@ -0,0 +1,239 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.text.ParseException; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.ldaptive.LdapUtils; + +/** + * Bean for an matching rule schema element. + * + * <pre> + MatchingRuleDescription = LPAREN WSP + numericoid ; object identifier + [ SP "NAME" SP qdescrs ] ; short names (descriptors) + [ SP "DESC" SP qdstring ] ; description + [ SP "OBSOLETE" ] ; not active + SP "SYNTAX" SP numericoid ; assertion syntax + extensions WSP RPAREN ; extensions + * </pre> + * + * @author Middleware Services + */ +public class MatchingRule extends AbstractNamedSchemaElement +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1117; + + /** Pattern to match definitions. */ + private static final Pattern DEFINITION_PATTERN = Pattern.compile( + WSP_REGEX + "\\(" + + WSP_REGEX + "(" + NO_WSP_REGEX + ")" + + WSP_REGEX + "(?:NAME (?:'([^']+)'|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:DESC '([^']*)')?" + + WSP_REGEX + "(OBSOLETE)?" + + WSP_REGEX + "(?:SYNTAX (" + NO_WSP_REGEX + "))?" + + WSP_REGEX + "(?:(X-[^ ]+.*))?" + + WSP_REGEX + "\\)" + WSP_REGEX); + + /** OID. */ + private final String oid; + + /** Syntax OID. */ + private String syntaxOID; + + + /** + * Creates a new matching rule. + * + * @param s oid + */ + public MatchingRule(final String s) + { + oid = s; + } + + + /** + * Creates a new matching rule. + * + * @param oid oid + * @param names names + * @param description description + * @param obsolete obsolete + * @param syntaxOID syntax OID + * @param extensions extensions + */ + // CheckStyle:ParameterNumber|HiddenField OFF + public MatchingRule( + final String oid, + final String[] names, + final String description, + final boolean obsolete, + final String syntaxOID, + final Extensions extensions) + { + this(oid); + setNames(names); + setDescription(description); + setObsolete(obsolete); + setSyntaxOID(syntaxOID); + setExtensions(extensions); + } + // CheckStyle:ParameterNumber|HiddenField ON + + + /** + * Returns the oid. + * + * @return oid + */ + public String getOID() + { + return oid; + } + + + /** + * Returns the syntax oid. + * + * @return syntax oid + */ + public String getSyntaxOID() + { + return syntaxOID; + } + + + /** + * Sets the syntax oid. + * + * @param s syntax oid + */ + public void setSyntaxOID(final String s) + { + syntaxOID = s; + } + + + /** + * Parses the supplied definition string and creates an initialized matching rule. + * + * @param definition to parse + * + * @return matching rule + * + * @throws ParseException if the supplied definition is invalid + */ + public static MatchingRule parse(final String definition) + throws ParseException + { + final Matcher m = DEFINITION_PATTERN.matcher(definition); + if (!m.matches()) { + throw new ParseException("Invalid matching rule definition: " + definition, definition.length()); + } + + final MatchingRule mrd = new MatchingRule(m.group(1).trim()); + + // CheckStyle:MagicNumber OFF + // parse names + if (m.group(2) != null) { + mrd.setNames(SchemaUtils.parseDescriptors(m.group(2).trim())); + } else if (m.group(3) != null) { + mrd.setNames(SchemaUtils.parseDescriptors(m.group(3).trim())); + } + + mrd.setDescription(m.group(4) != null ? m.group(4).trim() : null); + mrd.setObsolete(m.group(5) != null); + mrd.setSyntaxOID(m.group(6) != null ? m.group(6).trim() : null); + + // parse extensions + if (m.group(7) != null) { + mrd.setExtensions(Extensions.parse(m.group(7).trim())); + } + return mrd; + // CheckStyle:MagicNumber ON + } + + + @Override + public String format() + { + final StringBuilder sb = new StringBuilder("( "); + sb.append(oid).append(" "); + if (getNames() != null && getNames().length > 0) { + sb.append("NAME "); + sb.append(SchemaUtils.formatDescriptors(getNames())); + } + if (getDescription() != null) { + sb.append("DESC "); + sb.append(SchemaUtils.formatDescriptors(getDescription())); + } + if (isObsolete()) { + sb.append("OBSOLETE "); + } + if (syntaxOID != null) { + sb.append("SYNTAX ").append(syntaxOID).append(" "); + } + if (getExtensions() != null) { + sb.append(getExtensions().format()); + } + sb.append(")"); + return sb.toString(); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof MatchingRule) { + final MatchingRule v = (MatchingRule) o; + return LdapUtils.areEqual(oid, v.oid) && + LdapUtils.areEqual(getNames(), v.getNames()) && + LdapUtils.areEqual(getDescription(), v.getDescription()) && + LdapUtils.areEqual(isObsolete(), v.isObsolete()) && + LdapUtils.areEqual(syntaxOID, v.syntaxOID) && + LdapUtils.areEqual(getExtensions(), v.getExtensions()); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + oid, + getNames(), + getDescription(), + isObsolete(), + syntaxOID, + getExtensions()); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::oid=%s, names=%s, description=%s, obsolete=%s, " + + "synxtaxOID=%s, extensions=%s]", + getClass().getName(), + hashCode(), + oid, + Arrays.toString(getNames()), + getDescription(), + isObsolete(), + syntaxOID, + getExtensions()); + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/MatchingRuleUse.java b/core/src/main/java/org/ldaptive/schema/MatchingRuleUse.java new file mode 100644 index 0000000..50465e2 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/MatchingRuleUse.java
@@ -0,0 +1,246 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.text.ParseException; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.ldaptive.LdapUtils; + +/** + * Bean for an matching rule use schema element. + * + * <pre> + MatchingRuleUseDescription = LPAREN WSP + numericoid ; object identifier + [ SP "NAME" SP qdescrs ] ; short names (descriptors) + [ SP "DESC" SP qdstring ] ; description + [ SP "OBSOLETE" ] ; not active + SP "APPLIES" SP oids ; attribute types + extensions WSP RPAREN ; extensions + * </pre> + * + * @author Middleware Services + */ +public class MatchingRuleUse extends AbstractNamedSchemaElement +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1123; + + /** Pattern to match definitions. */ + private static final Pattern DEFINITION_PATTERN = Pattern.compile( + WSP_REGEX + "\\(" + + WSP_REGEX + "(" + NO_WSP_REGEX + ")" + + WSP_REGEX + "(?:NAME (?:'([^']+)'|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:DESC '([^']*)')?" + + WSP_REGEX + "(OBSOLETE)?" + + WSP_REGEX + "(?:APPLIES (?:(" + NO_WSP_REGEX + ")|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:(X-[^ ]+.*))?" + + WSP_REGEX + "\\)" + WSP_REGEX); + + /** OID. */ + private final String oid; + + /** Superior classes. */ + private String[] appliesAttributeTypes; + + + /** + * Creates a new matching rule use. + * + * @param s oid + */ + public MatchingRuleUse(final String s) + { + oid = s; + } + + + /** + * Creates a new matching rule use. + * + * @param oid oid + * @param names names + * @param description description + * @param obsolete obsolete + * @param appliesAttributeTypes applies attribute types + * @param extensions extensions + */ + // CheckStyle:ParameterNumber|HiddenField OFF + public MatchingRuleUse( + final String oid, + final String[] names, + final String description, + final boolean obsolete, + final String[] appliesAttributeTypes, + final Extensions extensions) + { + this(oid); + setNames(names); + setDescription(description); + setObsolete(obsolete); + setAppliesAttributeTypes(appliesAttributeTypes); + setExtensions(extensions); + } + // CheckStyle:ParameterNumber|HiddenField ON + + + /** + * Returns the oid. + * + * @return oid + */ + public String getOID() + { + return oid; + } + + + /** + * Returns the applies attribute types. + * + * @return attribute types + */ + public String[] getAppliesAttributeTypes() + { + return appliesAttributeTypes; + } + + + /** + * Sets the applies attribute types. + * + * @param s attribute types + */ + public void setAppliesAttributeTypes(final String[] s) + { + appliesAttributeTypes = s; + } + + + /** + * Parses the supplied definition string and creates an initialized matching rule use. + * + * @param definition to parse + * + * @return matching rule use + * + * @throws ParseException if the supplied definition is invalid + */ + public static MatchingRuleUse parse(final String definition) + throws ParseException + { + final Matcher m = DEFINITION_PATTERN.matcher(definition); + if (!m.matches()) { + throw new ParseException("Invalid matching rule use definition: " + definition, definition.length()); + } + + final MatchingRuleUse mrud = new MatchingRuleUse(m.group(1).trim()); + + // CheckStyle:MagicNumber OFF + // parse names + if (m.group(2) != null) { + mrud.setNames(SchemaUtils.parseDescriptors(m.group(2).trim())); + } else if (m.group(3) != null) { + mrud.setNames(SchemaUtils.parseDescriptors(m.group(3).trim())); + } + + mrud.setDescription(m.group(4) != null ? m.group(4).trim() : null); + mrud.setObsolete(m.group(5) != null); + + // parse applies attribute types + if (m.group(6) != null) { + mrud.setAppliesAttributeTypes(SchemaUtils.parseOIDs(m.group(6).trim())); + } else if (m.group(7) != null) { + mrud.setAppliesAttributeTypes(SchemaUtils.parseOIDs(m.group(7).trim())); + } + + // parse extensions + if (m.group(8) != null) { + mrud.setExtensions(Extensions.parse(m.group(8).trim())); + } + return mrud; + // CheckStyle:MagicNumber ON + } + + + @Override + public String format() + { + final StringBuilder sb = new StringBuilder("( "); + sb.append(oid).append(" "); + if (getNames() != null && getNames().length > 0) { + sb.append("NAME "); + sb.append(SchemaUtils.formatDescriptors(getNames())); + } + if (getDescription() != null) { + sb.append("DESC "); + sb.append(SchemaUtils.formatDescriptors(getDescription())); + } + if (isObsolete()) { + sb.append("OBSOLETE "); + } + if (appliesAttributeTypes != null && appliesAttributeTypes.length > 0) { + sb.append("APPLIES "); + sb.append(SchemaUtils.formatOids(appliesAttributeTypes)); + } + if (getExtensions() != null) { + sb.append(getExtensions().format()); + } + sb.append(")"); + return sb.toString(); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof MatchingRuleUse) { + final MatchingRuleUse v = (MatchingRuleUse) o; + return LdapUtils.areEqual(oid, v.oid) && + LdapUtils.areEqual(getNames(), v.getNames()) && + LdapUtils.areEqual(getDescription(), v.getDescription()) && + LdapUtils.areEqual(isObsolete(), v.isObsolete()) && + LdapUtils.areEqual(appliesAttributeTypes, v.appliesAttributeTypes) && + LdapUtils.areEqual(getExtensions(), v.getExtensions()); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + oid, + getNames(), + getDescription(), + isObsolete(), + appliesAttributeTypes, + getExtensions()); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::oid=%s, names=%s, description=%s, obsolete=%s, " + + "appliesAttributeTypes=%s, extensions=%s]", + getClass().getName(), + hashCode(), + oid, + Arrays.toString(getNames()), + getDescription(), + isObsolete(), + Arrays.toString(appliesAttributeTypes), + getExtensions()); + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/NameForm.java b/core/src/main/java/org/ldaptive/schema/NameForm.java new file mode 100644 index 0000000..a53aa97 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/NameForm.java
@@ -0,0 +1,328 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.text.ParseException; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.ldaptive.LdapUtils; + +/** + * Bean for a name form schema element. + * + * <pre> + NameFormDescription = LPAREN WSP + numericoid ; object identifier + [ SP "NAME" SP qdescrs ] ; short names (descriptors) + [ SP "DESC" SP qdstring ] ; description + [ SP "OBSOLETE" ] ; not active + SP "OC" SP oid ; structural object class + SP "MUST" SP oids ; attribute types + [ SP "MAY" SP oids ] ; attribute types + extensions WSP RPAREN ; extensions + * </pre> + * + * @author Middleware Services + */ +public class NameForm extends AbstractNamedSchemaElement +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1163; + + /** Pattern to match definitions. */ + private static final Pattern DEFINITION_PATTERN = Pattern.compile( + WSP_REGEX + "\\(" + + WSP_REGEX + "(" + NO_WSP_REGEX + ")" + + WSP_REGEX + "(?:NAME (?:'([^']+)'|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:DESC '([^']*)')?" + + WSP_REGEX + "(OBSOLETE)?" + + WSP_REGEX + "(?:OC (" + NO_WSP_REGEX + "))?" + + WSP_REGEX + "(?:MUST (?:(" + NO_WSP_REGEX + ")|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:MAY (?:(" + NO_WSP_REGEX + ")|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:(X-[^ ]+.*))?" + + WSP_REGEX + "\\)" + WSP_REGEX); + + /** OID. */ + private final String oid; + + /** Structural object class. */ + private String structuralClass; + + /** Required attributes. */ + private String[] requiredAttributes; + + /** Optional attributes. */ + private String[] optionalAttributes; + + + /** + * Creates a new name form. + * + * @param s oid + */ + public NameForm(final String s) + { + oid = s; + } + + + /** + * Creates a new name form. + * + * @param oid oid + * @param names names + * @param description description + * @param obsolete obsolete + * @param structuralClass structural object class + * @param requiredAttributes required attributes + * @param optionalAttributes optional attributes + * @param extensions extensions + */ + // CheckStyle:ParameterNumber|HiddenField OFF + public NameForm( + final String oid, + final String[] names, + final String description, + final boolean obsolete, + final String structuralClass, + final String[] requiredAttributes, + final String[] optionalAttributes, + final Extensions extensions) + { + this(oid); + setNames(names); + setDescription(description); + setObsolete(obsolete); + setStructuralClass(structuralClass); + setRequiredAttributes(requiredAttributes); + setOptionalAttributes(optionalAttributes); + setExtensions(extensions); + } + // CheckStyle:ParameterNumber|HiddenField ON + + + /** + * Returns the oid. + * + * @return oid + */ + public String getOID() + { + return oid; + } + + + /** + * Returns the structural object class. + * + * @return structural object class + */ + public String getStructuralClass() + { + return structuralClass; + } + + + /** + * Sets the structural object class. + * + * @param s structural object class + */ + public void setStructuralClass(final String s) + { + structuralClass = s; + } + + + /** + * Returns the required attributes. + * + * @return required attributes + */ + public String[] getRequiredAttributes() + { + return requiredAttributes; + } + + + /** + * Sets the required attributes. + * + * @param s required attributes + */ + public void setRequiredAttributes(final String[] s) + { + requiredAttributes = s; + } + + + /** + * Returns the optional attributes. + * + * @return optional attributes + */ + public String[] getOptionalAttributes() + { + return optionalAttributes; + } + + + /** + * Sets the optional attributes. + * + * @param s optional attributes + */ + public void setOptionalAttributes(final String[] s) + { + optionalAttributes = s; + } + + + /** + * Parses the supplied definition string and creates an initialized name form. + * + * @param definition to parse + * + * @return name form + * + * @throws ParseException if the supplied definition is invalid + */ + public static NameForm parse(final String definition) + throws ParseException + { + final Matcher m = DEFINITION_PATTERN.matcher(definition); + if (!m.matches()) { + throw new ParseException("Invalid name form definition: " + definition, definition.length()); + } + + final NameForm nfd = new NameForm(m.group(1).trim()); + + // CheckStyle:MagicNumber OFF + // parse names + if (m.group(2) != null) { + nfd.setNames(SchemaUtils.parseDescriptors(m.group(2).trim())); + } else if (m.group(3) != null) { + nfd.setNames(SchemaUtils.parseDescriptors(m.group(3).trim())); + } + + nfd.setDescription(m.group(4) != null ? m.group(4).trim() : null); + nfd.setObsolete(m.group(5) != null); + nfd.setStructuralClass(m.group(6) != null ? m.group(6).trim() : null); + + // parse required attributes + if (m.group(7) != null) { + nfd.setRequiredAttributes(SchemaUtils.parseOIDs(m.group(7).trim())); + } else if (m.group(8) != null) { + nfd.setRequiredAttributes(SchemaUtils.parseOIDs(m.group(8).trim())); + } + + // parse optional attributes + if (m.group(9) != null) { + nfd.setOptionalAttributes(SchemaUtils.parseOIDs(m.group(9).trim())); + } else if (m.group(10) != null) { + nfd.setOptionalAttributes(SchemaUtils.parseOIDs(m.group(10).trim())); + } + + // parse extensions + if (m.group(11) != null) { + nfd.setExtensions(Extensions.parse(m.group(11).trim())); + } + return nfd; + // CheckStyle:MagicNumber ON + } + + + @Override + public String format() + { + final StringBuilder sb = new StringBuilder("( "); + sb.append(oid).append(" "); + if (getNames() != null && getNames().length > 0) { + sb.append("NAME "); + sb.append(SchemaUtils.formatDescriptors(getNames())); + } + if (getDescription() != null) { + sb.append("DESC "); + sb.append(SchemaUtils.formatDescriptors(getDescription())); + } + if (isObsolete()) { + sb.append("OBSOLETE "); + } + if (structuralClass != null) { + sb.append("OC ").append(structuralClass).append(" "); + } + if (requiredAttributes != null && requiredAttributes.length > 0) { + sb.append("MUST "); + sb.append(SchemaUtils.formatOids(requiredAttributes)); + } + if (optionalAttributes != null && optionalAttributes.length > 0) { + sb.append("MAY "); + sb.append(SchemaUtils.formatOids(optionalAttributes)); + } + if (getExtensions() != null) { + sb.append(getExtensions().format()); + } + sb.append(")"); + return sb.toString(); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof NameForm) { + final NameForm v = (NameForm) o; + return LdapUtils.areEqual(oid, v.oid) && + LdapUtils.areEqual(getNames(), v.getNames()) && + LdapUtils.areEqual(getDescription(), v.getDescription()) && + LdapUtils.areEqual(isObsolete(), v.isObsolete()) && + LdapUtils.areEqual(structuralClass, v.structuralClass) && + LdapUtils.areEqual(requiredAttributes, v.requiredAttributes) && + LdapUtils.areEqual(optionalAttributes, v.optionalAttributes) && + LdapUtils.areEqual(getExtensions(), v.getExtensions()); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + oid, + getNames(), + getDescription(), + isObsolete(), + structuralClass, + requiredAttributes, + optionalAttributes, + getExtensions()); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::oid=%s, names=%s, description=%s, obsolete=%s, " + + "structuralClass=%s, requiredAttributes=%s, " + + "optionalAttributes=%s, extensions=%s]", + getClass().getName(), + hashCode(), + oid, + Arrays.toString(getNames()), + getDescription(), + isObsolete(), + structuralClass, + Arrays.toString(requiredAttributes), + Arrays.toString(optionalAttributes), + getExtensions()); + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/ObjectClass.java b/core/src/main/java/org/ldaptive/schema/ObjectClass.java new file mode 100644 index 0000000..39136d0 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/ObjectClass.java
@@ -0,0 +1,375 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.text.ParseException; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.ldaptive.LdapUtils; + +/** + * Bean for an object class schema element. + * + * <pre> + ObjectClassDescription = LPAREN WSP + numericoid ; object identifier + [ SP "NAME" SP qdescrs ] ; short names (descriptors) + [ SP "DESC" SP qdstring ] ; description + [ SP "OBSOLETE" ] ; not active + [ SP "SUP" SP oids ] ; superior object classes + [ SP kind ] ; kind of class + [ SP "MUST" SP oids ] ; attribute types + [ SP "MAY" SP oids ] ; attribute types + extensions WSP RPAREN + * </pre> + * + * @author Middleware Services + */ +public class ObjectClass extends AbstractNamedSchemaElement +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1109; + + /** Pattern to match definitions. */ + private static final Pattern DEFINITION_PATTERN = Pattern.compile( + WSP_REGEX + "\\(" + + WSP_REGEX + "(" + NO_WSP_REGEX + ")" + + WSP_REGEX + "(?:NAME (?:'([^']+)'|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:DESC '([^']*)')?" + + WSP_REGEX + "(OBSOLETE)?" + + WSP_REGEX + "(?:SUP (?:(" + NO_WSP_REGEX + ")|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(\\p{Alpha}+)?" + + WSP_REGEX + "(?:MUST (?:(" + NO_WSP_REGEX + ")|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:MAY (?:(" + NO_WSP_REGEX + ")|\\(([^\\)]+)\\)))?" + + WSP_REGEX + "(?:(X-[^ ]+.*))?" + + WSP_REGEX + "\\)" + WSP_REGEX); + + /** OID. */ + private final String oid; + + /** Superior classes. */ + private String[] superiorClasses; + + /** Object class type. */ + private ObjectClassType objectClassType; + + /** Required attributes. */ + private String[] requiredAttributes; + + /** Optional attributes. */ + private String[] optionalAttributes; + + + /** + * Creates a new object class. + * + * @param s oid + */ + public ObjectClass(final String s) + { + oid = s; + } + + + /** + * Creates a new object class. + * + * @param oid oid + * @param names names + * @param description description + * @param obsolete obsolete + * @param superiorClasses superior classes + * @param objectClassType object class type + * @param requiredAttributes required attributes + * @param optionalAttributes optional attributes + * @param extensions extensions + */ + // CheckStyle:ParameterNumber|HiddenField OFF + public ObjectClass( + final String oid, + final String[] names, + final String description, + final boolean obsolete, + final String[] superiorClasses, + final ObjectClassType objectClassType, + final String[] requiredAttributes, + final String[] optionalAttributes, + final Extensions extensions) + { + this(oid); + setNames(names); + setDescription(description); + setObsolete(obsolete); + setSuperiorClasses(superiorClasses); + setObjectClassType(objectClassType); + setRequiredAttributes(requiredAttributes); + setOptionalAttributes(optionalAttributes); + setExtensions(extensions); + } + // CheckStyle:ParameterNumber|HiddenField ON + + + /** + * Returns the oid. + * + * @return oid + */ + public String getOID() + { + return oid; + } + + + /** + * Returns the superior classes. + * + * @return superior classes + */ + public String[] getSuperiorClasses() + { + return superiorClasses; + } + + + /** + * Sets the superior classes. + * + * @param s superior classes + */ + public void setSuperiorClasses(final String[] s) + { + superiorClasses = s; + } + + + /** + * Returns the object class type. + * + * @return object class type + */ + public ObjectClassType getObjectClassType() + { + return objectClassType; + } + + + /** + * Sets the object class type. + * + * @param type object class type + */ + public void setObjectClassType(final ObjectClassType type) + { + objectClassType = type; + } + + + /** + * Returns the required attributes. + * + * @return required attributes + */ + public String[] getRequiredAttributes() + { + return requiredAttributes; + } + + + /** + * Sets the required attributes. + * + * @param s required attributes + */ + public void setRequiredAttributes(final String[] s) + { + requiredAttributes = s; + } + + + /** + * Returns the optional attributes. + * + * @return optional attributes + */ + public String[] getOptionalAttributes() + { + return optionalAttributes; + } + + + /** + * Sets the optional attributes. + * + * @param s optional attributes + */ + public void setOptionalAttributes(final String[] s) + { + optionalAttributes = s; + } + + + /** + * Parses the supplied definition string and creates an initialized object class. + * + * @param definition to parse + * + * @return object class + * + * @throws ParseException if the supplied definition is invalid + */ + public static ObjectClass parse(final String definition) + throws ParseException + { + final Matcher m = DEFINITION_PATTERN.matcher(definition); + if (!m.matches()) { + throw new ParseException("Invalid object class definition: " + definition, definition.length()); + } + + final ObjectClass ocd = new ObjectClass(m.group(1).trim()); + + // CheckStyle:MagicNumber OFF + // parse names + if (m.group(2) != null) { + ocd.setNames(SchemaUtils.parseDescriptors(m.group(2).trim())); + } else if (m.group(3) != null) { + ocd.setNames(SchemaUtils.parseDescriptors(m.group(3).trim())); + } + + ocd.setDescription(m.group(4) != null ? m.group(4).trim() : null); + ocd.setObsolete(m.group(5) != null); + + // parse superior classes + if (m.group(6) != null) { + ocd.setSuperiorClasses(SchemaUtils.parseOIDs(m.group(6).trim())); + } else if (m.group(7) != null) { + ocd.setSuperiorClasses(SchemaUtils.parseOIDs(m.group(7).trim())); + } + + if (m.group(8) != null) { + ocd.setObjectClassType(ObjectClassType.valueOf(m.group(8).trim())); + } + + // parse required attributes + if (m.group(9) != null) { + ocd.setRequiredAttributes(SchemaUtils.parseOIDs(m.group(9).trim())); + } else if (m.group(10) != null) { + ocd.setRequiredAttributes(SchemaUtils.parseOIDs(m.group(10).trim())); + } + + // parse optional attributes + if (m.group(11) != null) { + ocd.setOptionalAttributes(SchemaUtils.parseOIDs(m.group(11).trim())); + } else if (m.group(12) != null) { + ocd.setOptionalAttributes(SchemaUtils.parseOIDs(m.group(12).trim())); + } + + // parse extensions + if (m.group(13) != null) { + ocd.setExtensions(Extensions.parse(m.group(13).trim())); + } + return ocd; + // CheckStyle:MagicNumber ON + } + + + @Override + public String format() + { + final StringBuilder sb = new StringBuilder("( "); + sb.append(oid).append(" "); + if (getNames() != null && getNames().length > 0) { + sb.append("NAME "); + sb.append(SchemaUtils.formatDescriptors(getNames())); + } + if (getDescription() != null) { + sb.append("DESC "); + sb.append(SchemaUtils.formatDescriptors(getDescription())); + } + if (isObsolete()) { + sb.append("OBSOLETE "); + } + if (superiorClasses != null && superiorClasses.length > 0) { + sb.append("SUP "); + sb.append(SchemaUtils.formatOids(superiorClasses)); + } + if (objectClassType != null) { + sb.append(objectClassType.name()).append(" "); + } + if (requiredAttributes != null && requiredAttributes.length > 0) { + sb.append("MUST "); + sb.append(SchemaUtils.formatOids(requiredAttributes)); + } + if (optionalAttributes != null && optionalAttributes.length > 0) { + sb.append("MAY "); + sb.append(SchemaUtils.formatOids(optionalAttributes)); + } + if (getExtensions() != null) { + sb.append(getExtensions().format()); + } + sb.append(")"); + return sb.toString(); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof ObjectClass) { + final ObjectClass v = (ObjectClass) o; + return LdapUtils.areEqual(oid, v.oid) && + LdapUtils.areEqual(getNames(), v.getNames()) && + LdapUtils.areEqual(getDescription(), v.getDescription()) && + LdapUtils.areEqual(isObsolete(), v.isObsolete()) && + LdapUtils.areEqual(superiorClasses, v.superiorClasses) && + LdapUtils.areEqual(objectClassType, v.objectClassType) && + LdapUtils.areEqual(requiredAttributes, v.requiredAttributes) && + LdapUtils.areEqual(optionalAttributes, v.optionalAttributes) && + LdapUtils.areEqual(getExtensions(), v.getExtensions()); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + oid, + getNames(), + getDescription(), + isObsolete(), + superiorClasses, + objectClassType, + requiredAttributes, + optionalAttributes, + getExtensions()); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::oid=%s, names=%s, description=%s, obsolete=%s, " + + "superiorClasses=%s, objectClassType=%s, requiredAttributes=%s, " + + "optionalAttributes=%s, extensions=%s]", + getClass().getName(), + hashCode(), + oid, + Arrays.toString(getNames()), + getDescription(), + isObsolete(), + Arrays.toString(superiorClasses), + objectClassType, + Arrays.toString(requiredAttributes), + Arrays.toString(optionalAttributes), + getExtensions()); + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/ObjectClassType.java b/core/src/main/java/org/ldaptive/schema/ObjectClassType.java new file mode 100644 index 0000000..d51e5cb --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/ObjectClassType.java
@@ -0,0 +1,23 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +/** + * Enum for an attribute usage schema element. + * + * <pre> + ObjectClassType = "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" + * </pre> + * + * @author Middleware Services + */ +public enum ObjectClassType { + + /** abstract. */ + ABSTRACT, + + /** structural. */ + STRUCTURAL, + + /** auxiliary. */ + AUXILIARY +}
diff --git a/core/src/main/java/org/ldaptive/schema/Schema.java b/core/src/main/java/org/ldaptive/schema/Schema.java new file mode 100644 index 0000000..fccac80 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/Schema.java
@@ -0,0 +1,508 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import org.ldaptive.LdapUtils; + +/** + * Bean that contains the schema definitions in RFC 4512. + * + * @author Middleware Services + */ +public class Schema +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1181; + + /** Attribute types. */ + private Collection<AttributeType> attributeTypes = Collections.emptySet(); + + /** DIT content rules. */ + private Collection<DITContentRule> ditContentRules = Collections.emptySet(); + + /** DIT structure rules. */ + private Collection<DITStructureRule> ditStructureRules = Collections.emptySet(); + + /** Syntaxes. */ + private Collection<Syntax> syntaxes = Collections.emptySet(); + + /** Matching rules. */ + private Collection<MatchingRule> matchingRules = Collections.emptySet(); + + /** Matching rule uses. */ + private Collection<MatchingRuleUse> matchingRuleUses = Collections.emptySet(); + + /** Name forms. */ + private Collection<NameForm> nameForms = Collections.emptySet(); + + /** Object classes. */ + private Collection<ObjectClass> objectClasses = Collections.emptySet(); + + + /** Default constructor. */ + public Schema() {} + + + /** + * Creates a new schema. + * + * @param attributeTypes attribute types + * @param ditContentRules DIT content rules + * @param ditStructureRules DIT structure rules + * @param syntaxes syntaxes + * @param matchingRules matching rules + * @param matchingRuleUses matching rule uses + * @param nameForms name forms + * @param objectClasses object classses + */ + // CheckStyle:ParameterNumber|HiddenField OFF + public Schema( + final Collection<AttributeType> attributeTypes, + final Collection<DITContentRule> ditContentRules, + final Collection<DITStructureRule> ditStructureRules, + final Collection<Syntax> syntaxes, + final Collection<MatchingRule> matchingRules, + final Collection<MatchingRuleUse> matchingRuleUses, + final Collection<NameForm> nameForms, + final Collection<ObjectClass> objectClasses) + { + setAttributeTypes(attributeTypes); + setDitContentRules(ditContentRules); + setDitStructureRules(ditStructureRules); + setSyntaxes(syntaxes); + setMatchingRules(matchingRules); + setMatchingRuleUses(matchingRuleUses); + setNameForms(nameForms); + setObjectClasses(objectClasses); + } + // CheckStyle:ParameterNumber|HiddenField ON + + + /** + * Returns the attribute types. + * + * @return attribute types + */ + public Collection<AttributeType> getAttributeTypes() + { + return attributeTypes; + } + + + /** + * Returns the attribute type with the supplied OID or name. + * + * @param name OID or name + * + * @return attribute type or null if name does not exist + */ + public AttributeType getAttributeType(final String name) + { + for (AttributeType at : attributeTypes) { + if (at.getOID().equals(name) || at.hasName(name)) { + return at; + } + } + return null; + } + + + /** + * Sets the attribute types. + * + * @param c attribute types + */ + public void setAttributeTypes(final Collection<AttributeType> c) + { + attributeTypes = c; + } + + + /** + * Returns the attribute names in this schema that represent binary data. This includes attributes with a syntax OID + * of '1.3.6.1.4.1.1466.115.121.1.5' and any syntax with the 'X-NOT-HUMAN-READABLE' extension. + * + * @return binary attribute names + */ + public String[] getBinaryAttributeNames() + { + final List<String> binaryAttrs = new ArrayList<>(); + for (AttributeType type : attributeTypes) { + boolean isBinary = false; + final String syntaxOid = type.getSyntaxOID(false); + if ("1.3.6.1.4.1.1466.115.121.1.5".equals(syntaxOid)) { + isBinary = true; + } else { + final Syntax syntax = getSyntax(syntaxOid); + if (syntax != null && Syntax.containsBooleanExtension(syntax, "X-NOT-HUMAN-READABLE")) { + isBinary = true; + } + } + if (isBinary) { + Collections.addAll(binaryAttrs, type.getNames()); + } + } + return binaryAttrs.toArray(new String[binaryAttrs.size()]); + } + + + /** + * Returns the DIT content rules. + * + * @return DIT content rules + */ + public Collection<DITContentRule> getDitContentRules() + { + return ditContentRules; + } + + + /** + * Returns the DIT content rule with the supplied OID or name. + * + * @param name OID or name + * + * @return DIT content rule or null if name does not exist + */ + public DITContentRule getDITContentRule(final String name) + { + for (DITContentRule rule : ditContentRules) { + if (rule.getOID().equals(name) || rule.hasName(name)) { + return rule; + } + } + return null; + } + + + /** + * Sets the DIT content rules. + * + * @param c DIT content rules + */ + public void setDitContentRules(final Collection<DITContentRule> c) + { + ditContentRules = c; + } + + + /** + * Returns the DIT structure rules. + * + * @return DIT structure rules + */ + public Collection<DITStructureRule> getDitStructureRules() + { + return ditStructureRules; + } + + + /** + * Returns the DIT structure rule with the supplied ID. + * + * @param id rule ID + * + * @return DIT structure rule or null if id does not exist + */ + public DITStructureRule getDITStructureRule(final int id) + { + for (DITStructureRule rule : ditStructureRules) { + if (rule.getID() == id) { + return rule; + } + } + return null; + } + + + /** + * Returns the DIT structure rule with the supplied name. + * + * @param name rule name + * + * @return DIT structure rule or null if name does not exist + */ + public DITStructureRule getDITStructureRule(final String name) + { + for (DITStructureRule rule : ditStructureRules) { + if (rule.hasName(name)) { + return rule; + } + } + return null; + } + + + /** + * Sets the DIT structure rules. + * + * @param c DIT structure rules + */ + public void setDitStructureRules(final Collection<DITStructureRule> c) + { + ditStructureRules = c; + } + + + /** + * Returns the syntaxes. + * + * @return syntaxes + */ + public Collection<Syntax> getSyntaxes() + { + return syntaxes; + } + + + /** + * Returns the syntax with the supplied OID. + * + * @param oid OID + * + * @return syntax or null if OID does not exist + */ + public Syntax getSyntax(final String oid) + { + for (Syntax syntax : syntaxes) { + if (syntax.getOID().equals(oid)) { + return syntax; + } + } + return null; + } + + + /** + * Sets the syntaxes. + * + * @param c syntaxes + */ + public void setSyntaxes(final Collection<Syntax> c) + { + syntaxes = c; + } + + + /** + * Returns the matching rules. + * + * @return matching rules + */ + public Collection<MatchingRule> getMatchingRules() + { + return matchingRules; + } + + + /** + * Returns the matching rule with the supplied OID or name. + * + * @param name OID or name + * + * @return matching rule or null if name does not exist + */ + public MatchingRule getMatchingRule(final String name) + { + for (MatchingRule rule : matchingRules) { + if (rule.getOID().equals(name) || rule.hasName(name)) { + return rule; + } + } + return null; + } + + + /** + * Sets the matching rules. + * + * @param c matching rules + */ + public void setMatchingRules(final Collection<MatchingRule> c) + { + matchingRules = c; + } + + + /** + * Returns the matching rule uses. + * + * @return matching rule ueses + */ + public Collection<MatchingRuleUse> getMatchingRuleUses() + { + return matchingRuleUses; + } + + + /** + * Returns the matching rule use with the supplied OID or name. + * + * @param name OID or name + * + * @return matching rule use or null if name does not exist + */ + public MatchingRuleUse getMatchingRuleUse(final String name) + { + for (MatchingRuleUse rule : matchingRuleUses) { + if (rule.getOID().equals(name) || rule.hasName(name)) { + return rule; + } + } + return null; + } + + + /** + * Sets the matching rule uses. + * + * @param c matching rule uses + */ + public void setMatchingRuleUses(final Collection<MatchingRuleUse> c) + { + matchingRuleUses = c; + } + + + /** + * Returns the name forms. + * + * @return name forms + */ + public Collection<NameForm> getNameForms() + { + return nameForms; + } + + + /** + * Returns the name form with the supplied OID or name. + * + * @param name OID or name + * + * @return name form or null if name does not exist + */ + public NameForm getNameForm(final String name) + { + for (NameForm form : nameForms) { + if (form.getOID().equals(name) || form.hasName(name)) { + return form; + } + } + return null; + } + + + /** + * Sets the name forms. + * + * @param c name forms + */ + public void setNameForms(final Collection<NameForm> c) + { + nameForms = c; + } + + + /** + * Returns the object classes. + * + * @return object classes + */ + public Collection<ObjectClass> getObjectClasses() + { + return objectClasses; + } + + + /** + * Returns the object class with the supplied OID or name. + * + * @param name OID or name + * + * @return object class or null if name does not exist + */ + public ObjectClass getObjectClass(final String name) + { + for (ObjectClass oc : objectClasses) { + if (oc.getOID().equals(name) || oc.hasName(name)) { + return oc; + } + } + return null; + } + + + /** + * Sets the object classes. + * + * @param c object classes + */ + public void setObjectClasses(final Collection<ObjectClass> c) + { + objectClasses = c; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof Schema) { + final Schema v = (Schema) o; + return LdapUtils.areEqual(attributeTypes, v.attributeTypes) && + LdapUtils.areEqual(ditContentRules, v.ditContentRules) && + LdapUtils.areEqual(ditStructureRules, v.ditStructureRules) && + LdapUtils.areEqual(syntaxes, v.syntaxes) && + LdapUtils.areEqual(matchingRules, v.matchingRules) && + LdapUtils.areEqual(matchingRuleUses, v.matchingRuleUses) && + LdapUtils.areEqual(nameForms, v.nameForms) && + LdapUtils.areEqual(objectClasses, v.objectClasses); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + attributeTypes, + ditContentRules, + ditStructureRules, + syntaxes, + matchingRules, + matchingRuleUses, + nameForms, + objectClasses); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::attributeTypes=%s, ditContentRules=%s, " + + "ditStructureRules=%s, syntaxes=%s, matchingRules=%s, " + + "matchingRuleUses=%s, nameForms=%s, objectClasses=%s]", + getClass().getName(), + hashCode(), + attributeTypes, + ditContentRules, + ditStructureRules, + syntaxes, + matchingRules, + matchingRuleUses, + nameForms, + objectClasses); + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/SchemaElement.java b/core/src/main/java/org/ldaptive/schema/SchemaElement.java new file mode 100644 index 0000000..e1322ce --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/SchemaElement.java
@@ -0,0 +1,19 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +/** + * Interface for schema elements. + * + * @author Middleware Services + */ +public interface SchemaElement +{ + + + /** + * Returns this schema element as formatted string per RFC 4512. + * + * @return formatted string + */ + String format(); +}
diff --git a/core/src/main/java/org/ldaptive/schema/SchemaFactory.java b/core/src/main/java/org/ldaptive/schema/SchemaFactory.java new file mode 100644 index 0000000..e2fd2ce --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/SchemaFactory.java
@@ -0,0 +1,204 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.ReturnAttributes; +import org.ldaptive.SearchExecutor; +import org.ldaptive.SearchResult; +import org.ldaptive.SearchScope; +import org.ldaptive.io.LdifReader; +import org.ldaptive.schema.io.AttributeTypeValueTranscoder; +import org.ldaptive.schema.io.DITContentRuleValueTranscoder; +import org.ldaptive.schema.io.DITStructureRuleValueTranscoder; +import org.ldaptive.schema.io.MatchingRuleUseValueTranscoder; +import org.ldaptive.schema.io.MatchingRuleValueTranscoder; +import org.ldaptive.schema.io.NameFormValueTranscoder; +import org.ldaptive.schema.io.ObjectClassValueTranscoder; +import org.ldaptive.schema.io.SyntaxValueTranscoder; + +/** + * Factory to create {@link Schema} objects from an LDAP entry. + * + * @author Middleware Services + */ +public final class SchemaFactory +{ + + /** Attribute on the root DSE indicating the location of the subschema entry. */ + private static final String SUBSCHEMA_SUBENTRY_ATTR_NAME = "subschemaSubentry"; + + /** Attribute types attribute name on the subschema entry. */ + private static final String ATTRIBUTE_TYPES_ATTR_NAME = "attributeTypes"; + + /** DIT content rules attribute name on the subschema entry. */ + private static final String DIT_CONTENT_RULES_ATTR_NAME = "dITContentRules"; + + /** DIT structure rules attribute name on the subschema entry. */ + private static final String DIT_STRUCTURE_RULES_ATTR_NAME = "dITStructureRules"; + + /** LDAP syntaxes attribute name on the subschema entry. */ + private static final String LDAP_SYNTAXES_ATTR_NAME = "ldapSyntaxes"; + + /** Matching rules attribute name on the subschema entry. */ + private static final String MATCHING_RULES_ATTR_NAME = "matchingRules"; + + /** Matching rule use attribute name on the subschema entry. */ + private static final String MATCHING_RULE_USE_ATTR_NAME = "matchingRuleUse"; + + /** Name forms attribute name on the subschema entry. */ + private static final String NAME_FORMS_ATTR_NAME = "nameForms"; + + /** Object classes attribute name on the subschema entry. */ + private static final String OBJECT_CLASS_ATTR_NAME = "objectClasses"; + + + /** Default constructor. */ + private SchemaFactory() {} + + + /** + * Creates a new schema. The input stream should contain the LDIF for the subschema entry. + * + * @param is containing the schema ldif + * + * @return schema created from the ldif + * + * @throws IOException if an error occurs reading the input stream + */ + public static Schema createSchema(final InputStream is) + throws IOException + { + final LdifReader reader = new LdifReader(new InputStreamReader(is)); + return createSchema(reader.read().getEntry()); + } + + + /** + * Creates a new schema. The subschema subentry is searched for on the root DSE, followed by searching for the + * subschema entry itself. + * + * @param factory to obtain an LDAP connection from + * + * @return schema created from the connection factory + * + * @throws LdapException if the search fails + */ + public static Schema createSchema(final ConnectionFactory factory) + throws LdapException + { + final LdapEntry rootDSE = getLdapEntry(factory, "", "(objectClass=*)", new String[] {SUBSCHEMA_SUBENTRY_ATTR_NAME}); + final String entryDn = rootDSE.getAttribute(SUBSCHEMA_SUBENTRY_ATTR_NAME).getStringValue(); + return createSchema(getLdapEntry(factory, entryDn, "(objectClass=subSchema)", ReturnAttributes.ALL.value())); + } + + + /** + * Creates a new schema. The entryDn is searched to obtain the schema. + * + * @param factory to obtain an LDAP connection from + * @param entryDn the subschema entry + * + * @return schema created from the connection factory + * + * @throws LdapException if the search fails + */ + public static Schema createSchema(final ConnectionFactory factory, final String entryDn) + throws LdapException + { + return createSchema(getLdapEntry(factory, entryDn, "(objectClass=subSchema)", ReturnAttributes.ALL.value())); + } + + + /** + * Creates a new schema. The schema entry is parsed to obtain the schema. + * + * @param schemaEntry containing the schema + * + * @return schema created from the entry + */ + public static Schema createSchema(final LdapEntry schemaEntry) + { + if (schemaEntry == null) { + throw new IllegalArgumentException("Schema entry cannot be null"); + } + + final Schema schema = new Schema(); + + final LdapAttribute atAttr = schemaEntry.getAttribute(ATTRIBUTE_TYPES_ATTR_NAME); + if (atAttr != null) { + schema.setAttributeTypes(atAttr.getValues(new AttributeTypeValueTranscoder())); + } + + final LdapAttribute dcrAttr = schemaEntry.getAttribute(DIT_CONTENT_RULES_ATTR_NAME); + if (dcrAttr != null) { + schema.setDitContentRules(dcrAttr.getValues(new DITContentRuleValueTranscoder())); + } + + final LdapAttribute dsrAttr = schemaEntry.getAttribute(DIT_STRUCTURE_RULES_ATTR_NAME); + if (dsrAttr != null) { + schema.setDitStructureRules(dsrAttr.getValues(new DITStructureRuleValueTranscoder())); + } + + final LdapAttribute sAttr = schemaEntry.getAttribute(LDAP_SYNTAXES_ATTR_NAME); + if (sAttr != null) { + schema.setSyntaxes(sAttr.getValues(new SyntaxValueTranscoder())); + } + + final LdapAttribute mrAttr = schemaEntry.getAttribute(MATCHING_RULES_ATTR_NAME); + if (mrAttr != null) { + schema.setMatchingRules(mrAttr.getValues(new MatchingRuleValueTranscoder())); + } + + final LdapAttribute mruAttr = schemaEntry.getAttribute(MATCHING_RULE_USE_ATTR_NAME); + if (mruAttr != null) { + schema.setMatchingRuleUses(mruAttr.getValues(new MatchingRuleUseValueTranscoder())); + } + + final LdapAttribute nfAttr = schemaEntry.getAttribute(NAME_FORMS_ATTR_NAME); + if (nfAttr != null) { + schema.setNameForms(nfAttr.getValues(new NameFormValueTranscoder())); + } + + final LdapAttribute ocAttr = schemaEntry.getAttribute(OBJECT_CLASS_ATTR_NAME); + if (ocAttr != null) { + schema.setObjectClasses(ocAttr.getValues(new ObjectClassValueTranscoder())); + } + + return schema; + } + + + /** + * Searches for the supplied dn and returns its ldap entry. + * + * @param factory to obtain an LDAP connection from + * @param dn to search for + * @param filter search filter + * @param retAttrs attributes to return + * + * @return ldap entry + * + * @throws LdapException if the search fails + */ + protected static LdapEntry getLdapEntry( + final ConnectionFactory factory, + final String dn, + final String filter, + final String[] retAttrs) + throws LdapException + { + final SearchExecutor executor = new SearchExecutor(); + executor.setBaseDn(dn); + executor.setSearchScope(SearchScope.OBJECT); + executor.setReturnAttributes(retAttrs); + + final SearchResult result = executor.search(factory, filter).getResult(); + return result.getEntry(); + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/SchemaUtils.java b/core/src/main/java/org/ldaptive/schema/SchemaUtils.java new file mode 100644 index 0000000..0e60b34 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/SchemaUtils.java
@@ -0,0 +1,154 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +/** + * Provides utility methods for this package. + * + * @author Middleware Services + */ +public final class SchemaUtils +{ + + + /** Default constructor. */ + private SchemaUtils() {} + + + /** + * Parses the supplied descriptors string and returns it's contents as a string array. If the string contains a single + * quote it is assumed to be a multivalue descriptor of the form "'value1' 'value2' 'value3'". Otherwise it is treated + * as a single value descriptor. + * + * @param descrs string to parse + * + * @return array of descriptors + */ + public static String[] parseDescriptors(final String descrs) + { + if (descrs.contains("'")) { + final String[] quotedDescr = descrs.split(" "); + final String[] s = new String[quotedDescr.length]; + for (int i = 0; i < s.length; i++) { + s[i] = quotedDescr[i].substring(1, quotedDescr[i].length() - 1).trim(); + } + return s; + } else { + return new String[] {descrs}; + } + } + + + /** + * Parses the supplied OID string and returns it's contents as a string array. If the string contains a dollar sign it + * is assumed to be a multivalue OID of the form "value1 $ value2 $ value3". Otherwise it is treated as a single value + * OID. + * + * @param oids string to parse + * + * @return array of oids + */ + public static String[] parseOIDs(final String oids) + { + if (oids.contains("$")) { + final String[] s = oids.split("\\$"); + for (int i = 0; i < s.length; i++) { + s[i] = s[i].trim(); + } + return s; + } else { + return new String[] {oids}; + } + } + + + /** + * Parses the supplied number string and returns it's contents as a string array. + * + * @param numbers string to parse + * + * @return array of numbers + */ + public static int[] parseNumbers(final String numbers) + { + final String[] s = numbers.split(" "); + final int[] i = new int[s.length]; + for (int j = 0; j < i.length; j++) { + i[j] = Integer.parseInt(s[j].trim()); + } + return i; + } + + + /** + * Returns a formatted string to describe the supplied descriptors. + * + * @param descrs to format + * + * @return formatted string + */ + public static String formatDescriptors(final String... descrs) + { + final StringBuilder sb = new StringBuilder(); + if (descrs.length == 1) { + sb.append("'").append(descrs[0].replace("'", "\\27")).append("' "); + } else { + sb.append("( "); + for (String descr : descrs) { + sb.append("'").append(descr.replace("'", "\\27")).append("' "); + } + sb.append(") "); + } + return sb.toString(); + } + + + /** + * Returns a formatted string to describe the supplied OIDs. + * + * @param oids to format + * + * @return formatted string + */ + public static String formatOids(final String... oids) + { + final StringBuilder sb = new StringBuilder(); + if (oids.length == 1) { + sb.append(oids[0]).append(" "); + } else { + sb.append("( "); + for (int i = 0; i < oids.length; i++) { + sb.append(oids[i]); + if (i < oids.length - 1) { + sb.append(" $ "); + } else { + sb.append(" "); + } + } + sb.append(") "); + } + return sb.toString(); + } + + + /** + * Returns a formatted string to describe the supplied numbers. + * + * @param numbers to format + * + * @return formatted string + */ + public static String formatNumbers(final int... numbers) + { + final StringBuilder sb = new StringBuilder(); + if (numbers.length == 1) { + sb.append(numbers[0]).append(" "); + } else { + sb.append("( "); + for (int number : numbers) { + sb.append(number).append(" "); + } + sb.append(") "); + } + return sb.toString(); + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/Syntax.java b/core/src/main/java/org/ldaptive/schema/Syntax.java new file mode 100644 index 0000000..6539f08 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/Syntax.java
@@ -0,0 +1,161 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.text.ParseException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.ldaptive.LdapUtils; + +/** + * Bean for an attribute syntax schema element. + * + * <pre> + SyntaxDescription = LPAREN WSP + numericoid ; object identifier + [ SP "DESC" SP qdstring ] ; description + extensions WSP RPAREN ; extensions + * </pre> + * + * @author Middleware Services + */ +public class Syntax extends AbstractSchemaElement +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1129; + + /** Pattern to match definitions. */ + private static final Pattern DEFINITION_PATTERN = Pattern.compile( + WSP_REGEX + "\\(" + + WSP_REGEX + "(" + NO_WSP_REGEX + ")" + + WSP_REGEX + "(?:DESC '([^']+)')?" + + WSP_REGEX + "(?:(X-[^ ]+.*))?" + + WSP_REGEX + "\\)" + WSP_REGEX); + + /** OID. */ + private final String oid; + + + /** + * Creates a new attribute syntax. + * + * @param s oid + */ + public Syntax(final String s) + { + oid = s; + } + + + /** + * Creates a new attribute syntax. + * + * @param oid oid + * @param description description + * @param extensions extensions + */ + // CheckStyle:HiddenField OFF + public Syntax(final String oid, final String description, final Extensions extensions) + { + this(oid); + setDescription(description); + setExtensions(extensions); + } + // CheckStyle:HiddenField ON + + + /** + * Returns the oid. + * + * @return oid + */ + public String getOID() + { + return oid; + } + + + /** + * Parses the supplied definition string and creates an initialized attribute syntax. + * + * @param definition to parse + * + * @return attribute syntax + * + * @throws ParseException if the supplied definition is invalid + */ + public static Syntax parse(final String definition) + throws ParseException + { + final Matcher m = DEFINITION_PATTERN.matcher(definition); + if (!m.matches()) { + throw new ParseException("Invalid attribute syntax definition: " + definition, definition.length()); + } + + final Syntax asd = new Syntax(m.group(1).trim()); + + // CheckStyle:MagicNumber OFF + asd.setDescription(m.group(2) != null ? m.group(2).trim() : null); + + // parse extensions + if (m.group(3) != null) { + asd.setExtensions(Extensions.parse(m.group(3).trim())); + } + return asd; + // CheckStyle:MagicNumber ON + } + + + @Override + public String format() + { + final StringBuilder sb = new StringBuilder("( "); + sb.append(oid).append(" "); + if (getDescription() != null) { + sb.append("DESC "); + sb.append(SchemaUtils.formatDescriptors(getDescription())); + } + if (getExtensions() != null) { + sb.append(getExtensions().format()); + } + sb.append(")"); + return sb.toString(); + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof Syntax) { + final Syntax v = (Syntax) o; + return LdapUtils.areEqual(oid, v.oid) && + LdapUtils.areEqual(getDescription(), v.getDescription()) && + LdapUtils.areEqual(getExtensions(), v.getExtensions()); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, oid, getDescription(), getExtensions()); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::oid=%s, description=%s, extensions=%s]", + getClass().getName(), + hashCode(), + oid, + getDescription(), + getExtensions()); + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/io/AbstractSchemaElementValueTranscoder.java b/core/src/main/java/org/ldaptive/schema/io/AbstractSchemaElementValueTranscoder.java new file mode 100644 index 0000000..318338f --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/io/AbstractSchemaElementValueTranscoder.java
@@ -0,0 +1,24 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema.io; + +import org.ldaptive.io.AbstractStringValueTranscoder; +import org.ldaptive.schema.SchemaElement; + +/** + * Base class for schema element value transcoders. + * + * @param <T> type of schema element + * + * @author Middleware Services + */ +public abstract class AbstractSchemaElementValueTranscoder<T extends SchemaElement> + extends AbstractStringValueTranscoder<T> +{ + + + @Override + public String encodeStringValue(final T value) + { + return value.format(); + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/io/AttributeTypeValueTranscoder.java b/core/src/main/java/org/ldaptive/schema/io/AttributeTypeValueTranscoder.java new file mode 100644 index 0000000..e0b3233 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/io/AttributeTypeValueTranscoder.java
@@ -0,0 +1,32 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema.io; + +import java.text.ParseException; +import org.ldaptive.schema.AttributeType; + +/** + * Decodes and encodes an attribute type for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class AttributeTypeValueTranscoder extends AbstractSchemaElementValueTranscoder<AttributeType> +{ + + + @Override + public AttributeType decodeStringValue(final String value) + { + try { + return AttributeType.parse(value); + } catch (ParseException e) { + throw new IllegalArgumentException("Could not transcode attribute type", e); + } + } + + + @Override + public Class<AttributeType> getType() + { + return AttributeType.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/io/DITContentRuleValueTranscoder.java b/core/src/main/java/org/ldaptive/schema/io/DITContentRuleValueTranscoder.java new file mode 100644 index 0000000..e12059a --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/io/DITContentRuleValueTranscoder.java
@@ -0,0 +1,32 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema.io; + +import java.text.ParseException; +import org.ldaptive.schema.DITContentRule; + +/** + * Decodes and encodes a DIT content rule for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class DITContentRuleValueTranscoder extends AbstractSchemaElementValueTranscoder<DITContentRule> +{ + + + @Override + public DITContentRule decodeStringValue(final String value) + { + try { + return DITContentRule.parse(value); + } catch (ParseException e) { + throw new IllegalArgumentException("Could not transcode DIT content rule", e); + } + } + + + @Override + public Class<DITContentRule> getType() + { + return DITContentRule.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/io/DITStructureRuleValueTranscoder.java b/core/src/main/java/org/ldaptive/schema/io/DITStructureRuleValueTranscoder.java new file mode 100644 index 0000000..29e9f71 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/io/DITStructureRuleValueTranscoder.java
@@ -0,0 +1,32 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema.io; + +import java.text.ParseException; +import org.ldaptive.schema.DITStructureRule; + +/** + * Decodes and encodes a DIT structure rule for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class DITStructureRuleValueTranscoder extends AbstractSchemaElementValueTranscoder<DITStructureRule> +{ + + + @Override + public DITStructureRule decodeStringValue(final String value) + { + try { + return DITStructureRule.parse(value); + } catch (ParseException e) { + throw new IllegalArgumentException("Could not transcode DIT structure rule", e); + } + } + + + @Override + public Class<DITStructureRule> getType() + { + return DITStructureRule.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/io/MatchingRuleUseValueTranscoder.java b/core/src/main/java/org/ldaptive/schema/io/MatchingRuleUseValueTranscoder.java new file mode 100644 index 0000000..3bbd4ef --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/io/MatchingRuleUseValueTranscoder.java
@@ -0,0 +1,32 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema.io; + +import java.text.ParseException; +import org.ldaptive.schema.MatchingRuleUse; + +/** + * Decodes and encodes a matching rule use for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class MatchingRuleUseValueTranscoder extends AbstractSchemaElementValueTranscoder<MatchingRuleUse> +{ + + + @Override + public MatchingRuleUse decodeStringValue(final String value) + { + try { + return MatchingRuleUse.parse(value); + } catch (ParseException e) { + throw new IllegalArgumentException("Could not transcode matching rule use", e); + } + } + + + @Override + public Class<MatchingRuleUse> getType() + { + return MatchingRuleUse.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/io/MatchingRuleValueTranscoder.java b/core/src/main/java/org/ldaptive/schema/io/MatchingRuleValueTranscoder.java new file mode 100644 index 0000000..0965157 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/io/MatchingRuleValueTranscoder.java
@@ -0,0 +1,32 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema.io; + +import java.text.ParseException; +import org.ldaptive.schema.MatchingRule; + +/** + * Decodes and encodes a matching rule for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class MatchingRuleValueTranscoder extends AbstractSchemaElementValueTranscoder<MatchingRule> +{ + + + @Override + public MatchingRule decodeStringValue(final String value) + { + try { + return MatchingRule.parse(value); + } catch (ParseException e) { + throw new IllegalArgumentException("Could not transcode matching rule", e); + } + } + + + @Override + public Class<MatchingRule> getType() + { + return MatchingRule.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/io/NameFormValueTranscoder.java b/core/src/main/java/org/ldaptive/schema/io/NameFormValueTranscoder.java new file mode 100644 index 0000000..3ea09cc --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/io/NameFormValueTranscoder.java
@@ -0,0 +1,32 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema.io; + +import java.text.ParseException; +import org.ldaptive.schema.NameForm; + +/** + * Decodes and encodes a name form for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class NameFormValueTranscoder extends AbstractSchemaElementValueTranscoder<NameForm> +{ + + + @Override + public NameForm decodeStringValue(final String value) + { + try { + return NameForm.parse(value); + } catch (ParseException e) { + throw new IllegalArgumentException("Could not transcode name form", e); + } + } + + + @Override + public Class<NameForm> getType() + { + return NameForm.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/io/ObjectClassValueTranscoder.java b/core/src/main/java/org/ldaptive/schema/io/ObjectClassValueTranscoder.java new file mode 100644 index 0000000..f848d8d --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/io/ObjectClassValueTranscoder.java
@@ -0,0 +1,32 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema.io; + +import java.text.ParseException; +import org.ldaptive.schema.ObjectClass; + +/** + * Decodes and encodes an object class for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class ObjectClassValueTranscoder extends AbstractSchemaElementValueTranscoder<ObjectClass> +{ + + + @Override + public ObjectClass decodeStringValue(final String value) + { + try { + return ObjectClass.parse(value); + } catch (ParseException e) { + throw new IllegalArgumentException("Could not transcode object class", e); + } + } + + + @Override + public Class<ObjectClass> getType() + { + return ObjectClass.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/schema/io/SyntaxValueTranscoder.java b/core/src/main/java/org/ldaptive/schema/io/SyntaxValueTranscoder.java new file mode 100644 index 0000000..f867977 --- /dev/null +++ b/core/src/main/java/org/ldaptive/schema/io/SyntaxValueTranscoder.java
@@ -0,0 +1,32 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema.io; + +import java.text.ParseException; +import org.ldaptive.schema.Syntax; + +/** + * Decodes and encodes an attribute syntax for use in an ldap attribute value. + * + * @author Middleware Services + */ +public class SyntaxValueTranscoder extends AbstractSchemaElementValueTranscoder<Syntax> +{ + + + @Override + public Syntax decodeStringValue(final String value) + { + try { + return Syntax.parse(value); + } catch (ParseException e) { + throw new IllegalArgumentException("Could not transcode attribute syntax", e); + } + } + + + @Override + public Class<Syntax> getType() + { + return Syntax.class; + } +}
diff --git a/core/src/main/java/org/ldaptive/servlets/AbstractServletSearchExecutor.java b/core/src/main/java/org/ldaptive/servlets/AbstractServletSearchExecutor.java new file mode 100644 index 0000000..f2e27f2 --- /dev/null +++ b/core/src/main/java/org/ldaptive/servlets/AbstractServletSearchExecutor.java
@@ -0,0 +1,124 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.servlets; + +import java.io.IOException; +import java.util.Enumeration; +import java.util.Properties; +import javax.servlet.ServletConfig; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.ldaptive.LdapException; +import org.ldaptive.SearchExecutor; +import org.ldaptive.SearchResult; +import org.ldaptive.pool.ConnectionPoolType; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.props.PooledConnectionFactoryPropertySource; +import org.ldaptive.props.PropertySource.PropertyDomain; +import org.ldaptive.props.SearchRequestPropertySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Uses {@link PooledConnectionFactory} and {@link SearchExecutor} to perform search operations. These objects are + * configured from properties found in the servlet configuration. + * + * @author Middleware Services + */ +public abstract class AbstractServletSearchExecutor implements ServletSearchExecutor +{ + + /** Type of pool used, value is {@value}. */ + private static final String POOL_TYPE = "poolType"; + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Connections for searching. */ + private PooledConnectionFactory connectionFactory; + + /** Search executor for storing search properties. */ + private SearchExecutor searchExecutor; + + + @Override + public void initialize(final ServletConfig config) + { + searchExecutor = new SearchExecutor(); + + final SearchRequestPropertySource srSource = new SearchRequestPropertySource( + searchExecutor, + createProperties(config)); + srSource.initialize(); + logger.debug("searchExecutor = {}", searchExecutor); + + connectionFactory = new PooledConnectionFactory(); + + final PooledConnectionFactoryPropertySource cfPropSource = new PooledConnectionFactoryPropertySource( + connectionFactory, + createProperties(config)); + cfPropSource.setPoolType(ConnectionPoolType.valueOf(config.getInitParameter(POOL_TYPE))); + cfPropSource.initialize(); + logger.debug("connectionFactory = {}", connectionFactory); + } + + + /** + * Returns context specific properties based on the supplied JAAS options. + * + * @param config to read properties from + * + * @return properties + */ + protected static Properties createProperties(final ServletConfig config) + { + final Properties p = new Properties(); + final Enumeration<?> e = config.getInitParameterNames(); + while (e.hasMoreElements()) { + final String name = (String) e.nextElement(); + // if property name contains a dot, it isn't an ldaptive property + // else add the domain to the ldaptive properties + if (name.contains(".")) { + p.setProperty(name, config.getInitParameter(name)); + } else { + p.setProperty(PropertyDomain.LDAP.value() + name, config.getInitParameter(name)); + } + } + return p; + } + + + @Override + public void search(final HttpServletRequest request, final HttpServletResponse response) + throws LdapException, IOException + { + final String queryString = request.getParameter("query"); + if (queryString == null || queryString.isEmpty()) { + logger.info("Ignoring empty query"); + } else { + final SearchResult result = searchExecutor.search( + connectionFactory, + queryString, + request.getParameterValues("attrs")).getResult(); + writeResponse(result, response); + } + } + + + /** + * Writes the supplied search result to the servlet response output stream. + * + * @param result search result to write + * @param response to write to + * + * @throws IOException if an error occurs writing to the response + */ + protected abstract void writeResponse(final SearchResult result, final HttpServletResponse response) + throws IOException; + + + @Override + public void close() + { + connectionFactory.getConnectionPool().close(); + } +}
diff --git a/core/src/main/java/org/ldaptive/servlets/AttributeValueServletSearchExecutor.java b/core/src/main/java/org/ldaptive/servlets/AttributeValueServletSearchExecutor.java new file mode 100644 index 0000000..82fb014 --- /dev/null +++ b/core/src/main/java/org/ldaptive/servlets/AttributeValueServletSearchExecutor.java
@@ -0,0 +1,42 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.servlets; + +import java.io.IOException; +import java.io.OutputStream; +import javax.servlet.http.HttpServletResponse; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.SearchResult; + +/** + * Writes a single attribute value to the HTTP response. Useful for providing a mechanism to download large LDAP + * attributes, such as certificates and photos. See {@link AbstractServletSearchExecutor}. + * + * @author Middleware Services + */ +public class AttributeValueServletSearchExecutor extends AbstractServletSearchExecutor +{ + + + @Override + protected void writeResponse(final SearchResult result, final HttpServletResponse response) + throws IOException + { + final LdapEntry e = result.getEntry(); + if (e != null && e.size() > 0) { + final LdapAttribute a = e.getAttribute(); + if (a != null && a.size() > 0) { + if (a.isBinary()) { + response.setContentType("application/octet-stream"); + response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s.bin\"", a.getName())); + } else { + response.setContentType("text/plain"); + } + + final OutputStream out = response.getOutputStream(); + out.write(a.getBinaryValue()); + out.flush(); + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/servlets/Dsmlv1ServletSearchExecutor.java b/core/src/main/java/org/ldaptive/servlets/Dsmlv1ServletSearchExecutor.java new file mode 100644 index 0000000..747d21a --- /dev/null +++ b/core/src/main/java/org/ldaptive/servlets/Dsmlv1ServletSearchExecutor.java
@@ -0,0 +1,30 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.servlets; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; +import javax.servlet.http.HttpServletResponse; +import org.ldaptive.SearchResult; +import org.ldaptive.io.Dsmlv1Writer; + +/** + * Writes search results as DSML version 1. See {@link AbstractServletSearchExecutor}. + * + * @author Middleware Services + */ +public class Dsmlv1ServletSearchExecutor extends AbstractServletSearchExecutor +{ + + + @Override + protected void writeResponse(final SearchResult result, final HttpServletResponse response) + throws IOException + { + response.setContentType("text/xml"); + + final Dsmlv1Writer writer = new Dsmlv1Writer( + new BufferedWriter(new OutputStreamWriter(response.getOutputStream()))); + writer.write(result); + } +}
diff --git a/core/src/main/java/org/ldaptive/servlets/LdifServletSearchExecutor.java b/core/src/main/java/org/ldaptive/servlets/LdifServletSearchExecutor.java new file mode 100644 index 0000000..56e9429 --- /dev/null +++ b/core/src/main/java/org/ldaptive/servlets/LdifServletSearchExecutor.java
@@ -0,0 +1,29 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.servlets; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; +import javax.servlet.http.HttpServletResponse; +import org.ldaptive.SearchResult; +import org.ldaptive.io.LdifWriter; + +/** + * Writes search results in LDIF format. See {@link AbstractServletSearchExecutor}. + * + * @author Middleware Services + */ +public class LdifServletSearchExecutor extends AbstractServletSearchExecutor +{ + + + @Override + protected void writeResponse(final SearchResult result, final HttpServletResponse response) + throws IOException + { + response.setContentType("text/plain"); + + final LdifWriter writer = new LdifWriter(new BufferedWriter(new OutputStreamWriter(response.getOutputStream()))); + writer.write(result); + } +}
diff --git a/core/src/main/java/org/ldaptive/servlets/SearchServlet.java b/core/src/main/java/org/ldaptive/servlets/SearchServlet.java new file mode 100644 index 0000000..0f74e24 --- /dev/null +++ b/core/src/main/java/org/ldaptive/servlets/SearchServlet.java
@@ -0,0 +1,102 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.servlets; + +import java.io.IOException; +import java.util.Arrays; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Queries an LDAP and returns the result in the servlet response. The following init params can be set for this + * servlet: + * + * <ul> + * <li>poolType - BLOCKING or SOFTLIMIT</li> + * <li>searchExecutorClass - fully qualified class name that implements ServletSearchExecutor</li> + * </ul> + * + * <p>All other init params will set properties on:</p> + * + * <ul> + * <li>{@link org.ldaptive.SearchRequest}</li> + * <li>{@link org.ldaptive.ConnectionConfig}</li> + * <li>{@link org.ldaptive.pool.PoolConfig}</li> + * </ul> + * + * <p>Example: http://www.server.com/Search?query=uid=dfisher If you need to pass complex queries, such as + * (&(cn=daniel*)(surname=fisher)), then the query must be form encoded. If you only want to receive a subset of + * attributes those can be specified. Example: + * http://www.server.com/Search?query=uid=dfisher&attrs=givenname&attrs=surname</p> + * + * @author Middleware Services + */ +public final class SearchServlet extends HttpServlet +{ + + /** Custom search executor implementation, value is {@value}. */ + private static final String SEARCH_EXECUTOR_CLASS = "searchExecutorClass"; + + /** serial version uid. */ + private static final long serialVersionUID = 3437252581014900696L; + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Parses servlet requests and performs search operations. */ + private ServletSearchExecutor searchExecutor; + + + @Override + public void init(final ServletConfig config) + throws ServletException + { + super.init(config); + + final String searchExecutorClass = config.getInitParameter(SEARCH_EXECUTOR_CLASS); + if (searchExecutorClass != null) { + try { + logger.debug("Creating search executor: {}", searchExecutorClass); + searchExecutor = (ServletSearchExecutor) Class.forName(searchExecutorClass).newInstance(); + } catch (Exception e) { + logger.error("Error instantiating {}", searchExecutorClass, e); + throw new IllegalStateException(e); + } + } else { + searchExecutor = new Dsmlv1ServletSearchExecutor(); + } + searchExecutor.initialize(config); + } + + + @Override + public void service(final HttpServletRequest request, final HttpServletResponse response) + throws ServletException, IOException + { + logger.info( + "search={} for attributes={}", + request.getParameter("query"), + Arrays.toString(request.getParameterValues("attrs"))); + try { + searchExecutor.search(request, response); + } catch (Exception e) { + logger.error("Error performing search", e); + throw new ServletException(e); + } + } + + + @Override + public void destroy() + { + try { + searchExecutor.close(); + } finally { + super.destroy(); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/servlets/ServletSearchExecutor.java b/core/src/main/java/org/ldaptive/servlets/ServletSearchExecutor.java new file mode 100644 index 0000000..db8ad38 --- /dev/null +++ b/core/src/main/java/org/ldaptive/servlets/ServletSearchExecutor.java
@@ -0,0 +1,42 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.servlets; + +import java.io.IOException; +import javax.servlet.ServletConfig; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.ldaptive.LdapException; + +/** + * Interface to encapsulate servlet search operations. + * + * @author Middleware Services + */ +public interface ServletSearchExecutor +{ + + + /** + * Prepares this servlet search executor for use. + * + * @param config to initialize this object with + */ + void initialize(ServletConfig config); + + + /** + * Reads parameters from the request, performs an ldap search, and writes the result to the response. + * + * @param request servlet request to read search parameters from + * @param response servlet response to write ldap search result to + * + * @throws LdapException if an error occurs performing the search + * @throws IOException if an error occurs writing to the response + */ + void search(HttpServletRequest request, HttpServletResponse response) + throws LdapException, IOException; + + + /** Closes any resources associated with this servlet search executor. */ + void close(); +}
diff --git a/core/src/main/java/org/ldaptive/ssl/AbstractCredentialReader.java b/core/src/main/java/org/ldaptive/ssl/AbstractCredentialReader.java new file mode 100644 index 0000000..ad5124d --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/AbstractCredentialReader.java
@@ -0,0 +1,66 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.GeneralSecurityException; +import org.ldaptive.LdapUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base class for all credential readers. It provides support for loading files from resources on the classpath or a + * filepath. If a path is prefixed with the string "classpath:" it is interpreted as a classpath specification. If a + * path is prefixed with the string "file:" it is interpreted as a file path. Any other input throws + * IllegalArgumentException. + * + * @param <T> Type of credential read by this instance. + * + * @author Middleware Services + */ +public abstract class AbstractCredentialReader<T> implements CredentialReader<T> +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + + @Override + public T read(final String path, final String... params) + throws IOException, GeneralSecurityException + { + final InputStream is = LdapUtils.getResource(path); + if (is != null) { + logger.trace("Found resource at {}", path); + try { + final T credential = read(is, params); + logger.debug("Successfully loaded credential {} from path {}", credential, path); + return credential; + } finally { + is.close(); + } + } else { + logger.debug("Failed to load {}", path); + return null; + } + } + + + /** + * Gets a buffered input stream from the given input stream. If the given instance is already buffered, it is simply + * returned. + * + * @param is input stream from which to create buffered instance. + * + * @return buffered input stream. If the given instance is already buffered, it is simply returned. + */ + protected InputStream getBufferedInputStream(final InputStream is) + { + if (is.markSupported()) { + return is; + } else { + return new BufferedInputStream(is); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/AbstractSSLContextInitializer.java b/core/src/main/java/org/ldaptive/ssl/AbstractSSLContextInitializer.java new file mode 100644 index 0000000..825cadf --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/AbstractSSLContextInitializer.java
@@ -0,0 +1,123 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.GeneralSecurityException; +import java.util.Arrays; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import org.ldaptive.LdapUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides common implementation for SSL context initializer. + * + * @author Middleware Services + */ +public abstract class AbstractSSLContextInitializer implements SSLContextInitializer +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Trust managers. */ + protected TrustManager[] trustManagers; + + /** Hostname verifier config. */ + protected HostnameVerifierConfig hostnameVerifierConfig; + + + @Override + public TrustManager[] getTrustManagers() + throws GeneralSecurityException + { + final TrustManager[] tm = createTrustManagers(); + final TrustManager[] hostnameTrustManager = hostnameVerifierConfig != null ? + new TrustManager[] { + new HostnameVerifyingTrustManager( + hostnameVerifierConfig.getCertificateHostnameVerifier(), + hostnameVerifierConfig.getHostnames()), + } : null; + TrustManager[] aggregate = null; + if (tm == null) { + if (trustManagers == null) { + if (hostnameTrustManager != null) { + aggregate = aggregateTrustManagers(new DefaultTrustManager(), hostnameTrustManager[0]); + } + } else { + aggregate = aggregateTrustManagers(LdapUtils.concatArrays(trustManagers, hostnameTrustManager)); + } + } else { + aggregate = aggregateTrustManagers(LdapUtils.concatArrays(tm, trustManagers, hostnameTrustManager)); + } + return aggregate; + } + + + @Override + public void setTrustManagers(final TrustManager... managers) + { + trustManagers = managers; + } + + + @Override + public HostnameVerifierConfig getHostnameVerifierConfig() + { + return hostnameVerifierConfig; + } + + + @Override + public void setHostnameVerifierConfig(final HostnameVerifierConfig config) + { + hostnameVerifierConfig = config; + } + + + /** + * Creates any trust managers specific to this context initializer. + * + * @return trust managers + * + * @throws GeneralSecurityException if an errors occurs while loading the TrustManagers + */ + protected abstract TrustManager[] createTrustManagers() + throws GeneralSecurityException; + + + @Override + public SSLContext initSSLContext(final String protocol) + throws GeneralSecurityException + { + final KeyManager[] km = getKeyManagers(); + final TrustManager[] tm = getTrustManagers(); + logger.trace( + "Initialize SSLContext with keyManagers={} and trustManagers={}", Arrays.toString(km), Arrays.toString(tm)); + final SSLContext ctx = SSLContext.getInstance(protocol); + ctx.init(km, tm, null); + return ctx; + } + + + /** + * Creates an {@link AggregateTrustManager} containing the supplied trust managers. + * + * @param managers to aggregate + * + * @return array containing a single aggregate trust manager + */ + protected TrustManager[] aggregateTrustManagers(final TrustManager... managers) + { + X509TrustManager[] x509Managers = null; + if (managers != null) { + x509Managers = new X509TrustManager[managers.length]; + for (int i = 0; i < managers.length; i++) { + x509Managers[i] = (X509TrustManager) managers[i]; + } + } + return new TrustManager[] {new AggregateTrustManager(x509Managers)}; + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/AbstractTLSSocketFactory.java b/core/src/main/java/org/ldaptive/ssl/AbstractTLSSocketFactory.java new file mode 100644 index 0000000..0e2c999 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/AbstractTLSSocketFactory.java
@@ -0,0 +1,276 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.security.GeneralSecurityException; +import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides common implementation for TLSSocketFactory. + * + * @author Middleware Services + */ +public abstract class AbstractTLSSocketFactory extends SSLSocketFactory +{ + + /** Default SSL protocol, value is {@value}. */ + public static final String DEFAULT_PROTOCOL = "TLS"; + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** SSLSocketFactory used for creating SSL sockets. */ + protected SSLSocketFactory factory; + + /** SSL configuration options. */ + private SslConfig sslConfig; + + /** Socket configuration options. */ + private SocketConfig socketConfig; + + + /** + * Prepares this socket factory for use. Must be called before factory can be used. + * + * @throws GeneralSecurityException if the factory cannot be initialized + */ + public abstract void initialize() + throws GeneralSecurityException; + + + /** + * Returns the underlying SSL socket factory that this class uses for creating SSL Sockets. + * + * @return SSL socket factory + */ + public SSLSocketFactory getFactory() + { + return factory; + } + + + /** + * Returns the SSL configuration used by this socket factory. + * + * @return ssl config + */ + public SslConfig getSslConfig() + { + return sslConfig; + } + + + /** + * Sets the SSL configuration used by this socket factory. + * + * @param config ssl config + */ + public void setSslConfig(final SslConfig config) + { + sslConfig = config; + } + + + /** + * Returns the socket configuration used by this socket factory. + * + * @return socket config + */ + public SocketConfig getSocketConfig() + { + return socketConfig; + } + + + /** + * Sets the socket configuration used by this socket factory. + * + * @param config socket config + */ + public void setSocketConfig(final SocketConfig config) + { + socketConfig = config; + } + + + /** + * Initializes the supplied socket for use. + * + * @param socket SSL socket to initialize + * + * @return SSL socket + * + * @throws IOException if an I/O error occurs when initializing the socket + */ + protected SSLSocket initSSLSocket(final SSLSocket socket) + throws IOException + { + final SocketConfig socketC = getSocketConfig(); + if (socketC != null) { + socketC.configureSocket(socket); + } + + final SslConfig sslC = getSslConfig(); + if (sslC != null) { + if (sslC.getEnabledCipherSuites() != null) { + socket.setEnabledCipherSuites(sslC.getEnabledCipherSuites()); + } + if (sslC.getEnabledProtocols() != null) { + socket.setEnabledProtocols(sslC.getEnabledProtocols()); + } + if (sslC.getHandshakeCompletedListeners() != null) { + for (HandshakeCompletedListener listener : sslC.getHandshakeCompletedListeners()) { + socket.addHandshakeCompletedListener(listener); + } + } + } + return socket; + } + + + /** + * Returns a socket layered over an existing socket connected to the named host, at the given port. + * + * @param socket existing socket + * @param host server hostname + * @param port server port + * @param autoClose close the underlying socket when this socket is closed + * + * @return socket connected to the specified host and port + * + * @throws IOException if an I/O error occurs when creating the socket + */ + @Override + public Socket createSocket(final Socket socket, final String host, final int port, final boolean autoClose) + throws IOException + { + return initSSLSocket((SSLSocket) factory.createSocket(socket, host, port, autoClose)); + } + + + /** + * Creates an unconnected socket. + * + * @return unconnected socket + * + * @throws IOException if an I/O error occurs when creating the socket + */ + @Override + public Socket createSocket() + throws IOException + { + return initSSLSocket((SSLSocket) factory.createSocket()); + } + + + /** + * Creates a socket and connects it to the specified port number at the specified address. + * + * @param host server hostname + * @param port server port + * + * @return socket connected to the specified host and port + * + * @throws IOException if an I/O error occurs when creating the socket + */ + @Override + public Socket createSocket(final InetAddress host, final int port) + throws IOException + { + return initSSLSocket((SSLSocket) factory.createSocket(host, port)); + } + + + /** + * Creates a socket and connect it to the specified port number at the specified address. The socket will also be + * bound to the supplied local address and port. + * + * @param address server hostname + * @param port server port + * @param localAddress client hostname + * @param localPort client port + * + * @return socket connected to the specified host and port + * + * @throws IOException if an I/O error occurs when creating the socket + */ + @Override + public Socket createSocket( + final InetAddress address, + final int port, + final InetAddress localAddress, + final int localPort) + throws IOException + { + return initSSLSocket((SSLSocket) factory.createSocket(address, port, localAddress, localPort)); + } + + + /** + * Creates a socket and connects it to the specified port number at the specified address. + * + * @param host server hostname + * @param port server port + * + * @return socket connected to the specified host and port + * + * @throws IOException if an I/O error occurs when creating the socket + */ + @Override + public Socket createSocket(final String host, final int port) + throws IOException + { + return initSSLSocket((SSLSocket) factory.createSocket(host, port)); + } + + + /** + * Creates a socket and connect it to the specified port number at the specified address. The socket will also be + * bound to the supplied local address and port. + * + * @param host server hostname + * @param port server port + * @param localHost client hostname + * @param localPort client port + * + * @return socket connected to the specified host and port + * + * @throws IOException if an I/O error occurs when creating the socket + */ + @Override + public Socket createSocket(final String host, final int port, final InetAddress localHost, final int localPort) + throws IOException + { + return initSSLSocket((SSLSocket) factory.createSocket(host, port, localHost, localPort)); + } + + + /** + * Returns the list of cipher suites which are enabled by default. + * + * @return cipher suites + */ + @Override + public String[] getDefaultCipherSuites() + { + return factory.getDefaultCipherSuites(); + } + + + /** + * Returns the names of the cipher suites which could be enabled for use on an SSL connection. + * + * @return cipher suites + */ + @Override + public String[] getSupportedCipherSuites() + { + return factory.getSupportedCipherSuites(); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/AggregateTrustManager.java b/core/src/main/java/org/ldaptive/ssl/AggregateTrustManager.java new file mode 100644 index 0000000..b41995e --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/AggregateTrustManager.java
@@ -0,0 +1,176 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import javax.net.ssl.X509TrustManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Trust manager that delegates to multiple trust managers. + * + * @author Middleware Services + */ +public class AggregateTrustManager implements X509TrustManager +{ + + /** Enum to define how trust managers should be processed. */ + public enum Strategy { + + /** all trust managers must succeed. */ + ALL, + + /** any trust manager must succeed. */ + ANY + } + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Trust managers to invoke. */ + private final X509TrustManager[] trustManagers; + + /** Whether to require all trust managers succeed. */ + private final Strategy trustStrategy; + + + /** + * Creates a new aggregate trust manager with the ALL {@link Strategy}. + * + * @param managers to aggregate + */ + public AggregateTrustManager(final X509TrustManager... managers) + { + this(Strategy.ALL, managers); + } + + + /** + * Creates a new aggregate trust manager. + * + * @param strategy for processing trust managers + * @param managers to aggregate + */ + public AggregateTrustManager(final Strategy strategy, final X509TrustManager... managers) + { + if (strategy == null) { + throw new NullPointerException("Strategy cannot be null"); + } + trustStrategy = strategy; + trustManagers = managers; + } + + + /** + * Returns the trust managers that are aggregated. + * + * @return trust managers + */ + public X509TrustManager[] getTrustManagers() + { + return trustManagers; + } + + + /** + * Returns the trust strategy. + * + * @return trust strategy + */ + public Strategy getTrustStrategy() + { + return trustStrategy; + } + + + @Override + public void checkClientTrusted(final X509Certificate[] chain, final String authType) + throws CertificateException + { + if (trustManagers != null) { + CertificateException certEx = null; + for (X509TrustManager tm : trustManagers) { + try { + tm.checkClientTrusted(chain, authType); + logger.debug("checkClientTrusted for {} succeeded", tm); + if (trustStrategy == Strategy.ANY) { + return; + } + } catch (CertificateException e) { + logger.debug("checkClientTrusted for {} failed", tm); + if (trustStrategy == Strategy.ALL) { + throw e; + } + if (certEx == null) { + certEx = e; + } + } + } + if (certEx != null) { + throw certEx; + } + } + } + + + @Override + public void checkServerTrusted(final X509Certificate[] chain, final String authType) + throws CertificateException + { + if (trustManagers != null) { + CertificateException certEx = null; + for (X509TrustManager tm : trustManagers) { + try { + tm.checkServerTrusted(chain, authType); + logger.debug("checkServerTrusted for {} succeeded", tm); + if (trustStrategy == Strategy.ANY) { + return; + } + } catch (CertificateException e) { + logger.debug("checkServerTrusted for {} failed", tm); + if (trustStrategy == Strategy.ALL) { + throw e; + } + if (certEx == null) { + certEx = e; + } + } + } + if (certEx != null) { + throw certEx; + } + } + } + + + @Override + public X509Certificate[] getAcceptedIssuers() + { + final List<X509Certificate> issuers = new ArrayList<>(); + if (trustManagers != null) { + for (X509TrustManager tm : trustManagers) { + logger.debug("invoking getAcceptedIssuers for {}", tm); + Collections.addAll(issuers, tm.getAcceptedIssuers()); + } + } + return issuers.toArray(new X509Certificate[issuers.size()]); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::trustManagers=%s, trustStrategy=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(trustManagers), + trustStrategy); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/AllowAnyHostnameVerifier.java b/core/src/main/java/org/ldaptive/ssl/AllowAnyHostnameVerifier.java new file mode 100644 index 0000000..e03c328 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/AllowAnyHostnameVerifier.java
@@ -0,0 +1,29 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.cert.X509Certificate; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSession; + +/** + * Hostname verifier that returns true for any hostname. Use with caution. + * + * @author Middleware Services + */ +public class AllowAnyHostnameVerifier implements HostnameVerifier, CertificateHostnameVerifier +{ + + + @Override + public boolean verify(final String hostname, final SSLSession session) + { + return true; + } + + + @Override + public boolean verify(final String hostname, final X509Certificate cert) + { + return true; + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/AllowAnyTrustManager.java b/core/src/main/java/org/ldaptive/ssl/AllowAnyTrustManager.java new file mode 100644 index 0000000..5628587 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/AllowAnyTrustManager.java
@@ -0,0 +1,32 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import javax.net.ssl.X509TrustManager; + +/** + * Trust manager that trusts any certificate. Use with caution. + * + * @author Middleware Services + */ +public class AllowAnyTrustManager implements X509TrustManager +{ + + + @Override + public void checkClientTrusted(final X509Certificate[] chain, final String authType) + throws CertificateException {} + + + @Override + public void checkServerTrusted(final X509Certificate[] chain, final String authType) + throws CertificateException {} + + + @Override + public X509Certificate[] getAcceptedIssuers() + { + return new X509Certificate[0]; + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/CertificateHostnameVerifier.java b/core/src/main/java/org/ldaptive/ssl/CertificateHostnameVerifier.java new file mode 100644 index 0000000..85a4235 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/CertificateHostnameVerifier.java
@@ -0,0 +1,24 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.cert.X509Certificate; + +/** + * Interface for verifying a hostname matching a certificate. + * + * @author Middleware Services + */ +public interface CertificateHostnameVerifier +{ + + + /** + * Verify the supplied hostname matches the supplied certificate. + * + * @param hostname to verify + * @param cert to verify hostname against + * + * @return whether hostname is valid for the supplied certificate + */ + boolean verify(String hostname, X509Certificate cert); +}
diff --git a/core/src/main/java/org/ldaptive/ssl/CredentialConfig.java b/core/src/main/java/org/ldaptive/ssl/CredentialConfig.java new file mode 100644 index 0000000..9ae0e68 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/CredentialConfig.java
@@ -0,0 +1,26 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.GeneralSecurityException; + +/** + * Provides a base interface for all credential configurations. Since credential configs are invoked via reflection by + * the PropertyInvoker their method signatures are not important. They only need to be able to create an SSL context + * initializer once their properties have been set. + * + * @author Middleware Services + */ +public interface CredentialConfig +{ + + + /** + * Creates an SSL context initializer using the configured trust and authentication material in this config. + * + * @return SSL context initializer + * + * @throws GeneralSecurityException if the ssl context initializer cannot be created + */ + SSLContextInitializer createSSLContextInitializer() + throws GeneralSecurityException; +}
diff --git a/core/src/main/java/org/ldaptive/ssl/CredentialConfigFactory.java b/core/src/main/java/org/ldaptive/ssl/CredentialConfigFactory.java new file mode 100644 index 0000000..8310820 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/CredentialConfigFactory.java
@@ -0,0 +1,225 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; +import org.ldaptive.LdapUtils; + +/** + * Utility class for creating credential configs when the underlying credential is already available for use. + * + * @author Middleware Services + */ +public final class CredentialConfigFactory +{ + + + /** Default constructor. */ + private CredentialConfigFactory() {} + + + /** + * Creates a KeyStoreCredentialConfig from the supplied truststore. + * + * @param trustStore to create credential config from + * + * @return credential config + */ + public static CredentialConfig createKeyStoreCredentialConfig(final KeyStore trustStore) + { + return createKeyStoreCredentialConfig(trustStore, null, null, null, null); + } + + + /** + * Creates a KeyStoreCredentialConfig from the supplied truststore. + * + * @param trustStore to create credential config from + * @param trustStoreAliases to use in the truststore + * + * @return credential config + */ + public static CredentialConfig createKeyStoreCredentialConfig( + final KeyStore trustStore, + final String[] trustStoreAliases) + { + return createKeyStoreCredentialConfig(trustStore, trustStoreAliases, null, null, null); + } + + + /** + * Creates a KeyStoreCredentialConfig from the supplied keystore and password. + * + * @param keyStore to create credential config from + * @param keyStorePassword to unlock the keystore + * + * @return credential config + */ + public static CredentialConfig createKeyStoreCredentialConfig(final KeyStore keyStore, final String keyStorePassword) + { + return createKeyStoreCredentialConfig(null, null, keyStore, keyStorePassword, null); + } + + + /** + * Creates a KeyStoreCredentialConfig from the supplied keystore and password. + * + * @param keyStore to create credential config from + * @param keyStorePassword to unlock the keystore + * @param keyStoreAliases to use in the keystore + * + * @return credential config + */ + public static CredentialConfig createKeyStoreCredentialConfig( + final KeyStore keyStore, + final String keyStorePassword, + final String[] keyStoreAliases) + { + return createKeyStoreCredentialConfig(null, null, keyStore, keyStorePassword, keyStoreAliases); + } + + + /** + * Creates a KeyStoreCredentialConfig from the supplied truststore, keystore and password. + * + * @param trustStore to create credential config from + * @param keyStore to create credential config from + * @param keyStorePassword to unlock the keystore + * + * @return credential config + */ + public static CredentialConfig createKeyStoreCredentialConfig( + final KeyStore trustStore, + final KeyStore keyStore, + final String keyStorePassword) + { + return createKeyStoreCredentialConfig(trustStore, null, keyStore, keyStorePassword, null); + } + + + /** + * Creates a KeyStoreCredentialConfig from the supplied truststore, keystore and password. + * + * @param trustStore to create credential config from + * @param trustStoreAliases to use in the truststore + * @param keyStore to create credential config from + * @param keyStorePassword to unlock the keystore + * @param keyStoreAliases to use in the keystore + * + * @return credential config + */ + public static CredentialConfig createKeyStoreCredentialConfig( + final KeyStore trustStore, + final String[] trustStoreAliases, + final KeyStore keyStore, + final String keyStorePassword, + final String[] keyStoreAliases) + { + return + () -> { + final KeyStoreSSLContextInitializer sslInit = new KeyStoreSSLContextInitializer(); + if (trustStore != null) { + sslInit.setTrustKeystore(trustStore); + sslInit.setTrustAliases(trustStoreAliases); + } + if (keyStore != null) { + sslInit.setAuthenticationKeystore(keyStore); + sslInit.setAuthenticationPassword(keyStorePassword != null ? keyStorePassword.toCharArray() : null); + sslInit.setAuthenticationAliases(keyStoreAliases); + } + return sslInit; + }; + } + + + /** + * Creates a X509CredentialConfig from the supplied trust certificates. + * + * @param trustCertificates to create credential config from + * + * @return credential config + */ + public static CredentialConfig createX509CredentialConfig(final X509Certificate[] trustCertificates) + { + return createX509CredentialConfig(trustCertificates, null, null); + } + + + /** + * Creates a X509CredentialConfig from the supplied authentication certificate and private key. + * + * @param authenticationCertificate to create credential config from + * @param authenticationKey that belongs to the certificate + * + * @return credential config + */ + public static CredentialConfig createX509CredentialConfig( + final X509Certificate authenticationCertificate, + final PrivateKey authenticationKey) + { + return createX509CredentialConfig(null, authenticationCertificate, authenticationKey); + } + + + /** + * Creates a X509CredentialConfig from the supplied trust certificates, authentication certificate and private key. + * + * @param trustCertificates to create credential config from + * @param authenticationCertificate to create credential config from + * @param authenticationKey that belongs to the certificate + * + * @return credential config + */ + public static CredentialConfig createX509CredentialConfig( + final X509Certificate[] trustCertificates, + final X509Certificate authenticationCertificate, + final PrivateKey authenticationKey) + { + return + () -> { + final X509SSLContextInitializer sslInit = new X509SSLContextInitializer(); + if (trustCertificates != null) { + sslInit.setTrustCertificates(trustCertificates); + } + if (authenticationCertificate != null) { + sslInit.setAuthenticationCertificate(authenticationCertificate); + } + if (authenticationKey != null) { + sslInit.setAuthenticationKey(authenticationKey); + } + return sslInit; + }; + } + + + /** + * Creates a X509CredentialConfig from PEM encoded certificate(s). + * + * @param trustCertificates to create credential config from + * + * @return credential config + */ + public static CredentialConfig createX509CredentialConfig(final String trustCertificates) + { + return + () -> { + final X509SSLContextInitializer sslInit = new X509SSLContextInitializer(); + try { + if (trustCertificates != null) { + final X509CertificatesCredentialReader certsReader = new X509CertificatesCredentialReader(); + final InputStream trustCertStream = new ByteArrayInputStream(LdapUtils.utf8Encode(trustCertificates)); + sslInit.setTrustCertificates(certsReader.read(trustCertStream)); + trustCertStream.close(); + } + } catch (IOException e) { + throw new GeneralSecurityException(e); + } + return sslInit; + }; + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/CredentialReader.java b/core/src/main/java/org/ldaptive/ssl/CredentialReader.java new file mode 100644 index 0000000..7407f3f --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/CredentialReader.java
@@ -0,0 +1,47 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.io.IOException; +import java.io.InputStream; +import java.security.GeneralSecurityException; + +/** + * Reads a credential from an IO source. + * + * @param <T> Type of credential read by this instance. + * + * @author Middleware Services + */ +public interface CredentialReader<T> +{ + + + /** + * Reads a credential object from a path. + * + * @param path from which to read credential. + * @param params Arbitrary string parameters, e.g. password, needed to read the credential. + * + * @return credential read from data at path. + * + * @throws IOException On IO errors. + * @throws GeneralSecurityException On errors with the credential data. + */ + T read(String path, String... params) + throws IOException, GeneralSecurityException; + + + /** + * Reads a credential object from an input stream. + * + * @param is input stream from which to read credential. + * @param params Arbitrary string parameters, e.g. password, needed to read the credential. + * + * @return credential read from data in stream. + * + * @throws IOException On IO errors. + * @throws GeneralSecurityException On errors with the credential data. + */ + T read(InputStream is, String... params) + throws IOException, GeneralSecurityException; +}
diff --git a/core/src/main/java/org/ldaptive/ssl/DefaultHostnameVerifier.java b/core/src/main/java/org/ldaptive/ssl/DefaultHostnameVerifier.java new file mode 100644 index 0000000..d7a270d --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/DefaultHostnameVerifier.java
@@ -0,0 +1,259 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.nio.ByteBuffer; +import java.security.cert.CertificateParsingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSession; +import org.ldaptive.LdapUtils; +import org.ldaptive.asn1.DN; +import org.ldaptive.asn1.RDN; +import org.ldaptive.io.StringValueTranscoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Hostname verifier that provides an implementation similar to what occurs with JNDI startTLS. Verification occurs in + * the following order: + * + * <ul> + * <li>if hostname is IP, then cert must have exact match IP subjAltName</li> + * <li>hostname must match any DNS subjAltName if any exist</li> + * <li>hostname must match the first CN</li> + * <li>if cert begins with a wildcard, domains are used for matching</li> + * </ul> + * + * @author Middleware Services + */ +public class DefaultHostnameVerifier implements HostnameVerifier, CertificateHostnameVerifier +{ + + /** Enum for subject alt name types. */ + private enum SubjectAltNameType { + + /** other name (0). */ + OTHER_NAME, + + /** ref822 name (1). */ + RFC822_NAME, + + /** dns name (2). */ + DNS_NAME, + + /** x400 address (3). */ + X400_ADDRESS, + + /** directory name (4). */ + DIRECTORY_NAME, + + /** edi party name (5). */ + EDI_PARTY_NAME, + + /** uniform resource identifier (6). */ + UNIFORM_RESOURCE_IDENTIFIER, + + /** ip address (7). */ + IP_ADDRESS, + + /** registered id (8). */ + REGISTERED_ID + } + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Hostname verifier delegate. */ + private final HostnameVerifier verifier = new HostnameVerifierAdapter(this); + + + @Override + public boolean verify(final String hostname, final SSLSession session) + { + return verifier.verify(hostname, session); + } + + + /** + * Verify if the hostname is an IP address using {@link LdapUtils#isIPAddress(String)}. Delegates to {@link + * #verifyIP(String, X509Certificate)} and {@link #verifyDNS(String, X509Certificate)} accordingly. + * + * @param hostname to verify + * @param cert to verify hostname against + * + * @return whether hostname is valid for the supplied certificate + */ + @Override + public boolean verify(final String hostname, final X509Certificate cert) + { + logger.debug("verifying hostname={} against cert={}", hostname, cert.getSubjectX500Principal()); + + boolean b; + if (LdapUtils.isIPAddress(hostname)) { + b = verifyIP(hostname, cert); + } else { + b = verifyDNS(hostname, cert); + } + return b; + } + + + /** + * Verify the certificate allows use of the supplied IP address. + * + * <p>From RFC2818: In some cases, the URI is specified as an IP address rather than a hostname. In this case, the + * iPAddress subjectAltName must be present in the certificate and must exactly match the IP in the URI.</p> + * + * @param ip address to match in the certificate + * @param cert to inspect for the IP address + * + * @return whether the ip matched a subject alt name + */ + protected boolean verifyIP(final String ip, final X509Certificate cert) + { + final String[] subjAltNames = getSubjectAltNames(cert, SubjectAltNameType.IP_ADDRESS); + logger.debug("verifyIP using subjectAltNames={}", Arrays.toString(subjAltNames)); + for (String name : subjAltNames) { + if (ip.equalsIgnoreCase(name)) { + logger.debug("verifyIP found hostname match: {}", name); + return true; + } + } + return false; + } + + + /** + * Verify the certificate allows use of the supplied DNS name. Note that only the first CN is used. + * + * <p>From RFC2818: If a subjectAltName extension of type dNSName is present, that MUST be used as the identity. + * Otherwise, the (most specific) Common Name field in the Subject field of the certificate MUST be used. Although the + * use of the Common Name is existing practice, it is deprecated and Certification Authorities are encouraged to use + * the dNSName instead.</p> + * + * <p>Matching is performed using the matching rules specified by [RFC2459]. If more than one identity of a given type + * is present in the certificate (e.g., more than one dNSName name, a match in any one of the set is considered + * acceptable.)</p> + * + * @param hostname to match in the certificate + * @param cert to inspect for the hostname + * + * @return whether the hostname matched a subject alt name or CN + */ + protected boolean verifyDNS(final String hostname, final X509Certificate cert) + { + boolean verified = false; + final String[] subjAltNames = getSubjectAltNames(cert, SubjectAltNameType.DNS_NAME); + logger.debug("verifyDNS using subjectAltNames={}", Arrays.toString(subjAltNames)); + if (subjAltNames.length > 0) { + // if subject alt names exist, one must match + for (String name : subjAltNames) { + if (isMatch(hostname, name)) { + logger.debug("verifyDNS found hostname match: {}", name); + verified = true; + break; + } + } + } else { + final String[] cns = getCNs(cert); + logger.debug("verifyDNS using CN={}", Arrays.toString(cns)); + if (cns.length > 0) { + // the most specific CN refers to the last CN + if (isMatch(hostname, cns[cns.length - 1])) { + logger.debug("verifyDNS found hostname match: {}", cns[cns.length - 1]); + verified = true; + } + } + } + return verified; + } + + + /** + * Returns the subject alternative names matching the supplied name type from the supplied certificate. + * + * @param cert to get subject alt names from + * @param type subject alt name type + * + * @return subject alt names + */ + private String[] getSubjectAltNames(final X509Certificate cert, final SubjectAltNameType type) + { + final List<String> names = new ArrayList<>(); + try { + final Collection<List<?>> subjAltNames = cert.getSubjectAlternativeNames(); + if (subjAltNames != null) { + for (List<?> generalName : subjAltNames) { + final Integer nameType = (Integer) generalName.get(0); + if (nameType == type.ordinal()) { + names.add((String) generalName.get(1)); + } + } + } + } catch (CertificateParsingException e) { + logger.warn("Error reading subject alt names from certificate", e); + } + return names.toArray(new String[names.size()]); + } + + + /** + * Returns the CNs from the supplied certificate. + * + * @param cert to get CNs from + * + * @return CNs + */ + private String[] getCNs(final X509Certificate cert) + { + final List<String> names = new ArrayList<>(); + final byte[] encodedDn = cert.getSubjectX500Principal().getEncoded(); + if (encodedDn != null && encodedDn.length > 0) { + final DN dn = DN.decode(ByteBuffer.wrap(encodedDn)); + for (RDN rdn : dn.getRDNs()) { + // for multi value RDNs the first value is used + final String value = rdn.getAttributeValue("2.5.4.3", new StringValueTranscoder()); + if (value != null) { + names.add(value); + } + } + } + return names.toArray(new String[names.size()]); + } + + + /** + * Determines if the supplied hostname matches a name derived from the certificate. If the certificate name starts + * with '*', the domain components after the first '.' in each name are compared. + * + * @param hostname to match + * @param certName to match + * + * @return whether the hostname matched the cert name + */ + private boolean isMatch(final String hostname, final String certName) + { + // must start with '*' and contain two domain components + final boolean isWildcard = certName.startsWith("*.") && certName.indexOf('.') < certName.lastIndexOf('.'); + logger.trace("matching for hostname={}, certName={}, isWildcard={}", hostname, certName, isWildcard); + + boolean match; + if (isWildcard) { + final String certNameDomain = certName.substring(certName.indexOf(".")); + + final int hostnameIdx = hostname.contains(".") ? hostname.indexOf(".") : hostname.length(); + final String hostnameDomain = hostname.substring(hostnameIdx); + + match = certNameDomain.equalsIgnoreCase(hostnameDomain); + logger.trace("match={} for {} == {}", match, certNameDomain, hostnameDomain); + } else { + match = certName.equalsIgnoreCase(hostname); + logger.trace("match={} for {} == {}", match, certName, hostname); + } + return match; + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/DefaultSSLContextInitializer.java b/core/src/main/java/org/ldaptive/ssl/DefaultSSLContextInitializer.java new file mode 100644 index 0000000..3b648fd --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/DefaultSSLContextInitializer.java
@@ -0,0 +1,90 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.util.Arrays; +import javax.net.ssl.KeyManager; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; + +/** + * Provides a default implementation of SSL context initializer which allows the setting of trust and key managers in + * order to create an SSL context. + * + * @author Middleware Services + */ +public class DefaultSSLContextInitializer extends AbstractSSLContextInitializer +{ + + /** Key managers. */ + private KeyManager[] keyManagers; + + /** Whether default trust managers should be created. */ + private final boolean createDefaultTrustManagers; + + + /** Creates a new default ssl context initializer. Default trust managers will be produced. */ + public DefaultSSLContextInitializer() + { + this(true); + } + + + /** + * Creates a new default ssl context initializer. + * + * @param defaultTrustManagers whether default trust managers should be created + */ + public DefaultSSLContextInitializer(final boolean defaultTrustManagers) + { + createDefaultTrustManagers = defaultTrustManagers; + } + + + @Override + protected TrustManager[] createTrustManagers() + throws GeneralSecurityException + { + if (createDefaultTrustManagers) { + final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init((KeyStore) null); + return tmf.getTrustManagers(); + } + return null; + } + + + @Override + public KeyManager[] getKeyManagers() + throws GeneralSecurityException + { + return keyManagers; + } + + + /** + * Sets the key managers. + * + * @param managers key managers + */ + public void setKeyManagers(final KeyManager... managers) + { + keyManagers = managers; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::trustManagers=%s, hostnameVerifierConfig=%s, keyManagers=%s, createDefaultTrustManagers=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(trustManagers), + hostnameVerifierConfig, + Arrays.toString(keyManagers), + createDefaultTrustManagers); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/DefaultTrustManager.java b/core/src/main/java/org/ldaptive/ssl/DefaultTrustManager.java new file mode 100644 index 0000000..49a0c81 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/DefaultTrustManager.java
@@ -0,0 +1,84 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Loads the trust managers from the default {@link TrustManagerFactory} and delegates to those. + * + * @author Middleware Services + */ +public class DefaultTrustManager implements X509TrustManager +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Default trust managers. */ + private final X509TrustManager[] trustManagers; + + + /** Creates a new default trust manager. */ + public DefaultTrustManager() + { + try { + final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init((KeyStore) null); + + final TrustManager[] tm = tmf.getTrustManagers(); + trustManagers = new X509TrustManager[tm.length]; + for (int i = 0; i < tm.length; i++) { + trustManagers[i] = (X509TrustManager) tm[i]; + } + } catch (GeneralSecurityException e) { + throw new IllegalStateException(e); + } + } + + + @Override + public void checkClientTrusted(final X509Certificate[] chain, final String authType) + throws CertificateException + { + for (X509TrustManager tm : trustManagers) { + logger.trace("invoking checkClientTrusted for {}", tm); + tm.checkClientTrusted(chain, authType); + } + } + + + @Override + public void checkServerTrusted(final X509Certificate[] chain, final String authType) + throws CertificateException + { + for (X509TrustManager tm : trustManagers) { + logger.trace("invoking checkServerTrusted for {}", tm); + tm.checkServerTrusted(chain, authType); + } + } + + + @Override + public X509Certificate[] getAcceptedIssuers() + { + final List<X509Certificate> issuers = new ArrayList<>(); + if (trustManagers != null) { + for (X509TrustManager tm : trustManagers) { + logger.trace("invoking getAcceptedIssuers for {}", tm); + Collections.addAll(issuers, tm.getAcceptedIssuers()); + } + } + return issuers.toArray(new X509Certificate[issuers.size()]); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/HostnameVerifierAdapter.java b/core/src/main/java/org/ldaptive/ssl/HostnameVerifierAdapter.java new file mode 100644 index 0000000..bde68b7 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/HostnameVerifierAdapter.java
@@ -0,0 +1,64 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.cert.X509Certificate; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Adapts a {@link CertificateHostnameVerifier} for use as a {@link HostnameVerifier}. + * + * @author Middleware Services + */ +public class HostnameVerifierAdapter implements HostnameVerifier +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Hostname verifier to adapt. */ + private final CertificateHostnameVerifier hostnameVerifier; + + + /** + * Creates a new hostname verifier adapter. + * + * @param verifier verifier to adapt + */ + public HostnameVerifierAdapter(final CertificateHostnameVerifier verifier) + { + hostnameVerifier = verifier; + } + + + @Override + public boolean verify(final String hostname, final SSLSession session) + { + boolean b = false; + try { + String name = null; + if (hostname != null) { + // if IPv6 strip off the "[]" + if (hostname.startsWith("[") && hostname.endsWith("]")) { + name = hostname.substring(1, hostname.length() - 1).trim(); + } else { + name = hostname.trim(); + } + } + b = hostnameVerifier.verify(name, (X509Certificate) session.getPeerCertificates()[0]); + } catch (SSLPeerUnverifiedException e) { + logger.warn("Could not get certificate from SSL session {} for hostname {}", session, hostname, e); + } + return b; + } + + + @Override + public String toString() + { + return String.format("[%s@%d::hostnameVerifier=%s]", getClass().getName(), hashCode(), hostnameVerifier); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/HostnameVerifierConfig.java b/core/src/main/java/org/ldaptive/ssl/HostnameVerifierConfig.java new file mode 100644 index 0000000..1c3461a --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/HostnameVerifierConfig.java
@@ -0,0 +1,98 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.util.Arrays; +import org.ldaptive.AbstractConfig; + +/** + * Contains all the configuration data for hostname verification. + * + * @author Middleware Services + */ +public class HostnameVerifierConfig extends AbstractConfig +{ + + /** Certificate hostname verifier. */ + private CertificateHostnameVerifier certificateHostnameVerifier; + + /** Hostnames to verify. */ + private String[] hostnames; + + + /** Default constructor. */ + public HostnameVerifierConfig() {} + + + /** + * Creates a new hostname verifier config. + * + * @param verifier certificate hostname verifier + * @param names hostnames + */ + public HostnameVerifierConfig(final CertificateHostnameVerifier verifier, final String... names) + { + certificateHostnameVerifier = verifier; + hostnames = names; + } + + + /** + * Returns the certificate hostname verifier. + * + * @return certificate hostname verifier + */ + public CertificateHostnameVerifier getCertificateHostnameVerifier() + { + return certificateHostnameVerifier; + } + + + /** + * Sets the certificate hostname verifier. + * + * @param verifier certificate hostname verifier + */ + public void setCertificateHostnameVerifier(final CertificateHostnameVerifier verifier) + { + checkImmutable(); + logger.trace("setting certificateHostnameVerifier: {}", verifier); + certificateHostnameVerifier = verifier; + } + + + /** + * Returns the hostnames to verify. + * + * @return hostnames + */ + public String[] getHostnames() + { + return hostnames; + } + + + /** + * Sets the hostnames to verify. + * + * @param names hostnames + */ + public void setHostnames(final String... names) + { + checkImmutable(); + logger.trace("setting hostnames: {}", Arrays.toString(names)); + hostnames = names; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::certificateHostnameVerifier=%s, hostnames=%s]", + getClass().getName(), + hashCode(), + certificateHostnameVerifier, + Arrays.toString(hostnames)); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/HostnameVerifyingListener.java b/core/src/main/java/org/ldaptive/ssl/HostnameVerifyingListener.java new file mode 100644 index 0000000..1986f39 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/HostnameVerifyingListener.java
@@ -0,0 +1,98 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.io.IOException; +import javax.net.ssl.HandshakeCompletedEvent; +import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLPeerUnverifiedException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Handshake completed listener that invokes a hostname verifier. If hostname verification fails, the socket is closed + * and the SSL session is invalidated. + * + * @author Middleware Services + */ +public class HostnameVerifyingListener implements HandshakeCompletedListener +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Hostname verifier invoked when the handshake completes. */ + private final HostnameVerifier hostnameVerifier; + + /** Whether this listener has been invoked. */ + private boolean invoked; + + /** Whether hostname verification succeeded. */ + private boolean verified; + + /** Hostname used in verification. */ + private String hostname; + + + /** + * Creates a new verifying handshake completed listener. Hostname will be derived from the SSL session. + * + * @param verifier hostname verifier + */ + public HostnameVerifyingListener(final HostnameVerifier verifier) + { + hostnameVerifier = verifier; + } + + + /** + * Creates a new verifying handshake completed listener. + * + * @param verifier hostname verifier + * @param name hostname to verify + */ + public HostnameVerifyingListener(final HostnameVerifier verifier, final String name) + { + hostnameVerifier = verifier; + hostname = name; + } + + + @Override + public void handshakeCompleted(final HandshakeCompletedEvent event) + { + invoked = true; + if (hostname == null) { + hostname = event.getSession().getPeerHost(); + } + if (!hostnameVerifier.verify(hostname, event.getSession())) { + try { + event.getSocket().close(); + } catch (IOException e) { + logger.warn("Error closing SSL socket", e); + } + event.getSession().invalidate(); + } else { + verified = true; + } + } + + + /** + * Throws exception if hostname verification failed. + * + * @throws IllegalStateException if this listener has not been invoked + * @throws SSLPeerUnverifiedException if the hostname failed to verify + */ + public void peerVerified() + throws SSLPeerUnverifiedException + { + if (!invoked) { + throw new IllegalStateException("Handshake has not completed"); + } + if (!verified) { + throw new SSLPeerUnverifiedException( + String.format("Hostname '%s' does not match the hostname in the server's certificate", hostname)); + } + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/HostnameVerifyingTrustManager.java b/core/src/main/java/org/ldaptive/ssl/HostnameVerifyingTrustManager.java new file mode 100644 index 0000000..f894caf --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/HostnameVerifyingTrustManager.java
@@ -0,0 +1,105 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import javax.net.ssl.X509TrustManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Trust manager that delegates to {@link CertificateHostnameVerifier}. Any name that verifies passes this trust manager + * check. + * + * @author Middleware Services + */ +public class HostnameVerifyingTrustManager implements X509TrustManager +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Hostnames to allow. */ + private final String[] hostnames; + + /** Hostname verifier to use for trust. */ + private final CertificateHostnameVerifier hostnameVerifier; + + + /** + * Creates a new hostname verifying trust manager. + * + * @param verifier that establishes trust + * @param names to match against a certificate + */ + public HostnameVerifyingTrustManager(final CertificateHostnameVerifier verifier, final String... names) + { + hostnameVerifier = verifier; + hostnames = names; + } + + + @Override + public void checkClientTrusted(final X509Certificate[] chain, final String authType) + throws CertificateException + { + checkCertificateTrusted(chain[0]); + } + + + @Override + public void checkServerTrusted(final X509Certificate[] chain, final String authType) + throws CertificateException + { + checkCertificateTrusted(chain[0]); + } + + + /** + * Verifies the supplied certificate using the hostname verifier with each hostname. + * + * @param cert to verify + * + * @throws CertificateException if none of the hostnames verify + */ + private void checkCertificateTrusted(final X509Certificate cert) + throws CertificateException + { + for (String name : hostnames) { + if (hostnameVerifier.verify(name, cert)) { + logger.debug( + "checkCertificateTrusted for {} succeeded against {}", + hostnameVerifier, + cert != null ? cert.getSubjectX500Principal() : null); + return; + } + } + throw new CertificateException( + String.format( + "Hostname '%s' does not match the hostname in the server's " + + "certificate '%s'", + Arrays.toString(hostnames), + cert != null ? cert.getSubjectX500Principal() : null)); + } + + + @Override + public X509Certificate[] getAcceptedIssuers() + { + return new X509Certificate[0]; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::hostnameVerifier=%s, hostnames=%s]", + getClass().getName(), + hashCode(), + hostnameVerifier, + Arrays.toString(hostnames)); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/KeyStoreCredentialConfig.java b/core/src/main/java/org/ldaptive/ssl/KeyStoreCredentialConfig.java new file mode 100644 index 0000000..52a7b35 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/KeyStoreCredentialConfig.java
@@ -0,0 +1,300 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.Arrays; +import org.ldaptive.LdapUtils; + +/** + * Provides the properties necessary for creating an SSL context initializer with a keystore credential reader. + * + * @author Middleware Services + */ +public class KeyStoreCredentialConfig implements CredentialConfig +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1013; + + /** Handles loading keystores. */ + private final KeyStoreCredentialReader keyStoreReader = new KeyStoreCredentialReader(); + + /** Name of the truststore to use for the SSL connection. */ + private String trustStore; + + /** Password needed to open the truststore. */ + private String trustStorePassword; + + /** Truststore type. */ + private String trustStoreType; + + /** Truststore aliases to use. */ + private String[] trustStoreAliases; + + /** Name of the keystore to use for the SSL connection. */ + private String keyStore; + + /** Password needed to open the keystore. */ + private String keyStorePassword; + + /** Keystore type. */ + private String keyStoreType; + + /** Keystore aliases to use. */ + private String[] keyStoreAliases; + + + /** + * Returns the name of the truststore to use. + * + * @return truststore name + */ + public String getTrustStore() + { + return trustStore; + } + + + /** + * Sets the name of the truststore to use. + * + * @param name truststore name + */ + public void setTrustStore(final String name) + { + trustStore = name; + } + + + /** + * Returns the password for the truststore. + * + * @return truststore password + */ + public String getTrustStorePassword() + { + return trustStorePassword; + } + + + /** + * Sets the password for the truststore. + * + * @param password truststore password + */ + public void setTrustStorePassword(final String password) + { + trustStorePassword = password; + } + + + /** + * Returns the type of the truststore. + * + * @return truststore type + */ + public String getTrustStoreType() + { + return trustStoreType; + } + + + /** + * Sets the type of the truststore. + * + * @param type truststore type + */ + public void setTrustStoreType(final String type) + { + trustStoreType = type; + } + + + /** + * Returns the aliases of the truststore to use. + * + * @return truststore aliases + */ + public String[] getTrustStoreAliases() + { + return trustStoreAliases; + } + + + /** + * Sets the aliases of the truststore to use. + * + * @param aliases truststore aliases + */ + public void setTrustStoreAliases(final String... aliases) + { + trustStoreAliases = aliases; + } + + + /** + * Returns the name of the keystore to use. + * + * @return keystore name + */ + public String getKeyStore() + { + return keyStore; + } + + + /** + * Sets the name of the keystore to use. + * + * @param name keystore name + */ + public void setKeyStore(final String name) + { + keyStore = name; + } + + + /** + * Returns the password for the keystore. + * + * @return keystore password + */ + public String getKeyStorePassword() + { + return keyStorePassword; + } + + + /** + * Sets the password for the keystore. + * + * @param password keystore password + */ + public void setKeyStorePassword(final String password) + { + keyStorePassword = password; + } + + + /** + * Returns the type of the keystore. + * + * @return keystore type + */ + public String getKeyStoreType() + { + return keyStoreType; + } + + + /** + * Sets the type of the keystore. + * + * @param type keystore type + */ + public void setKeyStoreType(final String type) + { + keyStoreType = type; + } + + + /** + * Returns the aliases of the keystore to use. + * + * @return keystore aliases + */ + public String[] getKeyStoreAliases() + { + return keyStoreAliases; + } + + + /** + * Sets the aliases of the keystore to use. + * + * @param aliases keystore aliases + */ + public void setKeyStoreAliases(final String... aliases) + { + keyStoreAliases = aliases; + } + + + @Override + public SSLContextInitializer createSSLContextInitializer() + throws GeneralSecurityException + { + final KeyStoreSSLContextInitializer sslInit = new KeyStoreSSLContextInitializer(); + try { + if (trustStore != null) { + sslInit.setTrustKeystore(keyStoreReader.read(trustStore, trustStorePassword, trustStoreType)); + sslInit.setTrustAliases(trustStoreAliases); + } + if (keyStore != null) { + sslInit.setAuthenticationKeystore(keyStoreReader.read(keyStore, keyStorePassword, keyStoreType)); + sslInit.setAuthenticationPassword(keyStorePassword != null ? keyStorePassword.toCharArray() : null); + sslInit.setAuthenticationAliases(keyStoreAliases); + } + } catch (IOException e) { + throw new GeneralSecurityException(e); + } + return sslInit; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof KeyStoreCredentialConfig) { + final KeyStoreCredentialConfig v = (KeyStoreCredentialConfig) o; + return LdapUtils.areEqual(trustStore, v.trustStore) && + LdapUtils.areEqual(trustStoreType, v.trustStoreType) && + LdapUtils.areEqual(trustStorePassword, v.trustStorePassword) && + LdapUtils.areEqual(trustStoreAliases, v.trustStoreAliases) && + LdapUtils.areEqual(keyStore, v.keyStore) && + LdapUtils.areEqual(keyStoreType, v.keyStoreType) && + LdapUtils.areEqual(keyStorePassword, v.keyStorePassword) && + LdapUtils.areEqual(keyStoreAliases, v.keyStoreAliases); + } + return false; + } + + + @Override + public int hashCode() + { + return + LdapUtils.computeHashCode( + HASH_CODE_SEED, + trustStore, + trustStoreType, + trustStorePassword, + trustStoreAliases, + keyStore, + keyStoreType, + keyStorePassword, + keyStoreAliases); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::trustStore=%s, trustStoreType=%s, trustStoreAliases=%s, " + + "keyStore=%s, keyStoreType=%s, keyStoreAliases=%s]", + getClass().getName(), + hashCode(), + trustStore, + trustStoreType, + Arrays.toString(trustStoreAliases), + keyStore, + keyStoreType, + Arrays.toString(keyStoreAliases)); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/KeyStoreCredentialReader.java b/core/src/main/java/org/ldaptive/ssl/KeyStoreCredentialReader.java new file mode 100644 index 0000000..df6f56c --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/KeyStoreCredentialReader.java
@@ -0,0 +1,60 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.io.IOException; +import java.io.InputStream; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.util.Arrays; + +/** + * Reads keystore credentials from a classpath, filepath, or stream resource. + * + * @author Middleware Services + */ +public class KeyStoreCredentialReader extends AbstractCredentialReader<KeyStore> +{ + + + /** + * Reads a keystore from an input stream. + * + * @param is Input stream from which to read keystore. + * @param params Two optional parameters are supported: + * + * <ul> + * <li>keystore password</li> + * <li>keystore type; defaults to JVM default keystore format if omitted</li> + * </ul> + * + * <p>If only a single parameter is supplied, it is assumed to be the password.</p> + * + * @return keystore read from data in stream. + * + * @throws IOException On IO errors. + * @throws GeneralSecurityException On errors with the credential data. + */ + @Override + public KeyStore read(final InputStream is, final String... params) + throws IOException, GeneralSecurityException + { + char[] password = null; + if (params.length > 0 && params[0] != null) { + password = params[0].toCharArray(); + } + + String type = KeyStore.getDefaultType(); + if (params.length > 1 && params[1] != null) { + type = params[1]; + } + + final KeyStore keystore = KeyStore.getInstance(type); + if (is != null) { + keystore.load(getBufferedInputStream(is), password); + if (password != null) { + Arrays.fill(password, '0'); + } + } + return keystore; + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/KeyStoreSSLContextInitializer.java b/core/src/main/java/org/ldaptive/ssl/KeyStoreSSLContextInitializer.java new file mode 100644 index 0000000..aa47a49 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/KeyStoreSSLContextInitializer.java
@@ -0,0 +1,208 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.util.Arrays; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; + +/** + * Provides an SSL context initializer which can use java KeyStores to create key and trust managers. + * + * @author Middleware Services + */ +public class KeyStoreSSLContextInitializer extends AbstractSSLContextInitializer +{ + + /** KeyStore used to create trust managers. */ + private KeyStore trustKeystore; + + /** Aliases of trust entries to use. */ + private String[] trustAliases; + + /** KeyStore used to create key managers. */ + private KeyStore authenticationKeystore; + + /** Aliases of key entries to use. */ + private String[] authenticationAliases; + + /** Password used to access the authentication keystore. */ + private char[] authenticationPassword; + + + /** + * Returns the keystore to use for creating the trust managers. + * + * @return keystore + */ + public KeyStore getTrustKeystore() + { + return trustKeystore; + } + + + /** + * Sets the keystore to use for creating the trust managers. + * + * @param keystore to set + */ + public void setTrustKeystore(final KeyStore keystore) + { + trustKeystore = keystore; + } + + + /** + * Returns the aliases of the entries to use in the trust keystore + * + * @return trust aliases + */ + public String[] getTrustAliases() + { + return trustAliases; + } + + + /** + * Sets the aliases of the entries to use in the trust keystore. + * + * @param aliases to use + */ + public void setTrustAliases(final String... aliases) + { + trustAliases = aliases; + } + + + /** + * Returns the keystore to use for creating the key managers. + * + * @return keystore + */ + public KeyStore getAuthenticationKeystore() + { + return authenticationKeystore; + } + + + /** + * Sets the keystore to use for creating the key managers. + * + * @param keystore to set + */ + public void setAuthenticationKeystore(final KeyStore keystore) + { + authenticationKeystore = keystore; + } + + + /** + * Returns the aliases of the entries to use in the authentication keystore + * + * @return authentication aliases + */ + public String[] getAuthenticationAliases() + { + return authenticationAliases; + } + + + /** + * Sets the aliases of the entries to use in the authentication keystore. + * + * @param aliases to use + */ + public void setAuthenticationAliases(final String... aliases) + { + authenticationAliases = aliases; + } + + + /** + * Returns the password used for accessing the authentication keystore. + * + * @return authentication password + */ + public char[] getAuthenticationPassword() + { + return authenticationPassword; + } + + + /** + * Sets the password used for accessing the authentication keystore. + * + * @param password to use for authentication + */ + public void setAuthenticationPassword(final char[] password) + { + authenticationPassword = password; + } + + + @Override + protected TrustManager[] createTrustManagers() + throws GeneralSecurityException + { + TrustManager[] tm = null; + if (trustKeystore != null) { + final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + if (trustAliases != null) { + final KeyStore ks = KeyStoreUtils.newInstance(); + for (String alias : trustAliases) { + final KeyStore.Entry entry = KeyStoreUtils.getEntry(alias, trustKeystore, null); + KeyStoreUtils.setEntry(alias, entry, ks, null); + } + tmf.init(ks); + } else { + tmf.init(trustKeystore); + } + tm = tmf.getTrustManagers(); + } + return tm; + } + + + @Override + public KeyManager[] getKeyManagers() + throws GeneralSecurityException + { + KeyManager[] km = null; + if (authenticationKeystore != null && authenticationPassword != null) { + final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + if (authenticationAliases != null) { + final KeyStore ks = KeyStoreUtils.newInstance(authenticationPassword); + for (String alias : authenticationAliases) { + final KeyStore.Entry entry = KeyStoreUtils.getEntry(alias, authenticationKeystore, authenticationPassword); + KeyStoreUtils.setEntry(alias, entry, ks, authenticationPassword); + } + kmf.init(ks, authenticationPassword); + } else { + kmf.init(authenticationKeystore, authenticationPassword); + } + km = kmf.getKeyManagers(); + } + return km; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::trustManagers=%s, hostnameVerifierConfig=%s, trustKeystore=%s, trustAliases=%s, " + + "authenticationKeystore=%s, authenticationAliases=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(trustManagers), + hostnameVerifierConfig, + trustKeystore, + Arrays.toString(trustAliases), + authenticationKeystore, + Arrays.toString(authenticationAliases)); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/KeyStoreUtils.java b/core/src/main/java/org/ldaptive/ssl/KeyStoreUtils.java new file mode 100644 index 0000000..0bd25e8 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/KeyStoreUtils.java
@@ -0,0 +1,181 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.GeneralSecurityException; +import java.security.Key; +import java.security.KeyStore; +import java.security.cert.Certificate; + +/** + * Provides utility methods for using a {@link KeyStore}. + * + * @author Middleware Services + */ +public final class KeyStoreUtils +{ + + /** Default keystore type. */ + private static final String DEFAULT_TYPE = KeyStore.getDefaultType(); + + + /** Default constructor. */ + private KeyStoreUtils() {} + + + /** + * Creates a new {@link KeyStore} with the default keystore type and initializes it. + * + * @return initialized keystore + * + * @throws GeneralSecurityException if the keystore cannot be initialized + */ + public static KeyStore newInstance() + throws GeneralSecurityException + { + return newInstance(DEFAULT_TYPE); + } + + + /** + * Creates a new {@link KeyStore} with the default keystore type and initializes it. + * + * @param password to protect the keystore + * + * @return initialized keystore + * + * @throws GeneralSecurityException if the keystore cannot be initialized + */ + public static KeyStore newInstance(final char[] password) + throws GeneralSecurityException + { + return newInstance(DEFAULT_TYPE, password); + } + + + /** + * Creates a new {@link KeyStore} and initializes it. + * + * @param type of keystore instance + * + * @return initialized keystore + * + * @throws GeneralSecurityException if the keystore cannot be initialized + */ + public static KeyStore newInstance(final String type) + throws GeneralSecurityException + { + return newInstance(type, null); + } + + + /** + * Creates a new {@link KeyStore} and initializes it. + * + * @param type of keystore instance + * @param password to protect the keystore + * + * @return initialized keystore + * + * @throws GeneralSecurityException if the keystore cannot be initialized + */ + public static KeyStore newInstance(final String type, final char[] password) + throws GeneralSecurityException + { + final KeyStore.Builder builder = KeyStore.Builder.newInstance( + type, + null, + new KeyStore.PasswordProtection(password)); + return builder.getKeyStore(); + } + + + /** + * Returns a keystore entry from the supplied keystore. + * + * @param alias of the entry to return + * @param keystore to read the entry from + * @param password to access the keystore + * + * @return keystore entry + * + * @throws GeneralSecurityException if the keystore cannot be read + * @throws IllegalArgumentException if the alias does not exist + */ + public static KeyStore.Entry getEntry(final String alias, final KeyStore keystore, final char[] password) + throws GeneralSecurityException + { + if (!keystore.containsAlias(alias)) { + throw new IllegalArgumentException("KeyStore does not contain alias " + alias); + } + return keystore.getEntry(alias, password != null ? new KeyStore.PasswordProtection(password) : null); + } + + + /** + * Sets a keystore entry on the supplied keystore. + * + * @param alias of the supplied entry + * @param entry to set + * @param keystore to set the entry on + * @param password to protect the entry + * + * @throws GeneralSecurityException if the keystore cannot be modified + */ + public static void setEntry( + final String alias, + final KeyStore.Entry entry, + final KeyStore keystore, + final char[] password) + throws GeneralSecurityException + { + keystore.setEntry(alias, entry, password != null ? new KeyStore.PasswordProtection(password) : null); + } + + + /** + * Sets a key entry on the supplied keystore. + * + * @param alias of the supplied key + * @param keystore to set the key on + * @param password to protect the key + * @param key to set + * @param certs associated with the key + * + * @throws GeneralSecurityException if the keystore cannot be modified + */ + public static void setKeyEntry( + final String alias, + final KeyStore keystore, + final char[] password, + final Key key, + final Certificate... certs) + throws GeneralSecurityException + { + keystore.setKeyEntry(alias, key, password, certs); + } + + + /** + * Sets certificate entries on the supplied keystore. For certificate arrays of size greater than 1, the alias is + * appended with an index. + * + * @param alias of the supplied certificate(s) + * @param keystore to set the cert(s) on + * @param certs to set + * + * @throws GeneralSecurityException if the keystore cannot be modified + */ + public static void setCertificateEntry(final String alias, final KeyStore keystore, final Certificate... certs) + throws GeneralSecurityException + { + if (certs != null && certs.length > 0) { + if (certs.length == 1) { + keystore.setCertificateEntry(alias, certs[0]); + } else { + for (int i = 0; i < certs.length; i++) { + keystore.setCertificateEntry(String.format("%s%s", alias, i), certs[i]); + } + } + } + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/PrivateKeyCredentialReader.java b/core/src/main/java/org/ldaptive/ssl/PrivateKeyCredentialReader.java new file mode 100644 index 0000000..0652752 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/PrivateKeyCredentialReader.java
@@ -0,0 +1,46 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.io.IOException; +import java.io.InputStream; +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.PrivateKey; +import java.security.spec.PKCS8EncodedKeySpec; +import org.ldaptive.LdapUtils; + +/** + * Reads private key credentials from classpath, filepath, or stream resource. Supported private key formats include: + * PKCS8. + * + * @author Middleware Services + */ +public class PrivateKeyCredentialReader extends AbstractCredentialReader<PrivateKey> +{ + + + /** + * Reads a private key from an input stream. + * + * @param is Input stream from which to read private key. + * @param params A single optional parameter, algorithm, may be specified. The default is RSA. + * + * @return Private key read from data in stream. + * + * @throws IOException On IO errors. + * @throws GeneralSecurityException On errors with the credential data. + */ + @Override + public PrivateKey read(final InputStream is, final String... params) + throws IOException, GeneralSecurityException + { + String algorithm = "RSA"; + if (params.length > 0 && params[0] != null) { + algorithm = params[0]; + } + + final KeyFactory kf = KeyFactory.getInstance(algorithm); + final PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(LdapUtils.readInputStream(getBufferedInputStream(is))); + return kf.generatePrivate(spec); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/SSLContextInitializer.java b/core/src/main/java/org/ldaptive/ssl/SSLContextInitializer.java new file mode 100644 index 0000000..65aa28d --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/SSLContextInitializer.java
@@ -0,0 +1,75 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.GeneralSecurityException; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; + +/** + * Provides an interface for the initialization of new SSL contexts. + * + * @author Middleware Services + */ +public interface SSLContextInitializer +{ + + + /** + * Creates an initialized SSLContext for the supplied protocol. + * + * @param protocol type to use for SSL + * + * @return SSL context + * + * @throws GeneralSecurityException if the SSLContext cannot be created + */ + SSLContext initSSLContext(String protocol) + throws GeneralSecurityException; + + + /** + * Returns the trust managers used when creating SSL contexts. + * + * @return trust managers + * + * @throws GeneralSecurityException if an errors occurs while loading the TrustManagers + */ + TrustManager[] getTrustManagers() + throws GeneralSecurityException; + + + /** + * Sets the trust managers. May be in isolation or in conjunction with other trust material. + * + * @param managers trust managers + */ + void setTrustManagers(TrustManager... managers); + + + /** + * Returns the hostname verifier config used when created SSL contexts. + * + * @return hostname verifier config + */ + HostnameVerifierConfig getHostnameVerifierConfig(); + + + /** + * Sets the hostname verifier config. + * + * @param config hostname verifier config + */ + void setHostnameVerifierConfig(HostnameVerifierConfig config); + + + /** + * Returns the key managers used when creating SSL contexts. + * + * @return key managers + * + * @throws GeneralSecurityException if an errors occurs while loading the KeyManagers + */ + KeyManager[] getKeyManagers() + throws GeneralSecurityException; +}
diff --git a/core/src/main/java/org/ldaptive/ssl/SocketConfig.java b/core/src/main/java/org/ldaptive/ssl/SocketConfig.java new file mode 100644 index 0000000..e9425cf --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/SocketConfig.java
@@ -0,0 +1,333 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.net.Socket; +import java.net.SocketException; +import org.ldaptive.AbstractConfig; + +/** + * Contains the configuration data for sockets. + * + * @author Middleware Services + */ +public class SocketConfig extends AbstractConfig +{ + + /** Keep alive. */ + private Boolean keepAlive; + + /** OOB Inline. */ + private Boolean oobInline; + + /** Receive buffer size. */ + private Integer receiveBufferSize; + + /** Send buffer size. */ + private Integer sendBufferSize; + + /** Reuse address. */ + private Boolean reuseAddress; + + /** SO Linger. */ + private Integer soLinger; + + /** SO Timeout. */ + private Integer soTimeout; + + /** TCP No Delay. */ + private Boolean tcpNoDelay; + + /** Traffic Class. */ + private Integer trafficClass; + + + /** + * Returns whether this socket config contains any configuration data. + * + * @return whether all properties are null + */ + public boolean isEmpty() + { + return + keepAlive == null && oobInline == null && receiveBufferSize == null && sendBufferSize == null && + reuseAddress == null && soLinger == null && soTimeout == null && tcpNoDelay == null && trafficClass == null; + } + + + /** + * See {@link Socket#getKeepAlive()}. + * + * @return keep alive + */ + public Boolean getKeepAlive() + { + return keepAlive; + } + + + /** + * See {@link Socket#setKeepAlive(boolean)}. + * + * @param b keep alive + */ + public void setKeepAlive(final boolean b) + { + checkImmutable(); + logger.trace("setting keepAlive: {}", b); + keepAlive = b; + } + + + /** + * See {@link Socket#getOOBInline()}. + * + * @return OOB in line + */ + public Boolean getOOBInline() + { + return oobInline; + } + + + /** + * See {@link Socket#setOOBInline(boolean)}. + * + * @param b OOB in line + */ + public void setOOBInline(final boolean b) + { + checkImmutable(); + logger.trace("setting oobInline: {}", b); + oobInline = b; + } + + + /** + * See {@link Socket#getReceiveBufferSize()}. + * + * @return receive buffer size + */ + public Integer getReceiveBufferSize() + { + return receiveBufferSize; + } + + + /** + * See {@link Socket#setReceiveBufferSize(int)}. + * + * @param i receive buffer size + */ + public void setReceiveBufferSize(final int i) + { + checkImmutable(); + logger.trace("setting receiveBufferSize: {}", i); + receiveBufferSize = i; + } + + + /** + * See {@link Socket#getSendBufferSize()}. + * + * @return send buffer size + */ + public Integer getSendBufferSize() + { + return sendBufferSize; + } + + + /** + * See {@link Socket#setSendBufferSize(int)}. + * + * @param i send buffer size + */ + public void setSendBufferSize(final int i) + { + checkImmutable(); + logger.trace("setting sendBufferSize: {}", i); + sendBufferSize = i; + } + + + /** + * See {@link Socket#getReuseAddress()}. + * + * @return reuse address + */ + public Boolean getReuseAddress() + { + return reuseAddress; + } + + + /** + * See {@link Socket#setReuseAddress(boolean)}. + * + * @param b reuse address + */ + public void setReuseAddress(final boolean b) + { + checkImmutable(); + logger.trace("setting reuseAddress: {}", b); + reuseAddress = b; + } + + + /** + * See {@link Socket#getSoLinger()}. + * + * @return SO linger + */ + public Integer getSoLinger() + { + return soLinger; + } + + + /** + * See {@link Socket#setSoLinger(boolean, int)}. + * + * @param i SO linger + */ + public void setSoLinger(final int i) + { + checkImmutable(); + logger.trace("setting soLinger: {}", i); + soLinger = i; + } + + + /** + * See {@link Socket#getSoTimeout()}. + * + * @return SO timeout + */ + public Integer getSoTimeout() + { + return soTimeout; + } + + + /** + * See {@link Socket#setSoTimeout(int)}. + * + * @param i SO timeout + */ + public void setSoTimeout(final int i) + { + checkImmutable(); + logger.trace("setting soTimeout: {}", i); + soTimeout = i; + } + + + /** + * See {@link Socket#getTcpNoDelay()}. + * + * @return tcp no delay + */ + public Boolean getTcpNoDelay() + { + return tcpNoDelay; + } + + + /** + * See {@link Socket#setTcpNoDelay(boolean)}. + * + * @param b tcp no delay + */ + public void setTcpNoDelay(final boolean b) + { + checkImmutable(); + logger.trace("setting tcpNoDelay: {}", b); + tcpNoDelay = b; + } + + + /** + * See {@link Socket#getTrafficClass()}. + * + * @return traffic class + */ + public Integer getTrafficClass() + { + return trafficClass; + } + + + /** + * See {@link Socket#setTrafficClass(int)}. + * + * @param i traffic class + */ + public void setTrafficClass(final int i) + { + checkImmutable(); + logger.trace("setting trafficClass: {}", i); + trafficClass = i; + } + + + /** + * Applies this configuration to the supplied socket. + * + * @param socket to set properties on + * + * @throws SocketException if an error occurs invoking a socket setter + */ + public void configureSocket(final Socket socket) + throws SocketException + { + if (keepAlive != null) { + socket.setKeepAlive(keepAlive); + } + if (oobInline != null) { + socket.setOOBInline(oobInline); + } + if (reuseAddress != null) { + socket.setReuseAddress(reuseAddress); + } + if (tcpNoDelay != null) { + socket.setTcpNoDelay(tcpNoDelay); + } + if (receiveBufferSize != null) { + socket.setReceiveBufferSize(receiveBufferSize); + } + if (sendBufferSize != null) { + socket.setSendBufferSize(sendBufferSize); + } + if (soLinger != null) { + socket.setSoLinger(true, soLinger); + } + if (soTimeout != null) { + socket.setSoTimeout(soTimeout); + } + if (trafficClass != null) { + socket.setTrafficClass(trafficClass); + } + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::keepAlive=%s, oobInline=%s, receiveBufferSize=%s, " + + "sendBufferSize=%s, reuseAddress=%s, soLinger=%s, soTimeout=%s, " + + "tcpNoDelay=%s, trafficClass=%s]", + getClass().getName(), + hashCode(), + keepAlive, + oobInline, + receiveBufferSize, + sendBufferSize, + reuseAddress, + soLinger, + soTimeout, + tcpNoDelay, + trafficClass); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/SslConfig.java b/core/src/main/java/org/ldaptive/ssl/SslConfig.java new file mode 100644 index 0000000..bc8f0be --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/SslConfig.java
@@ -0,0 +1,298 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.util.Arrays; +import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.TrustManager; +import org.ldaptive.AbstractConfig; + +/** + * Contains all the configuration data for SSL and startTLS. Providers are not guaranteed to support all the options + * contained here. + * + * @author Middleware Services + */ +public class SslConfig extends AbstractConfig +{ + + /** Configuration for the trust and authentication material to use for SSL and startTLS. */ + private CredentialConfig credentialConfig; + + /** Trust managers. */ + private TrustManager[] trustManagers; + + /** Certificate hostname verifier. */ + private CertificateHostnameVerifier hostnameVerifier; + + /** Hostname verifier config. */ + private HostnameVerifierConfig hostnameVerifierConfig; + + /** Enabled cipher suites. */ + private String[] enabledCipherSuites; + + /** Enabled protocol versions. */ + private String[] enabledProtocols; + + /** Handshake completed listeners. */ + private HandshakeCompletedListener[] handshakeCompletedListeners; + + + /** Default constructor. */ + public SslConfig() {} + + + /** + * Creates a new ssl config. + * + * @param config credential config + */ + public SslConfig(final CredentialConfig config) + { + credentialConfig = config; + } + + + /** + * Creates a new ssl config. + * + * @param managers trust managers + */ + public SslConfig(final TrustManager... managers) + { + trustManagers = managers; + } + + + /** + * Creates a new ssl config. + * + * @param config credential config + * @param managers trust managers + */ + public SslConfig(final CredentialConfig config, final TrustManager... managers) + { + credentialConfig = config; + trustManagers = managers; + } + + + /** + * Returns whether this ssl config contains any configuration data. + * + * @return whether all properties are null + */ + public boolean isEmpty() + { + return + credentialConfig == null && trustManagers == null && hostnameVerifier == null && hostnameVerifierConfig == null && + enabledCipherSuites == null && enabledProtocols == null && handshakeCompletedListeners == null; + } + + + /** + * Returns the credential config. + * + * @return credential config + */ + public CredentialConfig getCredentialConfig() + { + return credentialConfig; + } + + + /** + * Sets the credential config. + * + * @param config credential config + */ + public void setCredentialConfig(final CredentialConfig config) + { + checkImmutable(); + logger.trace("setting credentialConfig: {}", config); + credentialConfig = config; + } + + + /** + * Returns the trust managers. + * + * @return trust managers + */ + public TrustManager[] getTrustManagers() + { + return trustManagers; + } + + + /** + * Sets the trust managers. + * + * @param managers trust managers + */ + public void setTrustManagers(final TrustManager... managers) + { + checkImmutable(); + logger.trace("setting trustManagers: {}", Arrays.toString(managers)); + trustManagers = managers; + } + + + /** + * Returns the hostname verifier. + * + * @return hostname verifier + */ + public CertificateHostnameVerifier getHostnameVerifier() + { + return hostnameVerifier; + } + + + /** + * Sets the hostname verifier. + * + * @param verifier hostname verifier + */ + public void setHostnameVerifier(final CertificateHostnameVerifier verifier) + { + checkImmutable(); + logger.trace("setting hostnameVerifier: {}", verifier); + hostnameVerifier = verifier; + } + + + /** + * Returns the hostname verifier config. + * + * @return hostname verifier config + */ + protected HostnameVerifierConfig getHostnameVerifierConfig() + { + return hostnameVerifierConfig; + } + + + /** + * Sets the hostname verifier config. + * + * @param config hostname verifier config + */ + protected void setHostnameVerifierConfig(final HostnameVerifierConfig config) + { + checkImmutable(); + logger.trace("setting hostnameVerifierConfig: {}", config); + hostnameVerifierConfig = config; + } + + + /** + * Returns the names of the SSL cipher suites to use for secure connections. + * + * @return cipher suites + */ + public String[] getEnabledCipherSuites() + { + return enabledCipherSuites; + } + + + /** + * Sets the SSL cipher suites to use for secure connections. + * + * @param suites cipher suites + */ + public void setEnabledCipherSuites(final String... suites) + { + checkImmutable(); + logger.trace("setting enabledCipherSuites: {}", Arrays.toString(suites)); + enabledCipherSuites = suites; + } + + + /** + * Returns the names of the SSL protocols to use for secure connections. + * + * @return enabled protocols + */ + public String[] getEnabledProtocols() + { + return enabledProtocols; + } + + + /** + * Sets the SSL protocol versions to use for secure connections. + * + * @param protocols enabled protocols + */ + public void setEnabledProtocols(final String... protocols) + { + checkImmutable(); + logger.trace("setting enabledProtocols: {}", Arrays.toString(protocols)); + enabledProtocols = protocols; + } + + + /** + * Returns the handshake completed listeners to use for secure connections. + * + * @return handshake completed listeners + */ + public HandshakeCompletedListener[] getHandshakeCompletedListeners() + { + return handshakeCompletedListeners; + } + + + /** + * Sets the handshake completed listeners to use for secure connections. + * + * @param listeners for SSL handshake events + */ + public void setHandshakeCompletedListeners(final HandshakeCompletedListener... listeners) + { + checkImmutable(); + logger.trace("setting handshakeCompletedListeners: {}", Arrays.toString(handshakeCompletedListeners)); + handshakeCompletedListeners = listeners; + } + + + /** + * Returns a ssl config initialized with the supplied config. + * + * @param config ssl config to read properties from + * + * @return ssl config + */ + public static SslConfig newSslConfig(final SslConfig config) + { + final SslConfig sc = new SslConfig(); + sc.setCredentialConfig(config.getCredentialConfig()); + sc.setTrustManagers(config.getTrustManagers()); + sc.setHostnameVerifier(config.getHostnameVerifier()); + sc.setHostnameVerifierConfig(config.getHostnameVerifierConfig()); + sc.setEnabledCipherSuites(config.getEnabledCipherSuites()); + sc.setEnabledProtocols(config.getEnabledProtocols()); + sc.setHandshakeCompletedListeners(config.getHandshakeCompletedListeners()); + return sc; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::credentialConfig=%s, trustManagers=%s, hostnameVerifier=%s, hostnameVerifierConfig=%s, " + + "enabledCipherSuites=%s, enabledProtocols=%s, handshakeCompletedListeners=%s]", + getClass().getName(), + hashCode(), + credentialConfig, + Arrays.toString(trustManagers), + hostnameVerifier, + hostnameVerifierConfig, + Arrays.toString(enabledCipherSuites), + Arrays.toString(enabledProtocols), + Arrays.toString(handshakeCompletedListeners)); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/TLSSocketFactory.java b/core/src/main/java/org/ldaptive/ssl/TLSSocketFactory.java new file mode 100644 index 0000000..e920755 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/TLSSocketFactory.java
@@ -0,0 +1,163 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.GeneralSecurityException; +import javax.net.SocketFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; + +/** + * An extension of SSLSocketFactory that leverages an SSL context initializer. Note that {@link #initialize()} must be + * called prior to using this socket factory. This means that this class cannot be passed to implementations that expect + * the socket factory to function immediately after construction. + * + * @author Middleware Services + */ +public class TLSSocketFactory extends AbstractTLSSocketFactory +{ + + + /** + * Creates the underlying SSLContext using truststore and keystore attributes and makes this factory ready for use. + * Must be called before factory can be used. + * + * @throws GeneralSecurityException if the SSLContext cannot be created + */ + @Override + public void initialize() + throws GeneralSecurityException + { + final SSLContextInitializer contextInitializer = createSSLContextInitializer(); + logger.trace("Using SSLContextInitializer={}", contextInitializer); + final SSLContext ctx = contextInitializer.initSSLContext(DEFAULT_PROTOCOL); + factory = ctx.getSocketFactory(); + } + + + /** + * Creates a {@link SSLContextInitializer} for use with this socket factory. + * + * @return SSL context initializer + * + * @throws GeneralSecurityException if the SSL context initializer cannot be created + */ + protected SSLContextInitializer createSSLContextInitializer() + throws GeneralSecurityException + { + SSLContextInitializer contextInitializer; + final SslConfig sslConfig = getSslConfig(); + if (sslConfig != null) { + final CredentialConfig credConfig = sslConfig.getCredentialConfig(); + final TrustManager[] managers = sslConfig.getTrustManagers(); + final HostnameVerifierConfig verifierConfig = sslConfig.getHostnameVerifierConfig(); + if (credConfig != null) { + contextInitializer = credConfig.createSSLContextInitializer(); + } else { + if (managers != null) { + contextInitializer = new DefaultSSLContextInitializer(false); + } else { + contextInitializer = new DefaultSSLContextInitializer(true); + } + } + + if (managers != null) { + contextInitializer.setTrustManagers(managers); + } + if (verifierConfig != null) { + contextInitializer.setHostnameVerifierConfig(verifierConfig); + } + } else { + contextInitializer = new DefaultSSLContextInitializer(); + } + return contextInitializer; + } + + + /** + * Returns the default SSL socket factory. + * + * @return socket factory + */ + public static SocketFactory getDefault() + { + final TLSSocketFactory sf = new TLSSocketFactory(); + try { + sf.initialize(); + } catch (GeneralSecurityException e) { + throw new IllegalArgumentException("Error initializing socket factory", e); + } + return sf; + } + + + /** + * Returns an instance of this socket factory configured with a hostname verifying trust manager. If the supplied ssl + * config does not contain trust managers, {@link HostnameVerifyingTrustManager} with {@link DefaultHostnameVerifier} + * is set. See {@link #addHostnameVerifyingTrustManager(SslConfig, String[])}. + * + * @param config to set on the socket factory + * @param names to use for hostname verification + * + * @return socket factory + */ + @SuppressWarnings("RedundantArrayCreation") + public static SSLSocketFactory getHostnameVerifierFactory(final SslConfig config, final String[] names) + { + final TLSSocketFactory sf = new TLSSocketFactory(); + if (config != null && !config.isEmpty()) { + sf.setSslConfig(SslConfig.newSslConfig(config)); + } else { + sf.setSslConfig(new SslConfig()); + } + final CertificateHostnameVerifier verifier = sf.getSslConfig().getHostnameVerifier(); + if (verifier == null) { + sf.getSslConfig().setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier(), names)); + } else { + sf.getSslConfig().setHostnameVerifierConfig(new HostnameVerifierConfig(verifier, names)); + } + try { + sf.initialize(); + } catch (GeneralSecurityException e) { + throw new IllegalArgumentException(e); + } + return sf; + } + + + /** + * Adds a {@link HostnameVerifyingTrustManager} to the supplied config if no trust managers have been configured. A + * {@link DefaultTrustManager} is also added in no {@link CredentialConfig} has been configured. + * + * @deprecated {@link HostnameVerifierConfig} should be used for hostname verification + * + * @param config to modify + * @param names of the hosts to verify + */ + @Deprecated + protected static void addHostnameVerifyingTrustManager(final SslConfig config, final String[] names) + { + if (config.getTrustManagers() == null) { + if (config.getCredentialConfig() == null) { + config.setTrustManagers( + new DefaultTrustManager(), + new HostnameVerifyingTrustManager(new DefaultHostnameVerifier(), names)); + } else { + config.setTrustManagers(new HostnameVerifyingTrustManager(new DefaultHostnameVerifier(), names)); + } + } + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::factory=%s, sslConfig=%s]", + getClass().getName(), + hashCode(), + getFactory(), + getSslConfig()); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/ThreadLocalTLSSocketFactory.java b/core/src/main/java/org/ldaptive/ssl/ThreadLocalTLSSocketFactory.java new file mode 100644 index 0000000..fc2f8ca --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/ThreadLocalTLSSocketFactory.java
@@ -0,0 +1,103 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.GeneralSecurityException; +import javax.net.SocketFactory; +import javax.net.ssl.SSLSocketFactory; + +/** + * TLSSocketFactory implementation that uses a thread local variable to store configuration. Useful for SSL + * configurations that can only retrieve the SSLSocketFactory from getDefault(). + * + * @author Middleware Services + */ +public class ThreadLocalTLSSocketFactory extends TLSSocketFactory +{ + + /** Thread local instance of the ssl config. */ + private static final ThreadLocalSslConfig THREAD_LOCAL_SSL_CONFIG = new ThreadLocalSslConfig(); + + + @Override + public SslConfig getSslConfig() + { + return THREAD_LOCAL_SSL_CONFIG.get(); + } + + + @Override + public void setSslConfig(final SslConfig config) + { + THREAD_LOCAL_SSL_CONFIG.set(config); + } + + + /** + * This returns the default SSL socket factory. + * + * @return socket factory + */ + public static SocketFactory getDefault() + { + final ThreadLocalTLSSocketFactory sf = new ThreadLocalTLSSocketFactory(); + if (sf.getSslConfig() == null) { + throw new NullPointerException("Thread local SslConfig has not been set"); + } + try { + sf.initialize(); + } catch (GeneralSecurityException e) { + throw new IllegalArgumentException("Error initializing socket factory", e); + } + return sf; + } + + + /** + * Returns an instance of this socket factory configured with a hostname verifying trust manager. If the supplied ssl + * config does not contain trust managers, {@link HostnameVerifyingTrustManager} with {@link DefaultHostnameVerifier} + * is set. See {@link #addHostnameVerifyingTrustManager(SslConfig, String[])}. + * + * @param config to set on the socket factory + * @param names to use for hostname verification + * + * @return socket factory + */ + public static SSLSocketFactory getHostnameVerifierFactory(final SslConfig config, final String[] names) + { + final ThreadLocalTLSSocketFactory sf = new ThreadLocalTLSSocketFactory(); + if (config != null && !config.isEmpty()) { + sf.setSslConfig(SslConfig.newSslConfig(config)); + } else { + sf.setSslConfig(new SslConfig()); + } + final CertificateHostnameVerifier verifier = sf.getSslConfig().getHostnameVerifier(); + if (verifier == null) { + sf.getSslConfig().setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier(), names)); + } else { + sf.getSslConfig().setHostnameVerifierConfig(new HostnameVerifierConfig(verifier, names)); + } + try { + sf.initialize(); + } catch (GeneralSecurityException e) { + throw new IllegalArgumentException(e); + } + return sf; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::factory=%s, sslConfig=%s]", + getClass().getName(), + hashCode(), + getFactory(), + getSslConfig()); + } + + + /** Thread local class for {@link SslConfig}. */ + private static class ThreadLocalSslConfig extends ThreadLocal<SslConfig> {} +}
diff --git a/core/src/main/java/org/ldaptive/ssl/X509CertificateCredentialReader.java b/core/src/main/java/org/ldaptive/ssl/X509CertificateCredentialReader.java new file mode 100644 index 0000000..6f80302 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/X509CertificateCredentialReader.java
@@ -0,0 +1,27 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.io.IOException; +import java.io.InputStream; +import java.security.GeneralSecurityException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; + +/** + * Loads an X.509 certificate credential from a classpath, filepath, or stream resource. Supported certificate formats + * include: PEM, DER, and PKCS7. + * + * @author Middleware Services + */ +public class X509CertificateCredentialReader extends AbstractCredentialReader<X509Certificate> +{ + + + @Override + public X509Certificate read(final InputStream is, final String... params) + throws IOException, GeneralSecurityException + { + final CertificateFactory cf = CertificateFactory.getInstance("X.509"); + return (X509Certificate) cf.generateCertificate(getBufferedInputStream(is)); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/X509CertificatesCredentialReader.java b/core/src/main/java/org/ldaptive/ssl/X509CertificatesCredentialReader.java new file mode 100644 index 0000000..6e1d5b2 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/X509CertificatesCredentialReader.java
@@ -0,0 +1,37 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.io.IOException; +import java.io.InputStream; +import java.security.GeneralSecurityException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + +/** + * Loads X.509 certificate credentials from a classpath, filepath, or stream resource. Supported certificate formats + * include: PEM, DER, and PKCS7. + * + * @author Middleware Services + */ +public class X509CertificatesCredentialReader extends AbstractCredentialReader<X509Certificate[]> +{ + + + @Override + public X509Certificate[] read(final InputStream is, final String... params) + throws IOException, GeneralSecurityException + { + final CertificateFactory cf = CertificateFactory.getInstance("X.509"); + final List<X509Certificate> certList = new ArrayList<>(); + final InputStream bufIs = getBufferedInputStream(is); + while (bufIs.available() > 0) { + final X509Certificate cert = (X509Certificate) cf.generateCertificate(bufIs); + if (cert != null) { + certList.add(cert); + } + } + return certList.toArray(new X509Certificate[certList.size()]); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/X509CredentialConfig.java b/core/src/main/java/org/ldaptive/ssl/X509CredentialConfig.java new file mode 100644 index 0000000..747a0f5 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/X509CredentialConfig.java
@@ -0,0 +1,162 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import org.ldaptive.LdapUtils; + +/** + * Provides the properties necessary for creating an SSL context initializer with an X.509 credential reader. + * + * @author Middleware Services + */ +public class X509CredentialConfig implements CredentialConfig +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 1009; + + /** Reads X.509 certificates credential. */ + private final X509CertificatesCredentialReader certsReader = new X509CertificatesCredentialReader(); + + /** Reads X.509 certificate credential. */ + private final X509CertificateCredentialReader certReader = new X509CertificateCredentialReader(); + + /** Reads private key credential. */ + private final PrivateKeyCredentialReader keyReader = new PrivateKeyCredentialReader(); + + /** Name of the trust certificates to use for the SSL connection. */ + private String trustCertificates; + + /** Name of the authentication certificate to use for the SSL connection. */ + private String authenticationCertificate; + + /** Name of the key to use for the SSL connection. */ + private String authenticationKey; + + + /** + * Returns the name of the trust certificates to use. + * + * @return trust certificates name + */ + public String getTrustCertificates() + { + return trustCertificates; + } + + + /** + * Sets the name of the trust certificates to use. + * + * @param name trust certificates name + */ + public void setTrustCertificates(final String name) + { + trustCertificates = name; + } + + + /** + * Returns the name of the authentication certificate to use. + * + * @return authentication certificate name + */ + public String getAuthenticationCertificate() + { + return authenticationCertificate; + } + + + /** + * Sets the name of the authentication certificate to use. + * + * @param name authentication certificate name + */ + public void setAuthenticationCertificate(final String name) + { + authenticationCertificate = name; + } + + + /** + * Returns the name of the authentication key to use. + * + * @return authentication key name + */ + public String getAuthenticationKey() + { + return authenticationKey; + } + + + /** + * Sets the name of the authentication key to use. + * + * @param name authentication key name + */ + public void setAuthenticationKey(final String name) + { + authenticationKey = name; + } + + + @Override + public SSLContextInitializer createSSLContextInitializer() + throws GeneralSecurityException + { + final X509SSLContextInitializer sslInit = new X509SSLContextInitializer(); + try { + if (trustCertificates != null) { + sslInit.setTrustCertificates(certsReader.read(trustCertificates)); + } + if (authenticationCertificate != null) { + sslInit.setAuthenticationCertificate(certReader.read(authenticationCertificate)); + } + if (authenticationKey != null) { + sslInit.setAuthenticationKey(keyReader.read(authenticationKey)); + } + } catch (IOException e) { + throw new GeneralSecurityException(e); + } + return sslInit; + } + + + @Override + public boolean equals(final Object o) + { + if (o == this) { + return true; + } + if (o instanceof X509CredentialConfig) { + final X509CredentialConfig v = (X509CredentialConfig) o; + return LdapUtils.areEqual(trustCertificates, v.trustCertificates) && + LdapUtils.areEqual(authenticationCertificate, v.authenticationCertificate) && + LdapUtils.areEqual(authenticationKey, v.authenticationKey); + } + return false; + } + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, trustCertificates, authenticationCertificate, authenticationKey); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::trustCertificates=%s, authenticationCertificate=%s, " + + "authenticationKey=%s]", + getClass().getName(), + hashCode(), + trustCertificates, + authenticationCertificate, + authenticationKey); + } +}
diff --git a/core/src/main/java/org/ldaptive/ssl/X509SSLContextInitializer.java b/core/src/main/java/org/ldaptive/ssl/X509SSLContextInitializer.java new file mode 100644 index 0000000..cf73cc4 --- /dev/null +++ b/core/src/main/java/org/ldaptive/ssl/X509SSLContextInitializer.java
@@ -0,0 +1,150 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; + +/** + * Provides an SSL context initializer which can use X.509 certificates to create key and trust managers. + * + * @author Middleware Services + */ +public class X509SSLContextInitializer extends AbstractSSLContextInitializer +{ + + /** Certificates used to create trust managers. */ + private X509Certificate[] trustCerts; + + /** Certificate used to create key managers. */ + private X509Certificate authenticationCert; + + /** Private key used to create key managers. */ + private PrivateKey authenticationKey; + + + /** + * Returns the certificates to use for creating the trust managers. + * + * @return X.509 certificates + */ + public X509Certificate[] getTrustCertificates() + { + return trustCerts; + } + + + /** + * Sets the certificates to use for creating the trust managers. + * + * @param certs X.509 certificates + */ + public void setTrustCertificates(final X509Certificate... certs) + { + trustCerts = certs; + } + + + /** + * Returns the certificate to use for creating the key managers. + * + * @return X.509 certificate + */ + public X509Certificate getAuthenticationCertificate() + { + return authenticationCert; + } + + + /** + * Sets the certificate to use for creating the key managers. + * + * @param cert X.509 certificate + */ + public void setAuthenticationCertificate(final X509Certificate cert) + { + authenticationCert = cert; + } + + + /** + * Returns the private key associated with the authentication certificate. + * + * @return private key + */ + public PrivateKey getAuthenticationKey() + { + return authenticationKey; + } + + + /** + * Sets the private key associated with the authentication certificate. + * + * @param key private key + */ + public void setAuthenticationKey(final PrivateKey key) + { + authenticationKey = key; + } + + + @Override + protected TrustManager[] createTrustManagers() + throws GeneralSecurityException + { + TrustManager[] tm = null; + if (trustCerts != null && trustCerts.length > 0) { + final KeyStore ks = KeyStoreUtils.newInstance(); + KeyStoreUtils.setCertificateEntry("ldap_trust_", ks, trustCerts); + + final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(ks); + tm = tmf.getTrustManagers(); + } + return tm; + } + + + @Override + public KeyManager[] getKeyManagers() + throws GeneralSecurityException + { + KeyManager[] km = null; + if (authenticationCert != null && authenticationKey != null) { + final KeyStore ks = KeyStoreUtils.newInstance(); + KeyStoreUtils.setKeyEntry( + "ldap_client_auth", + ks, + "changeit".toCharArray(), + authenticationKey, + authenticationCert); + + final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(ks, "changeit".toCharArray()); + km = kmf.getKeyManagers(); + } + return km; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::trustManagers=%s, hostnameVerifierConfig=%s, trustCerts=%s, authenticationCert=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(trustManagers), + hostnameVerifierConfig, + Arrays.toString(trustCerts), + authenticationCert); + } +}
diff --git a/core/src/main/resources/org/ldaptive/cli/AddOperationCli.examples b/core/src/main/resources/org/ldaptive/cli/AddOperationCli.examples new file mode 100644 index 0000000..6346fb9 --- /dev/null +++ b/core/src/main/resources/org/ldaptive/cli/AddOperationCli.examples
@@ -0,0 +1,6 @@ +- Add a new entry to an ldap directory + ldapadd -ldapUrl ldap://directory.ldaptive.org -file myentry.ldif + +- Display all the command line options available + + ldapadd -help
diff --git a/core/src/main/resources/org/ldaptive/cli/AuthenticationRequest.args b/core/src/main/resources/org/ldaptive/cli/AuthenticationRequest.args new file mode 100644 index 0000000..df576f2 --- /dev/null +++ b/core/src/main/resources/org/ldaptive/cli/AuthenticationRequest.args
@@ -0,0 +1,3 @@ +credential:to authenticate user with +returnAttributes:comma delimited list of attributes to return from the search +user:to authenticate
diff --git a/core/src/main/resources/org/ldaptive/cli/Authenticator.args b/core/src/main/resources/org/ldaptive/cli/Authenticator.args new file mode 100644 index 0000000..b4bd365 --- /dev/null +++ b/core/src/main/resources/org/ldaptive/cli/Authenticator.args
@@ -0,0 +1,5 @@ +authenticationHandler:fully qualified class name that implements org.ldaptive.auth.AuthenticationHandler +authenticationResponseHandlers:LDAP handlers for post authentication handling of responses +dnResolver:fully qualified class name that implements org.ldaptive.auth.DnResolver +entryResolver:fully qualified class name that implements org.ldaptive.auth.EntryResolver +resolveEntryOnFailure:whether to resolve the entry even if authentication fails (true|false) \ No newline at end of file
diff --git a/core/src/main/resources/org/ldaptive/cli/AuthenticatorCli.examples b/core/src/main/resources/org/ldaptive/cli/AuthenticatorCli.examples new file mode 100644 index 0000000..0dc7791 --- /dev/null +++ b/core/src/main/resources/org/ldaptive/cli/AuthenticatorCli.examples
@@ -0,0 +1,14 @@ +- Authenticate a user and return their ldap entry + + ldapauth -ldapUrl ldap://directory.ldaptive.org -baseDn dc=ldaptive,dc=org \ + -useStartTLS true -userFilter uupid={user} + +- Authenticate a user and return their mail attribute in dsmlv1 format + + ldapauth -ldapUrl ldap://directory.ldaptive.org -baseDn dc=ldaptive,dc=org \ + -useStartTLS true -dsmlv1 \ + -userFilter uupid={user} -returnAttributes mail + +- Display all the command line options available + + ldapauth -help
diff --git a/core/src/main/resources/org/ldaptive/cli/CompareOperationCli.examples b/core/src/main/resources/org/ldaptive/cli/CompareOperationCli.examples new file mode 100644 index 0000000..b627b40 --- /dev/null +++ b/core/src/main/resources/org/ldaptive/cli/CompareOperationCli.examples
@@ -0,0 +1,7 @@ +- Compare an attribute on an entry from an ldap directory + ldapcompare -ldapUrl ldap://directory.ldaptive.org \ + -dn uid=dfisher,ou=people,dc=ldaptive,dc=org -attribute uid:dfisher + +- Display all the command line options available + + ldapcompare -help
diff --git a/core/src/main/resources/org/ldaptive/cli/ConnectionConfig.args b/core/src/main/resources/org/ldaptive/cli/ConnectionConfig.args new file mode 100644 index 0000000..876bc43 --- /dev/null +++ b/core/src/main/resources/org/ldaptive/cli/ConnectionConfig.args
@@ -0,0 +1,12 @@ +bindControls:fully qualified class name(s) that implements org.ldaptive.control.Control +bindCredential:password for the bindDn +bindDn:fully qualified dn to bind as +bindSaslConfig:SASL configuration data +connectionInitializer:fully qualified class name that implements org.ldaptive.ConnectionInitializer +connectionStrategy:fully qualified class name that implements org.ldaptive.ConnectionStrategy +connectTimeout:milliseconds to wait for connections +ldapUrl:URL that identifies the LDAP server to search +responseTimeout:milliseconds to wait for LDAP operation responses +sslConfig:SSL configuration data +useSSL:whether to use SSL (true|false) +useStartTLS:whether to use startTLS (true|false)
diff --git a/core/src/main/resources/org/ldaptive/cli/DeleteOperationCli.examples b/core/src/main/resources/org/ldaptive/cli/DeleteOperationCli.examples new file mode 100644 index 0000000..3766762 --- /dev/null +++ b/core/src/main/resources/org/ldaptive/cli/DeleteOperationCli.examples
@@ -0,0 +1,7 @@ +- Delete an entry from an ldap directory + ldapdelete -ldapUrl ldap://directory.ldaptive.org \ + -dn uid=dfisher,ou=people,dc=ldaptive,dc=org + +- Display all the command line options available + + ldapdelete -help
diff --git a/core/src/main/resources/org/ldaptive/cli/SearchDnResolver.args b/core/src/main/resources/org/ldaptive/cli/SearchDnResolver.args new file mode 100644 index 0000000..e48e423 --- /dev/null +++ b/core/src/main/resources/org/ldaptive/cli/SearchDnResolver.args
@@ -0,0 +1,8 @@ +allowMultipleDns:whether finding multiple DNs should throw an exception (true|false) +baseDn:base dn +connectionFactory:fully qualified class name that implements org.ldaptive.ConnectionFactory +derefAliases:how to handle aliases (NEVER|SEARCHING|FINDING|ALWAYS) +followReferrals:how to handle referrals (true|false) +subtreeSearch:whether to search for the user using a subtree search (true|false) +userFilter:LDAP filter to search for the user +userFilterParameters:LDAP filter parameters to apply to the userFilter
diff --git a/core/src/main/resources/org/ldaptive/cli/SearchOperationCli.examples b/core/src/main/resources/org/ldaptive/cli/SearchOperationCli.examples new file mode 100644 index 0000000..0bd34f3 --- /dev/null +++ b/core/src/main/resources/org/ldaptive/cli/SearchOperationCli.examples
@@ -0,0 +1,19 @@ +- Search an ldap directory returning the mail attribute in ldif format + + ldapsearch -ldapUrl ldap://directory.ldaptive.org -baseDn dc=ldaptive,dc=org \ + -searchFilter uid=dfisher -returnAttributes mail + +- Search a ldap directory returning all attributes in dsmlv1 format + + ldapsearch -ldapUrl ldap://directory.ldaptive.org -baseDn dc=ldaptive,dc=org \ + -dsmlv1 -searchFilter uid=dfisher + +- Search a ldap directory as an authenticated user returning all attributes in dsmlv1 format + + ldapsearch -ldapUrl ldap://directory.ldaptive.org -baseDn dc=ldaptive,dc=org \ + -bindDn cn=manager,ou=people,dc=ldaptive,dc=org -useStartTLS true \ + -dsmlv1 -searchFilter uid=dfisher + +- Display all the command line options available + + ldapsearch -help
diff --git a/core/src/main/resources/org/ldaptive/cli/SearchRequest.args b/core/src/main/resources/org/ldaptive/cli/SearchRequest.args new file mode 100644 index 0000000..02e521f --- /dev/null +++ b/core/src/main/resources/org/ldaptive/cli/SearchRequest.args
@@ -0,0 +1,15 @@ +baseDn:base dn +binaryAttributes:comma delimited list of binary attributes +controls:fully qualified class name(s) that implements org.ldaptive.control.Control +derefAliases:how to handle aliases (NEVER|SEARCHING|FINDING|ALWAYS) +referralHandler:LDAP handler for referrals +intermediateResponseHandlers:LDAP handlers for intermediate responses +returnAttributes:comma delimited list of attributes to return from the search +searchEntryHandlers:LDAP handlers for post search processing of result entries +searchFilter:LDAP filter to execute +searchReferenceHandlers:LDAP handlers for result references +searchScope:scope of the search (OBJECT|ONELEVEL|SUBTREE) +sizeLimit:maximum number of entries to return +sortBehavior:how search results should be sorted +timeLimit:amount of time in milliseconds that search operations will block +typesOnly:whether to return only attribute types (true|false)
diff --git a/core/src/main/resources/org/ldaptive/cli/SslConfig.args b/core/src/main/resources/org/ldaptive/cli/SslConfig.args new file mode 100644 index 0000000..c80c932 --- /dev/null +++ b/core/src/main/resources/org/ldaptive/cli/SslConfig.args
@@ -0,0 +1,5 @@ +credentialConfig:fully qualified class name that implements org.ldaptive.ssl.CredentialConfig +enabledCipherSuites:comma delimited list of SSL cipher suites to use +enabledProtocols:comma delimited list of SSL protocol versions to use +handshakeCompletedListeners:fully qualified class name(s) that implements javax.net.ssl.HandshakeCompletedListener +trustManagers:fully qualified class name(s) that implements javax.net.ssl.TrustManager
diff --git a/core/src/test/java/org/ldaptive/ActivePassiveConnectionStrategyTest.java b/core/src/test/java/org/ldaptive/ActivePassiveConnectionStrategyTest.java new file mode 100644 index 0000000..5b3d52d --- /dev/null +++ b/core/src/test/java/org/ldaptive/ActivePassiveConnectionStrategyTest.java
@@ -0,0 +1,72 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link ActivePassiveConnectionStrategy}. + * + * @author Middleware Services + */ +public class ActivePassiveConnectionStrategyTest +{ + + /** Strategy to test. */ + private final ActivePassiveConnectionStrategy strategy = new ActivePassiveConnectionStrategy(); + + + /** + * URL test data. + * + * @return test data + */ + @DataProvider(name = "urls") + public Object[][] createURLs() + { + return + new Object[][] { + new Object[] { + new TestConnectionFactoryMetadata(), + null, + }, + new Object[] { + new TestConnectionFactoryMetadata("ldap://directory.ldaptive.org"), + new String[] {"ldap://directory.ldaptive.org"}, + }, + new Object[] { + new TestConnectionFactoryMetadata("ldap://directory-1.ldaptive.org ldap://directory-2.ldaptive.org"), + new String[] { + "ldap://directory-1.ldaptive.org", + "ldap://directory-2.ldaptive.org", + }, + }, + new Object[] { + new TestConnectionFactoryMetadata( + "ldap://directory-1.ldaptive.org ldap://directory-2.ldaptive.org " + + "ldap://directory-3.ldaptive.org", + 3), + new String[] { + "ldap://directory-1.ldaptive.org", + "ldap://directory-2.ldaptive.org", + "ldap://directory-3.ldaptive.org", + }, + }, + }; + } + + + /** + * @param metadata to get ldap urls from + * @param urls to compare + * + * @throws Exception On test failure. + */ + @Test(groups = {"provider"}, dataProvider = "urls") + public void getLdapUrls(final ConnectionFactoryMetadata metadata, final String[] urls) + throws Exception + { + Assert.assertEquals(strategy.getLdapUrls(metadata), urls); + } +}
diff --git a/core/src/test/java/org/ldaptive/CompareRequestTest.java b/core/src/test/java/org/ldaptive/CompareRequestTest.java new file mode 100644 index 0000000..865c3d2 --- /dev/null +++ b/core/src/test/java/org/ldaptive/CompareRequestTest.java
@@ -0,0 +1,55 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link CompareRequest}. + * + * @author Middleware Services + */ +public class CompareRequestTest +{ + + + /** + * Request test data. + * + * @return test data + */ + @DataProvider(name = "requests") + public Object[][] createRequests() + { + return + new Object[][] { + new Object[] { + new CompareRequest(null, null), "attribute=null", + }, + new Object[] { + new CompareRequest(null, new LdapAttribute()), "attribute=[null[]]", + }, + new Object[] { + new CompareRequest(null, new LdapAttribute("name", "value")), "attribute=[name[value]]", + }, + new Object[] { + new CompareRequest(null, new LdapAttribute("userPassword", "password")), "attribute=<suppressed>", + }, + }; + } + + + /** + * @param request containing properties + * @param string to compare + * + * @throws Exception On test failure. + */ + @Test(groups = {"compare"}, dataProvider = "requests") + public void testToString(final CompareRequest request, final String string) + throws Exception + { + Assert.assertEquals(request.toString().split(",")[1].trim(), string); + } +}
diff --git a/core/src/test/java/org/ldaptive/ConfigTest.java b/core/src/test/java/org/ldaptive/ConfigTest.java new file mode 100644 index 0000000..a6eed92 --- /dev/null +++ b/core/src/test/java/org/ldaptive/ConfigTest.java
@@ -0,0 +1,87 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import org.ldaptive.pool.PoolConfig; +import org.ldaptive.provider.ProviderConfig; +import org.ldaptive.sasl.SaslConfig; +import org.ldaptive.ssl.SocketConfig; +import org.ldaptive.ssl.SslConfig; +import org.testng.Assert; +import org.testng.AssertJUnit; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit tests for objects that extends {@link AbstractConfig}. + * + * @author Middleware Services + */ +public class ConfigTest +{ + + /** Map of default primitive type values. */ + private static final Map<Class<?>, Object> PRIMITIVE_TYPES = new HashMap<>(); + + /** + * Initialize primitive type values. + */ + static { + PRIMITIVE_TYPES.put(int.class, 0); + PRIMITIVE_TYPES.put(long.class, 0); + PRIMITIVE_TYPES.put(boolean.class, false); + } + + + /** + * Config test data. + * + * @return test data + */ + @DataProvider(name = "configs") + public Object[][] createConfigs() + { + return + new Object[][] { + new Object[] {new ConnectionConfig(), }, + new Object[] {new PoolConfig(), }, + new Object[] {new ProviderConfig(), }, + new Object[] {new SaslConfig(), }, + new Object[] {new SslConfig(), }, + new Object[] {new SocketConfig(), }, + }; + } + + + /** + * @param config to test + * + * @throws Exception On test failure. + */ + @Test(groups = {"config"}, dataProvider = "configs") + public void testImmutable( + // CheckStyle:IllegalType OFF + final AbstractConfig config) + // CheckStyle:IllegalType ON + throws Exception + { + config.makeImmutable(); + for (Method method : config.getClass().getMethods()) { + if (method.getName().startsWith("set") && method.getParameterTypes().length == 1) { + try { + final Class<?> type = method.getParameterTypes()[0]; + if (type.isPrimitive()) { + method.invoke(config, PRIMITIVE_TYPES.get(type)); + } else { + method.invoke(config, new Object[] {null}); + } + Assert.fail("Should have thrown IllegalStateException for " + method); + } catch (Exception e) { + AssertJUnit.assertEquals(IllegalStateException.class, e.getCause().getClass()); + } + } + } + } +}
diff --git a/core/src/test/java/org/ldaptive/DefaultConnectionStrategyTest.java b/core/src/test/java/org/ldaptive/DefaultConnectionStrategyTest.java new file mode 100644 index 0000000..98272db --- /dev/null +++ b/core/src/test/java/org/ldaptive/DefaultConnectionStrategyTest.java
@@ -0,0 +1,68 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link DefaultConnectionStrategy}. + * + * @author Middleware Services + */ +public class DefaultConnectionStrategyTest +{ + + /** Strategy to test. */ + private final DefaultConnectionStrategy strategy = new DefaultConnectionStrategy(); + + + /** + * URL test data. + * + * @return test data + */ + @DataProvider(name = "urls") + public Object[][] createURLs() + { + return + new Object[][] { + new Object[] { + new TestConnectionFactoryMetadata(), + null, + }, + new Object[] { + new TestConnectionFactoryMetadata("ldap://directory.ldaptive.org"), + new String[] {"ldap://directory.ldaptive.org"}, + }, + new Object[] { + new TestConnectionFactoryMetadata("ldap://directory-1.ldaptive.org ldap://directory-2.ldaptive.org"), + new String[] {"ldap://directory-1.ldaptive.org ldap://directory-2.ldaptive.org", }, + }, + new Object[] { + new TestConnectionFactoryMetadata( + "ldap://directory-1.ldaptive.org ldap://directory-2.ldaptive.org " + + "ldap://directory-3.ldaptive.org", + 3), + new String[] { + "ldap://directory-1.ldaptive.org ldap://directory-2.ldaptive.org " + + "ldap://directory-3.ldaptive.org", + }, + }, + }; + } + + + /** + * @param metadata to get ldap urls from + * @param urls to compare + * + * @throws Exception On test failure. + */ + @Test(groups = {"provider"}, dataProvider = "urls") + public void getLdapUrls(final ConnectionFactoryMetadata metadata, final String[] urls) + throws Exception + { + Assert.assertEquals(strategy.getLdapUrls(metadata), urls); + } +}
diff --git a/core/src/test/java/org/ldaptive/DnParserTest.java b/core/src/test/java/org/ldaptive/DnParserTest.java new file mode 100644 index 0000000..da68a98 --- /dev/null +++ b/core/src/test/java/org/ldaptive/DnParserTest.java
@@ -0,0 +1,258 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link DnParser}. + * + * @author Middleware Services + */ +public class DnParserTest +{ + + + /** + * DN test data. + * + * @return test data + */ + @DataProvider(name = "DNs") + public Object[][] createDNs() + { + return + new Object[][] { + /* single value DN */ + new Object[] { + "UID=jsmith", + "uid", + "jsmith", + }, + /* multi value DN */ + new Object[] { + "UID=jsmith,DC=ldaptive,DC=org", + "uid", + "jsmith", + }, + /* whitespace */ + new Object[] { + " UID = jsmith ,DC=ldaptive,DC=org", + "Uid", + "jsmith", + }, + /* case sensitivity */ + new Object[] { + "CN=Jim Smith,UID=jsmith,DC=ldaptive,DC=org", + "UId", + "jsmith", + }, + /* multi value RDN */ + new Object[] { + "OU=Sales+CN=J. Smith,DC=ldaptive,DC=org", + "ou", + "Sales", + }, + new Object[] { + "OU=Sales+CN=J. Smith,DC=ldaptive,DC=org", + "cn", + "J. Smith", + }, + /* escaped data */ + new Object[] { + "CN=James \"Jim\" Smith\\, III,DC=ldaptive,DC=org", + "CN", + "James \"Jim\" Smith, III", + }, + new Object[] { + "OU=Sales\\; Data\\+Algorithms,DC=ldaptive,DC=org", + "OU", + "Sales; Data+Algorithms", + }, + /* encoded data */ + new Object[] { + "CN=\\23John Smith\\20,DC=ldaptive,DC=org", + "CN", + "#John Smith ", + }, + new Object[] { + "CN=Lu\\C4\\8Di\\C4\\87", + "cn", + "Lučić", + }, + new Object[] { + "CN=Lu\\C4\\8D\\C4\\8Di\\C4\\87", + "cn", + "Luččić", + }, + new Object[] { + "CN=Lu\\C4\\8D\\C4\\8Di\\C4\\87o", + "cn", + "Luččićo", + }, + new Object[] { + "CN=\\C4\\87Lu\\C4\\8D\\C4\\8Di\\C4\\87o", + "cn", + "ćLuččićo", + }, + new Object[] { + "1.3.6.1.4.1.1466.0=#04024869,DC=ldaptive,DC=org", + "1.3.6.1.4.1.1466.0", + "Hi", + }, + new Object[] { + "0.9.2342.19200300.100.1.1=#04066A736D697468,DC=ldaptive,DC=org", + "0.9.2342.19200300.100.1.1", + "jsmith", + }, + /* invalid DNs, but can be parsed */ + new Object[] { + "UID=jsmith,,DC=ldaptive,DC=org", + ",dc", + "ldaptive", + }, + new Object[] { + "UID=john\\?smith", + "uid", + "john?smith", + }, + new Object[] { + "UID=john\\GGsmith", + "uid", + "johnGGsmith", + }, + new Object[] { + "UID=john\\", + "uid", + "john", + }, + }; + } + + + /** + * DN test data. + * + * @return test data + */ + @DataProvider(name = "invalidDNs") + public Object[][] createInvalidDNs() + { + return + new Object[][] { + /* invalid hex */ + new Object[] {"1.1.1=#GG", }, + new Object[] {"1.1.1=#000", }, + new Object[] {"1.1.1=#F", }, + new Object[] {"1.1.1=#", }, + /* unescaped characters*/ + new Object[] {"UID=john,smith", }, + new Object[] {"UID=john+smith", }, + new Object[] {"UID=john\\Fsmith", }, + /* missing equals */ + new Object[] {"UID", }, + new Object[] {"UID:jsmith", }, + /* missing value */ + new Object[] {"UID=", }, + new Object[] {"UID = ", }, + }; + } + + + /** + * @param dn to parse + * @param name of an attribute to test + * @param value of an attribute to test + * + * @throws Exception On test failure. + */ + @Test(groups = {"dnParser"}, dataProvider = "DNs") + public void testParsing(final String dn, final String name, final String value) + throws Exception + { + Assert.assertEquals(DnParser.getValue(dn, name), value); + } + + + /** + * @param dn to parse + * + * @throws Exception On test failure. + */ + @Test(groups = {"dnParser"}, dataProvider = "invalidDNs") + public void testInvalidParsing(final String dn) + throws Exception + { + try { + DnParser.getValue(dn, ""); + Assert.fail("Should have thrown IllegalArgumentException"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), IllegalArgumentException.class); + } + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"dnParser"}) + public void testSubstring() + throws Exception + { + final String dn = "CN=Jim Smith,UID=jsmith,DC=ldaptive,DC=org"; + try { + DnParser.substring(dn, -1); + Assert.fail("Should have thrown IndexOutOfBoundsException"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), IndexOutOfBoundsException.class); + } + Assert.assertEquals(DnParser.substring(dn, 0), "CN=Jim Smith,UID=jsmith,DC=ldaptive,DC=org"); + Assert.assertEquals(DnParser.substring(dn, 1), "UID=jsmith,DC=ldaptive,DC=org"); + Assert.assertEquals(DnParser.substring(dn, 2), "DC=ldaptive,DC=org"); + Assert.assertEquals(DnParser.substring(dn, 3), "DC=org"); + try { + DnParser.substring(dn, 4); + Assert.fail("Should have thrown IndexOutOfBoundsException"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), IndexOutOfBoundsException.class); + } + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"dnParser"}) + public void testSubstringEndIndex() + throws Exception + { + final String dn = "CN=Jim Smith,UID=jsmith,DC=ldaptive,DC=org"; + try { + DnParser.substring(dn, -1, 0); + Assert.fail("Should have thrown IndexOutOfBoundsException"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), IndexOutOfBoundsException.class); + } + try { + DnParser.substring(dn, 2, 1); + Assert.fail("Should have thrown IndexOutOfBoundsException"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), IndexOutOfBoundsException.class); + } + Assert.assertEquals(DnParser.substring(dn, 0, 4), "CN=Jim Smith,UID=jsmith,DC=ldaptive,DC=org"); + Assert.assertEquals(DnParser.substring(dn, 1, 4), "UID=jsmith,DC=ldaptive,DC=org"); + Assert.assertEquals(DnParser.substring(dn, 2, 4), "DC=ldaptive,DC=org"); + Assert.assertEquals(DnParser.substring(dn, 3, 4), "DC=org"); + + Assert.assertEquals(DnParser.substring(dn, 0, 1), "CN=Jim Smith"); + Assert.assertEquals(DnParser.substring(dn, 1, 2), "UID=jsmith"); + Assert.assertEquals(DnParser.substring(dn, 2, 3), "DC=ldaptive"); + Assert.assertEquals(DnParser.substring(dn, 3, 4), "DC=org"); + + Assert.assertEquals(DnParser.substring(dn, 0, 2), "CN=Jim Smith,UID=jsmith"); + Assert.assertEquals(DnParser.substring(dn, 2, 4), "DC=ldaptive,DC=org"); + try { + DnParser.substring(dn, 1, 5); + Assert.fail("Should have thrown IndexOutOfBoundsException"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), IndexOutOfBoundsException.class); + } + } +}
diff --git a/core/src/test/java/org/ldaptive/DnsSrvConnectionStrategyTest.java b/core/src/test/java/org/ldaptive/DnsSrvConnectionStrategyTest.java new file mode 100644 index 0000000..f4ee1ea --- /dev/null +++ b/core/src/test/java/org/ldaptive/DnsSrvConnectionStrategyTest.java
@@ -0,0 +1,75 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Arrays; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link DnsSrvConnectionStrategy}. + * + * @author Middleware Services + */ +public class DnsSrvConnectionStrategyTest +{ + + /** Strategy to test. */ + private final DnsSrvConnectionStrategy strategy = new DnsSrvConnectionStrategy(); + + + /** + * DNS test data. + * + * @return test data + */ + @DataProvider(name = "records") + public Object[][] createRecords() + { + return + new Object[][] { + new Object[] { + new DnsSrvConnectionStrategy.SrvRecord[] { + new DnsSrvConnectionStrategy.SrvRecord("0 0 389 larry.ldaptive.org.", 0), + new DnsSrvConnectionStrategy.SrvRecord("0 0 389 curly.ldaptive.org.", 0), + new DnsSrvConnectionStrategy.SrvRecord("0 0 389 moe.ldaptive.org.", 0), + }, + new DnsSrvConnectionStrategy.SrvRecord[] { + new DnsSrvConnectionStrategy.SrvRecord("0 0 389 larry.ldaptive.org.", 0), + new DnsSrvConnectionStrategy.SrvRecord("0 0 389 curly.ldaptive.org.", 0), + new DnsSrvConnectionStrategy.SrvRecord("0 0 389 moe.ldaptive.org.", 0), + }, + }, + new Object[] { + new DnsSrvConnectionStrategy.SrvRecord[] { + new DnsSrvConnectionStrategy.SrvRecord("5 100 389 larry.ldaptive.org.", 0), + new DnsSrvConnectionStrategy.SrvRecord("1 0 389 curly.ldaptive.org.", 0), + new DnsSrvConnectionStrategy.SrvRecord("3 200 389 moe.ldaptive.org.", 0), + }, + new DnsSrvConnectionStrategy.SrvRecord[] { + new DnsSrvConnectionStrategy.SrvRecord("1 0 389 curly.ldaptive.org.", 0), + new DnsSrvConnectionStrategy.SrvRecord("3 200 389 moe.ldaptive.org.", 0), + new DnsSrvConnectionStrategy.SrvRecord("5 100 389 larry.ldaptive.org.", 0), + }, + }, + }; + } + + + /** + * @param records to sort + * @param sorted to compare + * + * @throws Exception On test failure. + */ + @Test(groups = {"provider"}, dataProvider = "records") + public void sortSrvRecords( + final DnsSrvConnectionStrategy.SrvRecord[] records, + final DnsSrvConnectionStrategy.SrvRecord[] sorted) + throws Exception + { + Assert.assertEquals( + strategy.sortSrvRecords(Arrays.asList(records)).toArray(new DnsSrvConnectionStrategy.SrvRecord[records.length]), + sorted); + } +}
diff --git a/core/src/test/java/org/ldaptive/LdapAttributeTest.java b/core/src/test/java/org/ldaptive/LdapAttributeTest.java new file mode 100644 index 0000000..c106c82 --- /dev/null +++ b/core/src/test/java/org/ldaptive/LdapAttributeTest.java
@@ -0,0 +1,304 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.testng.AssertJUnit; +import org.testng.annotations.Test; + +/** + * Unit test for {@link LdapAttribute}. + * + * @author Middleware Services + */ +public class LdapAttributeTest +{ + + + /** Tests default sort behavior. */ + @Test(groups = {"bean"}) + public void defaultSortBehavior() + { + final LdapAttribute la = new LdapAttribute("givenName"); + AssertJUnit.assertEquals(SortBehavior.getDefaultSortBehavior(), la.getSortBehavior()); + AssertJUnit.assertEquals(0, la.size()); + AssertJUnit.assertNull(la.getStringValue()); + AssertJUnit.assertNull(la.getBinaryValue()); + AssertJUnit.assertEquals("givenName", la.getName()); + la.setName("sn"); + AssertJUnit.assertEquals("sn", la.getName()); + la.clear(); + AssertJUnit.assertEquals(0, la.size()); + } + + + /** Tests ordered sort behavior. */ + @Test(groups = {"bean"}) + public void orderedSortBehavior() + { + final LdapAttribute la = new LdapAttribute(SortBehavior.ORDERED); + AssertJUnit.assertEquals(SortBehavior.ORDERED, la.getSortBehavior()); + la.addStringValue("William", "Bill"); + + final String[] values = la.getStringValues().toArray(new String[2]); + AssertJUnit.assertEquals("William", values[0]); + AssertJUnit.assertEquals("Bill", values[1]); + la.clear(); + AssertJUnit.assertEquals(0, la.size()); + } + + + /** Tests sorted sort behavior. */ + @Test(groups = {"bean"}) + public void sortedSortBehavior() + { + final LdapAttribute la = new LdapAttribute(SortBehavior.SORTED); + AssertJUnit.assertEquals(SortBehavior.SORTED, la.getSortBehavior()); + la.addStringValue("William", "Bill"); + + final String[] values = la.getStringValues().toArray(new String[2]); + AssertJUnit.assertEquals("Bill", values[0]); + AssertJUnit.assertEquals("William", values[1]); + la.clear(); + AssertJUnit.assertEquals(0, la.size()); + } + + + /** Tests create with one value. */ + @Test(groups = {"bean"}) + public void createOne() + { + final LdapAttribute la = new LdapAttribute("givenName", "William"); + AssertJUnit.assertEquals("William", la.getStringValue()); + AssertJUnit.assertEquals(1, la.getStringValues().size()); + AssertJUnit.assertEquals("William", la.getStringValues().iterator().next()); + AssertJUnit.assertTrue(Arrays.equals("William".getBytes(), la.getBinaryValue())); + AssertJUnit.assertEquals(1, la.size()); + AssertJUnit.assertEquals(la, new LdapAttribute("givenName", "William")); + try { + la.addStringValue((String) null); + AssertJUnit.fail("Should have thrown IllegalArgumentException"); + } catch (Exception e) { + AssertJUnit.assertEquals(IllegalArgumentException.class, e.getClass()); + } + try { + la.addBinaryValue("Bill".getBytes()); + AssertJUnit.fail("Should have thrown IllegalArgumentException"); + } catch (Exception e) { + AssertJUnit.assertEquals(IllegalArgumentException.class, e.getClass()); + } + la.clear(); + AssertJUnit.assertEquals(0, la.size()); + } + + + /** Tests create with two values. */ + @Test(groups = {"bean"}) + public void createTwo() + { + final LdapAttribute la = new LdapAttribute("givenName", "Bill", "William"); + AssertJUnit.assertEquals(2, la.getStringValues().size()); + AssertJUnit.assertEquals(2, la.size()); + AssertJUnit.assertEquals(la, new LdapAttribute("givenName", "William", "Bill")); + la.removeStringValue("William"); + AssertJUnit.assertEquals(1, la.size()); + la.clear(); + AssertJUnit.assertEquals(0, la.size()); + } + + + /** Tests various string input. */ + @Test(groups = {"bean"}) + public void stringValue() + { + final LdapAttribute la = new LdapAttribute("cn", "William Wallace"); + AssertJUnit.assertEquals("William Wallace", la.getStringValue()); + AssertJUnit.assertEquals("William Wallace".getBytes(StandardCharsets.UTF_8), la.getBinaryValue()); + AssertJUnit.assertEquals(1, la.getStringValues().size()); + AssertJUnit.assertEquals(1, la.getBinaryValues().size()); + AssertJUnit.assertEquals(la, new LdapAttribute("cn", "William Wallace")); + try { + la.addStringValue((String[]) null); + AssertJUnit.fail("Should have thrown NullPointerException"); + } catch (Exception e) { + AssertJUnit.assertEquals(NullPointerException.class, e.getClass()); + } + try { + la.addBinaryValue("Bill".getBytes()); + AssertJUnit.fail("Should have thrown IllegalArgumentException"); + } catch (Exception e) { + AssertJUnit.assertEquals(IllegalArgumentException.class, e.getClass()); + } + la.clear(); + AssertJUnit.assertEquals(0, la.size()); + } + + + /** Tests multiple string input. */ + @Test(groups = {"bean"}) + public void stringValues() + { + final List<String> commonNames = new ArrayList<>(); + commonNames.add("Bill Wallace"); + commonNames.add("William Wallace"); + + final List<byte[]> binaryCommonNames = new ArrayList<>(); + binaryCommonNames.add("Bill Wallace".getBytes(StandardCharsets.UTF_8)); + binaryCommonNames.add("William Wallace".getBytes(StandardCharsets.UTF_8)); + + LdapAttribute la = new LdapAttribute(SortBehavior.UNORDERED); + la.setName("cn"); + la.addStringValue(commonNames.get(0)); + la.addStringValue(commonNames.get(1)); + AssertJUnit.assertNotNull(la.getStringValue()); + AssertJUnit.assertNotNull(la.getStringValues()); + AssertJUnit.assertEquals(2, la.getStringValues().size()); + AssertJUnit.assertNotNull(la.getBinaryValue()); + AssertJUnit.assertNotNull(la.getBinaryValues()); + AssertJUnit.assertEquals(2, la.getBinaryValues().size()); + la.clear(); + AssertJUnit.assertEquals(0, la.size()); + + la = new LdapAttribute(SortBehavior.ORDERED); + la.setName("cn"); + la.addStringValue(commonNames.get(0)); + la.addStringValue(commonNames.get(1)); + AssertJUnit.assertEquals("Bill Wallace", la.getStringValue()); + AssertJUnit.assertArrayEquals(commonNames.toArray(new String[2]), la.getStringValues().toArray(new String[2])); + AssertJUnit.assertEquals(2, la.getStringValues().size()); + AssertJUnit.assertEquals("Bill Wallace".getBytes(StandardCharsets.UTF_8), la.getBinaryValue()); + AssertJUnit.assertArrayEquals( + binaryCommonNames.toArray(new byte[2][0]), + la.getBinaryValues().toArray(new byte[2][0])); + AssertJUnit.assertEquals(2, la.getBinaryValues().size()); + la.clear(); + AssertJUnit.assertEquals(0, la.size()); + + la = new LdapAttribute(SortBehavior.SORTED); + la.setName("cn"); + la.addStringValue(commonNames.get(0)); + la.addStringValue(commonNames.get(1)); + AssertJUnit.assertEquals("Bill Wallace", la.getStringValue()); + AssertJUnit.assertArrayEquals(commonNames.toArray(new String[2]), la.getStringValues().toArray(new String[2])); + AssertJUnit.assertEquals(2, la.getStringValues().size()); + AssertJUnit.assertEquals("Bill Wallace".getBytes(StandardCharsets.UTF_8), la.getBinaryValue()); + AssertJUnit.assertArrayEquals( + binaryCommonNames.toArray(new byte[2][0]), + la.getBinaryValues().toArray(new byte[2][0])); + AssertJUnit.assertEquals(2, la.getBinaryValues().size()); + la.clear(); + AssertJUnit.assertEquals(0, la.size()); + } + + + /** Tests various binary input. */ + @Test(groups = {"bean"}) + public void binaryValue() + { + final LdapAttribute la = new LdapAttribute("jpegPhoto", "image".getBytes()); + AssertJUnit.assertTrue(Arrays.equals("image".getBytes(), la.getBinaryValue())); + AssertJUnit.assertEquals(1, la.getBinaryValues().size()); + AssertJUnit.assertEquals("aW1hZ2U=", la.getStringValue()); + AssertJUnit.assertEquals(1, la.getStringValues().size()); + AssertJUnit.assertEquals(la, new LdapAttribute("jpegPhoto", "image".getBytes())); + try { + la.addBinaryValue((byte[][]) null); + AssertJUnit.fail("Should have thrown NullPointerException"); + } catch (Exception e) { + AssertJUnit.assertEquals(NullPointerException.class, e.getClass()); + } + try { + la.addStringValue("Bill"); + AssertJUnit.fail("Should have thrown IllegalArgumentException"); + } catch (Exception e) { + AssertJUnit.assertEquals(IllegalArgumentException.class, e.getClass()); + } + la.clear(); + AssertJUnit.assertEquals(0, la.size()); + } + + + /** Tests multiple string input. */ + @Test(groups = {"bean"}) + public void binaryValues() + { + final List<byte[]> jpegPhotos = new ArrayList<>(); + jpegPhotos.add("image1".getBytes()); + jpegPhotos.add("image2".getBytes()); + + final List<String> stringJpegPhotos = new ArrayList<>(); + stringJpegPhotos.add("aW1hZ2Ux"); + stringJpegPhotos.add("aW1hZ2Uy"); + + LdapAttribute la = new LdapAttribute(SortBehavior.UNORDERED, true); + la.setName("jpegPhoto"); + la.addBinaryValue(jpegPhotos.get(0)); + la.addBinaryValue(jpegPhotos.get(1)); + AssertJUnit.assertNotNull(la.getStringValue()); + AssertJUnit.assertNotNull(la.getStringValues()); + AssertJUnit.assertEquals(2, la.getStringValues().size()); + AssertJUnit.assertNotNull(la.getBinaryValue()); + AssertJUnit.assertNotNull(la.getBinaryValues()); + AssertJUnit.assertEquals(2, la.getBinaryValues().size()); + la.clear(); + AssertJUnit.assertEquals(0, la.size()); + + la = new LdapAttribute(SortBehavior.ORDERED, true); + la.setName("jpegPhoto"); + la.addBinaryValue(jpegPhotos.get(0)); + la.addBinaryValue(jpegPhotos.get(1)); + AssertJUnit.assertEquals("aW1hZ2Ux", la.getStringValue()); + AssertJUnit.assertArrayEquals(stringJpegPhotos.toArray(new String[2]), la.getStringValues().toArray(new String[2])); + AssertJUnit.assertEquals(2, la.getStringValues().size()); + AssertJUnit.assertEquals("image1".getBytes(), la.getBinaryValue()); + AssertJUnit.assertArrayEquals(jpegPhotos.toArray(new byte[2][0]), la.getBinaryValues().toArray(new byte[2][0])); + AssertJUnit.assertEquals(2, la.getBinaryValues().size()); + la.clear(); + AssertJUnit.assertEquals(0, la.size()); + + la = new LdapAttribute(SortBehavior.SORTED, true); + la.setName("jpegPhoto"); + la.addBinaryValue(jpegPhotos.get(0)); + la.addBinaryValue(jpegPhotos.get(1)); + AssertJUnit.assertEquals("aW1hZ2Ux", la.getStringValue()); + AssertJUnit.assertArrayEquals(stringJpegPhotos.toArray(new String[2]), la.getStringValues().toArray(new String[2])); + AssertJUnit.assertEquals(2, la.getStringValues().size()); + AssertJUnit.assertEquals("image1".getBytes(), la.getBinaryValue()); + AssertJUnit.assertArrayEquals(jpegPhotos.toArray(new byte[2][0]), la.getBinaryValues().toArray(new byte[2][0])); + AssertJUnit.assertEquals(2, la.getBinaryValues().size()); + la.clear(); + AssertJUnit.assertEquals(0, la.size()); + } + + + /** Tests attribute options. */ + @Test(groups = {"bean"}) + public void attributeOptions() + { + LdapAttribute la = new LdapAttribute("cn", "William Wallace"); + AssertJUnit.assertEquals("cn", la.getName()); + AssertJUnit.assertEquals("cn", la.getName(true)); + AssertJUnit.assertEquals("cn", la.getName(false)); + AssertJUnit.assertNotNull(la.getOptions()); + AssertJUnit.assertEquals(0, la.getOptions().length); + + la = new LdapAttribute("cn;lang-ru", "Уильям Уоллес"); + AssertJUnit.assertEquals("cn;lang-ru", la.getName()); + AssertJUnit.assertEquals("cn;lang-ru", la.getName(true)); + AssertJUnit.assertEquals("cn", la.getName(false)); + AssertJUnit.assertNotNull(la.getOptions()); + AssertJUnit.assertEquals(1, la.getOptions().length); + AssertJUnit.assertEquals("lang-ru", la.getOptions()[0]); + + la = new LdapAttribute("cn;lang-lv;dynamic", "Viljams Voless"); + AssertJUnit.assertEquals("cn;lang-lv;dynamic", la.getName()); + AssertJUnit.assertEquals("cn;lang-lv;dynamic", la.getName(true)); + AssertJUnit.assertEquals("cn", la.getName(false)); + AssertJUnit.assertNotNull(la.getOptions()); + AssertJUnit.assertEquals(2, la.getOptions().length); + AssertJUnit.assertEquals("lang-lv", la.getOptions()[0]); + AssertJUnit.assertEquals("dynamic", la.getOptions()[1]); + } +}
diff --git a/core/src/test/java/org/ldaptive/LdapEntryTest.java b/core/src/test/java/org/ldaptive/LdapEntryTest.java new file mode 100644 index 0000000..dd22593 --- /dev/null +++ b/core/src/test/java/org/ldaptive/LdapEntryTest.java
@@ -0,0 +1,186 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.HashSet; +import java.util.Set; +import org.testng.AssertJUnit; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link LdapEntry}. + * + * @author Middleware Services + */ +public class LdapEntryTest +{ + + + /** + * Ldap attribute test data. + * + * @return ldap attributes + */ + @DataProvider(name = "attributes") + public Object[][] createSerializable() + { + return new Object[][] { + new Object[] { + new LdapAttribute("givenName", "John"), + new LdapAttribute("sn", "Doe"), + }, + }; + } + + + /** Tests default sort behavior. */ + @Test(groups = {"bean"}) + public void defaultSortBehavior() + { + final LdapEntry le = new LdapEntry("uid=1"); + AssertJUnit.assertEquals(SortBehavior.getDefaultSortBehavior(), le.getSortBehavior()); + AssertJUnit.assertEquals(0, le.size()); + AssertJUnit.assertNull(le.getAttribute()); + AssertJUnit.assertEquals("uid=1", le.getDn()); + le.setDn("uid=2"); + AssertJUnit.assertEquals("uid=2", le.getDn()); + le.clear(); + AssertJUnit.assertEquals(0, le.size()); + } + + + /** + * Tests ordered sort behavior. + * + * @param attr1 ldap attribute + * @param attr2 ldap attribute + */ + @Test(groups = {"bean"}, dataProvider = "attributes") + public void orderedSortBehavior(final LdapAttribute attr1, final LdapAttribute attr2) + { + final LdapEntry le = new LdapEntry(SortBehavior.ORDERED); + AssertJUnit.assertEquals(SortBehavior.ORDERED, le.getSortBehavior()); + le.addAttribute(attr2, attr1); + + final LdapAttribute[] attrs = le.getAttributes().toArray(new LdapAttribute[2]); + AssertJUnit.assertEquals(attr2, attrs[0]); + AssertJUnit.assertEquals(attr1, attrs[1]); + le.clear(); + AssertJUnit.assertEquals(0, le.size()); + } + + + /** + * Tests sorted sort behavior. + * + * @param attr1 ldap attribute + * @param attr2 ldap attribute + */ + @Test(groups = {"bean"}, dataProvider = "attributes") + public void sortedSortBehavior(final LdapAttribute attr1, final LdapAttribute attr2) + { + final LdapEntry le = new LdapEntry(SortBehavior.SORTED); + AssertJUnit.assertEquals(SortBehavior.SORTED, le.getSortBehavior()); + le.addAttribute(attr2, attr1); + + final LdapAttribute[] attrs = le.getAttributes().toArray(new LdapAttribute[2]); + AssertJUnit.assertEquals(attr1, attrs[0]); + AssertJUnit.assertEquals(attr2, attrs[1]); + le.clear(); + AssertJUnit.assertEquals(0, le.size()); + } + + + /** + * Tests create with one entry. + * + * @param attr1 ldap attribute + * @param attr2 ldap attribute + */ + @Test(groups = {"bean"}, dataProvider = "attributes") + public void createOne(final LdapAttribute attr1, final LdapAttribute attr2) + { + final LdapEntry le = new LdapEntry("uid=1", attr1); + AssertJUnit.assertEquals(attr1, le.getAttribute()); + AssertJUnit.assertEquals(attr1, le.getAttribute("givenName")); + AssertJUnit.assertEquals(attr1, le.getAttribute("givenname")); + AssertJUnit.assertEquals("givenName", le.getAttributeNames()[0]); + AssertJUnit.assertEquals(1, le.size()); + AssertJUnit.assertEquals(le, new LdapEntry("uid=1", attr1)); + le.clear(); + AssertJUnit.assertEquals(0, le.size()); + } + + + /** + * Tests create with two entries. + * + * @param attr1 ldap attribute + * @param attr2 ldap attribute + */ + @Test(groups = {"bean"}, dataProvider = "attributes") + public void createTwo(final LdapAttribute attr1, final LdapAttribute attr2) + { + final LdapEntry le = new LdapEntry("uid=1", attr2, attr1); + AssertJUnit.assertEquals(attr1, le.getAttribute("givenName")); + AssertJUnit.assertEquals(attr2, le.getAttribute("SN")); + AssertJUnit.assertEquals(2, le.getAttributeNames().length); + AssertJUnit.assertEquals(2, le.size()); + AssertJUnit.assertEquals(le, new LdapEntry("uid=1", attr1, attr2)); + le.removeAttribute(attr2); + AssertJUnit.assertEquals(1, le.size()); + le.clear(); + AssertJUnit.assertEquals(0, le.size()); + } + + + /** + * Tests create with a collection. + * + * @param attr1 ldap attribute + * @param attr2 ldap attribute + */ + @Test(groups = {"bean"}, dataProvider = "attributes") + public void createCollection(final LdapAttribute attr1, final LdapAttribute attr2) + { + final Set<LdapAttribute> s = new HashSet<>(); + s.add(attr1); + + final LdapEntry le = new LdapEntry("uid=1", s); + le.addAttribute(attr2); + AssertJUnit.assertEquals(attr1, le.getAttribute("GIVENNAME")); + AssertJUnit.assertEquals(attr2, le.getAttribute("sn")); + AssertJUnit.assertEquals(2, le.getAttributeNames().length); + AssertJUnit.assertEquals(2, le.size()); + AssertJUnit.assertEquals(le, new LdapEntry("uid=1", attr1, attr2)); + le.removeAttribute("GIVENNAME"); + AssertJUnit.assertEquals(1, le.size()); + le.clear(); + AssertJUnit.assertEquals(0, le.size()); + } + + + /** + * Tests attribute rename. + * + * @param attr1 ldap attribute + * @param attr2 ldap attribute + */ + @Test(groups = {"bean"}, dataProvider = "attributes") + public void renameAttribute(final LdapAttribute attr1, final LdapAttribute attr2) + { + final LdapEntry le = new LdapEntry("uid=1", attr2, attr1); + AssertJUnit.assertEquals("givenName", le.getAttribute("givenname").getName()); + le.renameAttribute(null, "firstName"); + AssertJUnit.assertEquals("givenName", le.getAttribute("givenname").getName()); + le.renameAttribute("noName", "firstName"); + AssertJUnit.assertEquals("givenName", le.getAttribute("givenname").getName()); + + final LdapAttribute la = le.getAttribute("givenName"); + le.renameAttribute("givenName", "firstName"); + AssertJUnit.assertNull(le.getAttribute("givenName")); + AssertJUnit.assertNotNull(le.getAttribute("firstName")); + AssertJUnit.assertEquals("firstName", la.getName()); + AssertJUnit.assertEquals("firstName", le.getAttribute("firstName").getName()); + } +}
diff --git a/core/src/test/java/org/ldaptive/LdapURLTest.java b/core/src/test/java/org/ldaptive/LdapURLTest.java new file mode 100644 index 0000000..cf5df07 --- /dev/null +++ b/core/src/test/java/org/ldaptive/LdapURLTest.java
@@ -0,0 +1,480 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Iterator; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link LdapURL}. + * + * @author Middleware Services + */ +public class LdapURLTest +{ + + + /** + * LDAP URL test data. + * + * @return test data + */ + // CheckStyle:MethodLength OFF + @DataProvider(name = "urls") + public Object[][] createURLs() + { + return + new Object[][] { + new Object[] { + new LdapURL("ldap://"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + null, + 389, + LdapURL.Entry.DEFAULT_BASE_DN, + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldaps://"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldaps", + null, + 636, + LdapURL.Entry.DEFAULT_BASE_DN, + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldap:///o=University%20of%20Michigan,c=US"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + null, + 389, + "o=University of Michigan,c=US", + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldap://ldap1.example.net/o=University%20of%20Michigan,c=US"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + "ldap1.example.net", + 389, + "o=University of Michigan,c=US", + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldap://ldap1.example.net/o=University%20of%20Michigan,c=US" + + "?postalAddress"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + "ldap1.example.net", + 389, + "o=University of Michigan,c=US", + new String[] {"postalAddress"}, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldap://ldap1.example.net:6666/o=University%20of%20Michigan,c=US" + + "??sub?(cn=Babs%20Jensen)"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + "ldap1.example.net", + 6666, + "o=University of Michigan,c=US", + LdapURL.Entry.DEFAULT_ATTRIBUTES, + SearchScope.SUBTREE, + new SearchFilter("(cn=Babs Jensen)")), + }, + }, + new Object[] { + new LdapURL("LDAP://ldap1.example.com/c=GB?objectClass?ONE"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + "ldap1.example.com", + 389, + "c=GB", + new String[] {"objectClass"}, + SearchScope.ONELEVEL, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldap://ldap2.example.com/o=Question%3f,c=US?mail"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + "ldap2.example.com", + 389, + "o=Question?,c=US", + new String[] {"mail"}, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldap://ldap2.example.com/o=Question%3f,c=US?mail"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + "ldap2.example.com", + 389, + "o=Question?,c=US", + new String[] {"mail"}, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldap://ldap3.example.com/o=Babsco,c=US" + + "???(four-octet=%5c00%5c00%5c00%5c04)"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + "ldap3.example.com", + 389, + "o=Babsco,c=US", + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + new SearchFilter("(four-octet=\\00\\00\\00\\04)")), + }, + }, + new Object[] { + new LdapURL("ldap://ldap.example.com/o=An%20Example%5C2C%20Inc.,c=US"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + "ldap.example.com", + 389, + "o=An Example\\2C Inc.,c=US", + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldap://directory.ldaptive.org"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + "directory.ldaptive.org", + 389, + LdapURL.Entry.DEFAULT_BASE_DN, + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldaps://directory.ldaptive.org"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldaps", + "directory.ldaptive.org", + 636, + LdapURL.Entry.DEFAULT_BASE_DN, + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldap://directory.ldaptive.org:10389"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + "directory.ldaptive.org", + 10389, + LdapURL.Entry.DEFAULT_BASE_DN, + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldap://directory.ldaptive.org:10389/dc=ldaptive,dc=org"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + "directory.ldaptive.org", + 10389, + "dc=ldaptive,dc=org", + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldap://directory.ldaptive.org:10389/dc=ldaptive,dc=org?cn"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + "directory.ldaptive.org", + 10389, + "dc=ldaptive,dc=org", + new String[] {"cn"}, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldap://directory.ldaptive.org:10389/dc=ldaptive,dc=org?cn,sn"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + "directory.ldaptive.org", + 10389, + "dc=ldaptive,dc=org", + new String[] {"cn", "sn"}, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldap://directory.ldaptive.org:10389/dc=ldaptive,dc=org" + + "?cn,sn?one"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + "directory.ldaptive.org", + 10389, + "dc=ldaptive,dc=org", + new String[] {"cn", "sn"}, + SearchScope.ONELEVEL, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldap://directory.ldaptive.org:10389/dc=ldaptive,dc=org" + + "?cn,sn?one?(uid=dfisher)"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldap", + "directory.ldaptive.org", + 10389, + "dc=ldaptive,dc=org", + new String[] {"cn", "sn"}, + SearchScope.ONELEVEL, + new SearchFilter("(uid=dfisher)")), + }, + }, + // multiple URLs + new Object[] { + new LdapURL("ldaps:// ldap://"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldaps", + null, + 636, + LdapURL.Entry.DEFAULT_BASE_DN, + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + new LdapURL.Entry( + "ldap", + null, + 389, + LdapURL.Entry.DEFAULT_BASE_DN, + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL("ldaps://directory1.ldaptive.org " + + "ldap://directory2.ldaptive.org:10389"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldaps", + "directory1.ldaptive.org", + 636, + LdapURL.Entry.DEFAULT_BASE_DN, + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + new LdapURL.Entry( + "ldap", + "directory2.ldaptive.org", + 10389, + LdapURL.Entry.DEFAULT_BASE_DN, + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL( + "ldaps://directory1.ldaptive.org/dc=ldaptive,dc=org " + + "ldap://directory2.ldaptive.org:10389/dc=ldaptive,dc=org"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldaps", + "directory1.ldaptive.org", + 636, + "dc=ldaptive,dc=org", + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + new LdapURL.Entry( + "ldap", + "directory2.ldaptive.org", + 10389, + "dc=ldaptive,dc=org", + LdapURL.Entry.DEFAULT_ATTRIBUTES, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL( + "ldaps://directory1.ldaptive.org/dc=ldaptive,dc=org?cn,sn " + + "ldap://directory2.ldaptive.org:10389/dc=ldaptive,dc=org?cn"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldaps", + "directory1.ldaptive.org", + 636, + "dc=ldaptive,dc=org", + new String[] {"cn", "sn"}, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + new LdapURL.Entry( + "ldap", + "directory2.ldaptive.org", + 10389, + "dc=ldaptive,dc=org", + new String[] {"cn"}, + LdapURL.Entry.DEFAULT_SCOPE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL( + "ldaps://directory1.ldaptive.org/dc=ldaptive,dc=org" + + "?cn,sn?base ldap://directory2.ldaptive.org:10389/" + + "dc=ldaptive,dc=org?cn?sub"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldaps", + "directory1.ldaptive.org", + 636, + "dc=ldaptive,dc=org", + new String[] {"cn", "sn"}, + SearchScope.OBJECT, + LdapURL.Entry.DEFAULT_FILTER), + new LdapURL.Entry( + "ldap", + "directory2.ldaptive.org", + 10389, + "dc=ldaptive,dc=org", + new String[] {"cn"}, + SearchScope.SUBTREE, + LdapURL.Entry.DEFAULT_FILTER), + }, + }, + new Object[] { + new LdapURL( + "ldaps://directory1.ldaptive.org/dc=ldaptive,dc=org?cn,sn?base?" + + "(uid=dfisher) ldap://directory2.ldaptive.org:10389/" + + "dc=ldaptive,dc=org?cn?sub?(uid=dfisher)"), + new LdapURL.Entry[] { + new LdapURL.Entry( + "ldaps", + "directory1.ldaptive.org", + 636, + "dc=ldaptive,dc=org", + new String[] {"cn", "sn"}, + SearchScope.OBJECT, + new SearchFilter("(uid=dfisher)")), + new LdapURL.Entry( + "ldap", + "directory2.ldaptive.org", + 10389, + "dc=ldaptive,dc=org", + new String[] {"cn"}, + SearchScope.SUBTREE, + new SearchFilter("(uid=dfisher)")), + }, + }, + }; + } + // CheckStyle:MethodLength ON + + + /** + * @param url LdapUrl to test + * @param entries to verify + * + * @throws Exception On test failure. + */ + @Test(groups = {"ldapURL"}, dataProvider = "urls") + public void testParsing(final LdapURL url, final LdapURL.Entry[] entries) + throws Exception + { + final Iterator<LdapURL.Entry> iter = url.getEntries().iterator(); + Assert.assertEquals(entries.length, url.size()); + for (LdapURL.Entry entry : entries) { + final LdapURL.Entry e = iter.next(); + compareEntries(entry, e); + } + + compareEntries(entries[0], url.getEntry()); + compareEntries(entries[entries.length - 1], url.getLastEntry()); + + final String[] hostnames = new String[entries.length]; + for (int i = 0; i < entries.length; i++) { + hostnames[i] = entries[i].getHostname(); + } + Assert.assertEquals(hostnames, url.getHostnames()); + + final String[] hostnamesWithSchemeAndPort = new String[entries.length]; + for (int i = 0; i < entries.length; i++) { + hostnamesWithSchemeAndPort[i] = entries[i].getHostnameWithSchemeAndPort(); + } + Assert.assertEquals(hostnamesWithSchemeAndPort, url.getHostnamesWithSchemeAndPort()); + + final String[] urls = new String[entries.length]; + for (int i = 0; i < entries.length; i++) { + urls[i] = entries[i].getUrl(); + } + Assert.assertEquals(urls, url.getUrls()); + } + + + /** + * Compare all the properties of the supplied entries. + * + * @param entry1 to compare + * @param entry2 to compare + */ + private void compareEntries(final LdapURL.Entry entry1, final LdapURL.Entry entry2) + { + Assert.assertEquals(entry1.getScheme(), entry2.getScheme()); + Assert.assertEquals(entry1.getHostname(), entry2.getHostname()); + Assert.assertEquals(entry1.getPort(), entry2.getPort()); + Assert.assertEquals(entry1.getBaseDn(), entry2.getBaseDn()); + Assert.assertEquals(entry1.getAttributes(), entry2.getAttributes()); + Assert.assertEquals(entry1.getScope(), entry2.getScope()); + Assert.assertEquals(entry1.getFilter(), entry2.getFilter()); + } +}
diff --git a/core/src/test/java/org/ldaptive/RandomConnectionStrategyTest.java b/core/src/test/java/org/ldaptive/RandomConnectionStrategyTest.java new file mode 100644 index 0000000..99d8b35 --- /dev/null +++ b/core/src/test/java/org/ldaptive/RandomConnectionStrategyTest.java
@@ -0,0 +1,76 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link RandomConnectionStrategy}. + * + * @author Middleware Services + */ +public class RandomConnectionStrategyTest +{ + + /** Strategy to test. */ + private final RandomConnectionStrategy strategy = new RandomConnectionStrategy(); + + + /** + * URL test data. + * + * @return test data + */ + @DataProvider(name = "urls") + public Object[][] createURLs() + { + return + new Object[][] { + new Object[] { + new TestConnectionFactoryMetadata(), + null, + }, + new Object[] { + new TestConnectionFactoryMetadata("ldap://directory.ldaptive.org"), + new String[] {"ldap://directory.ldaptive.org"}, + }, + new Object[] { + new TestConnectionFactoryMetadata("ldap://directory-1.ldaptive.org ldap://directory-2.ldaptive.org"), + new String[] { + "ldap://directory-1.ldaptive.org", + "ldap://directory-2.ldaptive.org", + }, + }, + new Object[] { + new TestConnectionFactoryMetadata( + "ldap://directory-1.ldaptive.org ldap://directory-2.ldaptive.org " + + "ldap://directory-3.ldaptive.org", + 3), + new String[] { + "ldap://directory-1.ldaptive.org", + "ldap://directory-2.ldaptive.org", + "ldap://directory-3.ldaptive.org", + }, + }, + }; + } + + + /** + * @param metadata to get ldap urls from + * @param urls to compare + * + * @throws Exception On test failure. + */ + @Test(groups = {"provider"}, dataProvider = "urls") + public void getLdapUrls(final ConnectionFactoryMetadata metadata, final String[] urls) + throws Exception + { + if (urls != null) { + Assert.assertEquals(strategy.getLdapUrls(metadata).length, urls.length); + } else { + Assert.assertEquals(strategy.getLdapUrls(metadata), urls); + } + } +}
diff --git a/core/src/test/java/org/ldaptive/RoundRobinConnectionStrategyTest.java b/core/src/test/java/org/ldaptive/RoundRobinConnectionStrategyTest.java new file mode 100644 index 0000000..126b117 --- /dev/null +++ b/core/src/test/java/org/ldaptive/RoundRobinConnectionStrategyTest.java
@@ -0,0 +1,116 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link RoundRobinConnectionStrategy}. + * + * @author Middleware Services + */ +public class RoundRobinConnectionStrategyTest +{ + + /** Strategy to test. */ + private final RoundRobinConnectionStrategy strategy = new RoundRobinConnectionStrategy(); + + + /** + * URL test data. + * + * @return test data + */ + @DataProvider(name = "urls") + public Object[][] createURLs() + { + return + new Object[][] { + new Object[] { + new TestConnectionFactoryMetadata(), + null, + }, + new Object[] { + new TestConnectionFactoryMetadata("ldap://directory.ldaptive.org"), + new String[] {"ldap://directory.ldaptive.org"}, + }, + new Object[] { + new TestConnectionFactoryMetadata("ldap://directory-1.ldaptive.org ldap://directory-2.ldaptive.org"), + new String[] { + "ldap://directory-1.ldaptive.org", + "ldap://directory-2.ldaptive.org", + }, + }, + new Object[] { + new TestConnectionFactoryMetadata( + "ldap://directory-1.ldaptive.org ldap://directory-2.ldaptive.org " + + "ldap://directory-3.ldaptive.org", + 0), + new String[] { + "ldap://directory-1.ldaptive.org", + "ldap://directory-2.ldaptive.org", + "ldap://directory-3.ldaptive.org", + }, + }, + new Object[] { + new TestConnectionFactoryMetadata( + "ldap://directory-1.ldaptive.org ldap://directory-2.ldaptive.org " + + "ldap://directory-3.ldaptive.org", + 1), + new String[] { + "ldap://directory-2.ldaptive.org", + "ldap://directory-3.ldaptive.org", + "ldap://directory-1.ldaptive.org", + }, + }, + new Object[] { + new TestConnectionFactoryMetadata( + "ldap://directory-1.ldaptive.org ldap://directory-2.ldaptive.org " + + "ldap://directory-3.ldaptive.org", + 2), + new String[] { + "ldap://directory-3.ldaptive.org", + "ldap://directory-1.ldaptive.org", + "ldap://directory-2.ldaptive.org", + }, + }, + new Object[] { + new TestConnectionFactoryMetadata( + "ldap://directory-1.ldaptive.org ldap://directory-2.ldaptive.org " + + "ldap://directory-3.ldaptive.org", + 3), + new String[] { + "ldap://directory-1.ldaptive.org", + "ldap://directory-2.ldaptive.org", + "ldap://directory-3.ldaptive.org", + }, + }, + new Object[] { + new TestConnectionFactoryMetadata( + "ldap://directory-1.ldaptive.org ldap://directory-2.ldaptive.org " + + "ldap://directory-3.ldaptive.org", + 4), + new String[] { + "ldap://directory-2.ldaptive.org", + "ldap://directory-3.ldaptive.org", + "ldap://directory-1.ldaptive.org", + }, + }, + }; + } + + + /** + * @param metadata to get ldap urls from + * @param urls to compare + * + * @throws Exception On test failure. + */ + @Test(groups = {"provider"}, dataProvider = "urls") + public void getLdapUrls(final ConnectionFactoryMetadata metadata, final String[] urls) + throws Exception + { + Assert.assertEquals(strategy.getLdapUrls(metadata), urls); + } +}
diff --git a/core/src/test/java/org/ldaptive/SearchFilterTest.java b/core/src/test/java/org/ldaptive/SearchFilterTest.java new file mode 100644 index 0000000..de3ab31 --- /dev/null +++ b/core/src/test/java/org/ldaptive/SearchFilterTest.java
@@ -0,0 +1,68 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SearchFilter}. + * + * @author Middleware Services + */ +public class SearchFilterTest +{ + + + /** + * Search filter test data. + * + * @return search filters + */ + @DataProvider(name = "filters") + public Object[][] createFilters() + { + final String f1 = "(&(givenName=Bill)(sn=Wallace))"; + final SearchFilter sf1 = new SearchFilter(f1); + final SearchFilter sf2 = new SearchFilter("(&(givenName={0})(sn={1}))"); + sf2.setParameter(0, "Bill"); + sf2.setParameter(1, "Wallace"); + + final SearchFilter sf3 = new SearchFilter("(&(givenName={name})(sn={1}))"); + sf3.setParameter("name", "Bill"); + sf3.setParameter(1, "Wallace"); + + final String f4 = "(&(givenName=Bill\\2a)(sn=Wa\\28ll\\29ace))"; + final SearchFilter sf4 = new SearchFilter("(&(givenName={firstname})(sn={lastname}))"); + sf4.setParameter("firstname", "Bill*"); + sf4.setParameter("lastname", "Wa(ll)ace"); + + final String f5 = "(&(givenName=\\42\\69\\6C\\6C)(sn=\\57\\61\\6C\\6C\\61\\63\\65))"; + final SearchFilter sf5 = new SearchFilter("(&(givenName={firstname})(sn={lastname}))"); + sf5.setParameter("firstname", new byte[] {'B', 'i', 'l', 'l', }); + sf5.setParameter("lastname", new byte[] {'W', 'a', 'l', 'l', 'a', 'c', 'e', }); + + return + new Object[][] { + new Object[] {f1, sf1, }, + new Object[] {f1, sf2, }, + new Object[] {f1, sf3, }, + new Object[] {f4, sf4, }, + new Object[] {f5, sf5, }, + }; + } + + + /** + * @param encodedFilter to compare against + * @param filter to format + * + * @throws Exception On test failure. + */ + @Test(groups = {"filter"}, dataProvider = "filters") + public void testFormat(final String encodedFilter, final SearchFilter filter) + throws Exception + { + Assert.assertEquals(filter.format(), encodedFilter); + } +}
diff --git a/core/src/test/java/org/ldaptive/SearchResultTest.java b/core/src/test/java/org/ldaptive/SearchResultTest.java new file mode 100644 index 0000000..6db77dc --- /dev/null +++ b/core/src/test/java/org/ldaptive/SearchResultTest.java
@@ -0,0 +1,190 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.HashSet; +import java.util.Set; +import org.testng.AssertJUnit; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SearchResult}. + * + * @author Middleware Services + */ +public class SearchResultTest +{ + + + /** + * Ldap entry test data. + * + * @return ldap entries + */ + @DataProvider(name = "entries") + public Object[][] createSerializable() + { + return new Object[][] { + new Object[] {new LdapEntry("uid=1"), new LdapEntry("uid=2"), }, + }; + } + + + /** Tests default sort behavior. */ + @Test(groups = {"bean"}) + public void defaultSortBehavior() + { + final SearchResult sr = new SearchResult(); + AssertJUnit.assertEquals(SortBehavior.getDefaultSortBehavior(), sr.getSortBehavior()); + AssertJUnit.assertEquals(0, sr.size()); + AssertJUnit.assertNull(sr.getEntry()); + sr.clear(); + AssertJUnit.assertEquals(0, sr.size()); + } + + + /** + * Tests ordered sort behavior. + * + * @param entry1 ldap entry + * @param entry2 ldap entry + */ + @Test(groups = {"bean"}, dataProvider = "entries") + public void orderedSortBehavior(final LdapEntry entry1, final LdapEntry entry2) + { + final SearchResult sr = new SearchResult(SortBehavior.ORDERED); + AssertJUnit.assertEquals(SortBehavior.ORDERED, sr.getSortBehavior()); + sr.addEntry(entry2, entry1); + + final LdapEntry[] entries = sr.getEntries().toArray(new LdapEntry[2]); + AssertJUnit.assertEquals(entry2, entries[0]); + AssertJUnit.assertEquals(entry1, entries[1]); + sr.clear(); + AssertJUnit.assertEquals(0, sr.size()); + } + + + /** + * Tests sorted sort behavior. + * + * @param entry1 ldap entry + * @param entry2 ldap entry + */ + @Test(groups = {"bean"}, dataProvider = "entries") + public void sortedSortBehavior(final LdapEntry entry1, final LdapEntry entry2) + { + final SearchResult sr = new SearchResult(SortBehavior.SORTED); + AssertJUnit.assertEquals(SortBehavior.SORTED, sr.getSortBehavior()); + sr.addEntry(entry2, entry1); + + final LdapEntry[] entries = sr.getEntries().toArray(new LdapEntry[2]); + AssertJUnit.assertEquals(entry1, entries[0]); + AssertJUnit.assertEquals(entry2, entries[1]); + sr.clear(); + AssertJUnit.assertEquals(0, sr.size()); + } + + + /** + * Tests create with one entry. + * + * @param entry1 ldap entry + * @param entry2 ldap entry + */ + @Test(groups = {"bean"}, dataProvider = "entries") + public void createOne(final LdapEntry entry1, final LdapEntry entry2) + { + final SearchResult sr = new SearchResult(entry1); + AssertJUnit.assertEquals(entry1, sr.getEntry()); + AssertJUnit.assertEquals(entry1, sr.getEntry("uid=1")); + AssertJUnit.assertEquals(entry1, sr.getEntry("UID=1")); + AssertJUnit.assertEquals("uid=1", sr.getEntryDns()[0]); + AssertJUnit.assertEquals(1, sr.size()); + AssertJUnit.assertEquals(sr, new SearchResult(entry1)); + sr.clear(); + AssertJUnit.assertEquals(0, sr.size()); + } + + + /** + * Tests create with two entries. + * + * @param entry1 ldap entry + * @param entry2 ldap entry + */ + @Test(groups = {"bean"}, dataProvider = "entries") + public void createTwo(final LdapEntry entry1, final LdapEntry entry2) + { + final SearchResult sr = new SearchResult(entry2, entry1); + AssertJUnit.assertEquals(entry1, sr.getEntry("uid=1")); + AssertJUnit.assertEquals(entry2, sr.getEntry("UID=2")); + AssertJUnit.assertEquals(2, sr.getEntryDns().length); + AssertJUnit.assertEquals(2, sr.size()); + AssertJUnit.assertEquals(sr, new SearchResult(entry1, entry2)); + sr.removeEntry(entry2); + AssertJUnit.assertEquals(1, sr.size()); + sr.clear(); + AssertJUnit.assertEquals(0, sr.size()); + } + + + /** + * Tests create with a collection. + * + * @param entry1 ldap entry + * @param entry2 ldap entry + */ + @Test(groups = {"bean"}, dataProvider = "entries") + public void createCollection(final LdapEntry entry1, final LdapEntry entry2) + { + final Set<LdapEntry> s = new HashSet<>(); + s.add(entry1); + + final SearchResult sr = new SearchResult(s); + sr.addEntry(entry2); + AssertJUnit.assertEquals(entry1, sr.getEntry("UID=1")); + AssertJUnit.assertEquals(entry2, sr.getEntry("uid=2")); + AssertJUnit.assertEquals(2, sr.getEntryDns().length); + AssertJUnit.assertEquals(2, sr.size()); + AssertJUnit.assertEquals(sr, new SearchResult(entry1, entry2)); + sr.removeEntry("UID=1"); + AssertJUnit.assertEquals(1, sr.size()); + sr.clear(); + AssertJUnit.assertEquals(0, sr.size()); + } + + + /** + * Unit test for {@link SearchResult#subResult(int, int)}. + * + * @param entry1 ldap entry + * @param entry2 ldap entry + */ + @Test(groups = {"bean"}, dataProvider = "entries") + public void subResult(final LdapEntry entry1, final LdapEntry entry2) + { + final SearchResult sr = new SearchResult(SortBehavior.SORTED); + sr.addEntry(entry2, entry1); + AssertJUnit.assertEquals(0, sr.subResult(2, 2).size()); + AssertJUnit.assertEquals(1, sr.subResult(1, 2).size()); + AssertJUnit.assertEquals(2, sr.subResult(0, 2).size()); + try { + sr.subResult(-1, 1); + AssertJUnit.fail("Should have thrown IndexOutOfBoundsException"); + } catch (Exception e) { + AssertJUnit.assertEquals(IndexOutOfBoundsException.class, e.getClass()); + } + try { + sr.subResult(0, 3); + AssertJUnit.fail("Should have thrown IndexOutOfBoundsException"); + } catch (Exception e) { + AssertJUnit.assertEquals(IndexOutOfBoundsException.class, e.getClass()); + } + try { + sr.subResult(1, 0); + AssertJUnit.fail("Should have thrown IndexOutOfBoundsException"); + } catch (Exception e) { + AssertJUnit.assertEquals(IndexOutOfBoundsException.class, e.getClass()); + } + } +}
diff --git a/core/src/test/java/org/ldaptive/SerializableTest.java b/core/src/test/java/org/ldaptive/SerializableTest.java new file mode 100644 index 0000000..fcb9395 --- /dev/null +++ b/core/src/test/java/org/ldaptive/SerializableTest.java
@@ -0,0 +1,116 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import org.ldaptive.jaas.LdapCredential; +import org.ldaptive.jaas.LdapDnPrincipal; +import org.ldaptive.jaas.LdapGroup; +import org.ldaptive.jaas.LdapPrincipal; +import org.ldaptive.jaas.LdapRole; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Test that objects that implement {@link Serializable} can be serialized. + * + * @author Middleware Services + */ +public class SerializableTest +{ + + + /** + * Serializable test data. + * + * @return serializable objects + */ + @DataProvider(name = "objects") + public Object[][] createSerializable() + { + final LdapAttribute attr1 = new LdapAttribute("string-name", "string-value1", "string-value2"); + final LdapAttribute attr2 = new LdapAttribute("binary-name", new byte[] {0x00, 0x01, }, new byte[] {0x02, 0x03, }); + final LdapEntry entry1 = new LdapEntry("entry-dn1", attr1, attr2); + final LdapEntry entry2 = new LdapEntry("entry-dn2", attr1, attr2); + final SearchResult result = new SearchResult(entry1, entry2); + + final LdapPrincipal prin = new LdapPrincipal("principal-name", entry1); + final LdapDnPrincipal dnPrin = new LdapDnPrincipal("dn-principal-name", entry2); + final LdapRole role = new LdapRole("role-name"); + final LdapCredential cred = new LdapCredential("credential"); + final LdapGroup group = new LdapGroup("principal-group-name"); + group.addMember(prin); + group.addMember(dnPrin); + group.addMember(role); + + return + new Object[][] { + new Object[] {attr1, }, + new Object[] {attr2, }, + new Object[] {entry1, }, + new Object[] {entry2, }, + new Object[] {result, }, + new Object[] {prin, }, + new Object[] {role, }, + new Object[] {cred, }, + new Object[] {group, }, + }; + } + + + /** + * @param s serializable object to test + * + * @throws Exception On test failure. + */ + @Test(groups = {"serialize"}, dataProvider = "objects") + public void testSerialize(final Serializable s) + throws Exception + { + Assert.assertEquals(deserialize(serialize(s)), s); + } + + + /** + * Serializes the supplied object. + * + * @param s to serialize + * + * @return serialized object + * + * @throws Exception if object cannot be serialized + */ + private byte[] serialize(final Serializable s) + throws Exception + { + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(bos)) { + oos.writeObject(s); + return bos.toByteArray(); + } finally { + bos.close(); + } + } + + + /** + * Deserializes the supplied byte array. + * + * @param b to deserialize + * + * @return deserialized object + * + * @throws Exception if object cannot be deserialized + */ + private Object deserialize(final byte[] b) + throws Exception + { + try (ObjectInputStream is = new ObjectInputStream(new ByteArrayInputStream(b))) { + return is.readObject(); + } + } +}
diff --git a/core/src/test/java/org/ldaptive/TestConnectionFactoryMetadata.java b/core/src/test/java/org/ldaptive/TestConnectionFactoryMetadata.java new file mode 100644 index 0000000..7b3eb60 --- /dev/null +++ b/core/src/test/java/org/ldaptive/TestConnectionFactoryMetadata.java
@@ -0,0 +1,62 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Helper class for connection strategy tests. + * + * @author Middleware Services + */ +public class TestConnectionFactoryMetadata implements ConnectionFactoryMetadata +{ + + /** ldap url. */ + private final String ldapUrl; + + /** connection count. */ + private final int connectionCount; + + + /** Creates a new test connection factory metadata. */ + public TestConnectionFactoryMetadata() + { + this(null, 0); + } + + + /** + * Creates a new test connection factory metadata. + * + * @param url ldap url + */ + public TestConnectionFactoryMetadata(final String url) + { + this(url, 0); + } + + + /** + * Creates a new test connection factory metadata. + * + * @param url ldap url + * @param count connection count + */ + public TestConnectionFactoryMetadata(final String url, final int count) + { + ldapUrl = url; + connectionCount = count; + } + + + @Override + public String getLdapUrl() + { + return ldapUrl; + } + + + @Override + public int getConnectionCount() + { + return connectionCount; + } +}
diff --git a/core/src/test/java/org/ldaptive/ad/GlobalIdentifierTest.java b/core/src/test/java/org/ldaptive/ad/GlobalIdentifierTest.java new file mode 100644 index 0000000..67a927b --- /dev/null +++ b/core/src/test/java/org/ldaptive/ad/GlobalIdentifierTest.java
@@ -0,0 +1,73 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link GlobalIdentifier}. + * + * @author Middleware Services + */ +public class GlobalIdentifierTest +{ + + + /** + * ObjectGuid test data. + * + * @return test data + * + * @throws Exception if test data cannot be generated + */ + @DataProvider(name = "guids") + public Object[][] createGuids() + throws Exception + { + return + new Object[][] { + new Object[] { + "{B1DB3CCA-72BD-4F31-9EBF-C70CD44BDA32}", + LdapUtils.base64Decode("yjzbsb1yMU+ev8cM1EvaMg=="), + }, + new Object[] { + "{0F0BF778-1C43-4D0C-82E6-BAD22D6AB646}", + LdapUtils.base64Decode("ePcLD0McDE2C5rrSLWq2Rg=="), + }, + new Object[] { + "{36B403E2-BA7F-4A83-8049-B3CD202C7032}", + LdapUtils.base64Decode("4gO0Nn+6g0qASbPNICxwMg=="), + }, + }; + } + + + /** + * @param guidString objectGuid string form + * @param guid global identifier + * + * @throws Exception On test failure. + */ + @Test(groups = {"ad"}, dataProvider = "guids") + public void testToString(final String guidString, final byte[] guid) + throws Exception + { + Assert.assertEquals(GlobalIdentifier.toString(guid), guidString); + } + + + /** + * @param guidString objectGuid string form + * @param guid global identifier + * + * @throws Exception On test failure. + */ + @Test(groups = {"ad"}, dataProvider = "guids") + public void testToBytes(final String guidString, final byte[] guid) + throws Exception + { + Assert.assertEquals(guid, GlobalIdentifier.toBytes(guidString)); + } +}
diff --git a/core/src/test/java/org/ldaptive/ad/SecurityIdentifierTest.java b/core/src/test/java/org/ldaptive/ad/SecurityIdentifierTest.java new file mode 100644 index 0000000..c5468ed --- /dev/null +++ b/core/src/test/java/org/ldaptive/ad/SecurityIdentifierTest.java
@@ -0,0 +1,73 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SecurityIdentifier}. + * + * @author Middleware Services + */ +public class SecurityIdentifierTest +{ + + + /** + * ObjectSid test data. + * + * @return ldap attribute values + * + * @throws Exception if test data cannot be generated + */ + @DataProvider(name = "sids") + public Object[][] createSids() + throws Exception + { + return + new Object[][] { + new Object[] { + "S-1-5-21-1051162837-3568060411-1686669321-1105", + LdapUtils.base64Decode("AQUAAAAAAAUVAAAA1XinPvtHrNQJiIhkUQQAAA=="), + }, + new Object[] { + "S-1-5-21-1051162837-3568060411-1686669321-3173", + LdapUtils.base64Decode("AQUAAAAAAAUVAAAA1XinPvtHrNQJiIhkZQwAAA=="), + }, + new Object[] { + "S-1-5-21-1051162837-3568060411-1686669321-1000", + LdapUtils.base64Decode("AQUAAAAAAAUVAAAA1XinPvtHrNQJiIhk6AMAAA=="), + }, + }; + } + + + /** + * @param sidString objectSid string form + * @param sid security identifier + * + * @throws Exception On test failure. + */ + @Test(groups = {"ad"}, dataProvider = "sids") + public void testToString(final String sidString, final byte[] sid) + throws Exception + { + Assert.assertEquals(sidString, SecurityIdentifier.toString(sid)); + } + + + /** + * @param sidString objectSid string form + * @param sid security identifier + * + * @throws Exception On test failure. + */ + @Test(groups = {"ad"}, dataProvider = "sids") + public void testToBytes(final String sidString, final byte[] sid) + throws Exception + { + Assert.assertEquals(sid, SecurityIdentifier.toBytes(sidString)); + } +}
diff --git a/core/src/test/java/org/ldaptive/ad/control/DirSyncControlTest.java b/core/src/test/java/org/ldaptive/ad/control/DirSyncControlTest.java new file mode 100644 index 0000000..8b4ee89 --- /dev/null +++ b/core/src/test/java/org/ldaptive/ad/control/DirSyncControlTest.java
@@ -0,0 +1,145 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link DirSyncControl}. + * + * @author Middleware Services + */ +public class DirSyncControlTest +{ + + + /** + * Dir sync request control test data. + * + * @return response test data + */ + @DataProvider(name = "request-response") + public Object[][] createData() + { + return + new Object[][] { + // flags=0, maxAttrCount=0, no cookie + // BER: 30:08:02:01:00:02:01:00:04:00 + new Object[] { + LdapUtils.base64Decode("MAgCAQACAQAEAA=="), + new DirSyncControl(), + }, + // flags=0, maxAttrCount=0, cookie + new Object[] { + LdapUtils.base64Decode( + "MHQCAQACAQAEbE1TRFMDAAAAAmDMQ7HCzQEAAAAAAAAAACgAAABbzwEAAAAAAAAA" + + "AAAAAAAAW88BAAAAAADzox7OKwdpRIu4ZIWpCoubAQAAAAAAAAABAAAAAAAAAPOj" + + "Hs4rB2lEi7hkhakKi5vyzwEAAAAAAA=="), + new DirSyncControl( + null, + new byte[] { + (byte) 0x4D, (byte) 0x53, (byte) 0x44, (byte) 0x53, (byte) 0x03, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x60, + (byte) 0xCC, (byte) 0x43, (byte) 0xB1, (byte) 0xC2, (byte) 0xCD, + (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x28, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x5B, (byte) 0xCF, + (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x5B, + (byte) 0xCF, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0xF3, (byte) 0xA3, (byte) 0x1E, + (byte) 0xCE, (byte) 0x2B, (byte) 0x07, (byte) 0x69, (byte) 0x44, + (byte) 0x8B, (byte) 0xB8, (byte) 0x64, (byte) 0x85, (byte) 0xA9, + (byte) 0x0A, (byte) 0x8B, (byte) 0x9B, (byte) 0x01, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xF3, + (byte) 0xA3, (byte) 0x1E, (byte) 0xCE, (byte) 0x2B, (byte) 0x07, + (byte) 0x69, (byte) 0x44, (byte) 0x8B, (byte) 0xB8, (byte) 0x64, + (byte) 0x85, (byte) 0xA9, (byte) 0x0A, (byte) 0x8B, (byte) 0x9B, + (byte) 0xF2, (byte) 0xCF, (byte) 0x01, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, + }, + true), + }, + // flags=ANCESTORS_FIRST_ORDER, maxAttrCount=100, no cookie + // BER: 30:09:02:02:08:00:02:01:64:04:00: + new Object[] { + LdapUtils.base64Decode("MAkCAggAAgFkBAA="), + new DirSyncControl( + new DirSyncControl.Flag[] {DirSyncControl.Flag.ANCESTORS_FIRST_ORDER, }, + null, + 100, + false), + }, + // flags=ANCESTORS_FIRST_ORDER, maxAttrCount=100, cookie + new Object[] { + LdapUtils.base64Decode( + "MHUCAggAAgFkBGxNU0RTAwAAAN2j6LS3ws0BAAAAAAAAAAAoAAAAW88BAAAAAAAA" + + "AAAAAAAAAFvPAQAAAAAA86MezisHaUSLuGSFqQqLmwEAAAAAAAAAAQAAAAAAAADz" + + "ox7OKwdpRIu4ZIWpCoubCdABAAAAAAA="), + new DirSyncControl( + new DirSyncControl.Flag[] {DirSyncControl.Flag.ANCESTORS_FIRST_ORDER, }, + new byte[] { + (byte) 0x4D, (byte) 0x53, (byte) 0x44, (byte) 0x53, (byte) 0x03, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xDD, (byte) 0xA3, + (byte) 0xE8, (byte) 0xB4, (byte) 0xB7, (byte) 0xC2, (byte) 0xCD, + (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x28, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x5B, (byte) 0xCF, + (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x5B, + (byte) 0xCF, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0xF3, (byte) 0xA3, (byte) 0x1E, + (byte) 0xCE, (byte) 0x2B, (byte) 0x07, (byte) 0x69, (byte) 0x44, + (byte) 0x8B, (byte) 0xB8, (byte) 0x64, (byte) 0x85, (byte) 0xA9, + (byte) 0x0A, (byte) 0x8B, (byte) 0x9B, (byte) 0x01, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xF3, + (byte) 0xA3, (byte) 0x1E, (byte) 0xCE, (byte) 0x2B, (byte) 0x07, + (byte) 0x69, (byte) 0x44, (byte) 0x8B, (byte) 0xB8, (byte) 0x64, + (byte) 0x85, (byte) 0xA9, (byte) 0x0A, (byte) 0x8B, (byte) 0x9B, + (byte) 0x09, (byte) 0xD0, (byte) 0x01, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, + }, + 100, + true), + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected dir sync control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "request-response") + public void encode(final byte[] berValue, final DirSyncControl expected) + throws Exception + { + Assert.assertEquals(expected.encode(), berValue); + } + + + /** + * @param berValue to decode. + * @param expected dir sync control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "request-response") + public void decode(final byte[] berValue, final DirSyncControl expected) + throws Exception + { + final DirSyncControl actual = new DirSyncControl(expected.getCriticality()); + actual.decode(berValue); + Assert.assertEquals(actual, expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/ad/control/ExtendedDnControlTest.java b/core/src/test/java/org/ldaptive/ad/control/ExtendedDnControlTest.java new file mode 100644 index 0000000..3376527 --- /dev/null +++ b/core/src/test/java/org/ldaptive/ad/control/ExtendedDnControlTest.java
@@ -0,0 +1,56 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link ExtendedDnControl}. + * + * @author Middleware Services + */ +public class ExtendedDnControlTest +{ + + + /** + * Extended DN control test data. + * + * @return response test data + */ + @DataProvider(name = "request") + public Object[][] createData() + { + return + new Object[][] { + // standard format + // BER: 30:03:02:01:01: + new Object[] { + LdapUtils.base64Decode("MAMCAQE="), + new ExtendedDnControl(), + }, + // hexadecimal format + // BER: 30:03:02:01:00 + new Object[] { + LdapUtils.base64Decode("MAMCAQA="), + new ExtendedDnControl(ExtendedDnControl.Flag.HEXADECIMAL), + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected extended dn control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "request") + public void encode(final byte[] berValue, final ExtendedDnControl expected) + throws Exception + { + Assert.assertEquals(expected.encode(), berValue); + } +}
diff --git a/core/src/test/java/org/ldaptive/ad/control/GetStatsControlTest.java b/core/src/test/java/org/ldaptive/ad/control/GetStatsControlTest.java new file mode 100644 index 0000000..7e0c07b --- /dev/null +++ b/core/src/test/java/org/ldaptive/ad/control/GetStatsControlTest.java
@@ -0,0 +1,74 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link GetStatsControl}. + * + * @author Middleware Services + */ +public class GetStatsControlTest +{ + + + /** + * Get stats control test data. + * + * @return response test data + */ + @DataProvider(name = "response") + public Object[][] createData() + { + final GetStatsControl ctrl = new GetStatsControl(); + ctrl.getStatistics().put("pagesReferenced", 45094); + ctrl.getStatistics().put("index", "Ancestors_index:0:N;"); + ctrl.getStatistics().put("pagesRedirtied", 2); + ctrl.getStatistics().put("entriesVisited", 5010); + ctrl.getStatistics().put("logRecordCount", 0); + ctrl.getStatistics().put("pagesDirtied", 0); + ctrl.getStatistics().put("entriesReturned", 1); + ctrl.getStatistics().put("callTime", 15); + ctrl.getStatistics().put("logRecordBytes", 0); + ctrl.getStatistics().put("threadCount", 1); + ctrl.getStatistics().put("pagesPreread", 0); + ctrl.getStatistics().put("pagesRead", 0); + ctrl.getStatistics().put("filter", "(uid=2)"); + return + new Object[][] { + // BER: + // 30:84:00:00:00:6E:02:01:01:02:01:01:02:01:03:02:01:0F:02:01:05:02: + // 01:01:02:01:06:02:02:13:92:02:01:07:04:0A:20:28:75:69:64:3D:32:29: + // 20:00:02:01:08:04:15:41:6E:63:65:73:74:6F:72:73:5F:69:6E:64:65:78: + // 3A:30:3A:4E:3B:00:02:01:09:02:03:00:B0:26:02:01:0A:02:01:00:02:01: + // 0B:02:01:00:02:01:0C:02:01:00:02:01:0D:02:01:02:02:01:0E:02:01:00: + // 02:01:0F:02:01:00: + new Object[] { + LdapUtils.base64Decode( + "MIQAAABuAgEBAgEBAgEDAgEPAgEFAgEBAgEGAgITkgIBBwQKICh1aWQ9MikgAAIB" + + "CAQVQW5jZXN0b3JzX2luZGV4OjA6TjsAAgEJAgMAsCYCAQoCAQACAQsCAQACAQwC" + + "AQACAQ0CAQICAQ4CAQACAQ8CAQA="), + ctrl, + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected get stats control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "response") + public void decode(final byte[] berValue, final GetStatsControl expected) + throws Exception + { + final GetStatsControl actual = new GetStatsControl(expected.getCriticality()); + actual.decode(berValue); + Assert.assertEquals(actual, expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/ad/control/SearchOptionsControlTest.java b/core/src/test/java/org/ldaptive/ad/control/SearchOptionsControlTest.java new file mode 100644 index 0000000..1ffcf89 --- /dev/null +++ b/core/src/test/java/org/ldaptive/ad/control/SearchOptionsControlTest.java
@@ -0,0 +1,56 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SearchOptionsControl}. + * + * @author Middleware Services + */ +public class SearchOptionsControlTest +{ + + + /** + * Search options control test data. + * + * @return response test data + */ + @DataProvider(name = "request") + public Object[][] createData() + { + return + new Object[][] { + // domain scope + // BER: 30:03:02:01:00 + new Object[] { + LdapUtils.base64Decode("MAMCAQA="), + new SearchOptionsControl(), + }, + // phantom root + // BER: 30:03:02:01:01: + new Object[] { + LdapUtils.base64Decode("MAMCAQE="), + new SearchOptionsControl(SearchOptionsControl.Flag.PHANTOM_ROOT), + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected search options control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "request") + public void encode(final byte[] berValue, final SearchOptionsControl expected) + throws Exception + { + Assert.assertEquals(expected.encode(), berValue); + } +}
diff --git a/core/src/test/java/org/ldaptive/ad/control/VerifyNameControlTest.java b/core/src/test/java/org/ldaptive/ad/control/VerifyNameControlTest.java new file mode 100644 index 0000000..a3b499b --- /dev/null +++ b/core/src/test/java/org/ldaptive/ad/control/VerifyNameControlTest.java
@@ -0,0 +1,50 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link VerifyNameControl}. + * + * @author Middleware Services + */ +public class VerifyNameControlTest +{ + + + /** + * Verify name control test data. + * + * @return response test data + */ + @DataProvider(name = "request") + public Object[][] createData() + { + return + new Object[][] { + // BER: + // 30:14:02:01:00:04:0F:61:64:2E:6C:64:61:70:74:69:76:65:2E:6F:72:67 + new Object[] { + LdapUtils.base64Decode("MBQCAQAED2FkLmxkYXB0aXZlLm9yZw=="), + new VerifyNameControl("ad.ldaptive.org"), + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected verify name control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "request") + public void encode(final byte[] berValue, final VerifyNameControl expected) + throws Exception + { + Assert.assertEquals(expected.encode(), berValue); + } +}
diff --git a/core/src/test/java/org/ldaptive/ad/io/DeltaTimeValueTranscoderTest.java b/core/src/test/java/org/ldaptive/ad/io/DeltaTimeValueTranscoderTest.java new file mode 100644 index 0000000..442d86e --- /dev/null +++ b/core/src/test/java/org/ldaptive/ad/io/DeltaTimeValueTranscoderTest.java
@@ -0,0 +1,53 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.io; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link DeltaTimeValueTranscoder}. + * + * @author Middleware Services + */ +public class DeltaTimeValueTranscoderTest +{ + + /** Transcoder to test. */ + private final DeltaTimeValueTranscoder transcoder = new DeltaTimeValueTranscoder(); + + + /** + * Time test data. + * + * @return time test data + * + * @throws Exception if test data cannot be generated + */ + @DataProvider(name = "times") + public Object[][] createDates() + throws Exception + { + return new Object[][] { + new Object[] { + 2592000000L, + "-25920000000000", + }, + }; + } + + + /** + * @param millis to compare + * @param deltaTime ldap attribute string value + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "times") + public void testTranscode(final Long millis, final String deltaTime) + throws Exception + { + Assert.assertEquals(transcoder.decodeStringValue(deltaTime), millis); + Assert.assertEquals(transcoder.encodeStringValue(millis), deltaTime); + } +}
diff --git a/core/src/test/java/org/ldaptive/ad/io/FileTimeValueTranscoderTest.java b/core/src/test/java/org/ldaptive/ad/io/FileTimeValueTranscoderTest.java new file mode 100644 index 0000000..809f78d --- /dev/null +++ b/core/src/test/java/org/ldaptive/ad/io/FileTimeValueTranscoderTest.java
@@ -0,0 +1,96 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.io; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link FileTimeValueTranscoder}. + * + * @author Middleware Services + */ +public class FileTimeValueTranscoderTest +{ + + /** Transcoder to test. */ + private final FileTimeValueTranscoder transcoder = new FileTimeValueTranscoder(); + + + /** + * Time test data. + * + * @return time test data + * + * @throws Exception if test data cannot be generated + */ + @DataProvider(name = "times") + public Object[][] createDates() + throws Exception + { + return new Object[][] { + new Object[] { + createDateTime("Z", 2014, 1, 28, 21, 54, 27, 711), + "130354196677110000", + }, + new Object[] { + createDateTime("Z", 2016, 2, 18, 15, 31, 32, 327), + "131002830923270000", + }, + }; + } + + + /** + * @param date to compare + * @param fileTime ldap attribute string value + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "times") + public void decodeStringValue(final ZonedDateTime date, final String fileTime) + throws Exception + { + Assert.assertEquals(transcoder.decodeStringValue(fileTime), date); + } + + + /** + * @param date to compare + * @param fileTime ldap attribute string value + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "times") + public void encodeStringValue(final ZonedDateTime date, final String fileTime) + throws Exception + { + Assert.assertEquals(transcoder.encodeStringValue(date), fileTime); + } + + + /** + * Creates a date time for testing. + * + * @param timezone of the date time + * @param values corresponding to date time fields + * + * @return date time + */ + protected ZonedDateTime createDateTime(final String timezone, final int... values) + { + return ZonedDateTime.of( + LocalDateTime.of( + values[0], + values[1], + values[2], + values[3], + values.length > 4 ? values[4] : 0, + values.length > 5 ? values[5] : 0).plus(values.length > 6 ? values[6] : 0, ChronoUnit.MILLIS), + ZoneId.of(timezone)); + } +}
diff --git a/core/src/test/java/org/ldaptive/ad/io/UnicodePwdValueTranscoderTest.java b/core/src/test/java/org/ldaptive/ad/io/UnicodePwdValueTranscoderTest.java new file mode 100644 index 0000000..9f00adf --- /dev/null +++ b/core/src/test/java/org/ldaptive/ad/io/UnicodePwdValueTranscoderTest.java
@@ -0,0 +1,135 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.io; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link UnicodePwdValueTranscoder}. + * + * @author Middleware Services + */ +public class UnicodePwdValueTranscoderTest +{ + + /** Transcoder to test. */ + private final UnicodePwdValueTranscoder transcoder = new UnicodePwdValueTranscoder(); + + + /** + * Password test data. + * + * @return passwords + * + * @throws Exception if test data cannot be generated + */ + @DataProvider(name = "passwords") + public Object[][] createPasswords() + throws Exception + { + return + new Object[][] { + new Object[] { + "password", + LdapUtils.base64Decode("IgBwAGEAcwBzAHcAbwByAGQAIgA="), + }, + new Object[] { + "The quick brown fox jumps over the lazy dog", + LdapUtils.base64Decode( + "IgBUAGgAZQAgAHEAdQBpAGMAawAgAGIAcgBvAHcAbgAgAGYAbwB4ACAAagB1AG0A" + + "cABzACAAbwB2AGUAcgAgAHQAaABlACAAbABhAHoAeQAgAGQAbwBnACIA"), + }, + new Object[] { + "1234567890", + LdapUtils.base64Decode("IgAxADIAMwA0ADUANgA3ADgAOQAwACIA"), + }, + new Object[] { + "`~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?", + LdapUtils.base64Decode( + "IgBgAH4AIQBAACMAJAAlAF4AJgAqACgAKQAtAF8APQArAFsAewBdAH0AXAB8ADsA" + + "OgAnACIALAA8AC4APgAvAD8AIgA="), + }, + new Object[] { + "", + LdapUtils.base64Decode("IgAiAA=="), + }, + }; + } + + + /** + * Password test data. + * + * @return passwords + * + * @throws Exception if test data cannot be generated + */ + @DataProvider(name = "invalid") + public Object[][] createInvalidPasswords() + throws Exception + { + return new Object[][] { + new Object[] { + null, + new byte[0], + }, + }; + } + + + /** + * @param pwd to encode + * @param unicodePwd encoded password + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "passwords") + public void testTranscode(final String pwd, final byte[] unicodePwd) + throws Exception + { + Assert.assertEquals(transcoder.encodeBinaryValue(pwd), unicodePwd); + Assert.assertEquals(transcoder.decodeBinaryValue(unicodePwd), pwd); + Assert.assertEquals(transcoder.decodeStringValue(transcoder.encodeStringValue(pwd)), pwd); + Assert.assertEquals(transcoder.encodeStringValue(pwd), LdapUtils.utf8Encode(unicodePwd)); + Assert.assertEquals(transcoder.decodeStringValue(LdapUtils.utf8Encode(unicodePwd)), pwd); + } + + + /** + * @param pwd to encode + * @param unicodePwd encoded password + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "invalid") + public void testInvalid(final String pwd, final byte[] unicodePwd) + throws Exception + { + try { + transcoder.encodeStringValue(pwd); + Assert.fail("Should have thrown exception"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), IllegalArgumentException.class); + } + try { + transcoder.encodeBinaryValue(pwd); + Assert.fail("Should have thrown exception"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), IllegalArgumentException.class); + } + try { + transcoder.decodeStringValue(LdapUtils.utf8Encode(unicodePwd)); + Assert.fail("Should have thrown exception"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), IllegalArgumentException.class); + } + try { + transcoder.decodeBinaryValue(unicodePwd); + Assert.fail("Should have thrown exception"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), IllegalArgumentException.class); + } + } +}
diff --git a/core/src/test/java/org/ldaptive/asn1/DERPathTest.java b/core/src/test/java/org/ldaptive/asn1/DERPathTest.java new file mode 100644 index 0000000..d601cc6 --- /dev/null +++ b/core/src/test/java/org/ldaptive/asn1/DERPathTest.java
@@ -0,0 +1,107 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link DERPath} class. + * + * @author Middleware Services + */ +public class DERPathTest +{ + + /** @throws Exception On test failure. */ + @Test(groups = {"asn1"}) + public void testPushPop() + throws Exception + { + final DERPath path = new DERPath("/SEQ"); + path.pushNode("OCTSTR"); + Assert.assertEquals(path.toString(), "/SEQ/OCTSTR"); + Assert.assertEquals(path.popNode(), "OCTSTR"); + path.pushNode("INT", 1); + Assert.assertEquals(path.toString(), "/SEQ/INT[1]"); + Assert.assertEquals(path.popNode(), "INT[1]"); + Assert.assertEquals(path.popNode(), "SEQ"); + Assert.assertNull(path.popNode()); + Assert.assertNull(path.popNode()); + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"asn1"}) + public void testEquals() + throws Exception + { + Assert.assertTrue(new DERPath("/SEQ[0]/OCTSTR[1]").equals(new DERPath("/SEQ[0]/OCTSTR[1]"))); + Assert.assertFalse(new DERPath("/SEQ[0]/OCTSTR[1]").equals(new DERPath("/SEQ[0]/OCTSTR[2]"))); + Assert.assertFalse(new DERPath("/SEQ[0]/OCTSTR[1]").equals(new DERPath("/SEQ/OCTSTR[2]"))); + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"asn1"}) + public void testHashcode() + throws Exception + { + Assert.assertEquals(new DERPath("/SEQ[0]/OCTSTR[1]").hashCode(), new DERPath("/SEQ[0]/OCTSTR[1]").hashCode()); + Assert.assertFalse(new DERPath("/SEQ[0]/OCTSTR[1]").hashCode() == new DERPath("/SEQ[0]/OCTSTR[2]").hashCode()); + Assert.assertFalse(new DERPath("/SEQ[0]/OCTSTR[1]").hashCode() == new DERPath("/SEQ/OCTSTR[2]").hashCode()); + } + + /** + * DER path test data. + * + * @return der paths + */ + @DataProvider(name = "paths") + public Object[][] createTestParams() + { + return + new Object[][] { + new Object[] { + "/SET/SEQ/INT[1]", + "/SET/SEQ/INT[1]", + }, + new Object[] { + "/SET/CTX(0)/INT", + "/SET/CTX(0)/INT", + }, + new Object[] { + "/SET/APP(0)[1]/CTX(1)", + "/SET/APP(0)[1]/CTX(1)", + }, + }; + } + + + /** + * @param testPath to test + * @param expected to test + * + * @throws Exception On test failure. + */ + @Test(groups = {"asn1"}, dataProvider = "paths") + public void testToString(final String testPath, final String expected) + throws Exception + { + Assert.assertEquals(new DERPath(testPath).toString(), expected); + } + + + /** + * @param testPath to test + * @param expected to test + * + * @throws Exception On test failure. + */ + @Test(groups = {"asn1"}, dataProvider = "paths") + public void testEquals(final String testPath, final String expected) + throws Exception + { + Assert.assertTrue(new DERPath(testPath).equals(new DERPath(expected))); + } +}
diff --git a/core/src/test/java/org/ldaptive/asn1/DNTest.java b/core/src/test/java/org/ldaptive/asn1/DNTest.java new file mode 100644 index 0000000..b611c9d --- /dev/null +++ b/core/src/test/java/org/ldaptive/asn1/DNTest.java
@@ -0,0 +1,356 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.nio.ByteBuffer; +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link DN}. + * + * @author Middleware Services + */ +public class DNTest +{ + + + /** + * DN test data. + * + * @return test data + * + * @throws Exception On test failure. + */ + // CheckStyle:MethodLength OFF + @DataProvider(name = "dns") + public Object[][] createData() + throws Exception + { + return + new Object[][] { + // CN=www.ldaptive.org, DC=vt, DC=edu + // BER 30:4A:31:19:30:17:06:03:55:04:03:13:10:77:77:77:2E:6C:64:61:70:74 + // 69:76:65:2E:6F:72:67:31:18:30:16:06:0A:09:92:26:89:93:F2:2C:64:01 + // 19:16:08:6C:64:61:70:74:69:76:65:31:13:30:11:06:0A:09:92:26:89:93 + // F2:2C:64:01:19:16:03:6F:72:67: + new Object[] { + new byte[] { + (byte) 0x30, (byte) 0x4A, (byte) 0x31, (byte) 0x19, (byte) 0x30, + (byte) 0x17, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x03, (byte) 0x13, (byte) 0x10, (byte) 0x77, (byte) 0x77, + (byte) 0x77, (byte) 0x2E, (byte) 0x6C, (byte) 0x64, (byte) 0x61, + (byte) 0x70, (byte) 0x74, (byte) 0x69, (byte) 0x76, (byte) 0x65, + (byte) 0x2E, (byte) 0x6F, (byte) 0x72, (byte) 0x67, (byte) 0x31, + (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x06, (byte) 0x0A, + (byte) 0x09, (byte) 0x92, (byte) 0x26, (byte) 0x89, (byte) 0x93, + (byte) 0xF2, (byte) 0x2C, (byte) 0x64, (byte) 0x01, (byte) 0x19, + (byte) 0x16, (byte) 0x08, (byte) 0x6C, (byte) 0x64, (byte) 0x61, + (byte) 0x70, (byte) 0x74, (byte) 0x69, (byte) 0x76, (byte) 0x65, + (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, + (byte) 0x0A, (byte) 0x09, (byte) 0x92, (byte) 0x26, (byte) 0x89, + (byte) 0x93, (byte) 0xF2, (byte) 0x2C, (byte) 0x64, (byte) 0x01, + (byte) 0x19, (byte) 0x16, (byte) 0x03, (byte) 0x6F, (byte) 0x72, + (byte) 0x67, + }, + new DN( + new RDN( + new AttributeValueAssertion( + "2.5.4.3", + new AttributeValueAssertion.Value(UniversalDERTag.PRINTSTR, "www.ldaptive.org".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "0.9.2342.19200300.100.1.25", + new AttributeValueAssertion.Value(UniversalDERTag.IA5STR, "ldaptive".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "0.9.2342.19200300.100.1.25", + new AttributeValueAssertion.Value(UniversalDERTag.IA5STR, "org".getBytes("UTF-8"))))), + }, + // DC=org, DC=ldaptive, UID=7 + CN=www.ldaptive.org + // BER 30:5B:31:2A:30:0F:06:0A:09:92:26:89:93:F2:2C:64:01:01:13:01:37:30 + // 17:06:03:55:04:03:13:10:77:77:77:2E:6C:64:61:70:74:69:76:65:2E:6F + // 72:67:31:18:30:16:06:0A:09:92:26:89:93:F2:2C:64:01:19:16:08:6C:64 + // 61:70:74:69:76:65:31:13:30:11:06:0A:09:92:26:89:93:F2:2C:64:01:19 + // 16:03:6F:72:67: + new Object[] { + new byte[] { + (byte) 0x30, (byte) 0x5B, (byte) 0x31, (byte) 0x2A, (byte) 0x30, + (byte) 0x0F, (byte) 0x06, (byte) 0x0A, (byte) 0x09, (byte) 0x92, + (byte) 0x26, (byte) 0x89, (byte) 0x93, (byte) 0xF2, (byte) 0x2C, + (byte) 0x64, (byte) 0x01, (byte) 0x01, (byte) 0x13, (byte) 0x01, + (byte) 0x37, (byte) 0x30, (byte) 0x17, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x13, (byte) 0x10, + (byte) 0x77, (byte) 0x77, (byte) 0x77, (byte) 0x2E, (byte) 0x6C, + (byte) 0x64, (byte) 0x61, (byte) 0x70, (byte) 0x74, (byte) 0x69, + (byte) 0x76, (byte) 0x65, (byte) 0x2E, (byte) 0x6F, (byte) 0x72, + (byte) 0x67, (byte) 0x31, (byte) 0x18, (byte) 0x30, (byte) 0x16, + (byte) 0x06, (byte) 0x0A, (byte) 0x09, (byte) 0x92, (byte) 0x26, + (byte) 0x89, (byte) 0x93, (byte) 0xF2, (byte) 0x2C, (byte) 0x64, + (byte) 0x01, (byte) 0x19, (byte) 0x16, (byte) 0x08, (byte) 0x6C, + (byte) 0x64, (byte) 0x61, (byte) 0x70, (byte) 0x74, (byte) 0x69, + (byte) 0x76, (byte) 0x65, (byte) 0x31, (byte) 0x13, (byte) 0x30, + (byte) 0x11, (byte) 0x06, (byte) 0x0A, (byte) 0x09, (byte) 0x92, + (byte) 0x26, (byte) 0x89, (byte) 0x93, (byte) 0xF2, (byte) 0x2C, + (byte) 0x64, (byte) 0x01, (byte) 0x19, (byte) 0x16, (byte) 0x03, + (byte) 0x6F, (byte) 0x72, (byte) 0x67, + }, + new DN( + new RDN( + new AttributeValueAssertion( + "0.9.2342.19200300.100.1.1", + new AttributeValueAssertion.Value(UniversalDERTag.PRINTSTR, "7".getBytes("UTF-8"))), + new AttributeValueAssertion( + "2.5.4.3", + new AttributeValueAssertion.Value(UniversalDERTag.PRINTSTR, "www.ldaptive.org".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "0.9.2342.19200300.100.1.25", + new AttributeValueAssertion.Value(UniversalDERTag.IA5STR, "ldaptive".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "0.9.2342.19200300.100.1.25", + new AttributeValueAssertion.Value(UniversalDERTag.IA5STR, "org".getBytes("UTF-8"))))), + }, + // O="CN=www.apache.org, foo", CN=www.example.org + // BER 30:3B:31:18:30:16:06:03:55:04:03:13:0F:77:77:77:2E:65:78:61:6D:70 + // 6C:65:2E:6F:72:67:31:1F:30:1D:06:03:55:04:0A:13:16:43:4E:3D:77:77 + // 77:2E:61:70:61:63:68:65:2E:6F:72:67:2C:20:66:6F:6F: + new Object[] { + new byte[]{ + (byte) 0x30, (byte) 0x3B, (byte) 0x31, (byte) 0x18, (byte) 0x30, + (byte) 0x16, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x03, (byte) 0x13, (byte) 0x0F, (byte) 0x77, (byte) 0x77, + (byte) 0x77, (byte) 0x2E, (byte) 0x65, (byte) 0x78, (byte) 0x61, + (byte) 0x6D, (byte) 0x70, (byte) 0x6C, (byte) 0x65, (byte) 0x2E, + (byte) 0x6F, (byte) 0x72, (byte) 0x67, (byte) 0x31, (byte) 0x1F, + (byte) 0x30, (byte) 0x1D, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x0A, (byte) 0x13, (byte) 0x16, (byte) 0x43, + (byte) 0x4E, (byte) 0x3D, (byte) 0x77, (byte) 0x77, (byte) 0x77, + (byte) 0x2E, (byte) 0x61, (byte) 0x70, (byte) 0x61, (byte) 0x63, + (byte) 0x68, (byte) 0x65, (byte) 0x2E, (byte) 0x6F, (byte) 0x72, + (byte) 0x67, (byte) 0x2C, (byte) 0x20, (byte) 0x66, (byte) 0x6F, + (byte) 0x6F, + }, + new DN( + new RDN( + new AttributeValueAssertion( + "2.5.4.3", + new AttributeValueAssertion.Value(UniversalDERTag.PRINTSTR, "www.example.org".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.10", + new AttributeValueAssertion.Value( + UniversalDERTag.PRINTSTR, + "CN=www.apache.org, foo".getBytes("UTF-8"))))), + }, + // O="foo, CN=www.apache.org,", CN=www.example.org + // BER 30:3C:31:18:30:16:06:03:55:04:03:13:0F:77:77:77:2E:65:78:61:6D:70 + // 6C:65:2E:6F:72:67:31:20:30:1E:06:03:55:04:0A:13:17:66:6F:6F:2C:20 + // 43:4E:3D:77:77:77:2E:61:70:61:63:68:65:2E:6F:72:67:2C: + new Object[] { + new byte[]{ + (byte) 0x30, (byte) 0x3C, (byte) 0x31, (byte) 0x18, (byte) 0x30, + (byte) 0x16, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x03, (byte) 0x13, (byte) 0x0F, (byte) 0x77, (byte) 0x77, + (byte) 0x77, (byte) 0x2E, (byte) 0x65, (byte) 0x78, (byte) 0x61, + (byte) 0x6D, (byte) 0x70, (byte) 0x6C, (byte) 0x65, (byte) 0x2E, + (byte) 0x6F, (byte) 0x72, (byte) 0x67, (byte) 0x31, (byte) 0x20, + (byte) 0x30, (byte) 0x1E, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x0A, (byte) 0x13, (byte) 0x17, (byte) 0x66, + (byte) 0x6F, (byte) 0x6F, (byte) 0x2C, (byte) 0x20, (byte) 0x43, + (byte) 0x4E, (byte) 0x3D, (byte) 0x77, (byte) 0x77, (byte) 0x77, + (byte) 0x2E, (byte) 0x61, (byte) 0x70, (byte) 0x61, (byte) 0x63, + (byte) 0x68, (byte) 0x65, (byte) 0x2E, (byte) 0x6F, (byte) 0x72, + (byte) 0x67, (byte) 0x2C, + }, + new DN( + new RDN( + new AttributeValueAssertion( + "2.5.4.3", + new AttributeValueAssertion.Value(UniversalDERTag.PRINTSTR, "www.example.org".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.10", + new AttributeValueAssertion.Value( + UniversalDERTag.PRINTSTR, + "foo, CN=www.apache.org,".getBytes("UTF-8"))))), + }, + // CN=login.live.com, OU=Passport, O=Microsoft Corporation, + // STREET=One Microsoft Way, L=Redmond, ST=Washington, + // OID.2.5.4.17=98052, C=US, SERIALNUMBER=600413485, + // OID.2.5.4.15="V1.0, Clause 5.(b)", + // OID.1.3.6.1.4.1.311.60.2.1.2=Washington, + // OID.1.3.6.1.4.1.311.60.2.1.3=US + // BER 30:84:00:00:01:0F:31:13:30:11:06:0B:2B:06:01:04:01:82:37:3C:02:01 + // 03:13:02:55:53:31:1B:30:19:06:0B:2B:06:01:04:01:82:37:3C:02:01:02 + // 13:0A:57:61:73:68:69:6E:67:74:6F:6E:31:1B:30:19:06:03:55:04:0F:13 + // 12:56:31:2E:30:2C:20:43:6C:61:75:73:65:20:35:2E:28:62:29:31:12:30 + // 10:06:03:55:04:05:13:09:36:30:30:34:31:33:34:38:35:31:0B:30:09:06 + // 03:55:04:06:13:02:55:53:31:0E:30:0C:06:03:55:04:11:14:05:39:38:30 + // 35:32:31:13:30:11:06:03:55:04:08:13:0A:57:61:73:68:69:6E:67:74:6F + // 6E:31:10:30:0E:06:03:55:04:07:14:07:52:65:64:6D:6F:6E:64:31:1A:30 + // 18:06:03:55:04:09:14:11:4F:6E:65:20:4D:69:63:72:6F:73:6F:66:74:20 + // 57:61:79:31:1E:30:1C:06:03:55:04:0A:14:15:4D:69:63:72:6F:73:6F:66 + // 74:20:43:6F:72:70:6F:72:61:74:69:6F:6E:31:11:30:0F:06:03:55:04:0B + // 14:08:50:61:73:73:70:6F:72:74:31:17:30:15:06:03:55:04:03:14:0E:6C + // 6F:67:69:6E:2E:6C:69:76:65:2E:63:6F:6D: + new Object[] { + LdapUtils.base64Decode( + "MIQAAAEPMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRswGQYLKwYBBAGCNzwCAQITCldh" + + "c2hpbmd0b24xGzAZBgNVBA8TElYxLjAsIENsYXVzZSA1LihiKTESMBAGA1UEBRMJ" + + "NjAwNDEzNDg1MQswCQYDVQQGEwJVUzEOMAwGA1UEERQFOTgwNTIxEzARBgNVBAgT" + + "Cldhc2hpbmd0b24xEDAOBgNVBAcUB1JlZG1vbmQxGjAYBgNVBAkUEU9uZSBNaWNy" + + "b3NvZnQgV2F5MR4wHAYDVQQKFBVNaWNyb3NvZnQgQ29ycG9yYXRpb24xETAPBgNV" + + "BAsUCFBhc3Nwb3J0MRcwFQYDVQQDFA5sb2dpbi5saXZlLmNvbQ=="), + new DN( + new RDN( + new AttributeValueAssertion( + "1.3.6.1.4.1.311.60.2.1.3", + new AttributeValueAssertion.Value(UniversalDERTag.PRINTSTR, "US".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "1.3.6.1.4.1.311.60.2.1.2", + new AttributeValueAssertion.Value(UniversalDERTag.PRINTSTR, "Washington".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.15", + new AttributeValueAssertion.Value(UniversalDERTag.PRINTSTR, "V1.0, Clause 5.(b)".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.5", + new AttributeValueAssertion.Value(UniversalDERTag.PRINTSTR, "600413485".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.6", + new AttributeValueAssertion.Value(UniversalDERTag.PRINTSTR, "US".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.17", + new AttributeValueAssertion.Value(UniversalDERTag.T61STR, "98052".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.8", + new AttributeValueAssertion.Value(UniversalDERTag.PRINTSTR, "Washington".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.7", + new AttributeValueAssertion.Value(UniversalDERTag.T61STR, "Redmond".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.9", + new AttributeValueAssertion.Value(UniversalDERTag.T61STR, "One Microsoft Way".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.10", + new AttributeValueAssertion.Value(UniversalDERTag.T61STR, "Microsoft Corporation".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.11", + new AttributeValueAssertion.Value(UniversalDERTag.T61STR, "Passport".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.3", + new AttributeValueAssertion.Value(UniversalDERTag.T61STR, "login.live.com".getBytes("UTF-8"))))), + }, + // C=US, DC=edu, DC=vt, ST=Virginia, L=Blacksburg, + // O=Virginia Polytechnic Institute and State University, + // OU=Middleware-Client, OU=SETI, SERIALNUMBER=1248110657961, + // CN=glider.cc.vt.edu + // BER 30:84:00:00:00:FA:31:19:30:17:06:03:55:04:03:0C:10:67:6C:69:64:65 + // 72:2E:63:63:2E:76:74:2E:65:64:75:31:16:30:14:06:03:55:04:05:13:0D + // 31:32:34:38:31:31:30:36:35:37:39:36:31:31:0D:30:0B:06:03:55:04:0B + // 0C:04:53:45:54:49:31:1A:30:18:06:03:55:04:0B:0C:11:4D:69:64:64:6C + // 65:77:61:72:65:2D:43:6C:69:65:6E:74:31:3C:30:3A:06:03:55:04:0A:0C + // 33:56:69:72:67:69:6E:69:61:20:50:6F:6C:79:74:65:63:68:6E:69:63:20 + // 49:6E:73:74:69:74:75:74:65:20:61:6E:64:20:53:74:61:74:65:20:55:6E + // 69:76:65:72:73:69:74:79:31:13:30:11:06:03:55:04:07:0C:0A:42:6C:61 + // 63:6B:73:62:75:72:67:31:11:30:0F:06:03:55:04:08:0C:08:56:69:72:67 + // 69:6E:69:61:31:12:30:10:06:0A:09:92:26:89:93:F2:2C:64:01:19:16:02 + // 76:74:31:13:30:11:06:0A:09:92:26:89:93:F2:2C:64:01:19:16:03:65:64 + // 75:31:0B:30:09:06:03:55:04:06:13:02:55:53: + new Object[] { + LdapUtils.base64Decode( + "MIQAAAD6MRkwFwYDVQQDDBBnbGlkZXIuY2MudnQuZWR1MRYwFAYDVQQFEw0xMjQ4" + + "MTEwNjU3OTYxMQ0wCwYDVQQLDARTRVRJMRowGAYDVQQLDBFNaWRkbGV3YXJlLUNs" + + "aWVudDE8MDoGA1UECgwzVmlyZ2luaWEgUG9seXRlY2huaWMgSW5zdGl0dXRlIGFu" + + "ZCBTdGF0ZSBVbml2ZXJzaXR5MRMwEQYDVQQHDApCbGFja3NidXJnMREwDwYDVQQI" + + "DAhWaXJnaW5pYTESMBAGCgmSJomT8ixkARkWAnZ0MRMwEQYKCZImiZPyLGQBGRYD" + + "ZWR1MQswCQYDVQQGEwJVUw=="), + new DN( + new RDN( + new AttributeValueAssertion( + "2.5.4.3", + new AttributeValueAssertion.Value(UniversalDERTag.UTF8STR, "glider.cc.vt.edu".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.5", + new AttributeValueAssertion.Value(UniversalDERTag.PRINTSTR, "1248110657961".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.11", + new AttributeValueAssertion.Value(UniversalDERTag.UTF8STR, "SETI".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.11", + new AttributeValueAssertion.Value(UniversalDERTag.UTF8STR, "Middleware-Client".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.10", + new AttributeValueAssertion.Value( + UniversalDERTag.UTF8STR, + "Virginia Polytechnic Institute and State University".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.7", + new AttributeValueAssertion.Value(UniversalDERTag.UTF8STR, "Blacksburg".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.8", + new AttributeValueAssertion.Value(UniversalDERTag.UTF8STR, "Virginia".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "0.9.2342.19200300.100.1.25", + new AttributeValueAssertion.Value(UniversalDERTag.IA5STR, "vt".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "0.9.2342.19200300.100.1.25", + new AttributeValueAssertion.Value(UniversalDERTag.IA5STR, "edu".getBytes("UTF-8")))), + new RDN( + new AttributeValueAssertion( + "2.5.4.6", + new AttributeValueAssertion.Value(UniversalDERTag.PRINTSTR, "US".getBytes("UTF-8"))))), + }, + }; + } + // CheckStyle:MethodLength ON + + + /** + * @param bytes to decode. + * @param expected to compare. + * + * @throws Exception On test failure. + */ + @Test(groups = {"asn1"}, dataProvider = "dns") + public void decode(final byte[] bytes, final DN expected) + throws Exception + { + Assert.assertEquals(DN.decode(ByteBuffer.wrap(bytes)), expected); + } + + + /** + * @param expected bytes to compare. + * @param sequence to encode. + * + * @throws Exception On test failure. + */ + @Test(groups = {"asn1"}, dataProvider = "dns") + public void encode(final byte[] expected, final DN sequence) + throws Exception + { + Assert.assertEquals(sequence.encode(), expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/asn1/IntegerTypeTest.java b/core/src/test/java/org/ldaptive/asn1/IntegerTypeTest.java new file mode 100644 index 0000000..ff55df3 --- /dev/null +++ b/core/src/test/java/org/ldaptive/asn1/IntegerTypeTest.java
@@ -0,0 +1,161 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.math.BigInteger; +import java.nio.ByteBuffer; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link IntegerType}. + * + * @author Middleware Services + */ +public class IntegerTypeTest +{ + + + /** + * Integer test data. + * + * @return test data + */ + @DataProvider(name = "ints") + public Object[][] createData() + { + return + new Object[][] { + new Object[] { + new byte[] {(byte) 0x00, }, + new BigInteger("0"), + new BigInteger("0"), + }, + new Object[] { + new byte[] {(byte) 0x01, }, + new BigInteger("1"), + new BigInteger("1"), + }, + new Object[] { + new byte[] {(byte) 0x7F, }, + new BigInteger("127"), + new BigInteger("127"), + }, + new Object[] { + new byte[] {(byte) 0x80, }, + new BigInteger("-128"), + new BigInteger("128"), + }, + new Object[] { + new byte[] {(byte) 0xFF, }, + new BigInteger("-1"), + new BigInteger("255"), + }, + new Object[] { + new byte[] {(byte) 0x01, (byte) 0x00, }, + new BigInteger("256"), + new BigInteger("256"), + }, + new Object[] { + new byte[] {(byte) 0x01, (byte) 0x7F, }, + new BigInteger("383"), + new BigInteger("383"), + }, + new Object[] { + new byte[] {(byte) 0x01, (byte) 0x80, }, + new BigInteger("384"), + new BigInteger("384"), + }, + new Object[] { + new byte[] {(byte) 0x01, (byte) 0xFF, }, + new BigInteger("511"), + new BigInteger("511"), + }, + new Object[] { + new byte[] {(byte) 0x02, (byte) 0x00, }, + new BigInteger("512"), + new BigInteger("512"), + }, + new Object[] { + new byte[] {(byte) 0x7F, (byte) 0x00, }, + new BigInteger("32512"), + new BigInteger("32512"), + }, + new Object[] { + new byte[] {(byte) 0x7F, (byte) 0xFF, }, + new BigInteger("32767"), + new BigInteger("32767"), + }, + new Object[] { + new byte[] {(byte) 0x80, (byte) 0x00, }, + new BigInteger("-32768"), + new BigInteger("32768"), + }, + new Object[] { + new byte[] {(byte) 0xFF, (byte) 0x00, }, + new BigInteger("-256"), + new BigInteger("65280"), + }, + new Object[] { + new byte[] {(byte) 0xFF, (byte) 0x7F, }, + new BigInteger("-129"), + new BigInteger("65407"), + }, + new Object[] { + new byte[] {(byte) 0xFF, (byte) 0xFF, }, + new BigInteger("-1"), + new BigInteger("65535"), + }, + }; + } + + + /** + * @param bytes to decode. + * @param expected int to compare. + * @param unsigned int to compare. + * + * @throws Exception On test failure. + */ + @Test(groups = {"asn1"}, dataProvider = "ints") + public void decode(final byte[] bytes, final BigInteger expected, final BigInteger unsigned) + throws Exception + { + Assert.assertEquals(IntegerType.decode(ByteBuffer.wrap(bytes)), expected); + } + + + /** + * @param bytes to decode. + * @param expected int to compare. + * @param unsigned int to compare. + * + * @throws Exception On test failure. + */ + @Test(groups = {"asn1"}, dataProvider = "ints") + public void decodeUnsigned(final byte[] bytes, final BigInteger expected, final BigInteger unsigned) + throws Exception + { + Assert.assertEquals(IntegerType.decodeUnsigned(ByteBuffer.wrap(bytes)), unsigned); + } + + + /** + * @param expected bytes to compare. + * @param integer to encode. + * @param unsigned int to compare. + * + * @throws Exception On test failure. + */ + @Test(groups = {"asn1"}, dataProvider = "ints") + public void encode(final byte[] expected, final BigInteger integer, final BigInteger unsigned) + throws Exception + { + if (integer.intValue() == -1 && expected.length > 1) { + // ignore multi byte negative 1 + return; + } else { + Assert.assertEquals(IntegerType.toBytes(integer), expected); + } + } +}
diff --git a/core/src/test/java/org/ldaptive/asn1/OidTypeTest.java b/core/src/test/java/org/ldaptive/asn1/OidTypeTest.java new file mode 100644 index 0000000..153f93a --- /dev/null +++ b/core/src/test/java/org/ldaptive/asn1/OidTypeTest.java
@@ -0,0 +1,171 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.nio.ByteBuffer; +import org.testng.Assert; +import org.testng.AssertJUnit; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link OidType}. + * + * @author Middleware Services + */ +public class OidTypeTest +{ + + + /** + * OID test data. + * + * @return test data + */ + @DataProvider(name = "oids") + public Object[][] createData() + { + return + new Object[][] { + new Object[] { + new byte[] {(byte) 0x01, }, + "0.1", + }, + // account + new Object[] { + new byte[] { + (byte) 0x09, (byte) 0x92, (byte) 0x26, (byte) 0x89, (byte) 0x93, + (byte) 0xF2, (byte) 0x2C, (byte) 0x64, (byte) 0x04, (byte) 0x05, + }, + "0.9.2342.19200300.100.4.5", + }, + // altServer + new Object[] { + new byte[] { + (byte) 0x2B, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x01, + (byte) 0x8B, (byte) 0x3A, (byte) 0x65, (byte) 0x78, (byte) 0x06, + }, + "1.3.6.1.4.1.1466.101.120.6", + }, + // aRecord + new Object[] { + new byte[] { + (byte) 0x09, (byte) 0x92, (byte) 0x26, (byte) 0x89, (byte) 0x93, + (byte) 0xF2, (byte) 0x2C, (byte) 0x64, (byte) 0x01, (byte) 0x1A, + }, + "0.9.2342.19200300.100.1.26", + }, + // associatedORAddress + new Object[] { + new byte[] { + (byte) 0x2B, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x01, + (byte) 0x83, (byte) 0x45, (byte) 0x07, (byte) 0x02, (byte) 0x06, + }, + "1.3.6.1.4.1.453.7.2.6", + }, + // attributeTypes + new Object[] { + new byte[] {(byte) 0x55, (byte) 0x15, (byte) 0x05, }, + "2.5.21.5", + }, + // calCalURI + new Object[] { + new byte[] { + (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7, + (byte) 0x14, (byte) 0x01, (byte) 0x04, (byte) 0x83, (byte) 0x5E, + }, + "1.2.840.113556.1.4.478", + }, + // caseExactIA5Match + new Object[] { + new byte[] { + (byte) 0x2B, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x01, + (byte) 0x8B, (byte) 0x3A, (byte) 0x6D, (byte) 0x72, (byte) 0x01, + }, + "1.3.6.1.4.1.1466.109.114.1", + }, + // CN + new Object[] { + new byte[] {(byte) 0x55, (byte) 0x04, (byte) 0x03, }, + "2.5.4.3", + }, + // distinguishedNameTableKey + new Object[] { + new byte[] { + (byte) 0x2B, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x01, + (byte) 0x83, (byte) 0x45, (byte) 0x07, (byte) 0x02, (byte) 0x03, + }, + "1.3.6.1.4.1.453.7.2.3", + }, + }; + } + + + /** + * OID test data. + * + * @return test data + */ + @DataProvider(name = "invalid-oids") + public Object[][] createInvalidData() + { + return + new Object[][] { + new Object[] {null, }, + new Object[] {"", }, + new Object[] {"0", }, + new Object[] {"1", }, + new Object[] {"2", }, + new Object[] {"3.1", }, + new Object[] {"..1", }, + new Object[] {"192.168.1.1", }, + new Object[] {".123452", }, + new Object[] {"1.", }, + new Object[] {"1.345.23.34..234", }, + new Object[] {"1.345.23.34.234.", }, + new Object[] {".12.345.77.234", }, + new Object[] {".12.345.77.234.", }, + new Object[] {"1.2.3.4.A.5", }, + new Object[] {"1,2", }, + }; + } + + + /** + * @param bytes to decode. + * @param expected oid to compare. + * + * @throws Exception On test failure. + */ + @Test(groups = {"asn1"}, dataProvider = "oids") + public void decode(final byte[] bytes, final String expected) + throws Exception + { + Assert.assertEquals(OidType.decode(ByteBuffer.wrap(bytes)), expected); + } + + + /** + * @param expected bytes to compare. + * @param oid to encode. + * + * @throws Exception On test failure. + */ + @Test(groups = {"asn1"}, dataProvider = "oids") + public void encode(final byte[] expected, final String oid) + throws Exception + { + Assert.assertEquals(OidType.toBytes(OidType.parse(oid)), expected); + } + + + /** @param oid to encode. */ + @Test(groups = {"asn1"}, dataProvider = "invalid-oids") + public void invalid(final String oid) + { + try { + new OidType(oid); + } catch (Exception e) { + AssertJUnit.assertEquals(IllegalArgumentException.class, e.getClass()); + } + } +}
diff --git a/core/src/test/java/org/ldaptive/asn1/UuidTypeTest.java b/core/src/test/java/org/ldaptive/asn1/UuidTypeTest.java new file mode 100644 index 0000000..a749289 --- /dev/null +++ b/core/src/test/java/org/ldaptive/asn1/UuidTypeTest.java
@@ -0,0 +1,80 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.asn1; + +import java.nio.ByteBuffer; +import java.util.UUID; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link UuidType}. + * + * @author Middleware Services + */ +public class UuidTypeTest +{ + + + /** + * UUID test data. + * + * @return test data + */ + @DataProvider(name = "uuids") + public Object[][] createData() + { + return + new Object[][] { + new Object[] { + new byte[] { + (byte) 0x12, + (byte) 0xE8, + (byte) 0xB3, + (byte) 0xA0, + (byte) 0x5E, + (byte) 0x58, + (byte) 0x10, + (byte) 0x31, + (byte) 0x82, + (byte) 0xBD, + (byte) 0x11, + (byte) 0x6F, + (byte) 0xF5, + (byte) 0x6E, + (byte) 0x4E, + (byte) 0x59, + }, + UUID.fromString("12e8b3a0-5e58-1031-82bd-116ff56e4e59"), + }, + }; + } + + + /** + * @param bytes to decode. + * @param expected uuid to compare. + * + * @throws Exception On test failure. + */ + @Test(groups = {"asn1"}, dataProvider = "uuids") + public void decode(final byte[] bytes, final UUID expected) + throws Exception + { + Assert.assertEquals(UuidType.decode(ByteBuffer.wrap(bytes)), expected); + } + + + /** + * @param expected bytes to compare. + * @param uuid to encode. + * + * @throws Exception On test failure. + */ + @Test(groups = {"asn1"}, dataProvider = "uuids") + public void encode(final byte[] expected, final UUID uuid) + throws Exception + { + Assert.assertEquals(UuidType.toBytes(uuid), expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/auth/ext/ActiveDirectoryAccountStateTest.java b/core/src/test/java/org/ldaptive/auth/ext/ActiveDirectoryAccountStateTest.java new file mode 100644 index 0000000..1546a80 --- /dev/null +++ b/core/src/test/java/org/ldaptive/auth/ext/ActiveDirectoryAccountStateTest.java
@@ -0,0 +1,90 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth.ext; + +import org.testng.AssertJUnit; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link ActiveDirectoryAccountState}. + * + * @author Middleware Services + */ +public class ActiveDirectoryAccountStateTest +{ + + + /** + * AD test data. + * + * @return error messages + */ + @DataProvider(name = "errors") + public Object[][] createTestParams() + { + return + new Object[][] { + new Object[] { + "80090308: LdapErr: DSID-0C09030B, comment: " + + "AcceptSecurityContext error, data 525, v893", + ActiveDirectoryAccountState.Error.NO_SUCH_USER, + }, + new Object[] { + "80090308: LdapErr: DSID-0C09030B, comment: " + + "AcceptSecurityContext error, data 52e, v893", + ActiveDirectoryAccountState.Error.LOGON_FAILURE, + }, + new Object[] { + "80090308: LdapErr: DSID-0C09030B, comment: " + + "AcceptSecurityContext error, data 530, v893", + ActiveDirectoryAccountState.Error.INVALID_LOGON_HOURS, + }, + new Object[] { + "80090308: LdapErr: DSID-0C09030B, comment: " + + "AcceptSecurityContext error, data 531, v893", + ActiveDirectoryAccountState.Error.INVALID_WORKSTATION, + }, + new Object[] { + "80090308: LdapErr: DSID-0C09030B, comment: " + + "AcceptSecurityContext error, data 532, v893", + ActiveDirectoryAccountState.Error.PASSWORD_EXPIRED, + }, + new Object[] { + "80090308: LdapErr: DSID-0C09030B, comment: " + + "AcceptSecurityContext error, data 533, v893", + ActiveDirectoryAccountState.Error.ACCOUNT_DISABLED, + }, + new Object[] { + "80090308: LdapErr: DSID-0C09030B, comment: " + + "AcceptSecurityContext error, data 701, v893", + ActiveDirectoryAccountState.Error.ACCOUNT_EXPIRED, + }, + new Object[] { + "80090308: LdapErr: DSID-0C09030B, comment: " + + "AcceptSecurityContext error, data 773, v893", + ActiveDirectoryAccountState.Error.PASSWORD_MUST_CHANGE, + }, + new Object[] { + "80090308: LdapErr: DSID-0C09030B, comment: " + + "AcceptSecurityContext error, data 775, v893", + ActiveDirectoryAccountState.Error.ACCOUNT_LOCKED_OUT, + }, + }; + } + + + /** + * Tests message parsing. + * + * @param message error message + * @param err corresponding error enum + * + * @throws Exception On test failure. + */ + @Test(groups = {"auth-ext"}, dataProvider = "errors") + public void parseMessage(final String message, final ActiveDirectoryAccountState.Error err) + throws Exception + { + AssertJUnit.assertEquals(err, ActiveDirectoryAccountState.Error.parse(message)); + } +}
diff --git a/core/src/test/java/org/ldaptive/auth/ext/EDirectoryAccountStateTest.java b/core/src/test/java/org/ldaptive/auth/ext/EDirectoryAccountStateTest.java new file mode 100644 index 0000000..960541f --- /dev/null +++ b/core/src/test/java/org/ldaptive/auth/ext/EDirectoryAccountStateTest.java
@@ -0,0 +1,74 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth.ext; + +import org.testng.AssertJUnit; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link EDirectoryAccountState}. + * + * @author Middleware Services + */ +public class EDirectoryAccountStateTest +{ + + + /** + * EDirectory test data. + * + * @return error messages + */ + @DataProvider(name = "errors") + public Object[][] createTestParams() + { + return + new Object[][] { + new Object[] { + "LDAP: error code 49 - NDS error: failed authentication (-669)", + EDirectoryAccountState.Error.FAILED_AUTHENTICATION, + }, + new Object[] { + "LDAP: error code 49 - NDS error: password expired (-223)", + EDirectoryAccountState.Error.PASSWORD_EXPIRED, + }, + new Object[] { + "LDAP: error code 49 - NDS error: bad password (-222)", + EDirectoryAccountState.Error.BAD_PASSWORD, + }, + new Object[] { + "LDAP: error code 49 - NDS error: log account expired (-220)", + EDirectoryAccountState.Error.ACCOUNT_EXPIRED, + }, + new Object[] { + "LDAP: error code 49 - NDS error: " + + "maximum logins exceeded or Q stn not server (-217)", + EDirectoryAccountState.Error.MAXIMUM_LOGINS_EXCEEDED, + }, + new Object[] { + "LDAP: error code 49 - NDS error: bad login time or Q halted (-218)", + EDirectoryAccountState.Error.LOGIN_TIME_LIMITED, + }, + new Object[] { + "LDAP: error code 49 - NDS error: login lockout (-197)", + EDirectoryAccountState.Error.LOGIN_LOCKOUT, + }, + }; + } + + + /** + * Tests message parsing. + * + * @param message error message + * @param err corresponding error enum + * + * @throws Exception On test failure. + */ + @Test(groups = {"auth-ext"}, dataProvider = "errors") + public void parseMessage(final String message, final EDirectoryAccountState.Error err) + throws Exception + { + AssertJUnit.assertEquals(err, EDirectoryAccountState.Error.parse(message)); + } +}
diff --git a/core/src/test/java/org/ldaptive/auth/ext/FreeIPAAccountStateTest.java b/core/src/test/java/org/ldaptive/auth/ext/FreeIPAAccountStateTest.java new file mode 100644 index 0000000..88ba5e0 --- /dev/null +++ b/core/src/test/java/org/ldaptive/auth/ext/FreeIPAAccountStateTest.java
@@ -0,0 +1,92 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth.ext; + +import org.ldaptive.ResultCode; +import org.testng.AssertJUnit; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link FreeIPAAccountState}. + * + * @author Middleware Services + */ +public class FreeIPAAccountStateTest +{ + + + /** + * FreeIPA test data. + * + * @return error messages + */ + @DataProvider(name = "errors") + public Object[][] createTestParams() + { + return + new Object[][] { + new Object[] { + ResultCode.NO_SUCH_OBJECT, + null, + FreeIPAAccountState.Error.ACCOUNT_NOT_FOUND, + }, + new Object[] { + ResultCode.INVALID_CREDENTIALS, + null, + FreeIPAAccountState.Error.CREDENTIAL_NOT_FOUND, + }, + new Object[] { + ResultCode.INSUFFICIENT_ACCESS_RIGHTS, + null, + FreeIPAAccountState.Error.FAILED_AUTHENTICATION, + }, + new Object[] { + ResultCode.UNWILLING_TO_PERFORM, + "Entry permanently locked.\n", + FreeIPAAccountState.Error.LOGIN_LOCKOUT, + }, + new Object[] { + ResultCode.UNWILLING_TO_PERFORM, + "Too many failed logins.\n", + FreeIPAAccountState.Error.MAXIMUM_LOGINS_EXCEEDED, + }, + new Object[] { + ResultCode.UNWILLING_TO_PERFORM, + "Account (Kerberos principal) is expired", + FreeIPAAccountState.Error.ACCOUNT_EXPIRED, + }, + new Object[] { + ResultCode.UNWILLING_TO_PERFORM, + "Account inactivated. Contact system administrator.", + FreeIPAAccountState.Error.ACCOUNT_DISABLED, + }, + new Object[] { + ResultCode.OPERATIONS_ERROR, + null, + FreeIPAAccountState.Error.UNKNOWN, + }, + new Object[] { + ResultCode.SUCCESS, + null, + null, + }, + }; + } + + + /** + * Tests message parsing. + * + * @param rc result code + * @param message error message + * @param err corresponding error enum + * + * @throws Exception On test failure. + */ + @Test(groups = {"auth-ext"}, dataProvider = "errors") + public void parse(final ResultCode rc, final String message, final FreeIPAAccountState.Error err) + throws Exception + { + AssertJUnit.assertEquals(err, FreeIPAAccountState.Error.parse(rc, message)); + } +}
diff --git a/core/src/test/java/org/ldaptive/cache/LRUCacheTest.java b/core/src/test/java/org/ldaptive/cache/LRUCacheTest.java new file mode 100644 index 0000000..11980b4 --- /dev/null +++ b/core/src/test/java/org/ldaptive/cache/LRUCacheTest.java
@@ -0,0 +1,108 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.cache; + +import java.time.Duration; +import org.ldaptive.LdapEntry; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Unit test for {@link LRUCache}. + * + * @author Middleware Services + */ +public class LRUCacheTest +{ + + /** Cache for testing. */ + private final LRUCache<SearchRequest> cache = new LRUCache<>(5, Duration.ofSeconds(60), Duration.ofSeconds(3)); + + + /** @throws Exception On test failure. */ + @BeforeClass(groups = {"cache"}) + public void initialize() + throws Exception + { + fillCache(); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"cache"}) + public void clear() + throws Exception + { + fillCache(); + AssertJUnit.assertEquals(5, cache.size()); + cache.clear(); + AssertJUnit.assertEquals(0, cache.size()); + cache.close(); + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"cache"}, threadPoolSize = 5, invocationCount = 100, timeOut = 60000) + public void get() + throws Exception + { + SearchResult result = cache.get(new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=3"))); + AssertJUnit.assertEquals(new SearchResult(new LdapEntry("uid=3,ou=test,dc=ldaptive,dc=org")), result); + result = cache.get(new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=4"))); + AssertJUnit.assertEquals(new SearchResult(new LdapEntry("uid=4,ou=test,dc=ldaptive,dc=org")), result); + result = cache.get(new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=5"))); + AssertJUnit.assertEquals(new SearchResult(new LdapEntry("uid=5,ou=test,dc=ldaptive,dc=org")), result); + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"cache"}) + public void put() + throws Exception + { + AssertJUnit.assertEquals(5, cache.size()); + cache.put( + new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=%s", new Object[] {"101"})), + new SearchResult(new LdapEntry("uid=101,ou=test,dc=ldaptive,dc=org"))); + cache.put( + new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=102")), + new SearchResult(new LdapEntry("uid=102,ou=test,dc=ldaptive,dc=org"))); + AssertJUnit.assertEquals(5, cache.size()); + + SearchResult result = cache.get( + new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=%s", new Object[] {"101"}))); + AssertJUnit.assertEquals(new SearchResult(new LdapEntry("uid=101,ou=test,dc=ldaptive,dc=org")), result); + result = cache.get(new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=102"))); + AssertJUnit.assertEquals(new SearchResult(new LdapEntry("uid=102,ou=test,dc=ldaptive,dc=org")), result); + AssertJUnit.assertNull(cache.get(new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=1")))); + } + + + /** Fills the cache with data. */ + private void fillCache() + { + cache.put( + new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=1")), + new SearchResult(new LdapEntry("uid=1,ou=test,dc=ldaptive,dc=org"))); + cache.put( + new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=2")), + new SearchResult(new LdapEntry("uid=2,ou=test,dc=ldaptive,dc=org"))); + cache.put( + new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=3")), + new SearchResult(new LdapEntry("uid=3,ou=test,dc=ldaptive,dc=org"))); + cache.put( + new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=4")), + new SearchResult(new LdapEntry("uid=4,ou=test,dc=ldaptive,dc=org"))); + cache.put( + new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=5")), + new SearchResult(new LdapEntry("uid=5,ou=test,dc=ldaptive,dc=org"))); + // ensure uid=1 and uid=2 get evicted first + cache.get(new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=3"))); + cache.get(new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=4"))); + cache.get(new SearchRequest("dc=ldaptive,dc=org", new SearchFilter("uid=5"))); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/AuthorizationIdentityResponseControlTest.java b/core/src/test/java/org/ldaptive/control/AuthorizationIdentityResponseControlTest.java new file mode 100644 index 0000000..881606a --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/AuthorizationIdentityResponseControlTest.java
@@ -0,0 +1,55 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link AuthorizationIdentityResponseControl}. + * + * @author Middleware Services + */ +public class AuthorizationIdentityResponseControlTest +{ + + + /** + * Authorization identity response control test data. + * + * @return response test data + */ + @DataProvider(name = "response") + public Object[][] createData() + { + return + new Object[][] { + // dn:uid=1,ou=test,dc=ldaptive,dc=org + // BER: + // 64:6E:3A:75:69:64:3D:31:2C:6F:75:3D:74:65:73:74:2C:64:63:3D:6C:64:61: + // 70:74:69:76:65:2C:64:63:3D:6F:72:67: + new Object[] { + LdapUtils.base64Decode("ZG46dWlkPTEsb3U9dGVzdCxkYz1sZGFwdGl2ZSxkYz1vcmc="), + new AuthorizationIdentityResponseControl("dn:uid=1,ou=test,dc=ldaptive,dc=org"), + }, + }; + } + + + /** + * @param berValue to decode. + * @param expected authorization identity response control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "response") + public void decode(final byte[] berValue, final AuthorizationIdentityResponseControl expected) + throws Exception + { + final AuthorizationIdentityResponseControl actual = new AuthorizationIdentityResponseControl( + expected.getCriticality()); + actual.decode(berValue); + Assert.assertEquals(actual, expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/EntryChangeNotificationControlTest.java b/core/src/test/java/org/ldaptive/control/EntryChangeNotificationControlTest.java new file mode 100644 index 0000000..6e3086b --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/EntryChangeNotificationControlTest.java
@@ -0,0 +1,60 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link EntryChangeNotificationControl}. + * + * @author Middleware Services + */ +public class EntryChangeNotificationControlTest +{ + + + /** + * Entry change notification control test data. + * + * @return response test data + */ + @DataProvider(name = "response") + public Object[][] createData() + { + return + new Object[][] { + // changeType=Modify + // BER: 30:03:0A:01:04 + new Object[] { + LdapUtils.base64Decode("MAMKAQQ="), + new EntryChangeNotificationControl(PersistentSearchChangeType.MODIFY), + }, + // changeType=ModDn, previousDn=uid=1,ou=test,dc=ldaptive,dc=org + // BER: + // 30:25:0A:01:08:04:20:75:69:64:3D:31:2C:6F:75:3D:74:65:73:74:2C:64: + // 63:3D:6C:64:61:70:74:69:76:65:2C:64:63:3D:6F:72:67 + new Object[] { + LdapUtils.base64Decode("MCUKAQgEIHVpZD0xLG91PXRlc3QsZGM9bGRhcHRpdmUsZGM9b3Jn"), + new EntryChangeNotificationControl(PersistentSearchChangeType.MODDN, "uid=1,ou=test,dc=ldaptive,dc=org", -1), + }, + }; + } + + + /** + * @param berValue to decode. + * @param expected entry change notification control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "response") + public void decode(final byte[] berValue, final EntryChangeNotificationControl expected) + throws Exception + { + final EntryChangeNotificationControl actual = new EntryChangeNotificationControl(expected.getCriticality()); + actual.decode(berValue); + Assert.assertEquals(actual, expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/PagedResultsControlTest.java b/core/src/test/java/org/ldaptive/control/PagedResultsControlTest.java new file mode 100644 index 0000000..f7d48d9 --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/PagedResultsControlTest.java
@@ -0,0 +1,229 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link PagedResultsControl}. + * + * @author Middleware Services + */ +public class PagedResultsControlTest +{ + + + /** + * Paged results control test data. + * + * @return response test data + */ + @DataProvider(name = "request-response") + public Object[][] createData() + { + return + new Object[][] { + // request size 0, no cookie + // BER: 30:05:02:01:00:04:00 + new Object[] { + LdapUtils.base64Decode("MAUCAQAEAA=="), + new PagedResultsControl(0, null, true), + }, + // request size 0, cookie + // BER: 30:0D:02:01:00:04:08:FF:FF:FF:FF:FF:FF:FF:FF + new Object[] { + LdapUtils.base64Decode("MA0CAQAECP//////////"), + new PagedResultsControl( + 0, + new byte[] { + (byte) 0xff, + (byte) 0xff, + (byte) 0xff, + (byte) 0xff, + (byte) 0xff, + (byte) 0xff, + (byte) 0xff, + (byte) 0xff, + }, + true), + }, + // request size 1, no cookie + // BER: 30:05:02:01:01:04:00 + new Object[] { + LdapUtils.base64Decode("MAUCAQEEAA=="), + new PagedResultsControl(1, null, true), + }, + // request size 1, cookie + // BER: 30:0D:02:01:01:04:08:EF:5C:15:00:00:00:00:00 + new Object[] { + LdapUtils.base64Decode("MA0CAQEECO9cFQAAAAAA"), + new PagedResultsControl( + 1, + new byte[] { + (byte) 0xef, + (byte) 0x5c, + (byte) 0x15, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + }, + true), + }, + // request size 20, no cookie + // BER: 30:05:02:01:14:04:00 + new Object[] { + LdapUtils.base64Decode("MAUCARQEAA=="), + new PagedResultsControl(20, null, true), + }, + // request size 20, cookie + // BER: 30:0D:02:01:14:04:08:A7:C7:18:00:00:00:00:00 + new Object[] { + LdapUtils.base64Decode("MA0CARQECKfHGAAAAAAA"), + new PagedResultsControl( + 20, + new byte[] { + (byte) 0xa7, + (byte) 0xc7, + (byte) 0x18, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + }, + true), + }, + // request size 0, 388 byte length cookie + // both the sequence and octet string use long form length + new Object[] { + LdapUtils.base64Decode( + "MIQAAAGNAgEABIQAAAGEAQAAAIQBAAD/////7E9EoNm4ztLWBSblnuyp1iZhZ/XM" + + "5IJk6DcibuopiDZU4AofIdRQT4hfyECUBna7AAAAAAEAAAAAAAAAfQ8AABwAAAAF" + + "AAAAAgAAAAAAAAAAAAAABAAAAAUAAQCpDgAA/QYAAP0GAAAAAAAAtBxsfUgmpECD" + + "Z+XSv7zT1gAAAAAEAAAAAQAAAAAAAAAAAAAAAQAAAAQAAAABAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAEAAAD/////AeNCb8/LArdUnvG/1PsdLkQipKip" + + "SVvzz/kAtrc1mcsAAAAAfwIAAAD7BgAACfwGAAD9BgAACakOAAB9DwAACH+AAA99" + + "AAAAAAAAAAAAAAD/////AAAAAAAAAAD/////DwAAABwAAAAdAAAAQW5jZXN0b3Jz" + + "X2luZGV4fwIAAAD7BgAACfwGAAD9BgAACakOAAAAAAAABH8CAAAA+wYAAAn8BgAA" + + "/QYAAAmpDgAA////////AAAAAA=="), + new PagedResultsControl( + 0, + new byte[] { + (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x84, + (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xec, (byte) 0x4f, (byte) 0x44, + (byte) 0xa0, (byte) 0xd9, (byte) 0xb8, (byte) 0xce, (byte) 0xd2, + (byte) 0xd6, (byte) 0x05, (byte) 0x26, (byte) 0xe5, (byte) 0x9e, + (byte) 0xec, (byte) 0xa9, (byte) 0xd6, (byte) 0x26, (byte) 0x61, + (byte) 0x67, (byte) 0xf5, (byte) 0xcc, (byte) 0xe4, (byte) 0x82, + (byte) 0x64, (byte) 0xe8, (byte) 0x37, (byte) 0x22, (byte) 0x6e, + (byte) 0xea, (byte) 0x29, (byte) 0x88, (byte) 0x36, (byte) 0x54, + (byte) 0xe0, (byte) 0x0a, (byte) 0x1f, (byte) 0x21, (byte) 0xd4, + (byte) 0x50, (byte) 0x4f, (byte) 0x88, (byte) 0x5f, (byte) 0xc8, + (byte) 0x40, (byte) 0x94, (byte) 0x06, (byte) 0x76, (byte) 0xbb, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x7d, (byte) 0x0f, (byte) 0x00, + (byte) 0x00, (byte) 0x1c, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x05, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x05, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0xa9, + (byte) 0x0e, (byte) 0x00, (byte) 0x00, (byte) 0xfd, (byte) 0x06, + (byte) 0x00, (byte) 0x00, (byte) 0xfd, (byte) 0x06, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0xb4, (byte) 0x1c, (byte) 0x6c, (byte) 0x7d, (byte) 0x48, + (byte) 0x26, (byte) 0xa4, (byte) 0x40, (byte) 0x83, (byte) 0x67, + (byte) 0xe5, (byte) 0xd2, (byte) 0xbf, (byte) 0xbc, (byte) 0xd3, + (byte) 0xd6, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01, + (byte) 0xe3, (byte) 0x42, (byte) 0x6f, (byte) 0xcf, (byte) 0xcb, + (byte) 0x02, (byte) 0xb7, (byte) 0x54, (byte) 0x9e, (byte) 0xf1, + (byte) 0xbf, (byte) 0xd4, (byte) 0xfb, (byte) 0x1d, (byte) 0x2e, + (byte) 0x44, (byte) 0x22, (byte) 0xa4, (byte) 0xa8, (byte) 0xa9, + (byte) 0x49, (byte) 0x5b, (byte) 0xf3, (byte) 0xcf, (byte) 0xf9, + (byte) 0x00, (byte) 0xb6, (byte) 0xb7, (byte) 0x35, (byte) 0x99, + (byte) 0xcb, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x7f, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0xfb, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x09, + (byte) 0xfc, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0xfd, + (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x09, (byte) 0xa9, + (byte) 0x0e, (byte) 0x00, (byte) 0x00, (byte) 0x7d, (byte) 0x0f, + (byte) 0x00, (byte) 0x00, (byte) 0x08, (byte) 0x7f, (byte) 0x80, + (byte) 0x00, (byte) 0x0f, (byte) 0x7d, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x1c, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x1d, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x41, (byte) 0x6e, (byte) 0x63, + (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x6f, (byte) 0x72, + (byte) 0x73, (byte) 0x5f, (byte) 0x69, (byte) 0x6e, (byte) 0x64, + (byte) 0x65, (byte) 0x78, (byte) 0x7f, (byte) 0x02, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0xfb, (byte) 0x06, (byte) 0x00, + (byte) 0x00, (byte) 0x09, (byte) 0xfc, (byte) 0x06, (byte) 0x00, + (byte) 0x00, (byte) 0xfd, (byte) 0x06, (byte) 0x00, (byte) 0x00, + (byte) 0x09, (byte) 0xa9, (byte) 0x0e, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, + (byte) 0x7f, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0xfb, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x09, + (byte) 0xfc, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0xfd, + (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x09, (byte) 0xa9, + (byte) 0x0e, (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, + }, + true), + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected paged results control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "request-response") + public void encode(final byte[] berValue, final PagedResultsControl expected) + throws Exception + { + Assert.assertEquals(expected.encode(), berValue); + } + + + /** + * @param berValue to decode. + * @param expected paged results control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "request-response") + public void decode(final byte[] berValue, final PagedResultsControl expected) + throws Exception + { + final PagedResultsControl actual = new PagedResultsControl(expected.getCriticality()); + actual.decode(berValue); + Assert.assertEquals(actual, expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/PasswordExpiredControlTest.java b/core/src/test/java/org/ldaptive/control/PasswordExpiredControlTest.java new file mode 100644 index 0000000..ade0039 --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/PasswordExpiredControlTest.java
@@ -0,0 +1,50 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link PasswordExpiredControl}. + * + * @author Middleware Services + */ +public class PasswordExpiredControlTest +{ + + + /** + * Password expired control test data. + * + * @return response test data + */ + @DataProvider(name = "response") + public Object[][] createData() + { + return new Object[][] { + // BER: 30 + new Object[] { + LdapUtils.base64Decode("MA=="), + new PasswordExpiredControl(), + }, + }; + } + + + /** + * @param berValue to decode. + * @param expected password expired control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "response") + public void decode(final byte[] berValue, final PasswordExpiredControl expected) + throws Exception + { + final PasswordExpiredControl actual = new PasswordExpiredControl(expected.getCriticality()); + actual.decode(berValue); + Assert.assertEquals(actual, expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/PasswordExpiringControlTest.java b/core/src/test/java/org/ldaptive/control/PasswordExpiringControlTest.java new file mode 100644 index 0000000..ce90aa0 --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/PasswordExpiringControlTest.java
@@ -0,0 +1,56 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link PasswordExpiringControl}. + * + * @author Middleware Services + */ +public class PasswordExpiringControlTest +{ + + + /** + * Password expiring control test data. + * + * @return response test data + */ + @DataProvider(name = "response") + public Object[][] createData() + { + return + new Object[][] { + // BER: 34:36:31 + new Object[] { + LdapUtils.base64Decode("NDYx"), + new PasswordExpiringControl(461), + }, + // BER: 33:38:34 + new Object[] { + LdapUtils.base64Decode("Mzg0"), + new PasswordExpiringControl(384), + }, + }; + } + + + /** + * @param berValue to decode. + * @param expected password expiring control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "response") + public void decode(final byte[] berValue, final PasswordExpiringControl expected) + throws Exception + { + final PasswordExpiringControl actual = new PasswordExpiringControl(expected.getCriticality()); + actual.decode(berValue); + Assert.assertEquals(actual, expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/PasswordPolicyControlTest.java b/core/src/test/java/org/ldaptive/control/PasswordPolicyControlTest.java new file mode 100644 index 0000000..32a802f --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/PasswordPolicyControlTest.java
@@ -0,0 +1,92 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link PasswordPolicyControl}. + * + * @author Middleware Services + */ +public class PasswordPolicyControlTest +{ + + + /** + * Password policy control test data. + * + * @return response test data + */ + @DataProvider(name = "response") + public Object[][] createData() + { + final PasswordPolicyControl p1 = new PasswordPolicyControl(); + p1.setTimeBeforeExpiration(2513067); + + final PasswordPolicyControl p2 = new PasswordPolicyControl(); + p2.setGraceAuthNsRemaining(4); + + final PasswordPolicyControl p3 = new PasswordPolicyControl(); + p3.setError(PasswordPolicyControl.Error.PASSWORD_EXPIRED); + + final PasswordPolicyControl p4 = new PasswordPolicyControl(); + p4.setError(PasswordPolicyControl.Error.ACCOUNT_LOCKED); + return + new Object[][] { + // Test case #1 + // only timeBeforeExpiration is set + // BER: 30:07:A0:05:80:03:26:58:AB + new Object[] { + LdapUtils.base64Decode("MAegBYADJlir"), + p1, + }, + // Test case #2 + // only graceAuthNsRemaining is set + // BER: 30:05:A0:03:81:01:04 + new Object[] { + LdapUtils.base64Decode("MAWgA4EBBA=="), + p2, + }, + // Test case #3 + // error=passwordExpired + // BER: 30:03:81:01:00 + new Object[] { + LdapUtils.base64Decode("MAOBAQA="), + p3, + }, + // Test case #4 + // error=accountLocked + // BER: 30:03:81:01:01 + new Object[] { + LdapUtils.base64Decode("MAOBAQE="), + p4, + }, + // Test case #5 + // empty control + // BER: 30:00 + new Object[] { + LdapUtils.base64Decode("MAA="), + new PasswordPolicyControl(), + }, + }; + } + + + /** + * @param berValue to decode. + * @param expected ppolicy control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "response") + public void decode(final byte[] berValue, final PasswordPolicyControl expected) + throws Exception + { + final PasswordPolicyControl actual = new PasswordPolicyControl(expected.getCriticality()); + actual.decode(berValue); + Assert.assertEquals(actual, expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/PersistentSearchRequestControlTest.java b/core/src/test/java/org/ldaptive/control/PersistentSearchRequestControlTest.java new file mode 100644 index 0000000..95ebe6c --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/PersistentSearchRequestControlTest.java
@@ -0,0 +1,66 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.util.EnumSet; +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link PersistentSearchRequestControl}. + * + * @author Middleware Services + */ +public class PersistentSearchRequestControlTest +{ + + + /** + * Persistent search request control test data. + * + * @return response test data + */ + @DataProvider(name = "request") + public Object[][] createData() + { + return + new Object[][] { + // all types, changesOnly=true, returnEcs=true + // BER: 30:09:02:01:0F:01:01:FF:01:01:FF + new Object[] { + LdapUtils.base64Decode("MAkCAQ8BAf8BAf8="), + new PersistentSearchRequestControl(EnumSet.allOf(PersistentSearchChangeType.class), true, true), + }, + // modify type, changesOnly=false, returnEcs=true + // BER: 30:09:02:01:04:01:01:00:01:01:FF + new Object[] { + LdapUtils.base64Decode("MAkCAQQBAQABAf8="), + new PersistentSearchRequestControl(EnumSet.of(PersistentSearchChangeType.MODIFY), false, true), + }, + // add and delete types, changesOnly=true, returnEcs=false + // BER: 30:09:02:01:03:01:01:FF:01:01:00 + new Object[] { + LdapUtils.base64Decode("MAkCAQMBAf8BAQA="), + new PersistentSearchRequestControl( + EnumSet.of(PersistentSearchChangeType.ADD, PersistentSearchChangeType.DELETE), + true, + false), + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected persistent search request control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "request") + public void encode(final byte[] berValue, final PersistentSearchRequestControl expected) + throws Exception + { + Assert.assertEquals(expected.encode(), berValue); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/ProxyAuthorizationControlTest.java b/core/src/test/java/org/ldaptive/control/ProxyAuthorizationControlTest.java new file mode 100644 index 0000000..1b06069 --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/ProxyAuthorizationControlTest.java
@@ -0,0 +1,55 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link ProxyAuthorizationControl}. + * + * @author Middleware Services + */ +public class ProxyAuthorizationControlTest +{ + + + /** + * Proxy authorization control test data. + * + * @return response test data + */ + @DataProvider(name = "request") + public Object[][] createData() + { + return + new Object[][] { + new Object[] { + new byte[0], + new ProxyAuthorizationControl(), + }, + // BER: + // 64:6E:3A:75:69:64:3D:31:2C:6F:75:3D:74:65:73:74:2C:64:63:3D:6C:64: + // 61:70:74:69:76:65:2C:64:63:3D:6F:72:67 + new Object[] { + LdapUtils.base64Decode("ZG46dWlkPTEsb3U9dGVzdCxkYz1sZGFwdGl2ZSxkYz1vcmc="), + new ProxyAuthorizationControl("dn:uid=1,ou=test,dc=ldaptive,dc=org"), + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected proxy authorization control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "request") + public void decode(final byte[] berValue, final ProxyAuthorizationControl expected) + throws Exception + { + Assert.assertEquals(expected.encode(), berValue); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/SessionTrackingControlTest.java b/core/src/test/java/org/ldaptive/control/SessionTrackingControlTest.java new file mode 100644 index 0000000..134e945 --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/SessionTrackingControlTest.java
@@ -0,0 +1,68 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SessionTrackingControl}. + * + * @author Middleware Services + */ +public class SessionTrackingControlTest +{ + + + /** + * Session tracking control test data. + * + * @return request test data + */ + @DataProvider(name = "request-response") + public Object[][] createData() + { + return + new Object[][] { + // BER: 30:42:04:09:31:39:32:2e:30:2e:32:2e:31:04:0f:61:70:70:2e:65:78:61:6d:70:6c:65:2e:63:6f:6d + // 04:1c:31:2e:33:2e:36:2e:31:2e:34:2e:31:2e:32:31:30:30:38:2e:31:30:38:2e:36:33:2e:31:2e:33 + // 04:06:62:6c:6f:67:67:73 + new Object[] { + LdapUtils.base64Decode( + "MEIECTE5Mi4wLjIuMQQPYXBwLmV4YW1wbGUuY29tBBwxLjMuNi4xLjQuMS4yMTAwOC4xMDguNjMuMS4zBAZibG9nZ3M="), + new SessionTrackingControl("192.0.2.1", "app.example.com", "1.3.6.1.4.1.21008.108.63.1.3", "bloggs"), + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected session tracking control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "request-response") + public void encode(final byte[] berValue, final SessionTrackingControl expected) + throws Exception + { + Assert.assertEquals(expected.encode(), berValue); + } + + + /** + * @param berValue to decode. + * @param expected session tracking control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "request-response") + public void decode(final byte[] berValue, final SessionTrackingControl expected) + throws Exception + { + final SessionTrackingControl actual = new SessionTrackingControl(); + actual.decode(berValue); + Assert.assertEquals(actual, expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/SortRequestControlTest.java b/core/src/test/java/org/ldaptive/control/SortRequestControlTest.java new file mode 100644 index 0000000..8215430 --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/SortRequestControlTest.java
@@ -0,0 +1,65 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SortRequestControl}. + * + * @author Middleware Services + */ +public class SortRequestControlTest +{ + + + /** + * Sort request control test data. + * + * @return response test data + */ + @DataProvider(name = "request") + public Object[][] createData() + { + return + new Object[][] { + // sort on createTimestamp + // BER: 30:13:30:11:04:0F:63:72:65:61:74:65:54:69:6D: + // 65:73:74:61:6D:70 + new Object[] { + LdapUtils.base64Decode("MBMwEQQPY3JlYXRlVGltZXN0YW1w"), + new SortRequestControl(new SortKey[] {new SortKey("createTimestamp")}, true), + }, + // sort on uugid + // BER: 30:19:30:17:04:05:75:75:67:69:64:80:0E:63:61:73: + // 65:45:78:61:63:74:4D:61:74:63:68 + new Object[] { + LdapUtils.base64Decode("MBkwFwQFdXVnaWSADmNhc2VFeGFjdE1hdGNo"), + new SortRequestControl(new SortKey[] {new SortKey("uugid", "caseExactMatch")}, true), + }, + // sort on uid, reverse order + // BER: 30:18:30:16:04:03:75:69:64:80:0C:69:6E:74:65:67: + // 65:72:4D:61:74:63:68:81:01:FF + new Object[] { + LdapUtils.base64Decode("MBgwFgQDdWlkgAxpbnRlZ2VyTWF0Y2iBAf8="), + new SortRequestControl(new SortKey[] {new SortKey("uid", "integerMatch", true)}, true), + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected sort request control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "request") + public void encode(final byte[] berValue, final SortRequestControl expected) + throws Exception + { + Assert.assertEquals(expected.encode(), berValue); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/SortResponseControlTest.java b/core/src/test/java/org/ldaptive/control/SortResponseControlTest.java new file mode 100644 index 0000000..761cc40 --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/SortResponseControlTest.java
@@ -0,0 +1,53 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.ldaptive.ResultCode; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SortResponseControl}. + * + * @author Middleware Services + */ +public class SortResponseControlTest +{ + + + /** + * Sort response control test data. + * + * @return response test data + */ + @DataProvider(name = "response") + public Object[][] createData() + { + return + new Object[][] { + // result code success + // BER: 30:03:0A:01:00 + new Object[] { + LdapUtils.base64Decode("MAMKAQA="), + new SortResponseControl(ResultCode.SUCCESS, true), + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected sort response control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "response") + public void decode(final byte[] berValue, final SortResponseControl expected) + throws Exception + { + final SortResponseControl actual = new SortResponseControl(expected.getCriticality()); + actual.decode(berValue); + Assert.assertEquals(actual, expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/SyncDoneControlTest.java b/core/src/test/java/org/ldaptive/control/SyncDoneControlTest.java new file mode 100644 index 0000000..fbc3de3 --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/SyncDoneControlTest.java
@@ -0,0 +1,71 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SyncDoneControl}. + * + * @author Middleware Services + */ +public class SyncDoneControlTest +{ + + + /** + * Sync done control test data. + * + * @return response test data + */ + @DataProvider(name = "response") + public Object[][] createData() + { + return + new Object[][] { + // 52 length cookie, refreshDeletes true + // BER:30:39:04:34:72:69:64:3D:30:30:30:2C:63:73:6E:3D:32:30:31:32:30:37 + // :30:33:32:30:34:38:30:30:2E:36:30:39:37:32:31:5A:23:30:30:30:30:30 + // :30:23:30:30:30:23:30:30:30:30:30:30:01:01:FF + new Object[] { + LdapUtils.base64Decode( + "MDkENHJpZD0wMDAsY3NuPTIwMTIwNzAzMjA0ODAwLjYwOTcyMVojMDAwMDAwIzAw" + + "MCMwMDAwMDABAf8="), + new SyncDoneControl( + new byte[] { + (byte) 0x72, (byte) 0x69, (byte) 0x64, (byte) 0x3D, (byte) 0x30, + (byte) 0x30, (byte) 0x30, (byte) 0x2C, (byte) 0x63, (byte) 0x73, + (byte) 0x6E, (byte) 0x3D, (byte) 0x32, (byte) 0x30, (byte) 0x31, + (byte) 0x32, (byte) 0x30, (byte) 0x37, (byte) 0x30, (byte) 0x33, + (byte) 0x32, (byte) 0x30, (byte) 0x34, (byte) 0x38, (byte) 0x30, + (byte) 0x30, (byte) 0x2E, (byte) 0x36, (byte) 0x30, (byte) 0x39, + (byte) 0x37, (byte) 0x32, (byte) 0x31, (byte) 0x5A, (byte) 0x23, + (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, + (byte) 0x30, (byte) 0x23, (byte) 0x30, (byte) 0x30, (byte) 0x30, + (byte) 0x23, (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, + (byte) 0x30, (byte) 0x30, + }, + true, + true), + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected sync done control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "response") + public void decode(final byte[] berValue, final SyncDoneControl expected) + throws Exception + { + final SyncDoneControl actual = new SyncDoneControl(expected.getCriticality()); + actual.decode(berValue); + Assert.assertEquals(actual, expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/SyncRequestControlTest.java b/core/src/test/java/org/ldaptive/control/SyncRequestControlTest.java new file mode 100644 index 0000000..87f178a --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/SyncRequestControlTest.java
@@ -0,0 +1,76 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SyncRequestControl}. + * + * @author Middleware Services + */ +public class SyncRequestControlTest +{ + + + /** + * Sync request control test data. + * + * @return response test data + */ + @DataProvider(name = "request") + public Object[][] createData() + { + return + new Object[][] { + // refresh only, reloadHint false + // BER:30:06:02:01:01:01:01:00 + new Object[] { + LdapUtils.base64Decode("MAYCAQEBAQA="), + new SyncRequestControl(SyncRequestControl.Mode.REFRESH_ONLY, true), + }, + // refresh and persist with cookie, reloadHint true + // BER:30:30:3C:0A:01:03:04:34:72:69:64:3D:30:30:30:2C:63:73:6E:3D:32: + // 30:31:32:30:37:30:36:31:38:31:35:35:32:2E:33:33:37:37:31:38:5A: + // 23:30:30:30:30:30:30:23:30:30:30:23:30:30:30:30:30:30:01:01:FF: + new Object[] { + LdapUtils.base64Decode( + "MDwCAQMENHJpZD0wMDAsY3NuPTIwMTIwNzA2MTgxNTUyLjMzNzcxOFojMDAwMDAw" + + "IzAwMCMwMDAwMDABAf8="), + new SyncRequestControl( + SyncRequestControl.Mode.REFRESH_AND_PERSIST, + new byte[] { + (byte) 0x72, (byte) 0x69, (byte) 0x64, (byte) 0x3D, (byte) 0x30, + (byte) 0x30, (byte) 0x30, (byte) 0x2C, (byte) 0x63, (byte) 0x73, + (byte) 0x6E, (byte) 0x3D, (byte) 0x32, (byte) 0x30, (byte) 0x31, + (byte) 0x32, (byte) 0x30, (byte) 0x37, (byte) 0x30, (byte) 0x36, + (byte) 0x31, (byte) 0x38, (byte) 0x31, (byte) 0x35, (byte) 0x35, + (byte) 0x32, (byte) 0x2E, (byte) 0x33, (byte) 0x33, (byte) 0x37, + (byte) 0x37, (byte) 0x31, (byte) 0x38, (byte) 0x5A, (byte) 0x23, + (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, + (byte) 0x30, (byte) 0x23, (byte) 0x30, (byte) 0x30, (byte) 0x30, + (byte) 0x23, (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, + (byte) 0x30, (byte) 0x30, + }, + true, + true), + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected sync request control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "request") + public void decode(final byte[] berValue, final SyncRequestControl expected) + throws Exception + { + Assert.assertEquals(expected.encode(), berValue); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/SyncStateControlTest.java b/core/src/test/java/org/ldaptive/control/SyncStateControlTest.java new file mode 100644 index 0000000..ef59ea7 --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/SyncStateControlTest.java
@@ -0,0 +1,111 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import java.util.UUID; +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SyncStateControl}. + * + * @author Middleware Services + */ +public class SyncStateControlTest +{ + + + /** + * Sync state control test data. + * + * @return response test data + */ + @DataProvider(name = "response") + public Object[][] createData() + { + return + new Object[][] { + // Add state, no cookie + // BER:30:15:0A:01:01:04:10:84:31:77:EC:5B:0E:10:31:82:7F:11:6F:F5:6E:4E + // :59 + new Object[] { + LdapUtils.base64Decode("MBUKAQEEEIQxd+xbDhAxgn8Rb/VuTlk="), + new SyncStateControl( + SyncStateControl.State.ADD, + UUID.fromString("843177ec-5b0e-1031-827f-116ff56e4e59"), + null, + false), + }, + // Modify state, cookie of length 52 + // BER:30:4B:0A:01:02:04:10:5D:5D:A5:D0:5B:E2:10:31:82:84:11:6F:F5:6E:4E + // :59:04:34:72:69:64:3D:30:30:30:2C:63:73:6E:3D:32:30:31:32:30:37:30 + // :36:31:38:31:35:35:32:2E:33:33:37:37:31:38:5A:23:30:30:30:30:30:30 + // :23:30:30:30:23:30:30:30:30:30:30: + new Object[] { + LdapUtils.base64Decode( + "MEsKAQIEEF1dpdBb4hAxgoQRb/VuTlkENHJpZD0wMDAsY3NuPTIwMTIwNzA2MTgx" + + "NTUyLjMzNzcxOFojMDAwMDAwIzAwMCMwMDAwMDA="), + new SyncStateControl( + SyncStateControl.State.MODIFY, + UUID.fromString("5d5da5d0-5be2-1031-8284-116ff56e4e59"), + new byte[] { + (byte) 0x72, (byte) 0x69, (byte) 0x64, (byte) 0x3D, (byte) 0x30, + (byte) 0x30, (byte) 0x30, (byte) 0x2C, (byte) 0x63, (byte) 0x73, + (byte) 0x6E, (byte) 0x3D, (byte) 0x32, (byte) 0x30, (byte) 0x31, + (byte) 0x32, (byte) 0x30, (byte) 0x37, (byte) 0x30, (byte) 0x36, + (byte) 0x31, (byte) 0x38, (byte) 0x31, (byte) 0x35, (byte) 0x35, + (byte) 0x32, (byte) 0x2E, (byte) 0x33, (byte) 0x33, (byte) 0x37, + (byte) 0x37, (byte) 0x31, (byte) 0x38, (byte) 0x5A, (byte) 0x23, + (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, + (byte) 0x30, (byte) 0x23, (byte) 0x30, (byte) 0x30, (byte) 0x30, + (byte) 0x23, (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, + (byte) 0x30, (byte) 0x30, + }, + false), + }, + // Add state, cookie length of 52, empty UUID + // BER:30:3B:0A:01:01:04:00:04:34:72:69:64:3D:30:30:30:2C:63:73:6E:3D:32 + // :30:31:33:30:32:31:35:32:31:32:33:32:30:2E:34:36:34:34:38:35:5A:23 + // :30:30:30:30:30:30:23:30:30:30:23:30:30:30:30:30:30: + new Object[] { + LdapUtils.base64Decode( + "MDsKAQEEAAQ0cmlkPTAwMCxjc249MjAxMzAyMTUyMTIzMjAuNDY0NDg1WiMwMDAw" + + "MDAjMDAwIzAwMDAwMA=="), + new SyncStateControl( + SyncStateControl.State.ADD, + null, + new byte[] { + (byte) 0x72, (byte) 0x69, (byte) 0x64, (byte) 0x3d, (byte) 0x30, + (byte) 0x30, (byte) 0x30, (byte) 0x2c, (byte) 0x63, (byte) 0x73, + (byte) 0x6e, (byte) 0x3d, (byte) 0x32, (byte) 0x30, (byte) 0x31, + (byte) 0x33, (byte) 0x30, (byte) 0x32, (byte) 0x31, (byte) 0x35, + (byte) 0x32, (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x32, + (byte) 0x30, (byte) 0x2e, (byte) 0x34, (byte) 0x36, (byte) 0x34, + (byte) 0x34, (byte) 0x38, (byte) 0x35, (byte) 0x5a, (byte) 0x23, + (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, + (byte) 0x30, (byte) 0x23, (byte) 0x30, (byte) 0x30, (byte) 0x30, + (byte) 0x23, (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, + (byte) 0x30, (byte) 0x30, + }, + false), + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected sync state control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "response") + public void decode(final byte[] berValue, final SyncStateControl expected) + throws Exception + { + final SyncStateControl actual = new SyncStateControl(expected.getCriticality()); + actual.decode(berValue); + Assert.assertEquals(actual, expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/VirtualListViewRequestControlTest.java b/core/src/test/java/org/ldaptive/control/VirtualListViewRequestControlTest.java new file mode 100644 index 0000000..825591b --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/VirtualListViewRequestControlTest.java
@@ -0,0 +1,101 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link VirtualListViewRequestControl}. + * + * @author Middleware Services + */ +public class VirtualListViewRequestControlTest +{ + + + /** + * Virtual list view request control test data. + * + * @return request test data + */ + @DataProvider(name = "request") + public Object[][] createData() + { + return + new Object[][] { + // before=0, after=9, offset=1, count=0, no cookie + // BER: 30:0e:02:01:00:02:01:09:a0:06:02:01:01:02:01:00 + new Object[] { + LdapUtils.base64Decode("MA4CAQACAQmgBgIBAQIBAA=="), + new VirtualListViewRequestControl(1, 0, 9, true), + }, + // before=0, after=9, offset=11, count=59, with cookie + // BER: 30:18:02:01:00:02:01:09:a0:06:02:01:0b:02:01:3b: + // 04:08:00:9a:96:01:00:00:00:00 + new Object[] { + LdapUtils.base64Decode("MBgCAQACAQmgBgIBCwIBOwQIAJqWAQAAAAA="), + new VirtualListViewRequestControl( + 11, + 0, + 9, + 59, + new byte[] { + (byte) 0x00, + (byte) 0x9a, + (byte) 0x96, + (byte) 0x01, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + }, + + true), + }, + // before=0, after=9, assertion=549810, no cookie + // BER: 30:0e:02:01:00:02:01:09:81:06:35:34:39:38:31:30 + new Object[] { + LdapUtils.base64Decode("MA4CAQACAQmBBjU0OTgxMA=="), + new VirtualListViewRequestControl("549810", 0, 9, true), + }, + // before=0, after=9, assertion=549820, with cookie + // BER: 30:18:02:01:00:02:01:09:81:06:35:34:39:38:32:30: + // 04:08:80:99:96:01:00:00:00:00 + new Object[] { + LdapUtils.base64Decode("MBgCAQACAQmBBjU0OTgyMAQIgJmWAQAAAAA="), + new VirtualListViewRequestControl( + "549820", + 0, + 9, + new byte[] { + (byte) 0x80, + (byte) 0x99, + (byte) 0x96, + (byte) 0x01, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + }, + + true), + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected virtual list view request control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "request") + public void encode(final byte[] berValue, final VirtualListViewRequestControl expected) + throws Exception + { + Assert.assertEquals(expected.encode(), berValue); + } +}
diff --git a/core/src/test/java/org/ldaptive/control/VirtualListViewResponseControlTest.java b/core/src/test/java/org/ldaptive/control/VirtualListViewResponseControlTest.java new file mode 100644 index 0000000..f4c82d9 --- /dev/null +++ b/core/src/test/java/org/ldaptive/control/VirtualListViewResponseControlTest.java
@@ -0,0 +1,123 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control; + +import org.ldaptive.LdapUtils; +import org.ldaptive.ResultCode; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link VirtualListViewResponseControl}. + * + * @author Middleware Services + */ +public class VirtualListViewResponseControlTest +{ + + + /** + * Virtual list view response control test data. + * + * @return response test data + */ + @DataProvider(name = "response") + public Object[][] createData() + { + return + new Object[][] { + // position=1, count=59, result=success, context not null + // BER: 30:13:02:01:01:02:01:3B:02:01:00:04:08:80:28:7D:08:00:00:00:00 + new Object[] { + LdapUtils.base64Decode("MBMCAQECATsCAQAECIAofQgAAAAA"), + new VirtualListViewResponseControl( + 1, + 59, + ResultCode.SUCCESS, + new byte[] { + (byte) 0x80, + (byte) 0x28, + (byte) 0x7D, + (byte) 0x08, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + }), + }, + // position=10, count=55, result=success, context not null + // BER: 30:13:02:01:0A:02:01:37:02:01:00:04:08:00:9A:96:01:00:00:00:00 + new Object[] { + LdapUtils.base64Decode("MBMCAQoCATcCAQAECACalgEAAAAA"), + new VirtualListViewResponseControl( + 10, + 55, + ResultCode.SUCCESS, + new byte[] { + (byte) 0x00, + (byte) 0x9A, + (byte) 0x96, + (byte) 0x01, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + }), + }, + // position=12, count=55, result=success, context not null + // BER: 30:13:02:01:0C:02:01:37:02:01:00:04:08:80:99:96:01:00:00:00:00 + new Object[] { + LdapUtils.base64Decode("MBMCAQwCATcCAQAECICZlgEAAAAA"), + new VirtualListViewResponseControl( + 12, + 55, + ResultCode.SUCCESS, + new byte[] { + (byte) 0x80, + (byte) 0x99, + (byte) 0x96, + (byte) 0x01, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + }), + }, + // position=22, count=55, result=success, context not null + // BER: 30:13:02:01:16:02:01:37:02:01:00:04:08:80:99:96:01:00:00:00:00 + new Object[] { + LdapUtils.base64Decode("MBMCARYCATcCAQAECICZlgEAAAAA"), + new VirtualListViewResponseControl( + 22, + 55, + ResultCode.SUCCESS, + new byte[] { + (byte) 0x80, + (byte) 0x99, + (byte) 0x96, + (byte) 0x01, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00, + }), + }, + }; + } + + + /** + * @param berValue to decode. + * @param expected virtual list view response control to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"control"}, dataProvider = "response") + public void decode(final byte[] berValue, final VirtualListViewResponseControl expected) + throws Exception + { + final VirtualListViewResponseControl actual = new VirtualListViewResponseControl(expected.getCriticality()); + actual.decode(berValue); + Assert.assertEquals(actual, expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/intermediate/SyncInfoMessageTest.java b/core/src/test/java/org/ldaptive/intermediate/SyncInfoMessageTest.java new file mode 100644 index 0000000..f29fcde --- /dev/null +++ b/core/src/test/java/org/ldaptive/intermediate/SyncInfoMessageTest.java
@@ -0,0 +1,125 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.intermediate; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SyncInfoMessage}. + * + * @author Middleware Services + */ +public class SyncInfoMessageTest +{ + + + /** + * Sync state control test data. + * + * @return response test data + */ + @DataProvider(name = "response") + public Object[][] createData() + { + final byte[] cookie = new byte[] { + (byte) 0x72, (byte) 0x69, (byte) 0x64, (byte) 0x3D, (byte) 0x30, + (byte) 0x30, (byte) 0x30, (byte) 0x2C, (byte) 0x63, (byte) 0x73, + (byte) 0x6E, (byte) 0x3D, (byte) 0x32, (byte) 0x30, (byte) 0x31, + (byte) 0x32, (byte) 0x30, (byte) 0x37, (byte) 0x30, (byte) 0x39, + (byte) 0x32, (byte) 0x30, (byte) 0x31, (byte) 0x33, (byte) 0x31, + (byte) 0x39, (byte) 0x2E, (byte) 0x37, (byte) 0x36, (byte) 0x34, + (byte) 0x39, (byte) 0x31, (byte) 0x35, (byte) 0x5A, (byte) 0x23, + (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, + (byte) 0x30, (byte) 0x23, (byte) 0x30, (byte) 0x30, (byte) 0x30, + (byte) 0x23, (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, + (byte) 0x30, (byte) 0x30, + }; + final SyncInfoMessage m1 = new SyncInfoMessage(); + m1.setMessageType(SyncInfoMessage.Type.REFRESH_DELETE); + m1.setCookie(cookie); + + final SyncInfoMessage m2 = new SyncInfoMessage(); + m2.setMessageType(SyncInfoMessage.Type.NEW_COOKIE); + m2.setCookie(cookie); + + final SyncInfoMessage m3 = new SyncInfoMessage(); + m3.setMessageType(SyncInfoMessage.Type.REFRESH_PRESENT); + m3.setCookie(cookie); + m3.setRefreshDone(false); + + final Set<UUID> uuids = new HashSet<>(); + uuids.add(UUID.fromString("5d5da5d0-5be2-1031-8284-116ff56e4e59")); + uuids.add(UUID.fromString("843177ec-5b0e-1031-827f-116ff56e4e59")); + + final SyncInfoMessage m4 = new SyncInfoMessage(); + m4.setMessageType(SyncInfoMessage.Type.SYNC_ID_SET); + m4.setCookie(cookie); + m4.setEntryUuids(uuids); + m4.setRefreshDeletes(true); + return + new Object[][] { + // refresh delete with cookie + // BER:A1:36:04:34:72:69:64:3D:30:30:30:2C:63:73:6E:3D:32:30:31:32:30: + // 37:30:39:32:30:31:33:31:39:2E:37:36:34:39:31:35:5A:23:30:30:30: + // 30:30:30:23:30:30:30:23:30:30:30:30:30:30 + new Object[] { + LdapUtils.base64Decode("oTYENHJpZD0wMDAsY3NuPTIwMTIwNzA5MjAxMzE5Ljc2NDkxNVojMDAwMDAwIzAw" + + "MCMwMDAwMDA="), + m1, + }, + // new cookie + // BER:80:34:72:69:64:3D:30:30:30:2C:63:73:6E:3D:32:30:31:32:30:37:30: + // 39:32:30:31:33:31:39:2E:37:36:34:39:31:35:5A:23:30:30:30:30:30: + // 30:23:30:30:30:23:30:30:30:30:30:30: + new Object[] { + LdapUtils.base64Decode("gDRyaWQ9MDAwLGNzbj0yMDEyMDcwOTIwMTMxOS43NjQ5MTVaIzAwMDAwMCMwMDAj" + + "MDAwMDAw"), + m2, + }, + // refresh present with cookie, refresh done false + // BER:A2:39:04:34:72:69:64:3D:30:30:30:2C:63:73:6E:3D:32:30:31:32:30: + // 37:30:39:32:30:31:33:31:39:2E:37:36:34:39:31:35:5A:23:30:30:30: + // 30:30:30:23:30:30:30:23:30:30:30:30:30:30:01:01:00: + new Object[] { + LdapUtils.base64Decode( + "ojkENHJpZD0wMDAsY3NuPTIwMTIwNzA5MjAxMzE5Ljc2NDkxNVojMDAwMDAwIzAw" + + "MCMwMDAwMDABAQA="), + m3, + }, + // sync id set, refresh deletes true + // BER:A3:5F:04:34:72:69:64:3D:30:30:30:2C:63:73:6E:3D:32:30:31:32:30: + // 37:30:39:32:30:31:33:31:39:2E:37:36:34:39:31:35:5A:23:30:30:30: + // 30:30:30:23:30:30:30:23:30:30:30:30:30:30:01:01:FF:31:24:04:10: + // 5D:5D:A5:D0:5B:E2:10:31:82:84:11:6F:F5:6E:4E:59:04:10:84:31:77: + // EC:5B:0E:10:31:82:7F:11:6F:F5:6E:4E:59: + new Object[] { + LdapUtils.base64Decode( + "o18ENHJpZD0wMDAsY3NuPTIwMTIwNzA5MjAxMzE5Ljc2NDkxNVojMDAwMDAwIzAw" + + "MCMwMDAwMDABAf8xJAQQXV2l0FviEDGChBFv9W5OWQQQhDF37FsOEDGCfxFv9W5O" + + "WQ=="), + m4, + }, + }; + } + + + /** + * @param berValue to encode. + * @param expected sync info message to test. + * + * @throws Exception On test failure. + */ + @Test(groups = {"intermediate"}, dataProvider = "response") + public void decode(final byte[] berValue, final SyncInfoMessage expected) + throws Exception + { + final SyncInfoMessage actual = new SyncInfoMessage(); + actual.decode(berValue); + Assert.assertEquals(actual, expected); + } +}
diff --git a/core/src/test/java/org/ldaptive/io/Base64Test.java b/core/src/test/java/org/ldaptive/io/Base64Test.java new file mode 100644 index 0000000..dc436ed --- /dev/null +++ b/core/src/test/java/org/ldaptive/io/Base64Test.java
@@ -0,0 +1,142 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Scanner; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link Base64}. + * + * @author Middleware Services + */ +public class Base64Test +{ + + + /** + * Base64 test data. + * + * @return base64 test data + */ + @DataProvider(name = "encode-decode") + public Object[][] createEncodeDecodeData() + { + return + new Object[][] { + new Object[] { + "".getBytes(StandardCharsets.UTF_8), + "", + }, + new Object[] { + "Hello World".getBytes(StandardCharsets.UTF_8), + "SGVsbG8gV29ybGQ=", + }, + new Object[] { + "Base64 Encode".getBytes(StandardCharsets.UTF_8), + "QmFzZTY0IEVuY29kZQ==", + }, + new Object[] { + new Scanner( + Base64Test.class.getResourceAsStream( + "/org/ldaptive/io/plaintext.txt")).useDelimiter("\\Z").next().getBytes(StandardCharsets.UTF_8), + new Scanner( + Base64Test.class.getResourceAsStream("/org/ldaptive/io/base64-0.txt")).useDelimiter("\\Z").next(), + }, + }; + } + + + /** + * Base64 test data. + * + * @return base64 test data + */ + @DataProvider(name = "decode-mime") + public Object[][] createDecodeMimeData() + { + return + new Object[][] { + new Object[] { + new Scanner( + Base64Test.class.getResourceAsStream( + "/org/ldaptive/io/plaintext.txt")).useDelimiter("\\Z").next().getBytes(StandardCharsets.UTF_8), + new Scanner( + Base64Test.class.getResourceAsStream("/org/ldaptive/io/base64-76.txt")).useDelimiter("\\Z").next(), + }, + new Object[] { + new Scanner( + Base64Test.class.getResourceAsStream( + "/org/ldaptive/io/plaintext.txt")).useDelimiter("\\Z").next().getBytes(StandardCharsets.UTF_8), + new Scanner( + Base64Test.class.getResourceAsStream("/org/ldaptive/io/base64-64.txt")).useDelimiter("\\Z").next(), + }, + }; + } + + + /** + * Base64 test data. + * + * @return base64 test data + */ + @DataProvider(name = "invalid-decode") + public Object[][] createInvalidDecode() + { + return new Object[][] { + new Object[] {"QmFzZTY0IEVuY29kZQå", }, + new Object[] {"QmFzZTY0IEVuY29kZQç", }, + }; + } + + + /** + * @param raw data to encode + * @param encoded valid encoding + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "encode-decode") + public void encodeAndDecode(final byte[] raw, final String encoded) + throws Exception + { + final String s = new String(Base64.getEncoder().encode(raw), StandardCharsets.UTF_8); + Assert.assertEquals(encoded, s); + Assert.assertEquals(raw, Base64.getDecoder().decode(s)); + } + + + /** + * @param raw data to encode + * @param encoded valid encoding + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "decode-mime") + public void decodeMime(final byte[] raw, final String encoded) + throws Exception + { + Assert.assertEquals(raw, Base64.getMimeDecoder().decode(encoded)); + } + + + /** + * @param data to decode + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "invalid-decode") + public void decodeException(final String data) + throws Exception + { + try { + Base64.getDecoder().decode(data); + Assert.fail("Should have thrown exception"); + } catch (Exception e) { + Assert.assertEquals(IllegalArgumentException.class, e.getClass()); + } + } +}
diff --git a/core/src/test/java/org/ldaptive/io/CertificateValueTranscoderTest.java b/core/src/test/java/org/ldaptive/io/CertificateValueTranscoderTest.java new file mode 100644 index 0000000..65662c1 --- /dev/null +++ b/core/src/test/java/org/ldaptive/io/CertificateValueTranscoderTest.java
@@ -0,0 +1,88 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.io.ByteArrayInputStream; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link CertificateValueTranscoder}. + * + * @author Middleware Services + */ +public class CertificateValueTranscoderTest +{ + + /** Certificate with CN=a.foo.com. */ + private static final String A_FOO_COM_CERT = + "MIIDrzCCApegAwIBAgIJAK+nL4I3GkjeMA0GCSqGSIb3DQEBBQUAMEMxEjAQBgNV" + + "BAMTCWEuZm9vLmNvbTEYMBYGCgmSJomT8ixkARkWCGxkYXB0aXZlMRMwEQYKCZIm" + + "iZPyLGQBGRYDb3JnMB4XDTEyMDExNzIxNDAxNVoXDTIyMDExNDIxNDAxNVowQzES" + + "MBAGA1UEAxMJYS5mb28uY29tMRgwFgYKCZImiZPyLGQBGRYIbGRhcHRpdmUxEzAR" + + "BgoJkiaJk/IsZAEZFgNvcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB" + + "AQDGRxBVvGZqHFWbYdbpOZaBf4H68b7zjiqbpXXq+mTfVOehIUeyL0624JsdmHLx" + + "oMNC7K9hAaM88wxcyhBRLRfo4ar1DJspzcFUoz2kFD7ytWGS2zwvV+VWnoXpPNiw" + + "9QuK6bdA/UYLIg/fk3TwshuoIT9VBJ4L3TRdOYYgH6WJBerQ2L5vMu91B9nBhNqR" + + "4RG8VFqwgwW9IoXBXC8XTZS5jd0bVoEoeA+PWVENQ3my5ilP4VUqo9h/jPdb8dFW" + + "3TNoaVHjOiTUOIpH+5cUmi0OkH2NzhTaWmCVoWuzFpvvB6PFHHxut2pDe8eGgc4x" + + "NdEvZDizbfY6JEb/fkwZ+Im9AgMBAAGjgaUwgaIwHQYDVR0OBBYEFPUscUXspD8Z" + + "LP3b6yybVhXhp5C2MHMGA1UdIwRsMGqAFPUscUXspD8ZLP3b6yybVhXhp5C2oUek" + + "RTBDMRIwEAYDVQQDEwlhLmZvby5jb20xGDAWBgoJkiaJk/IsZAEZFghsZGFwdGl2" + + "ZTETMBEGCgmSJomT8ixkARkWA29yZ4IJAK+nL4I3GkjeMAwGA1UdEwQFMAMBAf8w" + + "DQYJKoZIhvcNAQEFBQADggEBALam5DdoM7cyOS2GbiA7QAfZTJkBcVr4Fef9aDWR" + + "cG3kzbEbu1OXf3lkRW11H7gPLOgZGebSsxsv6YhKgAtz7py3lyH5QNkrN0OGI1ZA" + + "eXf76eSR4T26pYjxln26xyZUW/dcddQ0nSj9Yl52oFCWj38DqGaxP6hIu3DHGlcE" + + "PtpM2T4ZjWgrsqxL8N59zMb0Re9V4Xop7KmsLs3ThF3RWwmZdC1ba5LRPK6lKNF5" + + "CnSl5YzFUMnpzFZtneUhAHeFxrF+RV4f3bHLNs+sWjlmJo0ukCCnOzoiyE4oOJiL" + + "AhDym4nIfzng6fgYBeLT1Hp/bKHivQP4ef4wgre6r1ztnFA="; + + /** Transcoder to test. */ + private final CertificateValueTranscoder transcoder = new CertificateValueTranscoder(); + + + /** + * Certificate test data. + * + * @return ldap attribute values + * + * @throws Exception if test data cannot be generated + */ + @DataProvider(name = "certs") + public Object[][] createCerts() + throws Exception + { + final CertificateFactory cf = CertificateFactory.getInstance("X.509"); + final Certificate cert = cf.generateCertificate(new ByteArrayInputStream(LdapUtils.base64Decode(A_FOO_COM_CERT))); + + return + new Object[][] { + new Object[] { + cert, + "-----BEGIN CERTIFICATE-----\n" + A_FOO_COM_CERT + "\n-----END CERTIFICATE-----", + LdapUtils.base64Decode(A_FOO_COM_CERT), + }, + }; + } + + + /** + * @param cert certificate to compare + * @param s ldap attribute string value + * @param b ldap attribute binary value + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "certs") + public void testTranscode(final Certificate cert, final String s, final byte[] b) + throws Exception + { + Assert.assertEquals(cert, transcoder.decodeStringValue(s)); + Assert.assertEquals(cert, transcoder.decodeBinaryValue(b)); + Assert.assertEquals(s, transcoder.encodeStringValue(cert)); + Assert.assertEquals(b, transcoder.encodeBinaryValue(cert)); + } +}
diff --git a/core/src/test/java/org/ldaptive/io/GeneralizedTimeValueTranscoderTest.java b/core/src/test/java/org/ldaptive/io/GeneralizedTimeValueTranscoderTest.java new file mode 100644 index 0000000..bf33824 --- /dev/null +++ b/core/src/test/java/org/ldaptive/io/GeneralizedTimeValueTranscoderTest.java
@@ -0,0 +1,365 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link GeneralizedTimeValueTranscoder}. + * + * @author Middleware Services + */ +public class GeneralizedTimeValueTranscoderTest +{ + + /** Transcoder to test. */ + private final GeneralizedTimeValueTranscoder transcoder = new GeneralizedTimeValueTranscoder(); + + + /** + * Date test data. + * + * @return dates + * + * @throws Exception if test data cannot be generated + */ + @DataProvider(name = "dates") + public Object[][] createDates() + throws Exception + { + return + new Object[][] { + // no fraction + new Object[] { + createDateTime("Z", 1990, 10, 23, 17), + "1990102317Z", + "19901023170000.000Z", + }, + new Object[] { + createDateTime("GMT+04", 2007, 10, 27, 13), + "2007102713+04", + "20071027090000.000Z", + }, + new Object[] { + createDateTime("GMT-1030", 1993, 12, 15, 14), + "1993121514-1030", + "19931216003000.000Z", + }, + // dot fraction + new Object[] { + createDateTime("Z", 2006, 8, 18, 23, 35, 9, 600), + "2006081823.586Z", + "20060818233509.600Z", + }, + new Object[] { + createDateTime("GMT+0100", 2012, 2, 15, 2, 15, 0, 0), + "2012021502.250+0100", + "20120215011500.000Z", + }, + new Object[] { + createDateTime("GMT-1030", 2005, 6, 4, 5, 52, 55, 200), + "2005060405.882-1030", + "20050604162255.200Z", + }, + // comma fraction + new Object[] { + createDateTime("Z", 1992, 3, 1, 7, 20, 38, 400), + "1992030107,344Z", + "19920301072038.400Z", + }, + new Object[] { + createDateTime("GMT+0100", 2008, 3, 21, 23, 30, 14, 400), + "2008032123,504+0100", + "20080321223014.400Z", + }, + new Object[] { + createDateTime("GMT-1030", 2018, 4, 8, 6, 45, 43, 200), + "2018040806,762-1030", + "20180408171543.200Z", + }, + // min, no fraction + new Object[] { + createDateTime("Z", 1994, 6, 7, 11, 50), + "199406071150Z", + "19940607115000.000Z", + }, + new Object[] { + createDateTime("GMT+04", 2015, 8, 24, 12, 41), + "201508241241+04", + "20150824084100.000Z", + }, + new Object[] { + createDateTime("GMT-1030", 2012, 12, 19, 7, 31), + "201212190731-1030", + "20121219180100.000Z", + }, + // min, dot fraction + new Object[] { + createDateTime("Z", 2019, 5, 27, 13, 57, 46, 800), + "201905271357.780Z", + "20190527135746.800Z", + }, + new Object[] { + createDateTime("GMT+0100", 2001, 2, 23, 17, 32, 33, 180), + "200102231732.553+0100", + "20010223163233.180Z", + }, + new Object[] { + createDateTime("GMT-1030", 1997, 10, 27, 19, 32, 31, 860), + "199710271932.531-1030", + "19971028060231.860Z", + }, + // min, comma fraction + new Object[] { + createDateTime("Z", 2005, 1, 6, 7, 5, 19, 260), + "200501060705,321Z", + "20050106070519.260Z", + }, + new Object[] { + createDateTime("GMT+0100", 2019, 10, 1, 3, 53, 16, 260), + "201910010353,271+0100", + "20191001025316.260Z", + }, + new Object[] { + createDateTime("GMT-1030", 2003, 2, 4, 10, 56, 49, 560), + "200302041056,826-1030", + "20030204212649.560Z", + }, + // min, sec, no fraction + new Object[] { + createDateTime("Z", 1993, 3, 4, 1, 6, 45), + "19930304010645Z", + "19930304010645.000Z", + }, + new Object[] { + createDateTime("GMT+04", 1996, 11, 15, 2, 1, 33), + "19961115020133+04", + "19961114220133.000Z", + }, + new Object[] { + createDateTime("GMT-1030", 2012, 11, 4, 10, 37, 40), + "20121104103740-1030", + "20121104210740.000Z", + }, + // min, sec, dot fraction + new Object[] { + createDateTime("Z", 2016, 5, 17, 5, 31, 50, 193), + "20160517053150.193Z", + "20160517053150.193Z", + }, + new Object[] { + createDateTime("GMT+0100", 2006, 9, 28, 9, 50, 56, 142), + "20060928095056.142+0100", + "20060928085056.142Z", + }, + new Object[] { + createDateTime("GMT-1030", 1997, 7, 15, 17, 41, 7, 418), + "19970715174107.418-1030", + "19970716041107.418Z", + }, + // min, sec, comma fraction + new Object[] { + createDateTime("Z", 2003, 5, 11, 3, 55, 24, 11), + "20030511035524,011Z", + "20030511035524.011Z", + }, + new Object[] { + createDateTime("GMT+0100", 2000, 9, 8, 4, 38, 1, 536), + "20000908043801,536+0100", + "20000908033801.536Z", + }, + new Object[] { + createDateTime("GMT-1030", 1999, 5, 12, 3, 34, 16, 307), + "19990512033416.307-1030", + "19990512140416.307Z", + }, + // feb 29 in leap year + new Object[] { + createDateTime("Z", 2012, 2, 29, 0), + "2012022900Z", + "20120229000000.000Z", + }, + }; + } + + + /** + * Date test data. + * + * @return dates + * + * @throws Exception if test data cannot be generated + */ + @DataProvider(name = "invalid") + public Object[][] createInvalidSyntax() + throws Exception + { + return + new Object[][] { + // invalid month + new Object[] {"20050003193252Z"}, + new Object[] {"20011315121902Z"}, + new Object[] {"20065205051238Z"}, + new Object[] {"19989912035214Z"}, + // invalid day + new Object[] {"20130600153448Z"}, + new Object[] {"19970132100613Z"}, + new Object[] {"19990466184045Z"}, + new Object[] {"20180299184327Z"}, + // invalid hour + new Object[] {"19991104604515Z"}, + new Object[] {"19990611775328Z"}, + new Object[] {"20161126993226Z"}, + // invalid min + new Object[] {"20150120036044Z"}, + new Object[] {"19950801078428Z"}, + new Object[] {"20141110059918Z"}, + // invalid sec + new Object[] {"19970507065463Z"}, + new Object[] {"20010804024188Z"}, + new Object[] {"20100401071599Z"}, + // invalid timezone + new Object[] {"20110118183832Z+"}, + new Object[] {"20140828202734+2400"}, + new Object[] {"20020505162928+9900"}, + new Object[] {"20160404014028+1260"}, + new Object[] {"20020522033010+1299"}, + // leap second + new Object[] {"19981126110460Z"}, + // too short + new Object[] {"200"}, + new Object[] {"2009"}, + new Object[] {"20091"}, + new Object[] {"200912"}, + new Object[] {"2009122"}, + new Object[] {"20091220"}, + new Object[] {"200912200"}, + new Object[] {"2009122003"}, + // invalid characters + new Object[] {"2AA9122003Z"}, + new Object[] {"2009122003Y"}, + new Object[] {"2004072704BBZ"}, + new Object[] {"200407270431CCZ"}, + new Object[] {"20040727043108.DZ"}, + new Object[] {"20040727043108.DDZ"}, + new Object[] {"20040727043108.DDDZ"}, + // missing timezone + new Object[] {"2017092602"}, + new Object[] {"201709260206"}, + new Object[] {"20170926020649"}, + new Object[] {"20170926020649.5"}, + new Object[] {"20170926020649.56"}, + new Object[] {"20170926020649.567"}, + new Object[] {"20170926020649,2"}, + new Object[] {"20170926020649,23"}, + new Object[] {"20170926020649,234"}, + // invalid timezone character + new Object[] {"2010112415E"}, + new Object[] {"201011241520E"}, + new Object[] {"20101124152005E"}, + new Object[] {"20101124152005.1E"}, + new Object[] {"20101124152005.12E"}, + new Object[] {"20101124152005.122E"}, + new Object[] {"20130915044541ZF"}, + new Object[] {"20101124152005+0630F"}, + // missing fraction + new Object[] {"20020511040917.Z"}, + new Object[] {"20020511040917,Z"}, + // feb 29 in non-leap year + new Object[] {"2011022900Z"}, + new Object[] {""}, + new Object[] {null}, + }; + } + + + /** + * @param date to compare + * @param generalizedTime ldap attribute string value + * @param formatTime formatted ldap attribute string value + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "dates") + public void decodeGeneralized(final ZonedDateTime date, final String generalizedTime, final String formatTime) + throws Exception + { + Assert.assertEquals(transcoder.decodeStringValue(generalizedTime), date); + } + + + /** + * @param date to compare + * @param generalizedTime ldap attribute string value + * @param formatTime formatted ldap attribute string value + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "dates") + public void encodeFormat(final ZonedDateTime date, final String generalizedTime, final String formatTime) + throws Exception + { + Assert.assertEquals(transcoder.encodeStringValue(date), formatTime); + } + + + /** + * @param date to compare + * @param generalizedTime ldap attribute string value + * @param formatTime formatted ldap attribute string value + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "dates") + public void decodeFormat(final ZonedDateTime date, final String generalizedTime, final String formatTime) + throws Exception + { + Assert.assertEquals(transcoder.decodeStringValue(formatTime), date.withZoneSameInstant(ZoneOffset.UTC)); + } + + + /** + * @param generalizedTime ldap attribute string value + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "invalid") + public void testInvalid(final String generalizedTime) + throws Exception + { + try { + transcoder.decodeStringValue(generalizedTime); + Assert.fail("Should have thrown exception"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), IllegalArgumentException.class); + } + } + + + /** + * Creates a date time for testing. + * + * @param timezone of the date time + * @param values corresponding to date time fields + * + * @return date time + */ + protected ZonedDateTime createDateTime(final String timezone, final int... values) + { + return ZonedDateTime.of( + LocalDateTime.of( + values[0], + values[1], + values[2], + values[3], + values.length > 4 ? values[4] : 0, + values.length > 5 ? values[5] : 0).plus(values.length > 6 ? values[6] : 0, ChronoUnit.MILLIS), + ZoneId.of(timezone)); + } +}
diff --git a/core/src/test/java/org/ldaptive/io/HexTest.java b/core/src/test/java/org/ldaptive/io/HexTest.java new file mode 100644 index 0000000..a5c2df7 --- /dev/null +++ b/core/src/test/java/org/ldaptive/io/HexTest.java
@@ -0,0 +1,123 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.nio.charset.StandardCharsets; +import java.util.Scanner; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link Hex}. + * + * @author Middleware Services + */ +public class HexTest +{ + + + /** + * Hex test data. + * + * @return hex test data + */ + @DataProvider(name = "encode-decode") + public Object[][] createEncodeDecodeData() + { + return + new Object[][] { + new Object[] { + "".getBytes(StandardCharsets.UTF_8), + "", + }, + new Object[] { + "Hello World".getBytes(StandardCharsets.UTF_8), + "48656C6C6F20576F726C64", + }, + new Object[] { + "Hexadecimal Encode".getBytes(StandardCharsets.UTF_8), + "48657861646563696D616C20456E636F6465", + }, + new Object[] { + new Scanner( + HexTest.class.getResourceAsStream( + "/org/ldaptive/io/plaintext.txt")).useDelimiter("\\Z").next().getBytes(StandardCharsets.UTF_8), + new Scanner(HexTest.class.getResourceAsStream("/org/ldaptive/io/hex.txt")).useDelimiter("\\Z").next(), + }, + }; + } + + + /** + * Hex test data. + * + * @return hex test data + */ + @DataProvider(name = "invalid-decode") + public Object[][] createInvalidDecode() + { + return + new Object[][] { + // odd characters + new Object[] { + new char[] {'A', }, + }, + new Object[] { + new char[] {'A', 'B', 'C', }, + }, + new Object[] { + new char[] {'A', 'B', 'C', 'D', 'E', }, + }, + new Object[] { + new char[] {97}, + }, + // invalid characters + new Object[] { + new char[] {'A', 'l', }, + }, + new Object[] { + new char[] {'l', 'A', }, + }, + new Object[] { + new char[] {'0', '4', '*', 'b', }, + }, + new Object[] { + new char[] {'0', '4', 'b', '*', }, + }, + }; + } + + + /** + * @param raw data to encode + * @param encoded valid encoding + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "encode-decode") + public void encodeAndDecode(final byte[] raw, final String encoded) + throws Exception + { + final char[] c = Hex.encode(raw); + Assert.assertEquals(encoded.toCharArray(), c); + Assert.assertEquals(raw, Hex.decode(c)); + } + + + /** + * @param data to decode + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "invalid-decode") + public void decodeException(final char[] data) + throws Exception + { + try { + Hex.decode(data); + Assert.fail("Should have thrown exception"); + } catch (Exception e) { + Assert.assertEquals(IllegalArgumentException.class, e.getClass()); + } + } +}
diff --git a/core/src/test/java/org/ldaptive/io/UUIDValueTranscoderTest.java b/core/src/test/java/org/ldaptive/io/UUIDValueTranscoderTest.java new file mode 100644 index 0000000..9e59f03 --- /dev/null +++ b/core/src/test/java/org/ldaptive/io/UUIDValueTranscoderTest.java
@@ -0,0 +1,58 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.util.UUID; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link UUIDValueTranscoder}. + * + * @author Middleware Services + */ +public class UUIDValueTranscoderTest +{ + + /** Transcoder to test. */ + private final UUIDValueTranscoder transcoder = new UUIDValueTranscoder(); + + + /** + * UUID test data. + * + * @return ldap attribute values + * + * @throws Exception if test data cannot be generated + */ + @DataProvider(name = "uuids") + public Object[][] createUuids() + throws Exception + { + return + new Object[][] { + new Object[] {"313def52-1e6b-102a-99ba-d6537704ad77", }, + new Object[] {"86641130-5f20-1031-8c17-394bb0fda920", }, + new Object[] {"7bb84c1c-1b19-102a-8e02-cbbda55d336d", }, + new Object[] {"76988e4a-1b19-102a-81f0-cbbda55d336d", }, + new Object[] {"05411a1a-1b18-102a-97aa-cbbda55d336d", }, + new Object[] {"ff8eeaca-1b17-102a-88c1-cbbda55d336d", }, + new Object[] {"3973914a-1b19-102a-8aab-cbbda55d336d", }, + }; + } + + + /** + * @param s uuid to compare + * + * @throws Exception On test failure. + */ + @Test(groups = {"io"}, dataProvider = "uuids") + public void testTranscode(final String s) + throws Exception + { + final UUID uuid = UUID.fromString(s); + Assert.assertEquals(uuid, transcoder.decodeStringValue(s)); + Assert.assertEquals(s, transcoder.encodeStringValue(uuid)); + } +}
diff --git a/core/src/test/java/org/ldaptive/props/CredentialConfigParserTest.java b/core/src/test/java/org/ldaptive/props/CredentialConfigParserTest.java new file mode 100644 index 0000000..99f3af9 --- /dev/null +++ b/core/src/test/java/org/ldaptive/props/CredentialConfigParserTest.java
@@ -0,0 +1,134 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import org.ldaptive.ssl.KeyStoreCredentialConfig; +import org.ldaptive.ssl.X509CredentialConfig; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link CredentialConfigParser}. + * + * @author Middleware Services + */ +public class CredentialConfigParserTest +{ + + + /** + * Property test data. + * + * @return configuration properties + */ + @DataProvider(name = "properties") + public Object[][] createProperties() + { + final String p1 = "{trustCertificates=classpath:/ldaptive.trust.crt}"; + final X509CredentialConfig o1 = new X509CredentialConfig(); + o1.setTrustCertificates("classpath:/ldaptive.trust.crt"); + + final String p2 = "{{trustCertificates=classpath:/ldaptive.trust.crt}}"; + final X509CredentialConfig o2 = new X509CredentialConfig(); + o2.setTrustCertificates("classpath:/ldaptive.trust.crt"); + + final String p3 = "{trustCertificates=classpath:/ldaptive.trust.crt}" + + "{authenticationCertificate=classpath:/ldaptive.crt}"; + final X509CredentialConfig o3 = new X509CredentialConfig(); + o3.setTrustCertificates("classpath:/ldaptive.trust.crt"); + o3.setAuthenticationCertificate("classpath:/ldaptive.crt"); + + final String p4 = "{{trustCertificates=classpath:/ldaptive.trust.crt}" + + "{authenticationCertificate=classpath:/ldaptive.crt}}"; + final X509CredentialConfig o4 = new X509CredentialConfig(); + o4.setTrustCertificates("classpath:/ldaptive.trust.crt"); + o4.setAuthenticationCertificate("classpath:/ldaptive.crt"); + + final String p5 = "org.ldaptive.ssl.X509CredentialConfig" + + "{trustCertificates=file:ldaptive.trust.crt}"; + final X509CredentialConfig o5 = new X509CredentialConfig(); + o5.setTrustCertificates("file:ldaptive.trust.crt"); + + final String p6 = "org.ldaptive.ssl.X509CredentialConfig" + + "{{trustCertificates=file:ldaptive.trust.crt}}"; + final X509CredentialConfig o6 = new X509CredentialConfig(); + o6.setTrustCertificates("file:ldaptive.trust.crt"); + + final String p7 = "org.ldaptive.ssl.KeyStoreCredentialConfig" + + "{{trustStore=classpath:/ldaptive.truststore}{trustStoreType=BKS}}"; + final KeyStoreCredentialConfig o7 = new KeyStoreCredentialConfig(); + o7.setTrustStore("classpath:/ldaptive.truststore"); + o7.setTrustStoreType("BKS"); + + final String p8 = "org.ldaptive.ssl.KeyStoreCredentialConfig" + + "{{trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS}}"; + final KeyStoreCredentialConfig o8 = new KeyStoreCredentialConfig(); + o8.setTrustStore("classpath:/ldaptive.truststore"); + o8.setTrustStoreType("BKS"); + + final String p9 = "org.ldaptive.ssl.KeyStoreCredentialConfig" + + "{{trustStore=classpath:/ldaptive.truststore}" + + "{trustStoreType=BKS}" + + "{trustStoreAliases=alias1}}"; + final KeyStoreCredentialConfig o9 = new KeyStoreCredentialConfig(); + o9.setTrustStore("classpath:/ldaptive.truststore"); + o9.setTrustStoreType("BKS"); + o9.setTrustStoreAliases("alias1"); + + final String p10 = "org.ldaptive.ssl.KeyStoreCredentialConfig" + + "{{trustStore=classpath:/ldaptive.truststore}" + + "{trustStoreType=BKS}" + + "{trustStoreAliases=alias1,alias2}}"; + final KeyStoreCredentialConfig o10 = new KeyStoreCredentialConfig(); + o10.setTrustStore("classpath:/ldaptive.truststore"); + o10.setTrustStoreType("BKS"); + o10.setTrustStoreAliases("alias1", "alias2"); + + final String p11 = "org.ldaptive.ssl.KeyStoreCredentialConfig" + + "{{trustStore=file:/path/to/my/cacerts}" + + "{trustStorePassword=changeit}" + + "{trustStoreAliases=custom-1,custom-2}" + + "{keyStore=file:/path/to/my/ldaptive.keystore}" + + "{keyStorePassword=changeit}" + + "{keyStoreAliases=alias1,alias2}}"; + final KeyStoreCredentialConfig o11 = new KeyStoreCredentialConfig(); + o11.setTrustStore("file:/path/to/my/cacerts"); + o11.setTrustStorePassword("changeit"); + o11.setTrustStoreAliases("custom-1", "custom-2"); + o11.setKeyStore("file:/path/to/my/ldaptive.keystore"); + o11.setKeyStorePassword("changeit"); + o11.setKeyStoreAliases("alias1", "alias2"); + + return + new Object[][] { + new Object[] {p1, o1, }, + new Object[] {p2, o2, }, + new Object[] {p3, o3, }, + new Object[] {p4, o4, }, + new Object[] {p5, o5, }, + new Object[] {p6, o6, }, + new Object[] {p7, o7, }, + new Object[] {p8, o8, }, + new Object[] {p9, o9, }, + new Object[] {p10, o10, }, + new Object[] {p11, o11, }, + }; + } + + + /** + * @param property to test + * @param initialized object to compare + * + * @throws Exception On test failure. + */ + @Test(groups = {"props"}, dataProvider = "properties") + public void initializeType(final String property, final Object initialized) + throws Exception + { + Assert.assertTrue(CredentialConfigParser.isCredentialConfig(property)); + + final CredentialConfigParser parser = new CredentialConfigParser(property); + Assert.assertEquals(initialized, parser.initializeType()); + } +}
diff --git a/core/src/test/java/org/ldaptive/props/PropertyValueParserTest.java b/core/src/test/java/org/ldaptive/props/PropertyValueParserTest.java new file mode 100644 index 0000000..d4c5247 --- /dev/null +++ b/core/src/test/java/org/ldaptive/props/PropertyValueParserTest.java
@@ -0,0 +1,98 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.props; + +import java.time.Duration; +import org.ldaptive.handler.MergeAttributeEntryHandler; +import org.ldaptive.handler.RecursiveEntryHandler; +import org.ldaptive.pool.IdlePruneStrategy; +import org.ldaptive.sasl.CramMd5Config; +import org.ldaptive.sasl.Mechanism; +import org.ldaptive.sasl.QualityOfProtection; +import org.ldaptive.sasl.SaslConfig; +import org.ldaptive.sasl.SecurityStrength; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link PropertyValueParser}. + * + * @author Middleware Services + */ +public class PropertyValueParserTest +{ + + + /** + * Property test data. + * + * @return configuration properties + */ + @DataProvider(name = "properties") + public Object[][] createProperties() + { + final String p1 = "org.ldaptive.handler.RecursiveEntryHandler" + + "{{searchAttribute=member}{mergeAttributes=mail,department}}"; + final RecursiveEntryHandler o1 = new RecursiveEntryHandler(); + o1.setSearchAttribute("member"); + o1.setMergeAttributes("mail", "department"); + + final String p2 = "org.ldaptive.handler.MergeAttributeEntryHandler{ }"; + final MergeAttributeEntryHandler o2 = new MergeAttributeEntryHandler(); + + final String p3 = "org.ldaptive.pool.IdlePruneStrategy{{prunePeriod=PT1M}{idleTime=PT2M}"; + final IdlePruneStrategy o3 = new IdlePruneStrategy(); + o3.setPrunePeriod(Duration.ofMinutes(1)); + o3.setIdleTime(Duration.ofMinutes(2)); + + final String p4 = "org.ldaptive.sasl.CramMd5Config" + + "{{securityStrength=LOW}{qualityOfProtection=AUTH}}"; + final CramMd5Config o4 = new CramMd5Config(); + o4.setSecurityStrength(SecurityStrength.LOW); + o4.setQualityOfProtection(QualityOfProtection.AUTH); + + final String p5 = "{{mechanism=DIGEST_MD5}{authorizationId=test1}}"; + final SaslConfig o5 = new SaslConfig(); + o5.setMechanism(Mechanism.DIGEST_MD5); + o5.setAuthorizationId("test1"); + + final String p6 = "{mechanism=EXTERNAL}"; + final SaslConfig o6 = new SaslConfig(); + o6.setMechanism(Mechanism.EXTERNAL); + + return + new Object[][] { + new Object[] {p1, null, o1, }, + new Object[] {p2, null, o2, }, + new Object[] {p3, null, o3, }, + new Object[] {p4, null, o4, }, + new Object[] {p5, SaslConfig.class, o5, }, + new Object[] {p6, SaslConfig.class, o6, }, + }; + } + + + /** + * @param property to test + * @param type of object or null + * @param initialized object to compare + * + * @throws Exception On test failure. + */ + @Test(groups = {"props"}, dataProvider = "properties") + public void initializeType(final String property, final Class<?> type, final Object initialized) + throws Exception + { + PropertyValueParser parser; + if (type != null) { + parser = new PropertyValueParser(property, type.getName()); + Assert.assertTrue(PropertyValueParser.isParamsOnlyConfig(property)); + } else { + parser = new PropertyValueParser(property); + Assert.assertTrue(PropertyValueParser.isConfig(property)); + } + + final Object o = parser.initializeType(); + Assert.assertEquals(initialized.toString().split("::")[1], o.toString().split("::")[1]); + } +}
diff --git a/core/src/test/java/org/ldaptive/schema/AttributeTypeTest.java b/core/src/test/java/org/ldaptive/schema/AttributeTypeTest.java new file mode 100644 index 0000000..974cfde --- /dev/null +++ b/core/src/test/java/org/ldaptive/schema/AttributeTypeTest.java
@@ -0,0 +1,276 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.util.Collections; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit tests for {@link AttributeType}. + * + * @author Middleware Services + */ +public class AttributeTypeTest +{ + + + /** + * Test data for attribute type. + * + * @return attribute type and string definition + */ + @DataProvider(name = "definitions") + public Object[][] createDefinitions() + { + final Extensions ext = new Extensions(); + ext.addExtension("X-NDS_NAME", Collections.singletonList("Aliased Object Name")); + ext.addExtension("X-NDS_NONREMOVABLE", Collections.singletonList("1")); + ext.addExtension("X-NDS_FILTERED_REQUIRED", Collections.singletonList("1")); + + return + new Object[][] { + new Object[] { + new AttributeType( + "2.5.4.0", + null, + null, + false, + null, + null, + null, + null, + null, + false, + false, + false, + null, + null), + "( 2.5.4.0 )", + }, + new Object[] { + new AttributeType( + "2.5.4.0", + null, + null, + false, + null, + null, + null, + null, + "1.3.6.1.4.1.1466.115.121.1.38", + false, + false, + false, + null, + null), + "( 2.5.4.0 SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", + }, + new Object[] { + new AttributeType( + "2.5.4.0", + new String[] {"objectClass"}, + null, + false, + null, + null, + null, + null, + "1.3.6.1.4.1.1466.115.121.1.38", + false, + false, + false, + null, + null), + "( 2.5.4.0 NAME 'objectClass' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", + }, + new Object[] { + new AttributeType( + "2.5.4.0", + null, + "RFC4512: object classes of the entity", + false, + null, + null, + null, + null, + null, + false, + false, + false, + null, + null), + "( 2.5.4.0 DESC 'RFC4512: object classes of the entity' )", + }, + new Object[] { + new AttributeType( + "2.5.4.0", + new String[] {"objectClass"}, + null, + false, + null, + "objectIdentifierMatch", + null, + null, + "1.3.6.1.4.1.1466.115.121.1.38", + false, + false, + false, + null, + null), + "( 2.5.4.0 NAME 'objectClass' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", + }, + new Object[] { + new AttributeType( + "2.5.4.0", + new String[] {"objectClass"}, + "RFC4512: object classes of the entity", + false, + null, + "objectIdentifierMatch", + null, + null, + "1.3.6.1.4.1.1466.115.121.1.38", + false, + false, + false, + null, + null), + "( 2.5.4.0 NAME 'objectClass' DESC 'RFC4512: object classes of the entity' EQUALITY objectIdentifierMatch " + + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", + }, + new Object[] { + new AttributeType( + "2.5.21.9", + new String[] {"structuralObjectClass"}, + "RFC4512: structural object class of entry", + false, + null, + "objectIdentifierMatch", + null, + null, + "1.3.6.1.4.1.1466.115.121.1.38", + true, + false, + true, + AttributeUsage.DIRECTORY_OPERATION, + null), + "( 2.5.21.9 NAME 'structuralObjectClass' DESC 'RFC4512: structural object class of entry' " + + "EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 SINGLE-VALUE NO-USER-MODIFICATION " + + "USAGE directoryOperation )", + }, + new Object[] { + new AttributeType( + "2.5.18.1", + new String[] {"createTimestamp"}, + "RFC4512: time which object was created", + false, + null, + "generalizedTimeMatch", + "generalizedTimeOrderingMatch", + null, + "1.3.6.1.4.1.1466.115.121.1.24", + true, + false, + true, + AttributeUsage.DIRECTORY_OPERATION, + null), + "( 2.5.18.1 NAME 'createTimestamp' DESC 'RFC4512: time which object was created' " + + "EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch " + + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", + }, + new Object[] { + new AttributeType( + "2.5.4.1", + new String[] {"aliasedObjectName", "aliasedEntryName"}, + null, + false, + null, + null, + null, + null, + null, + false, + false, + false, + null, + null), + "( 2.5.4.1 NAME ( 'aliasedObjectName' 'aliasedEntryName' ) )", + }, + new Object[] { + new AttributeType( + "2.5.4.1", + new String[] {"aliasedObjectName", "aliasedEntryName"}, + "RFC4512: name of aliased object", + false, + null, + "distinguishedNameMatch", + null, + null, + "1.3.6.1.4.1.1466.115.121.1.12", + true, + false, + false, + null, + null), + "( 2.5.4.1 NAME ( 'aliasedObjectName' 'aliasedEntryName' ) DESC 'RFC4512: name of aliased object' " + + "EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + }, + new Object[] { + new AttributeType( + "0.9.2342.19200300.100.1.1", + new String[] {"uid"}, + null, + false, + null, + "caseIgnoreMatch", + null, + "caseIgnoreSubstringsMatch", + "1.3.6.1.4.1.1466.115.121.1.15{256}", + false, + false, + false, + null, + new Extensions("X-ORIGIN", Collections.singletonList("RFC 1274"))), + "( 0.9.2342.19200300.100.1.1 NAME 'uid' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch " + + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} X-ORIGIN 'RFC 1274' )", + }, + new Object[] { + new AttributeType( + "2.5.4.1", + new String[] {"aliasedObjectName"}, + null, + false, + null, + null, + null, + null, + "1.3.6.1.4.1.1466.115.121.1.12", + true, + false, + false, + null, + ext), + "( 2.5.4.1 NAME 'aliasedObjectName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE " + + "X-NDS_NAME 'Aliased Object Name' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' )", + }, + }; + } + + + /** + * @param type to compare + * @param definition to parse + * + * @throws Exception On test failure. + */ + @Test(groups = {"schema"}, dataProvider = "definitions") + public void parse(final AttributeType type, final String definition) + throws Exception + { + final AttributeType parsed = AttributeType.parse(definition); + Assert.assertEquals(type, parsed); + Assert.assertEquals(definition, parsed.format()); + Assert.assertEquals(type.format(), parsed.format()); + } +}
diff --git a/core/src/test/java/org/ldaptive/schema/DITContentRuleTest.java b/core/src/test/java/org/ldaptive/schema/DITContentRuleTest.java new file mode 100644 index 0000000..51e334b --- /dev/null +++ b/core/src/test/java/org/ldaptive/schema/DITContentRuleTest.java
@@ -0,0 +1,91 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit tests for {@link DITContentRule}. + * + * @author Middleware Services + */ +public class DITContentRuleTest +{ + + + /** + * Test data for DIT content rule. + * + * @return DIT content rule and string definition + */ + @DataProvider(name = "definitions") + public Object[][] createDefinitions() + { + return + new Object[][] { + new Object[] { + new DITContentRule("12.16.840.1.113730.3.2.2", null, null, false, null, null, null, null, null), + "( 12.16.840.1.113730.3.2.2 )", + }, + new Object[] { + new DITContentRule( + "12.16.840.1.113730.3.2.2", + new String[] {"dcrPerson"}, + null, + false, + null, + null, + null, + null, + null), + "( 12.16.840.1.113730.3.2.2 NAME 'dcrPerson' )", + }, + new Object[] { + new DITContentRule( + "12.16.840.1.113730.3.2.2", + new String[] {"dcrPerson"}, + "inetOrgPerson entries may only be members of the uidObject aux class", + false, + null, + null, + null, + null, + null), + "( 12.16.840.1.113730.3.2.2 NAME 'dcrPerson' DESC 'inetOrgPerson entries may only be members of the " + + "uidObject aux class' )", + }, + new Object[] { + new DITContentRule( + "12.16.840.1.113730.3.2.2", + new String[] {"dcrPerson"}, + "inetOrgPerson entries may only be members of the uidObject aux class", + false, + new String[] {"1.3.6.1.1.3.1"}, + null, + null, + null, + null), + "( 12.16.840.1.113730.3.2.2 NAME 'dcrPerson' DESC 'inetOrgPerson entries may only be members of the " + + "uidObject aux class' AUX 1.3.6.1.1.3.1 )", + }, + }; + } + + + /** + * @param contentRule to compare + * @param definition to parse + * + * @throws Exception On test failure. + */ + @Test(groups = {"schema"}, dataProvider = "definitions") + public void parse(final DITContentRule contentRule, final String definition) + throws Exception + { + final DITContentRule parsed = DITContentRule.parse(definition); + Assert.assertEquals(contentRule, parsed); + Assert.assertEquals(definition, parsed.format()); + Assert.assertEquals(contentRule.format(), parsed.format()); + } +}
diff --git a/core/src/test/java/org/ldaptive/schema/DITStructureRuleTest.java b/core/src/test/java/org/ldaptive/schema/DITStructureRuleTest.java new file mode 100644 index 0000000..c1bb518 --- /dev/null +++ b/core/src/test/java/org/ldaptive/schema/DITStructureRuleTest.java
@@ -0,0 +1,125 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.util.Collections; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit tests for {@link DITStructureRule}. + * + * @author Middleware Services + */ +public class DITStructureRuleTest +{ + + + /** + * Test data for DIT structure rule. + * + * @return DIT structure rule and string definition + */ + @DataProvider(name = "definitions") + public Object[][] createDefinitions() + { + return + new Object[][] { + new Object[] { + new DITStructureRule(2, null, null, false, null, null, null), + "( 2 )", + }, + new Object[] { + new DITStructureRule(2, new String[] {"uddiContactStructureRule"}, null, false, null, null, null), + "( 2 NAME 'uddiContactStructureRule' )", + }, + new Object[] { + new DITStructureRule( + 2, + new String[] {"uddiContactStructureRule"}, + null, + false, + "uddiContactNameForm", + null, + null), + "( 2 NAME 'uddiContactStructureRule' FORM uddiContactNameForm )", + }, + new Object[] { + new DITStructureRule( + 2, + new String[] {"uddiContactStructureRule"}, + null, + false, + "uddiContactNameForm", + new int[] {1}, + null), + "( 2 NAME 'uddiContactStructureRule' FORM uddiContactNameForm SUP 1 )", + }, + new Object[] { + new DITStructureRule( + 2, + new String[] {"uddiContactStructureRule"}, + null, + false, + "uddiContactNameForm", + new int[] {1}, + new Extensions("X-ORIGIN", Collections.singletonList("RFC 4403"))), + "( 2 NAME 'uddiContactStructureRule' FORM uddiContactNameForm SUP 1 X-ORIGIN 'RFC 4403' )", + }, + new Object[] { + new DITStructureRule(1, new String[] {"domainStructureRule"}, null, false, "domainNameForm", null, null), + "( 1 NAME 'domainStructureRule' FORM domainNameForm )", + }, + new Object[] { + new DITStructureRule( + 2, + new String[] {"organizationalUnitStructureRule"}, + null, + false, + "organizationalUnitNameForm", + new int[] {1}, + null), + "( 2 NAME 'organizationalUnitStructureRule' FORM organizationalUnitNameForm SUP 1 )", + }, + new Object[] { + new DITStructureRule( + 3, + new String[] {"inetOrgPersonStructureRule"}, + null, + false, + "inetOrgPersonNameForm", + new int[] {2}, + null), + "( 3 NAME 'inetOrgPersonStructureRule' FORM inetOrgPersonNameForm SUP 2 )", + }, + new Object[] { + new DITStructureRule( + 4, + new String[] {"groupOfNamesStructureRule"}, + null, + false, + "groupOfNamesNameForm", + new int[] {2, 3}, + null), + "( 4 NAME 'groupOfNamesStructureRule' FORM groupOfNamesNameForm SUP ( 2 3 ) )", + }, + }; + } + + + /** + * @param structureRule to compare + * @param definition to parse + * + * @throws Exception On test failure. + */ + @Test(groups = {"schema"}, dataProvider = "definitions") + public void parse(final DITStructureRule structureRule, final String definition) + throws Exception + { + final DITStructureRule parsed = DITStructureRule.parse(definition); + Assert.assertEquals(structureRule, parsed); + Assert.assertEquals(definition, parsed.format()); + Assert.assertEquals(structureRule.format(), parsed.format()); + } +}
diff --git a/core/src/test/java/org/ldaptive/schema/MatchingRuleTest.java b/core/src/test/java/org/ldaptive/schema/MatchingRuleTest.java new file mode 100644 index 0000000..5e38bee --- /dev/null +++ b/core/src/test/java/org/ldaptive/schema/MatchingRuleTest.java
@@ -0,0 +1,78 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit tests for {@link MatchingRule}. + * + * @author Middleware Services + */ +public class MatchingRuleTest +{ + + + /** + * Test data for matching rule. + * + * @return matching rule and string definition + */ + @DataProvider(name = "definitions") + public Object[][] createDefinitions() + { + return + new Object[][] { + new Object[] { + new MatchingRule("1.3.6.1.1.16.3", null, null, false, null, null), + "( 1.3.6.1.1.16.3 )", + }, + new Object[] { + new MatchingRule("1.3.6.1.1.16.3", new String[] {"UUIDOrderingMatch"}, null, false, null, null), + "( 1.3.6.1.1.16.3 NAME 'UUIDOrderingMatch' )", + }, + new Object[] { + new MatchingRule("1.3.6.1.1.16.3", new String[] {"UUIDOrderingMatch"}, null, false, "1.3.6.1.1.16.1", null), + "( 1.3.6.1.1.16.3 NAME 'UUIDOrderingMatch' SYNTAX 1.3.6.1.1.16.1 )", + }, + new Object[] { + new MatchingRule( + "2.5.13.27", + new String[] {"generalizedTimeMatch"}, + null, + false, + "1.3.6.1.4.1.1466.115.121.1.24", + null), + "( 2.5.13.27 NAME 'generalizedTimeMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", + }, + new Object[] { + new MatchingRule( + "2.5.13.6", + new String[] {"caseExactOrderingMatch"}, + null, + false, + "1.3.6.1.4.1.1466.115.121.1.15", + null), + "( 2.5.13.6 NAME 'caseExactOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + }, + }; + } + + + /** + * @param matchingRule to compare + * @param definition to parse + * + * @throws Exception On test failure. + */ + @Test(groups = {"schema"}, dataProvider = "definitions") + public void parse(final MatchingRule matchingRule, final String definition) + throws Exception + { + final MatchingRule parsed = MatchingRule.parse(definition); + Assert.assertEquals(matchingRule, parsed); + Assert.assertEquals(definition, parsed.format()); + Assert.assertEquals(matchingRule.format(), parsed.format()); + } +}
diff --git a/core/src/test/java/org/ldaptive/schema/MatchingRuleUseTest.java b/core/src/test/java/org/ldaptive/schema/MatchingRuleUseTest.java new file mode 100644 index 0000000..dfbae00 --- /dev/null +++ b/core/src/test/java/org/ldaptive/schema/MatchingRuleUseTest.java
@@ -0,0 +1,102 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit tests for {@link MatchingRuleUse}. + * + * @author Middleware Services + */ +public class MatchingRuleUseTest +{ + + + /** + * Test data for matching rule use. + * + * @return matching rule use and string definition + */ + @DataProvider(name = "definitions") + public Object[][] createDefinitions() + { + return + new Object[][] { + new Object[] { + new MatchingRuleUse("1.2.840.113556.1.4.804", null, null, false, null, null), + "( 1.2.840.113556.1.4.804 )", + }, + new Object[] { + new MatchingRuleUse("1.2.840.113556.1.4.804", new String[] {"integerBitOrMatch"}, null, false, null, null), + "( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' )", + }, + new Object[] { + new MatchingRuleUse( + "1.2.840.113556.1.4.804", + new String[] {"integerBitOrMatch"}, + null, + false, + new String[] { + "supportedLDAPVersion", + "entryTtl", + "uidNumber", + "gidNumber", + "olcConcurrency", + "olcConnMaxPending", + "olcConnMaxPendingAuth", + "olcIdleTimeout", + "olcIndexSubstrIfMinLen", + "olcIndexSubstrIfMaxLen", + "olcIndexSubstrAnyLen", + "olcIndexSubstrAnyStep", + "olcIndexIntLen", + "olcListenerThreads", + "olcLocalSSF", + "olcMaxDerefDepth", + "olcReplicationInterval", + "olcSockbufMaxIncoming", + "olcSockbufMaxIncomingAuth", + "olcThreads", + "olcToolThreads", + "olcWriteTimeout", + "olcDbCacheFree", + "olcDbCacheSize", + "olcDbDNcacheSize", + "olcDbIDLcacheSize", + "olcDbSearchStack", + "olcDbShmKey", + "olcDbMaxReaders", + "olcDbMaxSize", + "mailPreferenceOption", + }, + null), + "( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' APPLIES ( supportedLDAPVersion $ entryTtl $ uidNumber $ " + + "gidNumber $ olcConcurrency $ olcConnMaxPending $ olcConnMaxPendingAuth $ olcIdleTimeout $ " + + "olcIndexSubstrIfMinLen $ olcIndexSubstrIfMaxLen $ olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ " + + "olcIndexIntLen $ olcListenerThreads $ olcLocalSSF $ olcMaxDerefDepth $ olcReplicationInterval $ " + + "olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcThreads $ olcToolThreads $ olcWriteTimeout $ " + + "olcDbCacheFree $ olcDbCacheSize $ olcDbDNcacheSize $ olcDbIDLcacheSize $ olcDbSearchStack $ " + + "olcDbShmKey $ olcDbMaxReaders $ olcDbMaxSize $ mailPreferenceOption ) )", + }, + }; + } + + + /** + * @param matchingRule to compare + * @param definition to parse + * + * @throws Exception On test failure. + */ + @Test(groups = {"schema"}, dataProvider = "definitions") + public void parse(final MatchingRuleUse matchingRule, final String definition) + throws Exception + { + final MatchingRuleUse parsed = MatchingRuleUse.parse(definition); + Assert.assertEquals(matchingRule, parsed); + Assert.assertEquals(definition, parsed.format()); + Assert.assertEquals(matchingRule.format(), parsed.format()); + } +}
diff --git a/core/src/test/java/org/ldaptive/schema/NameFormTest.java b/core/src/test/java/org/ldaptive/schema/NameFormTest.java new file mode 100644 index 0000000..5d9eef3 --- /dev/null +++ b/core/src/test/java/org/ldaptive/schema/NameFormTest.java
@@ -0,0 +1,100 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.util.Collections; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit tests for {@link NameForm}. + * + * @author Middleware Services + */ +public class NameFormTest +{ + + + /** + * Test data for name form. + * + * @return name form and string definition + */ + @DataProvider(name = "definitions") + public Object[][] createDefinitions() + { + return + new Object[][] { + new Object[] { + new NameForm("1.3.6.1.1.10.15.1", null, null, false, null, null, null, null), + "( 1.3.6.1.1.10.15.1 )", + }, + new Object[] { + new NameForm( + "1.3.6.1.1.10.15.1", + new String[] {"uddiBusinessEntityNameForm"}, + null, + false, + null, + null, + null, + null), + "( 1.3.6.1.1.10.15.1 NAME 'uddiBusinessEntityNameForm' )", + }, + new Object[] { + new NameForm( + "1.3.6.1.1.10.15.1", + new String[] {"uddiBusinessEntityNameForm"}, + null, + false, + "uddiBusinessEntity", + null, + null, + null), + "( 1.3.6.1.1.10.15.1 NAME 'uddiBusinessEntityNameForm' OC uddiBusinessEntity )", + }, + new Object[] { + new NameForm( + "1.3.6.1.1.10.15.1", + new String[] {"uddiBusinessEntityNameForm"}, + null, + false, + "uddiBusinessEntity", + new String[] {"uddiBusinessKey"}, + null, + null), + "( 1.3.6.1.1.10.15.1 NAME 'uddiBusinessEntityNameForm' OC uddiBusinessEntity MUST uddiBusinessKey )", + }, + new Object[] { + new NameForm( + "1.3.6.1.1.10.15.1", + new String[] {"uddiBusinessEntityNameForm"}, + null, + false, + "uddiBusinessEntity", + new String[] {"uddiBusinessKey"}, + null, + new Extensions("X-ORIGIN", Collections.singletonList("RFC 4403"))), + "( 1.3.6.1.1.10.15.1 NAME 'uddiBusinessEntityNameForm' OC uddiBusinessEntity MUST uddiBusinessKey " + + "X-ORIGIN 'RFC 4403' )", + }, + }; + } + + + /** + * @param nameForm to compare + * @param definition to parse + * + * @throws Exception On test failure. + */ + @Test(groups = {"schema"}, dataProvider = "definitions") + public void parse(final NameForm nameForm, final String definition) + throws Exception + { + final NameForm parsed = NameForm.parse(definition); + Assert.assertEquals(nameForm, parsed); + Assert.assertEquals(definition, parsed.format()); + Assert.assertEquals(nameForm.format(), parsed.format()); + } +}
diff --git a/core/src/test/java/org/ldaptive/schema/ObjectClassTest.java b/core/src/test/java/org/ldaptive/schema/ObjectClassTest.java new file mode 100644 index 0000000..940db4c --- /dev/null +++ b/core/src/test/java/org/ldaptive/schema/ObjectClassTest.java
@@ -0,0 +1,221 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.util.Collections; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit tests for {@link ObjectClass}. + * + * @author Middleware Services + */ +public class ObjectClassTest +{ + + + /** + * Test data for object class. + * + * @return object class and string definition + */ + @DataProvider(name = "definitions") + public Object[][] createDefinitions() + { + return + new Object[][] { + new Object[] { + new ObjectClass("2.5.6.0", null, null, false, null, null, null, null, null), + "( 2.5.6.0 )", + }, + new Object[] { + new ObjectClass("2.5.6.0", new String[] {"top"}, null, false, null, null, null, null, null), + "( 2.5.6.0 NAME 'top' )", + }, + new Object[] { + new ObjectClass( + "2.5.6.0", + new String[] {"top"}, + "top of the superclass chain", + false, + null, + null, + null, + null, + null), + "( 2.5.6.0 NAME 'top' DESC 'top of the superclass chain' )", + }, + new Object[] { + new ObjectClass( + "2.5.6.0", + new String[] {"top"}, + "top of the superclass chain", + false, + null, + ObjectClassType.ABSTRACT, + null, + null, + null), + "( 2.5.6.0 NAME 'top' DESC 'top of the superclass chain' ABSTRACT )", + }, + new Object[] { + new ObjectClass( + "2.5.6.0", + new String[] {"top"}, + "top of the superclass chain", + false, + null, + ObjectClassType.ABSTRACT, + new String[] {"objectClass"}, + null, + null), + "( 2.5.6.0 NAME 'top' DESC 'top of the superclass chain' ABSTRACT MUST objectClass )", + }, + new Object[] { + new ObjectClass( + "1.3.6.1.4.1.1466.101.120.111", + new String[] {"extensibleObject"}, + "RFC4512: extensible object", + false, + new String[] {"top"}, + ObjectClassType.AUXILIARY, + null, + null, + null), + "( 1.3.6.1.4.1.1466.101.120.111 NAME 'extensibleObject' DESC 'RFC4512: extensible object' SUP top " + + "AUXILIARY )", + }, + new Object[] { + new ObjectClass( + "2.5.6.1", + new String[] {"alias"}, + "RFC4512: an alias", + false, + new String[] {"top"}, + ObjectClassType.STRUCTURAL, + new String[] {"aliasedObjectName"}, + null, + null), + "( 2.5.6.1 NAME 'alias' DESC 'RFC4512: an alias' SUP top STRUCTURAL MUST aliasedObjectName )", + }, + new Object[] { + new ObjectClass( + "1.3.6.1.4.1.4203.1.4.1", + new String[] {"OpenLDAProotDSE", "LDAProotDSE"}, + "OpenLDAP Root DSE object", + false, + new String[] {"top"}, + ObjectClassType.STRUCTURAL, + null, + new String[] {"cn"}, + null), + "( 1.3.6.1.4.1.4203.1.4.1 NAME ( 'OpenLDAProotDSE' 'LDAProotDSE' ) DESC 'OpenLDAP Root DSE object' SUP top " + + "STRUCTURAL MAY cn )", + }, + new Object[] { + new ObjectClass( + "2.5.17.0", + new String[] {"subentry"}, + "RFC3672: subentry", + false, + new String[] {"top"}, + ObjectClassType.STRUCTURAL, + new String[] {"cn", "subtreeSpecification"}, + null, + null), + "( 2.5.17.0 NAME 'subentry' DESC 'RFC3672: subentry' SUP top STRUCTURAL MUST ( cn $ subtreeSpecification ) )", + }, + new Object[] { + new ObjectClass( + "2.16.840.1.113730.3.2.3", + new String[] {"mailRecipient"}, + "", + false, + new String[] {"top"}, + ObjectClassType.AUXILIARY, + new String[] {"objectClass"}, + new String[] { + "cn", + "mail", + "mailAlternateAddress", + "mailHost", + "mailRoutingAddress", + "mailAccessDomain", + "mailAutoReplyMode", + "mailAutoReplyText", + "mailDeliveryOption", + "mailForwardingAddress", + "mailMessageStore", + "mailProgramDeliveryInfo", + "mailQuota", + "multiLineDescription", + "uid", + "userPassword", + }, + new Extensions("X-ORIGIN", Collections.singletonList("Netscape Messaging Server 4.x"))), + "( 2.16.840.1.113730.3.2.3 NAME 'mailRecipient' DESC '' SUP top AUXILIARY MUST objectClass " + + "MAY ( cn $ mail $ mailAlternateAddress $ mailHost $ mailRoutingAddress $ mailAccessDomain $ " + + "mailAutoReplyMode $ mailAutoReplyText $ mailDeliveryOption $ mailForwardingAddress $ mailMessageStore $ " + + "mailProgramDeliveryInfo $ mailQuota $ multiLineDescription $ uid $ userPassword ) " + + "X-ORIGIN 'Netscape Messaging Server 4.x' )", + }, + new Object[] { + new ObjectClass( + "2.5.6.5", + new String[] {"organizationalUnit"}, + "RFC2256: an organizational unit", + false, + new String[] {"top"}, + ObjectClassType.STRUCTURAL, + new String[] {"ou"}, + new String[] { + "userPassword", + "searchGuide", + "seeAlso", + "businessCategory", + "x121Address", + "registeredAddress", + "destinationIndicator", + "preferredDeliveryMethod", + "telexNumber", + "teletexTerminalIdentifier", + "telephoneNumber", + "internationaliSDNNumber", + "facsimileTelephoneNumber", + "street", + "postOfficeBox", + "postalCode", + "postalAddress", + "physicalDeliveryOfficeName", + "st", + "l", + "description", + }, + null), + "( 2.5.6.5 NAME 'organizationalUnit' DESC 'RFC2256: an organizational unit' SUP top STRUCTURAL MUST ou " + + "MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $ x121Address $ registeredAddress $ " + + "destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ " + + "telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $ street $ postOfficeBox $ " + + "postalCode $ postalAddress $ physicalDeliveryOfficeName $ st $ l $ description ) )", + }, + }; + } + + + /** + * @param objectClass to compare + * @param definition to parse + * + * @throws Exception On test failure. + */ + @Test(groups = {"schema"}, dataProvider = "definitions") + public void parse(final ObjectClass objectClass, final String definition) + throws Exception + { + final ObjectClass parsed = ObjectClass.parse(definition); + Assert.assertEquals(objectClass, parsed); + Assert.assertEquals(definition, parsed.format()); + Assert.assertEquals(objectClass.format(), parsed.format()); + } +}
diff --git a/core/src/test/java/org/ldaptive/schema/SyntaxTest.java b/core/src/test/java/org/ldaptive/schema/SyntaxTest.java new file mode 100644 index 0000000..b713a17 --- /dev/null +++ b/core/src/test/java/org/ldaptive/schema/SyntaxTest.java
@@ -0,0 +1,62 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.schema; + +import java.util.Collections; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit tests for {@link Syntax}. + * + * @author Middleware Services + */ +public class SyntaxTest +{ + + + /** + * Test data for attribute syntax. + * + * @return attribute syntax and string definition + */ + @DataProvider(name = "definitions") + public Object[][] createDefinitions() + { + return + new Object[][] { + new Object[] { + new Syntax("1.3.6.1.4.1.1466.115.121.1.5", null, null), + "( 1.3.6.1.4.1.1466.115.121.1.5 )", + }, + new Object[] { + new Syntax("1.3.6.1.4.1.1466.115.121.1.5", "Binary", null), + "( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' )", + }, + new Object[] { + new Syntax( + "1.3.6.1.4.1.1466.115.121.1.5", + "Binary", + new Extensions("X-NOT-HUMAN-READABLE", Collections.singletonList("TRUE"))), + "( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' X-NOT-HUMAN-READABLE 'TRUE' )", + }, + }; + } + + + /** + * @param attributeSyntax to compare + * @param definition to parse + * + * @throws Exception On test failure. + */ + @Test(groups = {"schema"}, dataProvider = "definitions") + public void parse(final Syntax attributeSyntax, final String definition) + throws Exception + { + final Syntax parsed = Syntax.parse(definition); + Assert.assertEquals(attributeSyntax, parsed); + Assert.assertEquals(definition, parsed.format()); + Assert.assertEquals(attributeSyntax.format(), parsed.format()); + } +}
diff --git a/core/src/test/java/org/ldaptive/ssl/DefaultHostnameVerifierTest.java b/core/src/test/java/org/ldaptive/ssl/DefaultHostnameVerifierTest.java new file mode 100644 index 0000000..fb85c39 --- /dev/null +++ b/core/src/test/java/org/ldaptive/ssl/DefaultHostnameVerifierTest.java
@@ -0,0 +1,408 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.io.ByteArrayInputStream; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link DefaultHostnameVerifier}. Generate key with: openssl genrsa -aes256 -out test.key 2048 Generate + * cert with: openssl req -new -x509 -sha1 -days 3650 -key test.key -out test.crt \ -subj + * "/CN=a.foo.com/DC=ldaptive/DC=org" -config openssl.cnf \ -extensions my_ext + * + * @author Middleware Services + */ +public class DefaultHostnameVerifierTest +{ + + /** Instance of the default hostname verifier. */ + private static final DefaultHostnameVerifier DEFAULT_VERIFIER = new DefaultHostnameVerifier(); + + /** Instance of the default startTLS hostname verifier. */ + private static final SunTLSHostnameVerifier SUN_VERIFIER = new SunTLSHostnameVerifier(); + + /** Certificate with CN=a.foo.com. */ + private static final String A_FOO_COM_CERT = + "MIIDrzCCApegAwIBAgIJAK+nL4I3GkjeMA0GCSqGSIb3DQEBBQUAMEMxEjAQBgNV" + + "BAMTCWEuZm9vLmNvbTEYMBYGCgmSJomT8ixkARkWCGxkYXB0aXZlMRMwEQYKCZIm" + + "iZPyLGQBGRYDb3JnMB4XDTEyMDExNzIxNDAxNVoXDTIyMDExNDIxNDAxNVowQzES" + + "MBAGA1UEAxMJYS5mb28uY29tMRgwFgYKCZImiZPyLGQBGRYIbGRhcHRpdmUxEzAR" + + "BgoJkiaJk/IsZAEZFgNvcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB" + + "AQDGRxBVvGZqHFWbYdbpOZaBf4H68b7zjiqbpXXq+mTfVOehIUeyL0624JsdmHLx" + + "oMNC7K9hAaM88wxcyhBRLRfo4ar1DJspzcFUoz2kFD7ytWGS2zwvV+VWnoXpPNiw" + + "9QuK6bdA/UYLIg/fk3TwshuoIT9VBJ4L3TRdOYYgH6WJBerQ2L5vMu91B9nBhNqR" + + "4RG8VFqwgwW9IoXBXC8XTZS5jd0bVoEoeA+PWVENQ3my5ilP4VUqo9h/jPdb8dFW" + + "3TNoaVHjOiTUOIpH+5cUmi0OkH2NzhTaWmCVoWuzFpvvB6PFHHxut2pDe8eGgc4x" + + "NdEvZDizbfY6JEb/fkwZ+Im9AgMBAAGjgaUwgaIwHQYDVR0OBBYEFPUscUXspD8Z" + + "LP3b6yybVhXhp5C2MHMGA1UdIwRsMGqAFPUscUXspD8ZLP3b6yybVhXhp5C2oUek" + + "RTBDMRIwEAYDVQQDEwlhLmZvby5jb20xGDAWBgoJkiaJk/IsZAEZFghsZGFwdGl2" + + "ZTETMBEGCgmSJomT8ixkARkWA29yZ4IJAK+nL4I3GkjeMAwGA1UdEwQFMAMBAf8w" + + "DQYJKoZIhvcNAQEFBQADggEBALam5DdoM7cyOS2GbiA7QAfZTJkBcVr4Fef9aDWR" + + "cG3kzbEbu1OXf3lkRW11H7gPLOgZGebSsxsv6YhKgAtz7py3lyH5QNkrN0OGI1ZA" + + "eXf76eSR4T26pYjxln26xyZUW/dcddQ0nSj9Yl52oFCWj38DqGaxP6hIu3DHGlcE" + + "PtpM2T4ZjWgrsqxL8N59zMb0Re9V4Xop7KmsLs3ThF3RWwmZdC1ba5LRPK6lKNF5" + + "CnSl5YzFUMnpzFZtneUhAHeFxrF+RV4f3bHLNs+sWjlmJo0ukCCnOzoiyE4oOJiL" + + "AhDym4nIfzng6fgYBeLT1Hp/bKHivQP4ef4wgre6r1ztnFA="; + + /** Certificate with CN=*.foo.com. */ + private static final String WC_FOO_COM_CERT = + "MIIDrzCCApegAwIBAgIJAJycqMrRasIKMA0GCSqGSIb3DQEBBQUAMEMxEjAQBgNV" + + "BAMUCSouZm9vLmNvbTEYMBYGCgmSJomT8ixkARkWCGxkYXB0aXZlMRMwEQYKCZIm" + + "iZPyLGQBGRYDb3JnMB4XDTEyMDExNzIyMjQ1N1oXDTIyMDExNDIyMjQ1N1owQzES" + + "MBAGA1UEAxQJKi5mb28uY29tMRgwFgYKCZImiZPyLGQBGRYIbGRhcHRpdmUxEzAR" + + "BgoJkiaJk/IsZAEZFgNvcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB" + + "AQDGRxBVvGZqHFWbYdbpOZaBf4H68b7zjiqbpXXq+mTfVOehIUeyL0624JsdmHLx" + + "oMNC7K9hAaM88wxcyhBRLRfo4ar1DJspzcFUoz2kFD7ytWGS2zwvV+VWnoXpPNiw" + + "9QuK6bdA/UYLIg/fk3TwshuoIT9VBJ4L3TRdOYYgH6WJBerQ2L5vMu91B9nBhNqR" + + "4RG8VFqwgwW9IoXBXC8XTZS5jd0bVoEoeA+PWVENQ3my5ilP4VUqo9h/jPdb8dFW" + + "3TNoaVHjOiTUOIpH+5cUmi0OkH2NzhTaWmCVoWuzFpvvB6PFHHxut2pDe8eGgc4x" + + "NdEvZDizbfY6JEb/fkwZ+Im9AgMBAAGjgaUwgaIwHQYDVR0OBBYEFPUscUXspD8Z" + + "LP3b6yybVhXhp5C2MHMGA1UdIwRsMGqAFPUscUXspD8ZLP3b6yybVhXhp5C2oUek" + + "RTBDMRIwEAYDVQQDFAkqLmZvby5jb20xGDAWBgoJkiaJk/IsZAEZFghsZGFwdGl2" + + "ZTETMBEGCgmSJomT8ixkARkWA29yZ4IJAJycqMrRasIKMAwGA1UdEwQFMAMBAf8w" + + "DQYJKoZIhvcNAQEFBQADggEBACG6nq5fSL8F1zHH0CP+sPWHJEh5OXErdhOfAKVc" + + "g0tfvYSI5gsyYTk87TZPTWkmpUUDn1keoVYqyXEaG8qAwL5cNUeYTze6R0GfB0UP" + + "jwmkCxZwKhZnN/ryXhzPIEJQHRsg2fYM0P2S6jUG9m92eyCUWrbolmwfkDotbvsS" + + "YE6m8oc7OaOVHQ20LDSLML3JOabONKSZW/BODI/ZzWzLNNU45xT4bGbtoyVwEerT" + + "WWsGAYdXbsREzuV9q3naEd4wl5CJRBFZtTIizM1RdxxbFrAhTkiDtURTERxLmFxY" + + "Nv3gLLhxykIoUIEtTxDjHgAiA02r3yBy5HfIC409WzmdVQI="; + + /** Certificate with CN=*.foo.bar.com. */ + private static final String WC_FOO_BAR_COM_CERT = + "MIIDuzCCAqOgAwIBAgIJAOxfZwQylIyjMA0GCSqGSIb3DQEBBQUAMEcxFjAUBgNV" + + "BAMUDSouZm9vLmJhci5jb20xGDAWBgoJkiaJk/IsZAEZFghsZGFwdGl2ZTETMBEG" + + "CgmSJomT8ixkARkWA29yZzAeFw0xMjAxMTgxNzE2MTBaFw0yMjAxMTUxNzE2MTBa" + + "MEcxFjAUBgNVBAMUDSouZm9vLmJhci5jb20xGDAWBgoJkiaJk/IsZAEZFghsZGFw" + + "dGl2ZTETMBEGCgmSJomT8ixkARkWA29yZzCCASIwDQYJKoZIhvcNAQEBBQADggEP" + + "ADCCAQoCggEBAMZHEFW8ZmocVZth1uk5loF/gfrxvvOOKpulder6ZN9U56EhR7Iv" + + "Trbgmx2YcvGgw0Lsr2EBozzzDFzKEFEtF+jhqvUMmynNwVSjPaQUPvK1YZLbPC9X" + + "5Vaehek82LD1C4rpt0D9RgsiD9+TdPCyG6ghP1UEngvdNF05hiAfpYkF6tDYvm8y" + + "73UH2cGE2pHhEbxUWrCDBb0ihcFcLxdNlLmN3RtWgSh4D49ZUQ1DebLmKU/hVSqj" + + "2H+M91vx0VbdM2hpUeM6JNQ4ikf7lxSaLQ6QfY3OFNpaYJWha7MWm+8Ho8UcfG63" + + "akN7x4aBzjE10S9kOLNt9jokRv9+TBn4ib0CAwEAAaOBqTCBpjAdBgNVHQ4EFgQU" + + "9SxxReykPxks/dvrLJtWFeGnkLYwdwYDVR0jBHAwboAU9SxxReykPxks/dvrLJtW" + + "FeGnkLahS6RJMEcxFjAUBgNVBAMUDSouZm9vLmJhci5jb20xGDAWBgoJkiaJk/Is" + + "ZAEZFghsZGFwdGl2ZTETMBEGCgmSJomT8ixkARkWA29yZ4IJAOxfZwQylIyjMAwG" + + "A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBABMssljEmqtJ1+2ci+l+8zzk" + + "Ak+xrkYNMWSjNVJ7B5pmD6MguMxfAiT2QNc0JaI0Zv4h+EprZeELQN3XsCwKRc13" + + "v+YuMyBH7xlXzvRQ+/0Y3x5BJKTUELzOdc95vhtwnPVfEwmNhzJAUXxfi0BnT9XZ" + + "J02ikAQ8RmtgeTUKDXLZP2xoIJ0YLc8dtdQ/M+ET6WH14kO01vqmk4ZX7oekHP2R" + + "W1oko9r9zXl9AKWqEd2p/hD8GiHdK2oS+Ob4Hc3k9UqxaAUxidsQmhRLBJKuHjIt" + + "GVqUK9J39FNxChacraSWTdx8yRQOxaKO5PfJDQRgCPg/9aV1AXQW+Y60ILvvHVA="; + + /** Certificate with CN=a-c.foo.com subjAltName=DNS:a.foo.com,DNS:b.foo.com,DNS:c.foo.com. */ + private static final String A_FOO_COM_ALTNAME_CERT = + "MIIEAzCCAuugAwIBAgIJAMMwgpWWMq0YMA0GCSqGSIb3DQEBBQUAMEUxFDASBgNV" + + "BAMTC2EtYy5mb28uY29tMRgwFgYKCZImiZPyLGQBGRYIbGRhcHRpdmUxEzARBgoJ" + + "kiaJk/IsZAEZFgNvcmcwHhcNMTIwMTE4MTYxMDQwWhcNMjIwMTE1MTYxMDQwWjBF" + + "MRQwEgYDVQQDEwthLWMuZm9vLmNvbTEYMBYGCgmSJomT8ixkARkWCGxkYXB0aXZl" + + "MRMwEQYKCZImiZPyLGQBGRYDb3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB" + + "CgKCAQEAxkcQVbxmahxVm2HW6TmWgX+B+vG+844qm6V16vpk31TnoSFHsi9OtuCb" + + "HZhy8aDDQuyvYQGjPPMMXMoQUS0X6OGq9QybKc3BVKM9pBQ+8rVhkts8L1flVp6F" + + "6TzYsPULium3QP1GCyIP35N08LIbqCE/VQSeC900XTmGIB+liQXq0Ni+bzLvdQfZ" + + "wYTakeERvFRasIMFvSKFwVwvF02UuY3dG1aBKHgPj1lRDUN5suYpT+FVKqPYf4z3" + + "W/HRVt0zaGlR4zok1DiKR/uXFJotDpB9jc4U2lpglaFrsxab7wejxRx8brdqQ3vH" + + "hoHOMTXRL2Q4s232OiRG/35MGfiJvQIDAQABo4H1MIHyMAwGA1UdEwEB/wQCMAAw" + + "CwYDVR0PBAQDAgTwMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB0GA1UdDgQWBBT1LHFF" + + "7KQ/GSz92+ssm1YV4aeQtjB1BgNVHSMEbjBsgBT1LHFF7KQ/GSz92+ssm1YV4aeQ" + + "tqFJpEcwRTEUMBIGA1UEAxMLYS1jLmZvby5jb20xGDAWBgoJkiaJk/IsZAEZFghs" + + "ZGFwdGl2ZTETMBEGCgmSJomT8ixkARkWA29yZ4IJAMMwgpWWMq0YMCoGA1UdEQQj" + + "MCGCCWEuZm9vLmNvbYIJYi5mb28uY29tggljLmZvby5jb20wDQYJKoZIhvcNAQEF" + + "BQADggEBAH59Ewi4dxchcQwgJgA3KkTu6CAb/5S3BCwjv0ERdnnoshrxqu2lrF3e" + + "2oW16kGpPdQiIw0OdD/XB3o2It01PjDzdBBBgCas2JtpoQi7/QH0qrvgFqgbzPLV" + + "5Ehv1ObyxYKdOMDO7hqYr3PMkYyu4MhsjKp6LRDuFGHqYGzfdUzIjpfPd+jZtiN8" + + "EBH+ZmG/PueGFd+vaQu3CIGIkG9fLrfpckUD87x/n6pa+cuWvuAd814fWJpdvLl1" + + "iGkLfFU0E2G5pzlk9AHyWiBwYbuUrwLVW7sT7awpnzQBf0NCNETcuRmML7YnunwI" + + "3pJosuWr0LZy4fQbu3CquXgY9GNpto8="; + + /** Certificate with CN=wc.foo.com subjAltName=DNS:*.foo.com. */ + private static final String WC_FOO_COM_ALTNAME_CERT = + "MIID6jCCAtKgAwIBAgIJAJrNbvmrBDUOMA0GCSqGSIb3DQEBBQUAMEQxEzARBgNV" + + "BAMTCndjLmZvby5jb20xGDAWBgoJkiaJk/IsZAEZFghsZGFwdGl2ZTETMBEGCgmS" + + "JomT8ixkARkWA29yZzAeFw0xMjAxMTgxNjI2MjJaFw0yMjAxMTUxNjI2MjJaMEQx" + + "EzARBgNVBAMTCndjLmZvby5jb20xGDAWBgoJkiaJk/IsZAEZFghsZGFwdGl2ZTET" + + "MBEGCgmSJomT8ixkARkWA29yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC" + + "ggEBAMZHEFW8ZmocVZth1uk5loF/gfrxvvOOKpulder6ZN9U56EhR7IvTrbgmx2Y" + + "cvGgw0Lsr2EBozzzDFzKEFEtF+jhqvUMmynNwVSjPaQUPvK1YZLbPC9X5Vaehek8" + + "2LD1C4rpt0D9RgsiD9+TdPCyG6ghP1UEngvdNF05hiAfpYkF6tDYvm8y73UH2cGE" + + "2pHhEbxUWrCDBb0ihcFcLxdNlLmN3RtWgSh4D49ZUQ1DebLmKU/hVSqj2H+M91vx" + + "0VbdM2hpUeM6JNQ4ikf7lxSaLQ6QfY3OFNpaYJWha7MWm+8Ho8UcfG63akN7x4aB" + + "zjE10S9kOLNt9jokRv9+TBn4ib0CAwEAAaOB3jCB2zAMBgNVHRMBAf8EAjAAMAsG" + + "A1UdDwQEAwIE8DATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQU9SxxReyk" + + "Pxks/dvrLJtWFeGnkLYwdAYDVR0jBG0wa4AU9SxxReykPxks/dvrLJtWFeGnkLah" + + "SKRGMEQxEzARBgNVBAMTCndjLmZvby5jb20xGDAWBgoJkiaJk/IsZAEZFghsZGFw" + + "dGl2ZTETMBEGCgmSJomT8ixkARkWA29yZ4IJAJrNbvmrBDUOMBQGA1UdEQQNMAuC" + + "CSouZm9vLmNvbTANBgkqhkiG9w0BAQUFAAOCAQEAcv8obBTxn7odtbjhc/Du36Zt" + + "T+HjeO4B8Claf1XgmX8lki2SDO2qOdwA0eaYcOJyKhbdIpspQrp7W8vzvSmN6NPg" + + "8XfAZ/xxDil8SfXwVjhHtAU4xYGeYRPY/1WCm8gKlWriV1ECRPn+sxs6DiG+HF7t" + + "fEwFBqg1m6FLGycm6H6NMSLL+1sr9MXqjSVetKIlzvGKi4ZdGMRjobGXSx12aCt9" + + "BfnIFAf8523sCADmpMs1th/blpzAfHkPXjtLa/6EC8Xj6EZfUaE8UGofgSpyS7wq" + + "2ICWGB2oi1ekDMQmP15GtyNm41B2s11KCdDhSCAJu0dyIqWztO3bAGVxR1YTtQ=="; + + /** Certificate with CN=127.0.0.1. */ + private static final String LOCALHOST_CERT = + "MIIDrzCCApegAwIBAgIJAO+cKkPsfU8rMA0GCSqGSIb3DQEBBQUAMEMxEjAQBgNV" + + "BAMTCTEyNy4wLjAuMTEYMBYGCgmSJomT8ixkARkWCGxkYXB0aXZlMRMwEQYKCZIm" + + "iZPyLGQBGRYDb3JnMB4XDTEyMDExNzIyMzM0MFoXDTIyMDExNDIyMzM0MFowQzES" + + "MBAGA1UEAxMJMTI3LjAuMC4xMRgwFgYKCZImiZPyLGQBGRYIbGRhcHRpdmUxEzAR" + + "BgoJkiaJk/IsZAEZFgNvcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB" + + "AQDGRxBVvGZqHFWbYdbpOZaBf4H68b7zjiqbpXXq+mTfVOehIUeyL0624JsdmHLx" + + "oMNC7K9hAaM88wxcyhBRLRfo4ar1DJspzcFUoz2kFD7ytWGS2zwvV+VWnoXpPNiw" + + "9QuK6bdA/UYLIg/fk3TwshuoIT9VBJ4L3TRdOYYgH6WJBerQ2L5vMu91B9nBhNqR" + + "4RG8VFqwgwW9IoXBXC8XTZS5jd0bVoEoeA+PWVENQ3my5ilP4VUqo9h/jPdb8dFW" + + "3TNoaVHjOiTUOIpH+5cUmi0OkH2NzhTaWmCVoWuzFpvvB6PFHHxut2pDe8eGgc4x" + + "NdEvZDizbfY6JEb/fkwZ+Im9AgMBAAGjgaUwgaIwHQYDVR0OBBYEFPUscUXspD8Z" + + "LP3b6yybVhXhp5C2MHMGA1UdIwRsMGqAFPUscUXspD8ZLP3b6yybVhXhp5C2oUek" + + "RTBDMRIwEAYDVQQDEwkxMjcuMC4wLjExGDAWBgoJkiaJk/IsZAEZFghsZGFwdGl2" + + "ZTETMBEGCgmSJomT8ixkARkWA29yZ4IJAO+cKkPsfU8rMAwGA1UdEwQFMAMBAf8w" + + "DQYJKoZIhvcNAQEFBQADggEBAEy+LQguZ0kDdRone/HDnNQfCtWplHU8rE/8oFZo" + + "ZVroGGo55zu5Iv66AljeLkTBp7FqIhH9JbwB8CF57g0Uuok560ttoWV/RPisW86p" + + "z7eURpPClyel5+uz/PUt8crdNhXqG5iRvO7NlJONVZfLf3KlilXcoSE13msv8X80" + + "pDXqOv61kZ4CKB1eAWMT5PXLsks47g42OtHKdOrGv+KGyiMUXmO/9Jxa44maXP6x" + + "s8nJ1c5f2zZaZEANTkvO6UFbYynAHisBn9xD++5OcjVJMgX1qOaoxurO2kov5oyw" + + "bLLuQaV6NVa+DPs6X6P1+iAmPQNj+Izqveq+8C1vyYdu9VU="; + + /** Certificate with CN=localhost subjAltName=IP:127.0.0.1. */ + private static final String LOCALHOST_ALTNAME_CERT = + "MIID4jCCAsqgAwIBAgIJAK/f77u+7Kw2MA0GCSqGSIb3DQEBBQUAMEMxEjAQBgNV" + + "BAMTCWxvY2FsaG9zdDEYMBYGCgmSJomT8ixkARkWCGxkYXB0aXZlMRMwEQYKCZIm" + + "iZPyLGQBGRYDb3JnMB4XDTEyMDExODE2MDY1NFoXDTIyMDExNTE2MDY1NFowQzES" + + "MBAGA1UEAxMJbG9jYWxob3N0MRgwFgYKCZImiZPyLGQBGRYIbGRhcHRpdmUxEzAR" + + "BgoJkiaJk/IsZAEZFgNvcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB" + + "AQDGRxBVvGZqHFWbYdbpOZaBf4H68b7zjiqbpXXq+mTfVOehIUeyL0624JsdmHLx" + + "oMNC7K9hAaM88wxcyhBRLRfo4ar1DJspzcFUoz2kFD7ytWGS2zwvV+VWnoXpPNiw" + + "9QuK6bdA/UYLIg/fk3TwshuoIT9VBJ4L3TRdOYYgH6WJBerQ2L5vMu91B9nBhNqR" + + "4RG8VFqwgwW9IoXBXC8XTZS5jd0bVoEoeA+PWVENQ3my5ilP4VUqo9h/jPdb8dFW" + + "3TNoaVHjOiTUOIpH+5cUmi0OkH2NzhTaWmCVoWuzFpvvB6PFHHxut2pDe8eGgc4x" + + "NdEvZDizbfY6JEb/fkwZ+Im9AgMBAAGjgdgwgdUwDAYDVR0TAQH/BAIwADALBgNV" + + "HQ8EBAMCBPAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHQYDVR0OBBYEFPUscUXspD8Z" + + "LP3b6yybVhXhp5C2MHMGA1UdIwRsMGqAFPUscUXspD8ZLP3b6yybVhXhp5C2oUek" + + "RTBDMRIwEAYDVQQDEwlsb2NhbGhvc3QxGDAWBgoJkiaJk/IsZAEZFghsZGFwdGl2" + + "ZTETMBEGCgmSJomT8ixkARkWA29yZ4IJAK/f77u+7Kw2MA8GA1UdEQQIMAaHBH8A" + + "AAEwDQYJKoZIhvcNAQEFBQADggEBAGa/YCXT/zUV48INqggR0ielSIXz1ztFKG4R" + + "sWDoh76MPwyDqONXA3azXKe5BkeXDQ+6cN+VTgHYCpaHnaWdAWgLVqs4prr5MIzk" + + "pxIRiVbayzRi0apUq5MyV/XGMECYOf3dPCT2P9Ph4jGJkLHKg66cKoxEPreoCToy" + + "GT/1gh18bJ0xAo1CMlc4rH5C1pOx+hOIurFIxjUg44TGnBxMYUmeH0S1B1rmkuFo" + + "h65ugoRzPU690x6DkscPxSQKexEjEZG+z0QnsQgaig6SY3bX2kKMa48QywLp0/Vo" + + "HddtVv0q6rQqonRHRuCyD+FuXUg0w7BVVRH9txYAsE5eciIc7z0="; + + /** Certificate with CN=a.foo.com/CN=b.foo.com. */ + private static final String A_FOO_COM_MV_CERT = + "MIIC2zCCAkSgAwIBAgIDAVJ9MA0GCSqGSIb3DQEBBQUAMFcxEzARBgoJkiaJk/Is" + + "ZAEZFgNvcmcxGDAWBgoJkiaJk/IsZAEZFghsZGFwdGl2ZTESMBAGA1UEAxMJYS5m" + + "b28uY29tMRIwEAYDVQQDEwliLmZvby5jb20wHhcNMTQwODI5MTk1MTE5WhcNMTQw" + + "OTI4MTk1MTE5WjBXMRMwEQYKCZImiZPyLGQBGRYDb3JnMRgwFgYKCZImiZPyLGQB" + + "GRYIbGRhcHRpdmUxEjAQBgNVBAMTCWEuZm9vLmNvbTESMBAGA1UEAxMJYi5mb28u" + + "Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrFV0ARzYvBJLXMLo8yex7" + + "aNATrAANh4S3utE/ce+xj2qTi+hl9xm0EU6Zal+iYGpsKqnpTPfNE8HVMbzOrrPB" + + "6fRMGS1AyRV3WOy+2mgdzi1P068PqpTkm+MjXF6El8OBnuGaIwLzvFMno0rV7lse" + + "UOLDYcEIl3BdVsIlH27KpQIDAQABo4G0MIGxMB0GA1UdDgQWBBSHRs4AN3PGdL/i" + + "OkPq/Cjjc6f8EDCBgQYDVR0jBHoweIAUh0bOADdzxnS/4jpD6vwo43On/BChW6RZ" + + "MFcxEzARBgoJkiaJk/IsZAEZFgNvcmcxGDAWBgoJkiaJk/IsZAEZFghsZGFwdGl2" + + "ZTESMBAGA1UEAxMJYS5mb28uY29tMRIwEAYDVQQDEwliLmZvby5jb22CAwFSfTAM" + + "BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAC++ms/hrIOiY4Gdyie8qiIW" + + "FAU/IZLkbFSPwFpVQrYLdN7m+xCIcq2+viaZdXG6QYOC8dYr2URoEoVm+DPfx2Hj" + + "TokXEIsNS7ODx8r/sBmJ2UHvRdPROtqwY4tCgYlf7LWD/s27eRVYCTZbcwMF1hBf" + + "aNe1VTBZ5MLkzyewZ6tW"; + + /** Certificate with CN=a.foo.com+b.foo.com. */ + private static final String A_FOO_COM_MV_RDN_CERT = + "MIIC1DCCAj2gAwIBAgIDAVJ9MA0GCSqGSIb3DQEBBQUAMFUxJDAQBgNVBAMTCWEu" + + "Zm9vLmNvbTAQBgNVBAMTCWIuZm9vLmNvbTEYMBYGCgmSJomT8ixkARkWCGxkYXB0" + + "aXZlMRMwEQYKCZImiZPyLGQBGRYDb3JnMB4XDTE0MDgyOTE5MjY1OVoXDTE0MDky" + + "ODE5MjY1OVowVTEkMBAGA1UEAxMJYS5mb28uY29tMBAGA1UEAxMJYi5mb28uY29t" + + "MRgwFgYKCZImiZPyLGQBGRYIbGRhcHRpdmUxEzARBgoJkiaJk/IsZAEZFgNvcmcw" + + "gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOC2KBN8MDiKHWEuv1pnIEcWYjHb" + + "D+NgAGVnZh7i8jEDRIVpWUzFj7FxNROEsAitZAanzpwo6jYeGmT60Vl4DpliuoVu" + + "Vt1Reem96Dp9/J7BL0QBv0fJErv/YRhNor4wSOuWI96TWHvCDEL4oDNuxEK46Nsn" + + "dAw10DFBRMWt1VcFAgMBAAGjgbEwga4wHQYDVR0OBBYEFB7EPqv9y/GqxBrJAMS4" + + "pEh2ktyTMH8GA1UdIwR4MHaAFB7EPqv9y/GqxBrJAMS4pEh2ktyToVmkVzBVMSQw" + + "EAYDVQQDEwlhLmZvby5jb20wEAYDVQQDEwliLmZvby5jb20xGDAWBgoJkiaJk/Is" + + "ZAEZFghsZGFwdGl2ZTETMBEGCgmSJomT8ixkARkWA29yZ4IDAVJ9MAwGA1UdEwQF" + + "MAMBAf8wDQYJKoZIhvcNAQEFBQADgYEALU4SluqREjvyztZDZRsVnKn0Wy5kQqh3" + + "wVN/U2Sv82+N6ulzqOttmEY/dq8UGH5QbIioGUTgWxycidYwzWCIT/+Gg+pwBcmz" + + "oTYxJY0aUKfvfy4p25dcaG360DMycUpmZHM+HpgEGOrMsLCewKshuR+D03pE9eH5" + + "AK1FbieXQtM="; + + /** Certificate with /CN=a.foo.com/O=foo, CN=b.embed.com,/. */ + private static final String END_B_EMBED_COM_CERT = + "MIICbjCCAdegAwIBAgIDAVJ9MA0GCSqGSIb3DQEBBQUAMDMxEjAQBgNVBAMTCWEu" + + "Zm9vLmNvbTEdMBsGA1UEChMUZm9vLCBDTj1iLmVtYmVkLmNvbSwwHhcNMTQwODIw" + + "MDQ1MDQ3WhcNMTQwOTE5MDQ1MDQ3WjAzMRIwEAYDVQQDEwlhLmZvby5jb20xHTAb" + + "BgNVBAoTFGZvbywgQ049Yi5lbWJlZC5jb20sMIGfMA0GCSqGSIb3DQEBAQUAA4GN" + + "ADCBiQKBgQCmODoBNwHc/1lReh98PU0Cwc9VWewd/Z7Ieoy48ScunJj+85XDtzYZ" + + "xv14kBuRGY1dDA282b3cQE5Q4AHen9rmmAAPQqU4jTPCcr51XyMzEdVn3AL4DYMb" + + "t7MkH09UikI+9KRrJLdRuLDX4UKfs1q1HBFuI5xETH2K9/Ck5aVghwIDAQABo4GP" + + "MIGMMB0GA1UdDgQWBBQhSWjpzcpwrouaTb+xrnzhP/o/ZDBdBgNVHSMEVjBUgBQh" + + "SWjpzcpwrouaTb+xrnzhP/o/ZKE3pDUwMzESMBAGA1UEAxMJYS5mb28uY29tMR0w" + + "GwYDVQQKExRmb28sIENOPWIuZW1iZWQuY29tLIIDAVJ9MAwGA1UdEwQFMAMBAf8w" + + "DQYJKoZIhvcNAQEFBQADgYEAgehg1PgzUh4uxz2k/8aSM4aizRqp5o9g9uuUn6BI" + + "swNWWa7BsF2G/NDdIj0cB34n8nYHlAn24UuIxZHAkT7L79hlkkGX/sal8ttga/8g" + + "Rr56cBlZoR8lbD+fLMJx1EmMRYOLVq9I7o+QkwuCyyBFaxQB2JGx1GeZTp0d14zO" + + "3UM="; + + /** Certificate with /CN=a.foo.com/O=CN=b.embed.com, foo/. */ + private static final String BEGIN_B_EMBED_COM_CERT = + "MIICazCCAdSgAwIBAgIDAVJ9MA0GCSqGSIb3DQEBBQUAMDIxEjAQBgNVBAMTCWEu" + + "Zm9vLmNvbTEcMBoGA1UEChMTQ049Yi5lbWJlZC5jb20sIGZvbzAeFw0xNDA4MjAw" + + "NDUzNDJaFw0xNDA5MTkwNDUzNDJaMDIxEjAQBgNVBAMTCWEuZm9vLmNvbTEcMBoG" + + "A1UEChMTQ049Yi5lbWJlZC5jb20sIGZvbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAw" + + "gYkCgYEA2oe29WdBaLWlYxKw8Hk8Gws19g5OpB+GG8yyef+P490iAg+M3n4+tXbd" + + "Jls9zTg6t5/8dAY6lfDCZBjdz9wCaJwE4g8YQr159iPAPOw1He1F6kHWcS3HUbfX" + + "Yzzv2G9gg0Ect3cFx3A+fFCrQTNumoHIE6dCO3E7DiEGnaVFVOECAwEAAaOBjjCB" + + "izAdBgNVHQ4EFgQUOeHQsTmcK1EGC5FMf+MPRVNWapcwXAYDVR0jBFUwU4AUOeHQ" + + "sTmcK1EGC5FMf+MPRVNWapehNqQ0MDIxEjAQBgNVBAMTCWEuZm9vLmNvbTEcMBoG" + + "A1UEChMTQ049Yi5lbWJlZC5jb20sIGZvb4IDAVJ9MAwGA1UdEwQFMAMBAf8wDQYJ" + + "KoZIhvcNAQEFBQADgYEAideRQI+/vGYAV4pP3vwB22mLwopN8Q7sKiH34l+Jt8ib" + + "UG9/HiI6nf2kizoqxK3yTWzQ7UpjsOI4pvNpXQ01IXcz9pdpUQOVCp60oEmWyie0" + + "qTSGaeM8OdLLJQeV9UZTZt7e/gnF+FHmrYcNKyM518IbJY+Pth87bJeFYcU7+MI="; + + /** Certificate with /CN=ldap-test-1.middleware.vt.edu/. */ + private static final String MW_CERT = + "MIIDhzCCAvCgAwIBAgIJAPpeFAkJP5xgMA0GCSqGSIb3DQEBBQUAMIGKMQswCQYD" + + "VQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWExEzARBgNVBAcTCkJsYWNrc2J1cmcx" + + "FjAUBgNVBAoTDVZpcmdpbmlhIFRlY2gxEzARBgNVBAsTCk1pZGRsZXdhcmUxJjAk" + + "BgNVBAMTHWxkYXAtdGVzdC0xLm1pZGRsZXdhcmUudnQuZWR1MB4XDTExMDkyNjE2" + + "NDczOFoXDTIxMDkyMzE2NDczOFowgYoxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhW" + + "aXJnaW5pYTETMBEGA1UEBxMKQmxhY2tzYnVyZzEWMBQGA1UEChMNVmlyZ2luaWEg" + + "VGVjaDETMBEGA1UECxMKTWlkZGxld2FyZTEmMCQGA1UEAxMdbGRhcC10ZXN0LTEu" + + "bWlkZGxld2FyZS52dC5lZHUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJWf" + + "/vBsfFn6sQo57IHrBzMlPARpDI1DJeqH7zl2UeVzeiZDjGiU4ETSjEsvvQRzLfXZ" + + "IgJEr1IEAzjCX8wKF4svrmkPK3KN6JvdlknM7Thw5p0NzAh2Bq1R1h7+bUvQJGep" + + "aizNM0od/mKrJnOnUCWEgcpG91mWg8b1PphGobeNAgMBAAGjgfIwge8wHQYDVR0O" + + "BBYEFMT2Hkcp6JFq242hWfdMOeT3/hZ1MIG/BgNVHSMEgbcwgbSAFMT2Hkcp6JFq" + + "242hWfdMOeT3/hZ1oYGQpIGNMIGKMQswCQYDVQQGEwJVUzERMA8GA1UECBMIVmly" + + "Z2luaWExEzARBgNVBAcTCkJsYWNrc2J1cmcxFjAUBgNVBAoTDVZpcmdpbmlhIFRl" + + "Y2gxEzARBgNVBAsTCk1pZGRsZXdhcmUxJjAkBgNVBAMTHWxkYXAtdGVzdC0xLm1p" + + "ZGRsZXdhcmUudnQuZWR1ggkA+l4UCQk/nGAwDAYDVR0TBAUwAwEB/zANBgkqhkiG" + + "9w0BAQUFAAOBgQBe0bV5iZyPupNh2zmdH7opuwldz1sxlkRdUQhKSlYsOqgAKDvS" + + "DypmR4mqntAULTFGZIdcQ1W8HJcnRc8KuPfNatAV8A9OqMbtDLnmfWkl33JPiDUd" + + "fIKCXuG4dZ6nn3RbjlKhXzHYADmJzdQNIC3M9eDQBEYmMy8+mV+ErVebBg=="; + + + /** + * Certificate test data. + * + * @return cert test data + * + * @throws Exception if test data cannot be generated + */ + @DataProvider(name = "certificates") + public Object[][] createCerts() + throws Exception + { + final CertificateFactory cf = CertificateFactory.getInstance("X.509"); + final X509Certificate aFooComCert = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(LdapUtils.base64Decode(A_FOO_COM_CERT))); + final X509Certificate wcFooComCert = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(LdapUtils.base64Decode(WC_FOO_COM_CERT))); + final X509Certificate wcFooBarComCert = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(LdapUtils.base64Decode(WC_FOO_BAR_COM_CERT))); + final X509Certificate aFooComAltNameCert = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(LdapUtils.base64Decode(A_FOO_COM_ALTNAME_CERT))); + final X509Certificate wcFooComAltNameCert = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(LdapUtils.base64Decode(WC_FOO_COM_ALTNAME_CERT))); + final X509Certificate localhostCert = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(LdapUtils.base64Decode(LOCALHOST_CERT))); + final X509Certificate localhostAltNameCert = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(LdapUtils.base64Decode(LOCALHOST_ALTNAME_CERT))); + final X509Certificate aFooComMvCert = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(LdapUtils.base64Decode(A_FOO_COM_MV_CERT))); + final X509Certificate aFooComMvRdnCert = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(LdapUtils.base64Decode(A_FOO_COM_MV_RDN_CERT))); + final X509Certificate endBEmbedComCert = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(LdapUtils.base64Decode(END_B_EMBED_COM_CERT))); + final X509Certificate beginBEmbedComCert = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(LdapUtils.base64Decode(BEGIN_B_EMBED_COM_CERT))); + final X509Certificate mwCert = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(LdapUtils.base64Decode(MW_CERT))); + + return + new Object[][] { + /* a.foo.com == CN=a.foo.com */ + new Object[] {"a.foo.com", aFooComCert, true, }, + /* b.foo.com != CN=a.foo.com */ + new Object[] {"b.foo.com", aFooComCert, false, }, + /* a.foo.com == CN=*.foo.com */ + new Object[] {"a.foo.com", wcFooComCert, true, }, + /* b.foo.com == CN=*.foo.com */ + new Object[] {"b.foo.com", wcFooComCert, true, }, + /* a.b.foo.com != CN=*.foo.com */ + new Object[] {"a.b.foo.com", wcFooComCert, false, }, + /* a.foo.com != CN=*.foo.bar.com */ + new Object[] {"a.foo.com", wcFooBarComCert, false, }, + /* a.b.foo.bar.com != CN=*.foo.bar.com */ + new Object[] {"a.b.foo.bar.com", wcFooBarComCert, false, }, + /* a.foo.bar.com == CN=*.foo.bar.com */ + new Object[] {"a.foo.bar.com", wcFooBarComCert, true, }, + /* a.foo.com == subjAltName: DNS=a.foo.com */ + new Object[] {"a.foo.com", aFooComAltNameCert, true, }, + /* b.foo.com == subjAltName: DNS=b.foo.com */ + new Object[] {"b.foo.com", aFooComAltNameCert, true, }, + /* a.foo.com == subjAltName: DNS=*.foo.com */ + new Object[] {"a.foo.com", wcFooComAltNameCert, true, }, + /* b.foo.com == subjAltName: DNS=*.foo.com */ + new Object[] {"b.foo.com", wcFooComAltNameCert, true, }, + /* a.b.foo.com != subjAltName: DNS=*.foo.com */ + new Object[] {"a.b.foo.com", wcFooComAltNameCert, false, }, + /* 10.0.0.1 != CN=127.0.0.1 */ + new Object[] {"10.0.0.1", localhostCert, false, }, + /* 127.0.0.1 != CN=127.0.0.1, IPs can only match subjAltName */ + new Object[] {"127.0.0.1", localhostCert, false, }, + /* 127.0.0.1 == subjAltName: IP=127.0.0.1 */ + new Object[] {"127.0.0.1", localhostAltNameCert, true, }, + /* a.foo.com != CN=a.foo.com/CN=b.foo.com */ + new Object[] {"a.foo.com", aFooComMvCert, false, }, + /* b.foo.com == CN=a.foo.com/CN=b.foo.com */ + new Object[] {"b.foo.com", aFooComMvCert, true, }, + /* a.foo.com == CN=a.foo.com+CN=b.foo.com */ + new Object[] {"a.foo.com", aFooComMvRdnCert, true, }, + /* b.foo.com != CN=a.foo.com+CN=b.foo.com */ + new Object[] {"b.foo.com", aFooComMvRdnCert, false, }, + /* a.foo.com == CN=a.foo.com */ + new Object[] {"a.foo.com", endBEmbedComCert, true, }, + /* a.foo.com != CN=b.embed.com */ + new Object[] {"b.embed.com", endBEmbedComCert, false, }, + /* a.foo.com == CN=a.foo.com */ + new Object[] {"a.foo.com", beginBEmbedComCert, true, }, + /* a.foo.com != CN=b.embed.com */ + new Object[] {"b.embed.com", beginBEmbedComCert, false, }, + /* ldap-test-1.middleware.vt.edu == CN=ldap-test-1.middleware.vt.edu */ + new Object[] {"ldap-test-1.middleware.vt.edu", mwCert, true, }, + }; + } + + + /** + * @param hostname to match against the cert + * @param cert to extract hostname from + * @param pass whether the verify should succeed + * + * @throws Exception On test failure. + */ + @Test(groups = {"ssl"}, dataProvider = "certificates") + public void verifyDefault(final String hostname, final X509Certificate cert, final boolean pass) + throws Exception + { + Assert.assertEquals(DEFAULT_VERIFIER.verify(hostname, cert), pass); + } + + + /** + * @param hostname to match against the cert + * @param cert to extract hostname from + * @param pass whether the verify should succeed + * + * @throws Exception On test failure. + */ + @Test(groups = {"ssl"}, dataProvider = "certificates") + public void verifySun(final String hostname, final X509Certificate cert, final boolean pass) + throws Exception + { + Assert.assertEquals(SUN_VERIFIER.verify(hostname, cert), pass); + } +}
diff --git a/core/src/test/java/org/ldaptive/ssl/SSLContextInitializerTest.java b/core/src/test/java/org/ldaptive/ssl/SSLContextInitializerTest.java new file mode 100644 index 0000000..44ef0c8 --- /dev/null +++ b/core/src/test/java/org/ldaptive/ssl/SSLContextInitializerTest.java
@@ -0,0 +1,209 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.io.ByteArrayInputStream; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import javax.net.ssl.TrustManager; +import org.ldaptive.LdapUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SSLContextInitializer}. + * + * @author Middleware Services + */ +public class SSLContextInitializerTest +{ + + /** Certificate with CN=a.foo.com. */ + private static final String A_FOO_COM_CERT = + "MIIDrzCCApegAwIBAgIJAK+nL4I3GkjeMA0GCSqGSIb3DQEBBQUAMEMxEjAQBgNV" + + "BAMTCWEuZm9vLmNvbTEYMBYGCgmSJomT8ixkARkWCGxkYXB0aXZlMRMwEQYKCZIm" + + "iZPyLGQBGRYDb3JnMB4XDTEyMDExNzIxNDAxNVoXDTIyMDExNDIxNDAxNVowQzES" + + "MBAGA1UEAxMJYS5mb28uY29tMRgwFgYKCZImiZPyLGQBGRYIbGRhcHRpdmUxEzAR" + + "BgoJkiaJk/IsZAEZFgNvcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB" + + "AQDGRxBVvGZqHFWbYdbpOZaBf4H68b7zjiqbpXXq+mTfVOehIUeyL0624JsdmHLx" + + "oMNC7K9hAaM88wxcyhBRLRfo4ar1DJspzcFUoz2kFD7ytWGS2zwvV+VWnoXpPNiw" + + "9QuK6bdA/UYLIg/fk3TwshuoIT9VBJ4L3TRdOYYgH6WJBerQ2L5vMu91B9nBhNqR" + + "4RG8VFqwgwW9IoXBXC8XTZS5jd0bVoEoeA+PWVENQ3my5ilP4VUqo9h/jPdb8dFW" + + "3TNoaVHjOiTUOIpH+5cUmi0OkH2NzhTaWmCVoWuzFpvvB6PFHHxut2pDe8eGgc4x" + + "NdEvZDizbfY6JEb/fkwZ+Im9AgMBAAGjgaUwgaIwHQYDVR0OBBYEFPUscUXspD8Z" + + "LP3b6yybVhXhp5C2MHMGA1UdIwRsMGqAFPUscUXspD8ZLP3b6yybVhXhp5C2oUek" + + "RTBDMRIwEAYDVQQDEwlhLmZvby5jb20xGDAWBgoJkiaJk/IsZAEZFghsZGFwdGl2" + + "ZTETMBEGCgmSJomT8ixkARkWA29yZ4IJAK+nL4I3GkjeMAwGA1UdEwQFMAMBAf8w" + + "DQYJKoZIhvcNAQEFBQADggEBALam5DdoM7cyOS2GbiA7QAfZTJkBcVr4Fef9aDWR" + + "cG3kzbEbu1OXf3lkRW11H7gPLOgZGebSsxsv6YhKgAtz7py3lyH5QNkrN0OGI1ZA" + + "eXf76eSR4T26pYjxln26xyZUW/dcddQ0nSj9Yl52oFCWj38DqGaxP6hIu3DHGlcE" + + "PtpM2T4ZjWgrsqxL8N59zMb0Re9V4Xop7KmsLs3ThF3RWwmZdC1ba5LRPK6lKNF5" + + "CnSl5YzFUMnpzFZtneUhAHeFxrF+RV4f3bHLNs+sWjlmJo0ukCCnOzoiyE4oOJiL" + + "AhDym4nIfzng6fgYBeLT1Hp/bKHivQP4ef4wgre6r1ztnFA="; + + /** Certificate for testing. */ + private final X509Certificate testCert; + + + /** + * Default constructor. + * + * @throws Exception on test failure + */ + public SSLContextInitializerTest() + throws Exception + { + final CertificateFactory cf = CertificateFactory.getInstance("X.509"); + testCert = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(LdapUtils.base64Decode(A_FOO_COM_CERT))); + } + + + /** + * SSLContextInitializer test data. + * + * @return cert test data + * + * @throws Exception if test data cannot be generated + */ + @DataProvider(name = "initializers") + public Object[][] createInitializers() + throws Exception + { + // default ssl context initializer + final DefaultSSLContextInitializer defaultWithTM = new DefaultSSLContextInitializer(); + defaultWithTM.setTrustManagers(new AllowAnyTrustManager()); + final DefaultSSLContextInitializer defaultWithHV = new DefaultSSLContextInitializer(); + defaultWithHV.setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier(), "test")); + final DefaultSSLContextInitializer defaultWithTMHV = new DefaultSSLContextInitializer(); + defaultWithTMHV.setTrustManagers(new AllowAnyTrustManager()); + defaultWithTMHV.setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier(), "test")); + final DefaultSSLContextInitializer defaultNoTrustWithTM = new DefaultSSLContextInitializer(false); + defaultNoTrustWithTM.setTrustManagers(new AllowAnyTrustManager()); + final DefaultSSLContextInitializer defaultNoTrustWithHV = new DefaultSSLContextInitializer(false); + defaultNoTrustWithHV.setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier(), "test")); + final DefaultSSLContextInitializer defaultNoTrustWithTMHV = new DefaultSSLContextInitializer(false); + defaultNoTrustWithTMHV.setTrustManagers(new AllowAnyTrustManager()); + defaultNoTrustWithTMHV.setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier(), "test")); + + // x509 ssl context initializer + final X509SSLContextInitializer x509 = new X509SSLContextInitializer(); + x509.setTrustCertificates(testCert); + final X509SSLContextInitializer x509WithTM = new X509SSLContextInitializer(); + x509WithTM.setTrustCertificates(testCert); + x509WithTM.setTrustManagers(new AllowAnyTrustManager()); + final X509SSLContextInitializer x509WithHV = new X509SSLContextInitializer(); + x509WithHV.setTrustCertificates(testCert); + x509WithHV.setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier(), "test")); + final X509SSLContextInitializer x509WithTMHV = new X509SSLContextInitializer(); + x509WithTMHV.setTrustCertificates(testCert); + x509WithTMHV.setTrustManagers(new AllowAnyTrustManager()); + x509WithTMHV.setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier(), "test")); + final X509SSLContextInitializer x509NoTrustWithTM = new X509SSLContextInitializer(); + x509NoTrustWithTM.setTrustManagers(new AllowAnyTrustManager()); + final X509SSLContextInitializer x509NoTrustWithHV = new X509SSLContextInitializer(); + x509NoTrustWithHV.setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier(), "test")); + final X509SSLContextInitializer x509NoTrustWithTMHV = new X509SSLContextInitializer(); + x509NoTrustWithTMHV.setTrustManagers(new AllowAnyTrustManager()); + x509NoTrustWithTMHV.setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier(), "test")); + + return + new Object[][] { + new Object[] {new DefaultSSLContextInitializer(), "sun.security.ssl.X509TrustManagerImpl", }, + new Object[] { + defaultWithTM, + "sun.security.ssl.X509TrustManagerImpl", + "org.ldaptive.ssl.AllowAnyTrustManager", + }, + new Object[] { + defaultWithHV, + "sun.security.ssl.X509TrustManagerImpl", + "org.ldaptive.ssl.HostnameVerifyingTrustManager", + }, + new Object[] { + defaultWithTMHV, + "sun.security.ssl.X509TrustManagerImpl", + "org.ldaptive.ssl.AllowAnyTrustManager", + "org.ldaptive.ssl.HostnameVerifyingTrustManager", + }, + new Object[] {new DefaultSSLContextInitializer(false), "", }, + new Object[] { + defaultNoTrustWithTM, + "org.ldaptive.ssl.AllowAnyTrustManager", + }, + // default trust added + new Object[] { + defaultNoTrustWithHV, + "org.ldaptive.ssl.DefaultTrustManager", + "org.ldaptive.ssl.HostnameVerifyingTrustManager", + }, + new Object[] { + defaultNoTrustWithTMHV, + "org.ldaptive.ssl.AllowAnyTrustManager", + "org.ldaptive.ssl.HostnameVerifyingTrustManager", + }, + new Object[] { + x509, + "sun.security.ssl.X509TrustManagerImpl", + }, + new Object[] { + x509WithTM, + "sun.security.ssl.X509TrustManagerImpl", + "org.ldaptive.ssl.AllowAnyTrustManager", + }, + new Object[] { + x509WithHV, + "sun.security.ssl.X509TrustManagerImpl", + "org.ldaptive.ssl.HostnameVerifyingTrustManager", + }, + new Object[] { + x509WithTMHV, + "sun.security.ssl.X509TrustManagerImpl", + "org.ldaptive.ssl.AllowAnyTrustManager", + "org.ldaptive.ssl.HostnameVerifyingTrustManager", + }, + new Object[] {new X509SSLContextInitializer(), "", }, + new Object[] { + x509NoTrustWithTM, + "org.ldaptive.ssl.AllowAnyTrustManager", + }, + // default trust added + new Object[] { + x509NoTrustWithHV, + "org.ldaptive.ssl.DefaultTrustManager", + "org.ldaptive.ssl.HostnameVerifyingTrustManager", + }, + new Object[] { + x509NoTrustWithTMHV, + "org.ldaptive.ssl.AllowAnyTrustManager", + "org.ldaptive.ssl.HostnameVerifyingTrustManager", + }, + }; + } + + + /** + * @param initializer to get trust managers from + * @param clazz types to compare with + * + * @throws Exception On test failure. + */ + @Test(groups = {"ssl"}, dataProvider = "initializers") + public void getTrustManagers(final SSLContextInitializer initializer, final String... clazz) + throws Exception + { + final TrustManager[] tm = initializer.getTrustManagers(); + if (tm == null) { + Assert.assertEquals(1, clazz.length); + Assert.assertEquals("", clazz[0]); + } else { + Assert.assertEquals(tm.length, 1); + Assert.assertTrue(tm[0] instanceof AggregateTrustManager); + final AggregateTrustManager aggregate = (AggregateTrustManager) tm[0]; + Assert.assertEquals(aggregate.getTrustManagers().length, clazz.length); + for (int i = 0; i < aggregate.getTrustManagers().length; i++) { + Assert.assertEquals(aggregate.getTrustManagers()[i].getClass().getName(), clazz[i]); + } + } + } +}
diff --git a/core/src/test/java/org/ldaptive/ssl/SunTLSHostnameVerifier.java b/core/src/test/java/org/ldaptive/ssl/SunTLSHostnameVerifier.java new file mode 100644 index 0000000..80850a3 --- /dev/null +++ b/core/src/test/java/org/ldaptive/ssl/SunTLSHostnameVerifier.java
@@ -0,0 +1,57 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLSession; +// CheckStyle:IllegalImport OFF +import sun.security.util.HostnameChecker; +// CheckStyle:IllegalImport ON + +/** + * A {@link HostnameVerifier} that delegates to the internal Sun implementation at sun.security.util.HostnameChecker. + * This is the implementation used by JNDI with StartTLS. + * + * @author Middleware Services + */ +public class SunTLSHostnameVerifier implements HostnameVerifier, CertificateHostnameVerifier +{ + + + @Override + public boolean verify(final String hostname, final SSLSession session) + { + boolean b; + try { + b = verify(hostname, (X509Certificate) session.getPeerCertificates()[0]); + } catch (SSLPeerUnverifiedException e) { + b = false; + } + return b; + } + + + /** + * Expose convenience method for testing. + * + * @param hostname to verify + * @param cert to verify hostname against + * + * @return whether the certificate is allowed + */ + @Override + public boolean verify(final String hostname, final X509Certificate cert) + { + boolean b; + final HostnameChecker checker = HostnameChecker.getInstance(HostnameChecker.TYPE_LDAP); + try { + checker.match(hostname, cert); + b = true; + } catch (CertificateException e) { + b = false; + } + return b; + } +}
diff --git a/core/src/test/resources/org/ldaptive/io/base64-0.txt b/core/src/test/resources/org/ldaptive/io/base64-0.txt new file mode 100644 index 0000000..8c48fc5 --- /dev/null +++ b/core/src/test/resources/org/ldaptive/io/base64-0.txt
@@ -0,0 +1 @@ +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYw== \ No newline at end of file
diff --git a/core/src/test/resources/org/ldaptive/io/base64-64.txt b/core/src/test/resources/org/ldaptive/io/base64-64.txt new file mode 100644 index 0000000..6cb90d6 --- /dev/null +++ b/core/src/test/resources/org/ldaptive/io/base64-64.txt
@@ -0,0 +1,21846 @@ +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wg +cmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFt +IGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3Is +IG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1 +c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQu +IFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4g +QWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lz +LCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1 +bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVp +IG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRh +IHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBz +ZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3Vz +Y2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1 +Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2Nl +IGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRl +bXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3Ji +aSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVp +cyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2ls +aXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUg +bGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2Nl +IGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJv +cyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0 +cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5k +dW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1l +dCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVt +IGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhh +cmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1 +cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVu +dHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGln +dWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMs +IGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJp +cyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1 +cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1 +bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBk +YXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFz +IGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1h +ZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVs +dW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNp +bGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4g +TmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2Ug +YWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBt +aS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVz +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVu +YyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1w +b3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBm +YWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3Ig +YXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBF +dGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5p +YSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVz +dCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xl +c3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50 +IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBv +cnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRp +cyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMg +bW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMg +bGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2 +dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxp +Y2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1 +ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBx +dWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlv +LiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxh +IHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1w +ZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIg +aWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBV +dCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxs +YSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0g +c29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0 +aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlw +c3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0 +LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1w +ZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQ +cmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUu +IEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4g +RnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFs +aXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3Vl +IGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8g +YSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRp +cyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVu +dCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMu +IE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFj +dXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVl +dCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2ku +IEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3Us +IHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lk +dW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBq +dXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1 +ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4g +b3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZh +bXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBD +dXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywg +bnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMg +YWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBw +b3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBp +ZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMg +bWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGli +dXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4g +Vml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4g +TnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBt +ZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0 +IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRh +IGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVu +aW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBv +c3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24g +ZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBN +b3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2 +ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2lu +IHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxl +bWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWku +IFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVz +IGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5p +YmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxs +ZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERv +bmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9z +IHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1 +c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNx +dWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1 +Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJh +ZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlz +LiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQg +YWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQg +bWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVz +IHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdl +dCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFBy +YWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBG +dXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1 +cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4g +Q3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1 +cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25l +YyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlx +dWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50 +IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNv +bW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0 +IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVs +ZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQg +ZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBn +cmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBl +Z2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJp +cyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5h +IGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUg +cG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVj +aWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1 +bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxh +Y3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRl +bGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1 +dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1 +Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlx +dWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBt +b2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1 +c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMg +cHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0 +dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9k +IG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFt +ZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQg +bmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVs +dHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1 +cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlh +IGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVy +YXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBz +b2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEg +dGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxh +Y3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRh +dGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEg +bG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZp +dGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0g +bnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1 +ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBl +bGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxh +IGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUs +IG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFi +aXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVu +ZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVy +bmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0 +IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVy +YXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwg +ZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEg +bnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFj +aW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQg +bWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVh +bSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBl +Z2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3Bl +bmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBE +dWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBF +dGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZl +bGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVy +dXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQg +YW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRp +cGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBo +ZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJo +LiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQg +bnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9y +ZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVh +bSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBs +dWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhl +bmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFs +aXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25l +YyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJp +c3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVn +ZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4g +ZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVk +ZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUg +YWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRp +dG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIElu +dGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3Vs +YSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0 +cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25z +ZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4g +U3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlz +LiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBt +YXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhv +bmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVs +bGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3Ig +ZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0 +dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBl +cmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBh +YyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1 +IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5p +YSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxl +bnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBt +ZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBl +ZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNl +cXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJp +Y2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xv +ci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRl +bXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBl +dCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWdu +YSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBk +dWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBl +cm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxp +cy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4g +TWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50 +ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9u +IHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25z +ZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMg +YXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGlu +Y2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVz +ZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3Rp +YnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVu +ZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVk +ZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBx +dWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUu +IE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3Rl +dHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlz +bCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNz +YS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlz +IHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmlu +YXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5v +biBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmlt +LCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0 +aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxl +bnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlw +c3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBz +b2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlz +bW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1 +cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdl +dCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5v +biBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1 +Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUg +dXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRp +ZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVy +IHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZl +bGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGlj +aXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0g +bmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlz +IG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3Rh +cyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50 +IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUg +ZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1h +dXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2 +ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1v +ZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBk +aWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0 +dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNj +aXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0g +YWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUg +bmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3Jw +ZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCklu +IHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGln +bmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0 +IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2Rp +byBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFy +Y3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxs +ZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1 +cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVz +dCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9y +dGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0 +aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBm +YXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVj +IHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBh +IGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVy +bmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVs +LCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVt +LiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwg +ZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBo +YXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQg +YW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJk +aWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBk +b2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFl +c2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMs +IHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2 +ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8g +YWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJt +ZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4g +VXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVs +aXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxh +bmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1 +aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50 +IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJs +YW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50 +dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1v +cmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNp +ZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBk +aWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xl +c3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIg +YW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFj +LCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRy +dW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3Qg +ZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRy +ZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCBy +aXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29s +bGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxs +ZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9z +IHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0 +IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFz +IHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNl +ZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFs +aXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUg +YSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxp +dC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0 +IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFy +aXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBt +aS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlz +IHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFt +IHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlz +aSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1 +cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZl +bGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBp +biwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWku +IEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNp +ZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0 +IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0 +aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4g +UGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpO +dWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVl +IGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxh +Y3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVx +dWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBh +bGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxh +IG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBx +dWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8s +IHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24s +IG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmli +aCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVu +ZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFi +aXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3Jl +bSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVx +dWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVj +dG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFu +dGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEg +ZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4g +UHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNh +Z2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxp +Y2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1 +aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5p +bSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1 +dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRl +bGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rp +by4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9y +dG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4s +IHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVz +dG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5h +ci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRp +c3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBv +cm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11 +cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29k +YWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBh +YyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxh +LCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8u +IER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNl +ZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRl +LCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNp +bmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlz +IHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3Ug +ZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFt +LiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNv +bW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVz +dC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4g +UHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVs +bGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBs +ZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBp +biBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVz +dGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFs +bGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3Jh +dmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVy +IGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJp +c3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3Vs +YS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBp +c2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0 +aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVz +IHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3Nh +IG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMg +bm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVy +IG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBl +dSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBs +ZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBk +aWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRv +bG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNp +dCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIElu +dGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0 +IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRl +cmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFs +bGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8s +IG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25h +IHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkg +dGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEu +IEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVl +dCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVn +aWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3Vz +LiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQ +cmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQg +bGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxl +bWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBv +cm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxl +bywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVz +dC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1 +bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBB +bGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9z +dWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNz +YSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2Vz +IG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNl +cyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0 +aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMg +ZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jh +dmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNp +IHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0 +b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGll +LiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2 +aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVt +LCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFj +dXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlh +bSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBh +ZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBN +YXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVu +dGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBw +b3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1 +bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNp +ZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZl +cm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVz +IGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVh +biB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlh +bSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENy +YXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0 +dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxl +bnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUg +bG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMg +ZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0 +YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBw +b3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEu +IFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBh +bWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0g +bm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBw +b3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0 +ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1 +ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMg +c2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBm +cmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMg +dXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVz +cXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29u +ZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBh +ZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2Fn +aXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBs +YWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2lt +IHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBw +bGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlz +IHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUu +IE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4g +TWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1w +dXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxh +Y2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBu +b24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIElu +IGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMg +dml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1 +cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZl +c3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4g +U2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFz +IHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxs +YSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1 +cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBD +dXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1 +bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVz +IGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1 +bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBq +dXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1 +cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVy +aXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVj +IHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4g +U2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1 +cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFs +aXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVz +LiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBt +YXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2Vt +LiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEs +IGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBu +b24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlz +IHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1 +cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0 +IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50 +dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1 +bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQg +bWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21t +b2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50 +ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmlj +ZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmli +ZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBw +bGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBh +bGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQg +ZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9s +bGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1 +bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFu +dGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVz +LCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVt +IGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNp +dCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0u +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyBy +aG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBh +Y2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51 +bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3Np +bSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0 +aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoK +TnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGlu +Y2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNv +bGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMg +aWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNl +ZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyBy +aXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2 +ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFt +ZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGli +dWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3Vt +IGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBu +b24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBj +dXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9y +Y2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwg +c29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZh +dWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1 +bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBs +YWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBp +cHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4g +QWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1 +bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xs +aXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxs +YW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3Rp +YnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jhdmlk +YSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2Vs +ZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5j +LiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4g +TnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0 +ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1 +bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2 +YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxl +bWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRp +cy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMg +aW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWws +IHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2Ug +cXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxp +cyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJh +ZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlv +IG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUg +c2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxh +bSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4g +QWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5p +c2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVk +ZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2lu +ZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVs +dW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVu +dGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1 +cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNz +YS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVs +bGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4K +ClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEg +YXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQg +dGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVz +LiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1 +cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMg +aW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xs +aXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBj +b25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5l +bmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUg +ZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jh +dmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQ +cm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJp +cy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBO +dWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBs +ZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8g +bm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBl +dCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNp +bmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51 +bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVt +IGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0 +cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNl +ZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBk +YXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0 +dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJp +Y2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0 +ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGlj +aXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1 +cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBl +cmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwg +dmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBj +b25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQg +dXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBh +dWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIg +ZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkg +ZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVu +dHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1l +dHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZv +bHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBs +ZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5p +c2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZl +bGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMg +aWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1 +cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0 +IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVn +ZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1v +ZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2 +ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2Vt +cGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlz +IGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRl +bXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0g +c2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2 +YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4g +dHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNz +ZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1 +bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1 +cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1 +c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVz +ZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIs +IG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0 +IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVs +bGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxh +Y3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwg +bW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVu +dGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVz +IHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4g +TWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNp +IG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29u +dmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3Ig +cGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNs +IHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxp +c2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2Eg +ZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJh +Yml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRh +ZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxp +dCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGll +biwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQs +IGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNj +aXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0 +b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29u +ZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWdu +YS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlx +dWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJj +dSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBR +dWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2 +ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25l +YyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBj +b25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRp +cywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Ig +b3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBs +b3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNt +b2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1 +cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGlu +LiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwg +cGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyBy +aXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1h +ZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNl +ZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQg +dmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5k +aXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEs +IG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1 +dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVn +ZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5h +dGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3Jl +ZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQg +YWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQg +c29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0 +dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhp +Y3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1 +cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBl +dSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBh +YyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1l +dHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUs +IG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQs +IGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUg +bWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVu +aW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVz +IGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2Vz +IHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29u +Z3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0 +dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNh +cGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0 +LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5j +IHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVp +IHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBp +YWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxh +bmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3Nh +IG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3Iu +IE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBj +b252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBh +dCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1h +ZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMg +YWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVp +c3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5p +c2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0 +IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBh +IHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3Qs +IGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFl +LCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUg +dmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBv +cnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVj +ZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBE +dWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBl +cmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2 +ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1 +dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJt +ZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVy +dXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVl +IHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBp +cHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQs +IGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJp +Y2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBs +b2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0 +YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxl +bnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwg +ZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1 +cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlz +IHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFy +Y3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVh +biBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhh +c2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBj +b25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoK +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wg +cmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFt +IGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3Is +IG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1 +c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQu +IFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4g +QWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lz +LCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1 +bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVp +IG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRh +IHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBz +ZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3Vz +Y2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1 +Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2Nl +IGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRl +bXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3Ji +aSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVp +cyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2ls +aXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUg +bGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2Nl +IGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJv +cyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0 +cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5k +dW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1l +dCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVt +IGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhh +cmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1 +cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVu +dHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGln +dWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMs +IGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJp +cyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1 +cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1 +bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBk +YXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFz +IGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1h +ZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVs +dW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNp +bGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4g +TmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2Ug +YWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBt +aS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVz +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVu +YyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1w +b3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBm +YWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3Ig +YXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBF +dGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5p +YSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVz +dCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xl +c3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50 +IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBv +cnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRp +cyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMg +bW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMg +bGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2 +dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxp +Y2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1 +ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBx +dWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlv +LiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxh +IHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1w +ZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIg +aWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBV +dCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxs +YSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0g +c29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0 +aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlw +c3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0 +LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1w +ZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQ +cmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUu +IEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4g +RnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFs +aXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3Vl +IGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8g +YSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRp +cyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVu +dCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMu +IE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFj +dXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVl +dCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2ku +IEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3Us +IHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lk +dW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBq +dXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1 +ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4g +b3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZh +bXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBD +dXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywg +bnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMg +YWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBw +b3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBp +ZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMg +bWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGli +dXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4g +Vml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4g +TnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBt +ZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0 +IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRh +IGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVu +aW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBv +c3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24g +ZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBN +b3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2 +ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2lu +IHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxl +bWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWku +IFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVz +IGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5p +YmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxs +ZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERv +bmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9z +IHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1 +c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNx +dWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1 +Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJh +ZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlz +LiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQg +YWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQg +bWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVz +IHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdl +dCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFBy +YWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBG +dXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1 +cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4g +Q3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1 +cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25l +YyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlx +dWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50 +IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNv +bW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0 +IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVs +ZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQg +ZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBn +cmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBl +Z2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJp +cyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5h +IGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUg +cG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVj +aWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1 +bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxh +Y3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRl +bGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1 +dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1 +Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlx +dWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBt +b2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1 +c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMg +cHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0 +dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9k +IG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFt +ZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQg +bmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVs +dHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1 +cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlh +IGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVy +YXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBz +b2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEg +dGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxh +Y3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRh +dGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEg +bG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZp +dGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0g +bnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1 +ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBl +bGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxh +IGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUs +IG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFi +aXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVu +ZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVy +bmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0 +IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVy +YXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwg +ZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEg +bnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFj +aW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQg +bWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVh +bSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBl +Z2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3Bl +bmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBE +dWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBF +dGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZl +bGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVy +dXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQg +YW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRp +cGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBo +ZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJo +LiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQg +bnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9y +ZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVh +bSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBs +dWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhl +bmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFs +aXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25l +YyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJp +c3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVn +ZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4g +ZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVk +ZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUg +YWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRp +dG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIElu +dGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3Vs +YSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0 +cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25z +ZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4g +U3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlz +LiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBt +YXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhv +bmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVs +bGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3Ig +ZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0 +dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBl +cmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBh +YyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1 +IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5p +YSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxl +bnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBt +ZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBl +ZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNl +cXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJp +Y2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xv +ci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRl +bXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBl +dCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWdu +YSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBk +dWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBl +cm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxp +cy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4g +TWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50 +ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9u +IHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25z +ZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMg +YXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGlu +Y2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVz +ZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3Rp +YnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVu +ZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVk +ZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBx +dWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUu +IE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3Rl +dHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlz +bCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNz +YS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlz +IHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmlu +YXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5v +biBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmlt +LCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0 +aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxl +bnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlw +c3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBz +b2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlz +bW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1 +cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdl +dCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5v +biBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1 +Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUg +dXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRp +ZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVy +IHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZl +bGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGlj +aXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0g +bmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlz +IG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3Rh +cyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50 +IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUg +ZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1h +dXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2 +ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1v +ZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBk +aWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0 +dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNj +aXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0g +YWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUg +bmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3Jw +ZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCklu +IHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGln +bmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0 +IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2Rp +byBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFy +Y3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxs +ZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1 +cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVz +dCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9y +dGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0 +aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBm +YXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVj +IHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBh +IGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVy +bmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVs +LCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVt +LiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwg +ZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBo +YXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQg +YW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJk +aWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBk +b2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFl +c2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMs +IHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2 +ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8g +YWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJt +ZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4g +VXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVs +aXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxh +bmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1 +aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50 +IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJs +YW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50 +dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1v +cmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNp +ZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBk +aWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xl +c3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIg +YW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFj +LCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRy +dW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3Qg +ZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRy +ZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCBy +aXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29s +bGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxs +ZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9z +IHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0 +IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFz +IHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNl +ZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFs +aXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUg +YSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxp +dC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0 +IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFy +aXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBt +aS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlz +IHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFt +IHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlz +aSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1 +cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZl +bGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBp +biwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWku +IEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNp +ZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0 +IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0 +aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4g +UGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpO +dWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVl +IGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxh +Y3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVx +dWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBh +bGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxh +IG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBx +dWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8s +IHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24s +IG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmli +aCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVu +ZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFi +aXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3Jl +bSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVx +dWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVj +dG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFu +dGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEg +ZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4g +UHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNh +Z2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxp +Y2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1 +aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5p +bSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1 +dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRl +bGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rp +by4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9y +dG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4s +IHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVz +dG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5h +ci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRp +c3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBv +cm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11 +cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29k +YWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBh +YyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxh +LCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8u +IER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNl +ZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRl +LCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNp +bmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlz +IHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3Ug +ZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFt +LiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNv +bW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVz +dC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4g +UHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVs +bGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBs +ZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBp +biBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVz +dGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFs +bGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3Jh +dmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVy +IGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJp +c3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3Vs +YS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBp +c2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0 +aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVz +IHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3Nh +IG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMg +bm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVy +IG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBl +dSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBs +ZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBk +aWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRv +bG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNp +dCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIElu +dGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0 +IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRl +cmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFs +bGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8s +IG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25h +IHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkg +dGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEu +IEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVl +dCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVn +aWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3Vz +LiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQ +cmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQg +bGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxl +bWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBv +cm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxl +bywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVz +dC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1 +bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBB +bGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9z +dWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNz +YSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2Vz +IG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNl +cyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0 +aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMg +ZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jh +dmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNp +IHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0 +b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGll +LiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2 +aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVt +LCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFj +dXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlh +bSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBh +ZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBN +YXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVu +dGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBw +b3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1 +bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNp +ZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZl +cm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVz +IGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVh +biB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlh +bSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENy +YXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0 +dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxl +bnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUg +bG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMg +ZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0 +YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBw +b3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEu +IFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBh +bWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0g +bm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBw +b3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0 +ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1 +ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMg +c2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBm +cmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMg +dXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVz +cXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29u +ZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBh +ZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2Fn +aXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBs +YWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2lt +IHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBw +bGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlz +IHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUu +IE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4g +TWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1w +dXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxh +Y2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBu +b24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIElu +IGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMg +dml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1 +cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZl +c3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4g +U2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFz +IHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxs +YSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1 +cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBD +dXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1 +bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVz +IGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1 +bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBq +dXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1 +cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVy +aXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVj +IHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4g +U2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1 +cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFs +aXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVz +LiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBt +YXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2Vt +LiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEs +IGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBu +b24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlz +IHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1 +cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0 +IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50 +dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1 +bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQg +bWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21t +b2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50 +ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmlj +ZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmli +ZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBw +bGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBh +bGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQg +ZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9s +bGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1 +bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFu +dGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVz +LCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVt +IGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNp +dCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0u +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyBy +aG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBh +Y2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51 +bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3Np +bSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0 +aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoK +TnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGlu +Y2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNv +bGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMg +aWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNl +ZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyBy +aXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2 +ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFt +ZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGli +dWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3Vt +IGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBu +b24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBj +dXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9y +Y2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwg +c29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZh +dWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1 +bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBs +YWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBp +cHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4g +QWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1 +bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xs +aXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxs +YW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3Rp +YnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jhdmlk +YSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2Vs +ZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5j +LiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4g +TnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0 +ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1 +bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2 +YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxl +bWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRp +cy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMg +aW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWws +IHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2Ug +cXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxp +cyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJh +ZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlv +IG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUg +c2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxh +bSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4g +QWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5p +c2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVk +ZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2lu +ZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVs +dW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVu +dGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1 +cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNz +YS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVs +bGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4K +ClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEg +YXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQg +dGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVz +LiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1 +cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMg +aW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xs +aXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBj +b25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5l +bmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUg +ZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jh +dmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQ +cm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJp +cy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBO +dWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBs +ZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8g +bm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBl +dCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNp +bmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51 +bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVt +IGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0 +cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNl +ZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBk +YXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0 +dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJp +Y2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0 +ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGlj +aXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1 +cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBl +cmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwg +dmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBj +b25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQg +dXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBh +dWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIg +ZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkg +ZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVu +dHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1l +dHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZv +bHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBs +ZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5p +c2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZl +bGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMg +aWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1 +cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0 +IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVn +ZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1v +ZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2 +ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2Vt +cGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlz +IGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRl +bXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0g +c2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2 +YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4g +dHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNz +ZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1 +bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1 +cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1 +c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVz +ZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIs +IG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0 +IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVs +bGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxh +Y3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwg +bW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVu +dGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVz +IHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4g +TWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNp +IG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29u +dmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3Ig +cGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNs +IHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxp +c2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2Eg +ZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJh +Yml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRh +ZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxp +dCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGll +biwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQs +IGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNj +aXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0 +b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29u +ZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWdu +YS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlx +dWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJj +dSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBR +dWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2 +ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25l +YyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBj +b25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRp +cywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Ig +b3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBs +b3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNt +b2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1 +cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGlu +LiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwg +cGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyBy +aXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1h +ZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNl +ZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQg +dmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5k +aXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEs +IG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1 +dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVn +ZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5h +dGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3Jl +ZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQg +YWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQg +c29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0 +dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhp +Y3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1 +cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBl +dSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBh +YyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1l +dHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUs +IG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQs +IGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUg +bWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVu +aW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVz +IGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2Vz +IHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29u +Z3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0 +dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNh +cGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0 +LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5j +IHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVp +IHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBp +YWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxh +bmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3Nh +IG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3Iu +IE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBj +b252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBh +dCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1h +ZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMg +YWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVp +c3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5p +c2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0 +IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBh +IHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3Qs +IGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFl +LCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUg +dmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBv +cnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVj +ZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBE +dWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBl +cmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2 +ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1 +dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJt +ZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVy +dXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVl +IHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBp +cHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQs +IGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJp +Y2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBs +b2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0 +YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxl +bnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwg +ZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1 +cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlz +IHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFy +Y3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVh +biBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhh +c2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBj +b25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoK +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wg +cmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFt +IGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3Is +IG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1 +c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQu +IFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4g +QWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lz +LCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1 +bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVp +IG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRh +IHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBz +ZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3Vz +Y2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1 +Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2Nl +IGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRl +bXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3Ji +aSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVp +cyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2ls +aXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUg +bGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2Nl +IGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJv +cyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0 +cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5k +dW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1l +dCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVt +IGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhh +cmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1 +cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVu +dHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGln +dWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMs +IGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJp +cyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1 +cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1 +bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBk +YXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFz +IGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1h +ZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVs +dW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNp +bGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4g +TmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2Ug +YWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBt +aS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVz +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVu +YyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1w +b3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBm +YWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3Ig +YXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBF +dGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5p +YSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVz +dCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xl +c3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50 +IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBv +cnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRp +cyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMg +bW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMg +bGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2 +dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxp +Y2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1 +ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBx +dWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlv +LiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxh +IHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1w +ZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIg +aWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBV +dCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxs +YSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0g +c29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0 +aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlw +c3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0 +LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1w +ZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQ +cmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUu +IEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4g +RnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFs +aXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3Vl +IGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8g +YSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRp +cyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVu +dCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMu +IE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFj +dXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVl +dCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2ku +IEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3Us +IHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lk +dW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBq +dXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1 +ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4g +b3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZh +bXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBD +dXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywg +bnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMg +YWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBw +b3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBp +ZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMg +bWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGli +dXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4g +Vml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4g +TnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBt +ZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0 +IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRh +IGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVu +aW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBv +c3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24g +ZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBN +b3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2 +ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2lu +IHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxl +bWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWku +IFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVz +IGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5p +YmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxs +ZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERv +bmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9z +IHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1 +c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNx +dWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1 +Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJh +ZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlz +LiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQg +YWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQg +bWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVz +IHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdl +dCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFBy +YWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBG +dXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1 +cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4g +Q3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1 +cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25l +YyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlx +dWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50 +IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNv +bW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0 +IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVs +ZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQg +ZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBn +cmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBl +Z2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJp +cyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5h +IGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUg +cG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVj +aWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1 +bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxh +Y3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRl +bGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1 +dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1 +Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlx +dWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBt +b2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1 +c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMg +cHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0 +dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9k +IG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFt +ZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQg +bmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVs +dHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1 +cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlh +IGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVy +YXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBz +b2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEg +dGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxh +Y3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRh +dGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEg +bG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZp +dGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0g +bnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1 +ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBl +bGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxh +IGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUs +IG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFi +aXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVu +ZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVy +bmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0 +IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVy +YXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwg +ZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEg +bnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFj +aW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQg +bWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVh +bSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBl +Z2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3Bl +bmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBE +dWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBF +dGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZl +bGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVy +dXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQg +YW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRp +cGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBo +ZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJo +LiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQg +bnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9y +ZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVh +bSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBs +dWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhl +bmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFs +aXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25l +YyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJp +c3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVn +ZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4g +ZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVk +ZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUg +YWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRp +dG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIElu +dGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3Vs +YSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0 +cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25z +ZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4g +U3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlz +LiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBt +YXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhv +bmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVs +bGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3Ig +ZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0 +dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBl +cmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBh +YyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1 +IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5p +YSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxl +bnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBt +ZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBl +ZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNl +cXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJp +Y2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xv +ci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRl +bXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBl +dCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWdu +YSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBk +dWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBl +cm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxp +cy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4g +TWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50 +ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9u +IHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25z +ZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMg +YXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGlu +Y2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVz +ZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3Rp +YnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVu +ZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVk +ZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBx +dWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUu +IE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3Rl +dHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlz +bCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNz +YS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlz +IHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmlu +YXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5v +biBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmlt +LCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0 +aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxl +bnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlw +c3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBz +b2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlz +bW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1 +cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdl +dCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5v +biBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1 +Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUg +dXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRp +ZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVy +IHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZl +bGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGlj +aXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0g +bmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlz +IG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3Rh +cyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50 +IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUg +ZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1h +dXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2 +ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1v +ZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBk +aWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0 +dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNj +aXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0g +YWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUg +bmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3Jw +ZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCklu +IHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGln +bmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0 +IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2Rp +byBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFy +Y3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxs +ZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1 +cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVz +dCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9y +dGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0 +aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBm +YXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVj +IHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBh +IGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVy +bmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVs +LCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVt +LiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwg +ZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBo +YXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQg +YW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJk +aWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBk +b2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFl +c2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMs +IHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2 +ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8g +YWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJt +ZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4g +VXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVs +aXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxh +bmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1 +aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50 +IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJs +YW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50 +dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1v +cmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNp +ZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBk +aWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xl +c3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIg +YW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFj +LCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRy +dW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3Qg +ZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRy +ZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCBy +aXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29s +bGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxs +ZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9z +IHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0 +IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFz +IHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNl +ZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFs +aXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUg +YSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxp +dC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0 +IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFy +aXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBt +aS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlz +IHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFt +IHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlz +aSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1 +cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZl +bGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBp +biwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWku +IEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNp +ZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0 +IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0 +aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4g +UGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpO +dWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVl +IGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxh +Y3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVx +dWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBh +bGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxh +IG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBx +dWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8s +IHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24s +IG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmli +aCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVu +ZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFi +aXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3Jl +bSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVx +dWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVj +dG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFu +dGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEg +ZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4g +UHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNh +Z2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxp +Y2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1 +aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5p +bSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1 +dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRl +bGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rp +by4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9y +dG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4s +IHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVz +dG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5h +ci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRp +c3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBv +cm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11 +cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29k +YWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBh +YyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxh +LCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8u +IER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNl +ZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRl +LCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNp +bmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlz +IHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3Ug +ZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFt +LiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNv +bW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVz +dC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4g +UHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVs +bGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBs +ZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBp +biBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVz +dGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFs +bGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3Jh +dmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVy +IGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJp +c3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3Vs +YS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBp +c2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0 +aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVz +IHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3Nh +IG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMg +bm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVy +IG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBl +dSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBs +ZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBk +aWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRv +bG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNp +dCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIElu +dGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0 +IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRl +cmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFs +bGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8s +IG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25h +IHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkg +dGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEu +IEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVl +dCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVn +aWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3Vz +LiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQ +cmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQg +bGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxl +bWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBv +cm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxl +bywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVz +dC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1 +bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBB +bGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9z +dWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNz +YSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2Vz +IG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNl +cyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0 +aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMg +ZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jh +dmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNp +IHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0 +b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGll +LiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2 +aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVt +LCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFj +dXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlh +bSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBh +ZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBN +YXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVu +dGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBw +b3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1 +bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNp +ZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZl +cm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVz +IGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVh +biB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlh +bSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENy +YXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0 +dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxl +bnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUg +bG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMg +ZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0 +YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBw +b3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEu +IFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBh +bWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0g +bm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBw +b3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0 +ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1 +ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMg +c2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBm +cmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMg +dXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVz +cXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29u +ZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBh +ZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2Fn +aXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBs +YWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2lt +IHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBw +bGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlz +IHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUu +IE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4g +TWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1w +dXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxh +Y2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBu +b24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIElu +IGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMg +dml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1 +cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZl +c3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4g +U2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFz +IHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxs +YSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1 +cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBD +dXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1 +bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVz +IGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1 +bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBq +dXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1 +cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVy +aXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVj +IHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4g +U2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1 +cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFs +aXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVz +LiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBt +YXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2Vt +LiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEs +IGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBu +b24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlz +IHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1 +cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0 +IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50 +dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1 +bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQg +bWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21t +b2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50 +ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmlj +ZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmli +ZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBw +bGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBh +bGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQg +ZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9s +bGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1 +bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFu +dGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVz +LCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVt +IGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNp +dCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0u +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyBy +aG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBh +Y2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51 +bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3Np +bSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0 +aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoK +TnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGlu +Y2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNv +bGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMg +aWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNl +ZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyBy +aXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2 +ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFt +ZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGli +dWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3Vt +IGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBu +b24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBj +dXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9y +Y2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwg +c29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZh +dWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1 +bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBs +YWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBp +cHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4g +QWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1 +bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xs +aXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxs +YW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3Rp +YnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jhdmlk +YSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2Vs +ZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5j +LiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4g +TnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0 +ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1 +bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2 +YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxl +bWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRp +cy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMg +aW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWws +IHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2Ug +cXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxp +cyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJh +ZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlv +IG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUg +c2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxh +bSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4g +QWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5p +c2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVk +ZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2lu +ZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVs +dW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVu +dGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1 +cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNz +YS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVs +bGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4K +ClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEg +YXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQg +dGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVz +LiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1 +cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMg +aW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xs +aXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBj +b25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5l +bmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUg +ZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jh +dmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQ +cm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJp +cy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBO +dWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBs +ZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8g +bm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBl +dCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNp +bmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51 +bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVt +IGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0 +cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNl +ZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBk +YXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0 +dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJp +Y2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0 +ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGlj +aXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1 +cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBl +cmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwg +dmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBj +b25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQg +dXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBh +dWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIg +ZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkg +ZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVu +dHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1l +dHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZv +bHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBs +ZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5p +c2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZl +bGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMg +aWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1 +cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0 +IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVn +ZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1v +ZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2 +ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2Vt +cGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlz +IGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRl +bXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0g +c2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2 +YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4g +dHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNz +ZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1 +bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1 +cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1 +c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVz +ZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIs +IG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0 +IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVs +bGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxh +Y3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwg +bW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVu +dGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVz +IHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4g +TWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNp +IG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29u +dmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3Ig +cGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNs +IHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxp +c2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2Eg +ZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJh +Yml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRh +ZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxp +dCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGll +biwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQs +IGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNj +aXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0 +b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29u +ZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWdu +YS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlx +dWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJj +dSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBR +dWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2 +ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25l +YyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBj +b25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRp +cywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Ig +b3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBs +b3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNt +b2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1 +cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGlu +LiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwg +cGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyBy +aXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1h +ZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNl +ZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQg +dmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5k +aXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEs +IG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1 +dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVn +ZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5h +dGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3Jl +ZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQg +YWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQg +c29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0 +dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhp +Y3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1 +cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBl +dSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBh +YyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1l +dHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUs +IG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQs +IGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUg +bWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVu +aW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVz +IGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2Vz +IHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29u +Z3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0 +dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNh +cGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0 +LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5j +IHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVp +IHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBp +YWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxh +bmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3Nh +IG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3Iu +IE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBj +b252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBh +dCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1h +ZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMg +YWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVp +c3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5p +c2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0 +IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBh +IHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3Qs +IGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFl +LCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUg +dmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBv +cnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVj +ZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBE +dWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBl +cmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2 +ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1 +dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJt +ZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVy +dXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVl +IHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBp +cHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQs +IGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJp +Y2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBs +b2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0 +YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxl +bnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwg +ZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1 +cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlz +IHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFy +Y3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVh +biBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhh +c2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBj +b25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoK +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wg +cmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFt +IGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3Is +IG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1 +c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQu +IFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4g +QWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lz +LCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1 +bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVp +IG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRh +IHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBz +ZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3Vz +Y2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1 +Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2Nl +IGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRl +bXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3Ji +aSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVp +cyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2ls +aXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUg +bGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2Nl +IGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJv +cyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0 +cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5k +dW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1l +dCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVt +IGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhh +cmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1 +cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVu +dHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGln +dWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMs +IGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJp +cyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1 +cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1 +bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBk +YXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFz +IGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1h +ZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVs +dW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNp +bGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4g +TmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2Ug +YWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBt +aS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVz +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVu +YyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1w +b3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBm +YWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3Ig +YXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBF +dGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5p +YSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVz +dCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xl +c3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50 +IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBv +cnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRp +cyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMg +bW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMg +bGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2 +dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxp +Y2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1 +ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBx +dWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlv +LiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxh +IHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1w +ZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIg +aWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBV +dCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxs +YSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0g +c29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0 +aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlw +c3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0 +LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1w +ZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQ +cmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUu +IEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4g +RnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFs +aXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3Vl +IGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8g +YSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRp +cyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVu +dCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMu +IE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFj +dXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVl +dCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2ku +IEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3Us +IHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lk +dW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBq +dXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1 +ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4g +b3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZh +bXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBD +dXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywg +bnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMg +YWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBw +b3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBp +ZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMg +bWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGli +dXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4g +Vml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4g +TnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBt +ZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0 +IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRh +IGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVu +aW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBv +c3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24g +ZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBN +b3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2 +ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2lu +IHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxl +bWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWku +IFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVz +IGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5p +YmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxs +ZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERv +bmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9z +IHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1 +c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNx +dWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1 +Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJh +ZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlz +LiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQg +YWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQg +bWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVz +IHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdl +dCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFBy +YWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBG +dXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1 +cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4g +Q3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1 +cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25l +YyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlx +dWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50 +IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNv +bW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0 +IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVs +ZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQg +ZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBn +cmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBl +Z2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJp +cyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5h +IGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUg +cG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVj +aWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1 +bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxh +Y3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRl +bGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1 +dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1 +Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlx +dWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBt +b2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1 +c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMg +cHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0 +dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9k +IG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFt +ZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQg +bmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVs +dHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1 +cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlh +IGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVy +YXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBz +b2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEg +dGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxh +Y3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRh +dGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEg +bG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZp +dGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0g +bnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1 +ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBl +bGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxh +IGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUs +IG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFi +aXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVu +ZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVy +bmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0 +IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVy +YXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwg +ZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEg +bnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFj +aW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQg +bWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVh +bSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBl +Z2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3Bl +bmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBE +dWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBF +dGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZl +bGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVy +dXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQg +YW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRp +cGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBo +ZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJo +LiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQg +bnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9y +ZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVh +bSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBs +dWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhl +bmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFs +aXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25l +YyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJp +c3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVn +ZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4g +ZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVk +ZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUg +YWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRp +dG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIElu +dGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3Vs +YSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0 +cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25z +ZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4g +U3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlz +LiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBt +YXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhv +bmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVs +bGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3Ig +ZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0 +dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBl +cmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBh +YyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1 +IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5p +YSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxl +bnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBt +ZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBl +ZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNl +cXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJp +Y2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xv +ci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRl +bXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBl +dCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWdu +YSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBk +dWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBl +cm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxp +cy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4g +TWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50 +ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9u +IHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25z +ZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMg +YXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGlu +Y2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVz +ZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3Rp +YnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVu +ZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVk +ZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBx +dWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUu +IE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3Rl +dHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlz +bCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNz +YS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlz +IHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmlu +YXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5v +biBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmlt +LCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0 +aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxl +bnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlw +c3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBz +b2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlz +bW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1 +cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdl +dCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5v +biBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1 +Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUg +dXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRp +ZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVy +IHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZl +bGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGlj +aXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0g +bmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlz +IG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3Rh +cyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50 +IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUg +ZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1h +dXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2 +ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1v +ZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBk +aWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0 +dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNj +aXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0g +YWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUg +bmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3Jw +ZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCklu +IHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGln +bmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0 +IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2Rp +byBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFy +Y3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxs +ZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1 +cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVz +dCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9y +dGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0 +aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBm +YXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVj +IHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBh +IGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVy +bmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVs +LCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVt +LiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwg +ZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBo +YXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQg +YW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJk +aWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBk +b2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFl +c2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMs +IHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2 +ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8g +YWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJt +ZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4g +VXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVs +aXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxh +bmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1 +aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50 +IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJs +YW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50 +dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1v +cmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNp +ZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBk +aWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xl +c3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIg +YW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFj +LCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRy +dW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3Qg +ZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRy +ZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCBy +aXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29s +bGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxs +ZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9z +IHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0 +IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFz +IHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNl +ZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFs +aXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUg +YSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxp +dC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0 +IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFy +aXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBt +aS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlz +IHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFt +IHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlz +aSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1 +cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZl +bGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBp +biwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWku +IEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNp +ZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0 +IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0 +aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4g +UGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpO +dWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVl +IGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxh +Y3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVx +dWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBh +bGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxh +IG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBx +dWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8s +IHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24s +IG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmli +aCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVu +ZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFi +aXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3Jl +bSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVx +dWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVj +dG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFu +dGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEg +ZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4g +UHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNh +Z2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxp +Y2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1 +aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5p +bSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1 +dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRl +bGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rp +by4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9y +dG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4s +IHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVz +dG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5h +ci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRp +c3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBv +cm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11 +cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29k +YWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBh +YyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxh +LCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8u +IER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNl +ZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRl +LCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNp +bmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlz +IHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3Ug +ZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFt +LiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNv +bW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVz +dC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4g +UHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVs +bGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBs +ZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBp +biBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVz +dGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFs +bGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3Jh +dmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVy +IGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJp +c3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3Vs +YS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBp +c2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0 +aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVz +IHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3Nh +IG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMg +bm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVy +IG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBl +dSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBs +ZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBk +aWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRv +bG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNp +dCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIElu +dGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0 +IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRl +cmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFs +bGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8s +IG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25h +IHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkg +dGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEu +IEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVl +dCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVn +aWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3Vz +LiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQ +cmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQg +bGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxl +bWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBv +cm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxl +bywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVz +dC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1 +bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBB +bGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9z +dWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNz +YSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2Vz +IG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNl +cyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0 +aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMg +ZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jh +dmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNp +IHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0 +b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGll +LiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2 +aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVt +LCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFj +dXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlh +bSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBh +ZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBN +YXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVu +dGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBw +b3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1 +bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNp +ZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZl +cm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVz +IGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVh +biB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlh +bSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENy +YXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0 +dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxl +bnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUg +bG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMg +ZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0 +YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBw +b3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEu +IFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBh +bWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0g +bm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBw +b3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0 +ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1 +ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMg +c2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBm +cmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMg +dXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVz +cXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29u +ZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBh +ZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2Fn +aXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBs +YWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2lt +IHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBw +bGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlz +IHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUu +IE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4g +TWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1w +dXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxh +Y2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBu +b24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIElu +IGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMg +dml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1 +cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZl +c3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4g +U2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFz +IHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxs +YSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1 +cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBD +dXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1 +bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVz +IGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1 +bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBq +dXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1 +cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVy +aXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVj +IHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4g +U2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1 +cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFs +aXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVz +LiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBt +YXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2Vt +LiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEs +IGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBu +b24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlz +IHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1 +cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0 +IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50 +dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1 +bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQg +bWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21t +b2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50 +ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmlj +ZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmli +ZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBw +bGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBh +bGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQg +ZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9s +bGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1 +bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFu +dGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVz +LCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVt +IGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNp +dCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0u +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyBy +aG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBh +Y2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51 +bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3Np +bSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0 +aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoK +TnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGlu +Y2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNv +bGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMg +aWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNl +ZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyBy +aXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2 +ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFt +ZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGli +dWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3Vt +IGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBu +b24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBj +dXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9y +Y2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwg +c29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZh +dWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1 +bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBs +YWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBp +cHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4g +QWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1 +bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xs +aXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxs +YW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3Rp +YnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jhdmlk +YSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2Vs +ZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5j +LiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4g +TnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0 +ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1 +bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2 +YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxl +bWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRp +cy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMg +aW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWws +IHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2Ug +cXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxp +cyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJh +ZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlv +IG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUg +c2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxh +bSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4g +QWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5p +c2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVk +ZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2lu +ZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVs +dW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVu +dGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1 +cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNz +YS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVs +bGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4K +ClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEg +YXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQg +dGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVz +LiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1 +cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMg +aW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xs +aXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBj +b25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5l +bmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUg +ZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jh +dmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQ +cm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJp +cy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBO +dWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBs +ZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8g +bm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBl +dCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNp +bmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51 +bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVt +IGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0 +cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNl +ZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBk +YXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0 +dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJp +Y2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0 +ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGlj +aXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1 +cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBl +cmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwg +dmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBj +b25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQg +dXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBh +dWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIg +ZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkg +ZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVu +dHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1l +dHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZv +bHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBs +ZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5p +c2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZl +bGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMg +aWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1 +cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0 +IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVn +ZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1v +ZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2 +ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2Vt +cGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlz +IGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRl +bXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0g +c2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2 +YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4g +dHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNz +ZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1 +bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1 +cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1 +c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVz +ZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIs +IG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0 +IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVs +bGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxh +Y3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwg +bW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVu +dGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVz +IHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4g +TWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNp +IG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29u +dmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3Ig +cGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNs +IHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxp +c2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2Eg +ZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJh +Yml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRh +ZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxp +dCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGll +biwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQs +IGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNj +aXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0 +b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29u +ZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWdu +YS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlx +dWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJj +dSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBR +dWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2 +ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25l +YyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBj +b25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRp +cywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Ig +b3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBs +b3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNt +b2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1 +cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGlu +LiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwg +cGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyBy +aXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1h +ZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNl +ZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQg +dmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5k +aXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEs +IG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1 +dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVn +ZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5h +dGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3Jl +ZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQg +YWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQg +c29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0 +dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhp +Y3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1 +cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBl +dSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBh +YyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1l +dHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUs +IG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQs +IGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUg +bWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVu +aW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVz +IGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2Vz +IHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29u +Z3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0 +dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNh +cGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0 +LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5j +IHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVp +IHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBp +YWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxh +bmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3Nh +IG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3Iu +IE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBj +b252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBh +dCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1h +ZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMg +YWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVp +c3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5p +c2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0 +IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBh +IHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3Qs +IGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFl +LCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUg +dmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBv +cnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVj +ZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBE +dWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBl +cmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2 +ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1 +dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJt +ZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVy +dXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVl +IHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBp +cHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQs +IGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJp +Y2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBs +b2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0 +YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxl +bnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwg +ZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1 +cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlz +IHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFy +Y3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVh +biBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhh +c2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBj +b25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoK +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wg +cmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFt +IGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3Is +IG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1 +c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQu +IFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4g +QWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lz +LCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1 +bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVp +IG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRh +IHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBz +ZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3Vz +Y2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1 +Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2Nl +IGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRl +bXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3Ji +aSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVp +cyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2ls +aXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUg +bGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2Nl +IGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJv +cyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0 +cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5k +dW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1l +dCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVt +IGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhh +cmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1 +cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVu +dHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGln +dWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMs +IGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJp +cyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1 +cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1 +bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBk +YXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFz +IGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1h +ZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVs +dW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNp +bGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4g +TmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2Ug +YWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBt +aS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVz +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVu +YyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1w +b3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBm +YWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3Ig +YXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBF +dGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5p +YSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVz +dCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xl +c3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50 +IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBv +cnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRp +cyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMg +bW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMg +bGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2 +dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxp +Y2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1 +ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBx +dWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlv +LiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxh +IHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1w +ZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIg +aWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBV +dCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxs +YSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0g +c29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0 +aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlw +c3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0 +LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1w +ZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQ +cmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUu +IEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4g +RnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFs +aXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3Vl +IGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8g +YSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRp +cyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVu +dCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMu +IE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFj +dXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVl +dCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2ku +IEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3Us +IHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lk +dW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBq +dXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1 +ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4g +b3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZh +bXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBD +dXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywg +bnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMg +YWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBw +b3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBp +ZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMg +bWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGli +dXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4g +Vml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4g +TnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBt +ZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0 +IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRh +IGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVu +aW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBv +c3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24g +ZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBN +b3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2 +ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2lu +IHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxl +bWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWku +IFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVz +IGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5p +YmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxs +ZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERv +bmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9z +IHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1 +c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNx +dWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1 +Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJh +ZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlz +LiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQg +YWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQg +bWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVz +IHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdl +dCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFBy +YWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBG +dXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1 +cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4g +Q3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1 +cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25l +YyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlx +dWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50 +IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNv +bW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0 +IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVs +ZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQg +ZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBn +cmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBl +Z2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJp +cyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5h +IGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUg +cG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVj +aWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1 +bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxh +Y3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRl +bGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1 +dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1 +Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlx +dWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBt +b2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1 +c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMg +cHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0 +dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9k +IG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFt +ZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQg +bmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVs +dHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1 +cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlh +IGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVy +YXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBz +b2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEg +dGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxh +Y3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRh +dGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEg +bG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZp +dGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0g +bnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1 +ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBl +bGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxh +IGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUs +IG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFi +aXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVu +ZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVy +bmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0 +IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVy +YXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwg +ZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEg +bnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFj +aW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQg +bWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVh +bSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBl +Z2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3Bl +bmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBE +dWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBF +dGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZl +bGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVy +dXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQg +YW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRp +cGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBo +ZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJo +LiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQg +bnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9y +ZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVh +bSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBs +dWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhl +bmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFs +aXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25l +YyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJp +c3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVn +ZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4g +ZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVk +ZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUg +YWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRp +dG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIElu +dGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3Vs +YSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0 +cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25z +ZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4g +U3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlz +LiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBt +YXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhv +bmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVs +bGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3Ig +ZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0 +dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBl +cmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBh +YyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1 +IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5p +YSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxl +bnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBt +ZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBl +ZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNl +cXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJp +Y2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xv +ci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRl +bXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBl +dCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWdu +YSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBk +dWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBl +cm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxp +cy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4g +TWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50 +ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9u +IHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25z +ZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMg +YXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGlu +Y2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVz +ZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3Rp +YnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVu +ZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVk +ZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBx +dWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUu +IE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3Rl +dHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlz +bCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNz +YS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlz +IHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmlu +YXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5v +biBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmlt +LCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0 +aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxl +bnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlw +c3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBz +b2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlz +bW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1 +cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdl +dCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5v +biBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1 +Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUg +dXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRp +ZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVy +IHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZl +bGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGlj +aXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0g +bmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlz +IG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3Rh +cyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50 +IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUg +ZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1h +dXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2 +ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1v +ZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBk +aWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0 +dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNj +aXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0g +YWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUg +bmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3Jw +ZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCklu +IHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGln +bmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0 +IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2Rp +byBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFy +Y3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxs +ZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1 +cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVz +dCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9y +dGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0 +aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBm +YXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVj +IHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBh +IGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVy +bmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVs +LCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVt +LiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwg +ZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBo +YXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQg +YW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJk +aWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBk +b2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFl +c2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMs +IHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2 +ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8g +YWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJt +ZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4g +VXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVs +aXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxh +bmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1 +aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50 +IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJs +YW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50 +dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1v +cmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNp +ZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBk +aWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xl +c3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIg +YW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFj +LCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRy +dW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3Qg +ZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRy +ZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCBy +aXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29s +bGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxs +ZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9z +IHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0 +IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFz +IHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNl +ZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFs +aXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUg +YSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxp +dC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0 +IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFy +aXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBt +aS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlz +IHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFt +IHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlz +aSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1 +cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZl +bGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBp +biwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWku +IEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNp +ZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0 +IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0 +aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4g +UGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpO +dWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVl +IGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxh +Y3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVx +dWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBh +bGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxh +IG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBx +dWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8s +IHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24s +IG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmli +aCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVu +ZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFi +aXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3Jl +bSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVx +dWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVj +dG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFu +dGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEg +ZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4g +UHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNh +Z2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxp +Y2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1 +aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5p +bSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1 +dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRl +bGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rp +by4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9y +dG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4s +IHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVz +dG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5h +ci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRp +c3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBv +cm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11 +cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29k +YWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBh +YyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxh +LCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8u +IER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNl +ZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRl +LCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNp +bmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlz +IHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3Ug +ZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFt +LiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNv +bW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVz +dC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4g +UHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVs +bGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBs +ZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBp +biBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVz +dGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFs +bGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3Jh +dmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVy +IGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJp +c3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3Vs +YS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBp +c2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0 +aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVz +IHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3Nh +IG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMg +bm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVy +IG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBl +dSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBs +ZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBk +aWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRv +bG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNp +dCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIElu +dGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0 +IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRl +cmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFs +bGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8s +IG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25h +IHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkg +dGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEu +IEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVl +dCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVn +aWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3Vz +LiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQ +cmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQg +bGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxl +bWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBv +cm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxl +bywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVz +dC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1 +bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBB +bGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9z +dWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNz +YSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2Vz +IG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNl +cyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0 +aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMg +ZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jh +dmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNp +IHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0 +b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGll +LiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2 +aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVt +LCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFj +dXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlh +bSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBh +ZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBN +YXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVu +dGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBw +b3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1 +bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNp +ZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZl +cm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVz +IGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVh +biB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlh +bSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENy +YXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0 +dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxl +bnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUg +bG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMg +ZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0 +YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBw +b3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEu +IFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBh +bWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0g +bm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBw +b3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0 +ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1 +ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMg +c2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBm +cmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMg +dXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVz +cXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29u +ZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBh +ZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2Fn +aXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBs +YWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2lt +IHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBw +bGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlz +IHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUu +IE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4g +TWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1w +dXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxh +Y2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBu +b24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIElu +IGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMg +dml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1 +cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZl +c3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4g +U2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFz +IHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxs +YSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1 +cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBD +dXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1 +bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVz +IGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1 +bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBq +dXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1 +cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVy +aXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVj +IHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4g +U2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1 +cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFs +aXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVz +LiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBt +YXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2Vt +LiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEs +IGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBu +b24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlz +IHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1 +cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0 +IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50 +dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1 +bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQg +bWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21t +b2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50 +ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmlj +ZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmli +ZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBw +bGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBh +bGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQg +ZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9s +bGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1 +bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFu +dGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVz +LCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVt +IGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNp +dCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0u +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyBy +aG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBh +Y2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51 +bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3Np +bSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0 +aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoK +TnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGlu +Y2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNv +bGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMg +aWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNl +ZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyBy +aXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2 +ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFt +ZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGli +dWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3Vt +IGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBu +b24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBj +dXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9y +Y2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwg +c29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZh +dWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1 +bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBs +YWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBp +cHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4g +QWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1 +bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xs +aXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxs +YW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3Rp +YnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jhdmlk +YSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2Vs +ZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5j +LiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4g +TnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0 +ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1 +bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2 +YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxl +bWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRp +cy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMg +aW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWws +IHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2Ug +cXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxp +cyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJh +ZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlv +IG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUg +c2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxh +bSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4g +QWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5p +c2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVk +ZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2lu +ZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVs +dW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVu +dGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1 +cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNz +YS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVs +bGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4K +ClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEg +YXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQg +dGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVz +LiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1 +cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMg +aW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xs +aXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBj +b25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5l +bmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUg +ZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jh +dmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQ +cm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJp +cy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBO +dWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBs +ZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8g +bm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBl +dCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNp +bmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51 +bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVt +IGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0 +cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNl +ZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBk +YXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0 +dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJp +Y2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0 +ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGlj +aXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1 +cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBl +cmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwg +dmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBj +b25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQg +dXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBh +dWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIg +ZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkg +ZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVu +dHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1l +dHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZv +bHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBs +ZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5p +c2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZl +bGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMg +aWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1 +cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0 +IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVn +ZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1v +ZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2 +ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2Vt +cGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlz +IGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRl +bXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0g +c2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2 +YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4g +dHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNz +ZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1 +bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1 +cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1 +c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVz +ZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIs +IG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0 +IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVs +bGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxh +Y3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwg +bW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVu +dGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVz +IHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4g +TWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNp +IG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29u +dmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3Ig +cGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNs +IHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxp +c2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2Eg +ZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJh +Yml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRh +ZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxp +dCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGll +biwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQs +IGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNj +aXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0 +b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29u +ZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWdu +YS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlx +dWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJj +dSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBR +dWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2 +ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25l +YyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBj +b25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRp +cywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Ig +b3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBs +b3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNt +b2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1 +cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGlu +LiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwg +cGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyBy +aXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1h +ZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNl +ZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQg +dmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5k +aXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEs +IG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1 +dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVn +ZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5h +dGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3Jl +ZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQg +YWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQg +c29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0 +dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhp +Y3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1 +cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBl +dSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBh +YyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1l +dHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUs +IG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQs +IGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUg +bWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVu +aW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVz +IGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2Vz +IHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29u +Z3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0 +dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNh +cGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0 +LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5j +IHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVp +IHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBp +YWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxh +bmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3Nh +IG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3Iu +IE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBj +b252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBh +dCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1h +ZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMg +YWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVp +c3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5p +c2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0 +IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBh +IHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3Qs +IGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFl +LCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUg +dmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBv +cnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVj +ZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBE +dWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBl +cmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2 +ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1 +dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJt +ZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVy +dXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVl +IHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBp +cHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQs +IGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJp +Y2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBs +b2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0 +YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxl +bnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwg +ZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1 +cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlz +IHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFy +Y3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVh +biBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhh +c2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBj +b25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoK +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wg +cmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFt +IGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3Is +IG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1 +c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQu +IFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4g +QWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lz +LCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1 +bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVp +IG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRh +IHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBz +ZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3Vz +Y2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1 +Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2Nl +IGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRl +bXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3Ji +aSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVp +cyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2ls +aXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUg +bGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2Nl +IGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJv +cyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0 +cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5k +dW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1l +dCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVt +IGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhh +cmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1 +cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVu +dHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGln +dWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMs +IGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJp +cyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1 +cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1 +bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBk +YXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFz +IGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1h +ZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVs +dW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNp +bGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4g +TmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2Ug +YWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBt +aS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVz +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVu +YyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1w +b3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBm +YWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3Ig +YXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBF +dGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5p +YSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVz +dCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xl +c3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50 +IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBv +cnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRp +cyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMg +bW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMg +bGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2 +dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxp +Y2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1 +ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBx +dWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlv +LiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxh +IHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1w +ZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIg +aWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBV +dCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxs +YSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0g +c29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0 +aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlw +c3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0 +LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1w +ZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQ +cmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUu +IEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4g +RnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFs +aXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3Vl +IGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8g +YSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRp +cyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVu +dCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMu +IE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFj +dXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVl +dCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2ku +IEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3Us +IHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lk +dW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBq +dXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1 +ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4g +b3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZh +bXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBD +dXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywg +bnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMg +YWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBw +b3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBp +ZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMg +bWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGli +dXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4g +Vml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4g +TnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBt +ZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0 +IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRh +IGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVu +aW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBv +c3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24g +ZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBN +b3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2 +ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2lu +IHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxl +bWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWku +IFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVz +IGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5p +YmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxs +ZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERv +bmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9z +IHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1 +c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNx +dWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1 +Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJh +ZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlz +LiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQg +YWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQg +bWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVz +IHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdl +dCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFBy +YWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBG +dXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1 +cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4g +Q3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1 +cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25l +YyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlx +dWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50 +IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNv +bW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0 +IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVs +ZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQg +ZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBn +cmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBl +Z2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJp +cyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5h +IGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUg +cG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVj +aWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1 +bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxh +Y3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRl +bGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1 +dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1 +Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlx +dWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBt +b2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1 +c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMg +cHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0 +dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9k +IG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFt +ZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQg +bmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVs +dHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1 +cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlh +IGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVy +YXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBz +b2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEg +dGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxh +Y3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRh +dGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEg +bG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZp +dGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0g +bnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1 +ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBl +bGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxh +IGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUs +IG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFi +aXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVu +ZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVy +bmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0 +IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVy +YXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwg +ZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEg +bnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFj +aW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQg +bWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVh +bSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBl +Z2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3Bl +bmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBE +dWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBF +dGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZl +bGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVy +dXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQg +YW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRp +cGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBo +ZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJo +LiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQg +bnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9y +ZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVh +bSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBs +dWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhl +bmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFs +aXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25l +YyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJp +c3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVn +ZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4g +ZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVk +ZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUg +YWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRp +dG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIElu +dGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3Vs +YSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0 +cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25z +ZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4g +U3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlz +LiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBt +YXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhv +bmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVs +bGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3Ig +ZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0 +dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBl +cmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBh +YyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1 +IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5p +YSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxl +bnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBt +ZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBl +ZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNl +cXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJp +Y2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xv +ci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRl +bXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBl +dCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWdu +YSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBk +dWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBl +cm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxp +cy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4g +TWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50 +ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9u +IHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25z +ZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMg +YXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGlu +Y2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVz +ZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3Rp +YnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVu +ZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVk +ZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBx +dWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUu +IE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3Rl +dHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlz +bCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNz +YS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlz +IHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmlu +YXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5v +biBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmlt +LCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0 +aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxl +bnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlw +c3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBz +b2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlz +bW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1 +cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdl +dCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5v +biBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1 +Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUg +dXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRp +ZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVy +IHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZl +bGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGlj +aXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0g +bmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlz +IG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3Rh +cyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50 +IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUg +ZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1h +dXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2 +ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1v +ZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBk +aWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0 +dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNj +aXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0g +YWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUg +bmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3Jw +ZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCklu +IHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGln +bmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0 +IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2Rp +byBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFy +Y3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxs +ZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1 +cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVz +dCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9y +dGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0 +aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBm +YXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVj +IHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBh +IGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVy +bmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVs +LCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVt +LiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwg +ZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBo +YXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQg +YW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJk +aWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBk +b2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFl +c2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMs +IHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2 +ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8g +YWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJt +ZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4g +VXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVs +aXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxh +bmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1 +aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50 +IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJs +YW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50 +dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1v +cmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNp +ZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBk +aWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xl +c3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIg +YW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFj +LCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRy +dW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3Qg +ZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRy +ZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCBy +aXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29s +bGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxs +ZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9z +IHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0 +IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFz +IHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNl +ZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFs +aXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUg +YSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxp +dC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0 +IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFy +aXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBt +aS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlz +IHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFt +IHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlz +aSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1 +cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZl +bGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBp +biwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWku +IEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNp +ZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0 +IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0 +aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4g +UGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpO +dWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVl +IGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxh +Y3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVx +dWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBh +bGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxh +IG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBx +dWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8s +IHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24s +IG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmli +aCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVu +ZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFi +aXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3Jl +bSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVx +dWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVj +dG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFu +dGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEg +ZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4g +UHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNh +Z2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxp +Y2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1 +aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5p +bSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1 +dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRl +bGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rp +by4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9y +dG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4s +IHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVz +dG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5h +ci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRp +c3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBv +cm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11 +cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29k +YWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBh +YyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxh +LCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8u +IER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNl +ZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRl +LCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNp +bmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlz +IHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3Ug +ZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFt +LiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNv +bW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVz +dC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4g +UHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVs +bGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBs +ZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBp +biBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVz +dGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFs +bGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3Jh +dmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVy +IGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJp +c3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3Vs +YS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBp +c2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0 +aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVz +IHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3Nh +IG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMg +bm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVy +IG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBl +dSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBs +ZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBk +aWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRv +bG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNp +dCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIElu +dGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0 +IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRl +cmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFs +bGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8s +IG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25h +IHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkg +dGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEu +IEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVl +dCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVn +aWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3Vz +LiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQ +cmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQg +bGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxl +bWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBv +cm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxl +bywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVz +dC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1 +bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBB +bGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9z +dWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNz +YSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2Vz +IG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNl +cyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0 +aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMg +ZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jh +dmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNp +IHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0 +b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGll +LiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2 +aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVt +LCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFj +dXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlh +bSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBh +ZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBN +YXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVu +dGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBw +b3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1 +bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNp +ZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZl +cm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVz +IGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVh +biB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlh +bSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENy +YXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0 +dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxl +bnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUg +bG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMg +ZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0 +YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBw +b3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEu +IFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBh +bWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0g +bm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBw +b3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0 +ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1 +ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMg +c2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBm +cmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMg +dXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVz +cXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29u +ZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBh +ZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2Fn +aXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBs +YWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2lt +IHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBw +bGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlz +IHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUu +IE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4g +TWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1w +dXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxh +Y2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBu +b24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIElu +IGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMg +dml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1 +cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZl +c3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4g +U2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFz +IHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxs +YSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1 +cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBD +dXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1 +bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVz +IGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1 +bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBq +dXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1 +cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVy +aXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVj +IHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4g +U2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1 +cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFs +aXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVz +LiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBt +YXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2Vt +LiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEs +IGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBu +b24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlz +IHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1 +cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0 +IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50 +dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1 +bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQg +bWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21t +b2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50 +ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmlj +ZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmli +ZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBw +bGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBh +bGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQg +ZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9s +bGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1 +bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFu +dGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVz +LCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVt +IGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNp +dCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0u +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyBy +aG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBh +Y2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51 +bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3Np +bSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0 +aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoK +TnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGlu +Y2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNv +bGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMg +aWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNl +ZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyBy +aXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2 +ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFt +ZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGli +dWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3Vt +IGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBu +b24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBj +dXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9y +Y2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwg +c29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZh +dWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1 +bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBs +YWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBp +cHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4g +QWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1 +bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xs +aXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxs +YW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3Rp +YnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jhdmlk +YSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2Vs +ZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5j +LiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4g +TnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0 +ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1 +bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2 +YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxl +bWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRp +cy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMg +aW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWws +IHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2Ug +cXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxp +cyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJh +ZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlv +IG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUg +c2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxh +bSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4g +QWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5p +c2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVk +ZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2lu +ZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVs +dW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVu +dGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1 +cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNz +YS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVs +bGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4K +ClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEg +YXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQg +dGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVz +LiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1 +cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMg +aW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xs +aXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBj +b25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5l +bmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUg +ZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jh +dmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQ +cm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJp +cy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBO +dWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBs +ZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8g +bm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBl +dCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNp +bmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51 +bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVt +IGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0 +cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNl +ZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBk +YXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0 +dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJp +Y2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0 +ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGlj +aXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1 +cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBl +cmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwg +dmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBj +b25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQg +dXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBh +dWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIg +ZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkg +ZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVu +dHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1l +dHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZv +bHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBs +ZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5p +c2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZl +bGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMg +aWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1 +cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0 +IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVn +ZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1v +ZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2 +ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2Vt +cGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlz +IGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRl +bXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0g +c2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2 +YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4g +dHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNz +ZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1 +bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1 +cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1 +c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVz +ZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIs +IG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0 +IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVs +bGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxh +Y3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwg +bW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVu +dGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVz +IHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4g +TWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNp +IG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29u +dmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3Ig +cGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNs +IHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxp +c2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2Eg +ZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJh +Yml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRh +ZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxp +dCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGll +biwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQs +IGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNj +aXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0 +b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29u +ZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWdu +YS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlx +dWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJj +dSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBR +dWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2 +ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25l +YyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBj +b25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRp +cywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Ig +b3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBs +b3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNt +b2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1 +cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGlu +LiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwg +cGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyBy +aXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1h +ZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNl +ZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQg +dmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5k +aXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEs +IG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1 +dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVn +ZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5h +dGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3Jl +ZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQg +YWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQg +c29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0 +dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhp +Y3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1 +cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBl +dSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBh +YyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1l +dHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUs +IG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQs +IGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUg +bWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVu +aW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVz +IGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2Vz +IHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29u +Z3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0 +dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNh +cGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0 +LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5j +IHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVp +IHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBp +YWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxh +bmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3Nh +IG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3Iu +IE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBj +b252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBh +dCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1h +ZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMg +YWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVp +c3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5p +c2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0 +IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBh +IHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3Qs +IGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFl +LCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUg +dmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBv +cnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVj +ZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBE +dWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBl +cmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2 +ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1 +dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJt +ZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVy +dXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVl +IHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBp +cHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQs +IGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJp +Y2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBs +b2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0 +YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxl +bnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwg +ZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1 +cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlz +IHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFy +Y3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVh +biBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhh +c2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBj +b25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoK +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wg +cmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFt +IGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3Is +IG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1 +c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQu +IFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4g +QWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lz +LCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1 +bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVp +IG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRh +IHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBz +ZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3Vz +Y2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1 +Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2Nl +IGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRl +bXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3Ji +aSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVp +cyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2ls +aXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUg +bGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2Nl +IGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJv +cyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0 +cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5k +dW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1l +dCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVt +IGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhh +cmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1 +cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVu +dHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGln +dWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMs +IGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJp +cyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1 +cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1 +bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBk +YXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFz +IGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1h +ZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVs +dW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNp +bGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4g +TmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2Ug +YWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBt +aS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVz +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVu +YyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1w +b3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBm +YWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3Ig +YXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBF +dGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5p +YSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVz +dCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xl +c3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50 +IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBv +cnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRp +cyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMg +bW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMg +bGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2 +dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxp +Y2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1 +ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBx +dWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlv +LiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxh +IHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1w +ZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIg +aWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBV +dCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxs +YSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0g +c29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0 +aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlw +c3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0 +LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1w +ZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQ +cmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUu +IEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4g +RnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFs +aXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3Vl +IGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8g +YSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRp +cyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVu +dCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMu +IE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFj +dXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVl +dCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2ku +IEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3Us +IHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lk +dW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBq +dXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1 +ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4g +b3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZh +bXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBD +dXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywg +bnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMg +YWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBw +b3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBp +ZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMg +bWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGli +dXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4g +Vml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4g +TnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBt +ZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0 +IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRh +IGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVu +aW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBv +c3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24g +ZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBN +b3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2 +ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2lu +IHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxl +bWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWku +IFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVz +IGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5p +YmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxs +ZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERv +bmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9z +IHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1 +c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNx +dWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1 +Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJh +ZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlz +LiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQg +YWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQg +bWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVz +IHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdl +dCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFBy +YWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBG +dXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1 +cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4g +Q3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1 +cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25l +YyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlx +dWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50 +IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNv +bW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0 +IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVs +ZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQg +ZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBn +cmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBl +Z2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJp +cyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5h +IGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUg +cG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVj +aWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1 +bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxh +Y3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRl +bGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1 +dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1 +Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlx +dWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBt +b2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1 +c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMg +cHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0 +dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9k +IG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFt +ZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQg +bmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVs +dHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1 +cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlh +IGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVy +YXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBz +b2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEg +dGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxh +Y3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRh +dGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEg +bG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZp +dGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0g +bnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1 +ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBl +bGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxh +IGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUs +IG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFi +aXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVu +ZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVy +bmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0 +IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVy +YXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwg +ZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEg +bnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFj +aW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQg +bWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVh +bSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBl +Z2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3Bl +bmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBE +dWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBF +dGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZl +bGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVy +dXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQg +YW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRp +cGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBo +ZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJo +LiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQg +bnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9y +ZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVh +bSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBs +dWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhl +bmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFs +aXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25l +YyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJp +c3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVn +ZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4g +ZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVk +ZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUg +YWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRp +dG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIElu +dGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3Vs +YSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0 +cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25z +ZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4g +U3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlz +LiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBt +YXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhv +bmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVs +bGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3Ig +ZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0 +dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBl +cmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBh +YyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1 +IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5p +YSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxl +bnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBt +ZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBl +ZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNl +cXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJp +Y2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xv +ci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRl +bXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBl +dCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWdu +YSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBk +dWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBl +cm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxp +cy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4g +TWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50 +ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9u +IHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25z +ZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMg +YXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGlu +Y2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVz +ZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3Rp +YnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVu +ZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVk +ZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBx +dWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUu +IE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3Rl +dHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlz +bCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNz +YS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlz +IHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmlu +YXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5v +biBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmlt +LCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0 +aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxl +bnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlw +c3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBz +b2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlz +bW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1 +cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdl +dCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5v +biBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1 +Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUg +dXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRp +ZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVy +IHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZl +bGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGlj +aXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0g +bmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlz +IG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3Rh +cyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50 +IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUg +ZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1h +dXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2 +ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1v +ZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBk +aWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0 +dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNj +aXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0g +YWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUg +bmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3Jw +ZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCklu +IHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGln +bmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0 +IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2Rp +byBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFy +Y3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxs +ZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1 +cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVz +dCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9y +dGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0 +aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBm +YXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVj +IHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBh +IGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVy +bmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVs +LCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVt +LiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwg +ZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBo +YXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQg +YW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJk +aWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBk +b2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFl +c2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMs +IHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2 +ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8g +YWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJt +ZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4g +VXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVs +aXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxh +bmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1 +aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50 +IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJs +YW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50 +dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1v +cmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNp +ZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBk +aWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xl +c3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIg +YW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFj +LCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRy +dW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3Qg +ZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRy +ZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCBy +aXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29s +bGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxs +ZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9z +IHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0 +IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFz +IHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNl +ZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFs +aXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUg +YSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxp +dC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0 +IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFy +aXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBt +aS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlz +IHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFt +IHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlz +aSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1 +cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZl +bGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBp +biwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWku +IEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNp +ZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0 +IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0 +aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4g +UGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpO +dWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVl +IGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxh +Y3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVx +dWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBh +bGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxh +IG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBx +dWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8s +IHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24s +IG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmli +aCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVu +ZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFi +aXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3Jl +bSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVx +dWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVj +dG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFu +dGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEg +ZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4g +UHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNh +Z2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxp +Y2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1 +aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5p +bSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1 +dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRl +bGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rp +by4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9y +dG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4s +IHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVz +dG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5h +ci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRp +c3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBv +cm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11 +cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29k +YWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBh +YyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxh +LCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8u +IER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNl +ZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRl +LCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNp +bmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlz +IHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3Ug +ZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFt +LiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNv +bW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVz +dC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4g +UHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVs +bGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBs +ZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBp +biBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVz +dGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFs +bGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3Jh +dmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVy +IGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJp +c3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3Vs +YS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBp +c2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0 +aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVz +IHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3Nh +IG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMg +bm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVy +IG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBl +dSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBs +ZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBk +aWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRv +bG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNp +dCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIElu +dGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0 +IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRl +cmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFs +bGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8s +IG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25h +IHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkg +dGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEu +IEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVl +dCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVn +aWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3Vz +LiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQ +cmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQg +bGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxl +bWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBv +cm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxl +bywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVz +dC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1 +bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBB +bGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9z +dWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNz +YSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2Vz +IG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNl +cyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0 +aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMg +ZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jh +dmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNp +IHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0 +b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGll +LiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2 +aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVt +LCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFj +dXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlh +bSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBh +ZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBN +YXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVu +dGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBw +b3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1 +bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNp +ZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZl +cm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVz +IGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVh +biB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlh +bSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENy +YXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0 +dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxl +bnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUg +bG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMg +ZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0 +YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBw +b3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEu +IFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBh +bWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0g +bm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBw +b3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0 +ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1 +ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMg +c2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBm +cmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMg +dXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVz +cXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29u +ZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBh +ZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2Fn +aXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBs +YWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2lt +IHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBw +bGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlz +IHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUu +IE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4g +TWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1w +dXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxh +Y2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBu +b24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIElu +IGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMg +dml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1 +cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZl +c3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4g +U2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFz +IHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxs +YSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1 +cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBD +dXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1 +bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVz +IGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1 +bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBq +dXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1 +cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVy +aXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVj +IHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4g +U2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1 +cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFs +aXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVz +LiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBt +YXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2Vt +LiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEs +IGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBu +b24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlz +IHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1 +cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0 +IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50 +dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1 +bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQg +bWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21t +b2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50 +ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmlj +ZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmli +ZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBw +bGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBh +bGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQg +ZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9s +bGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1 +bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFu +dGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVz +LCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVt +IGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNp +dCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0u +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyBy +aG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBh +Y2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51 +bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3Np +bSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0 +aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoK +TnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGlu +Y2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNv +bGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMg +aWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNl +ZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyBy +aXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2 +ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFt +ZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGli +dWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3Vt +IGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBu +b24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBj +dXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9y +Y2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwg +c29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZh +dWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1 +bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBs +YWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBp +cHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4g +QWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1 +bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xs +aXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxs +YW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3Rp +YnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jhdmlk +YSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2Vs +ZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5j +LiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4g +TnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0 +ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1 +bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2 +YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxl +bWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRp +cy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMg +aW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWws +IHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2Ug +cXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxp +cyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJh +ZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlv +IG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUg +c2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxh +bSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4g +QWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5p +c2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVk +ZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2lu +ZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVs +dW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVu +dGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1 +cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNz +YS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVs +bGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4K +ClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEg +YXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQg +dGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVz +LiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1 +cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMg +aW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xs +aXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBj +b25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5l +bmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUg +ZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jh +dmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQ +cm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJp +cy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBO +dWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBs +ZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8g +bm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBl +dCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNp +bmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51 +bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVt +IGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0 +cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNl +ZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBk +YXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0 +dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJp +Y2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0 +ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGlj +aXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1 +cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBl +cmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwg +dmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBj +b25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQg +dXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBh +dWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIg +ZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkg +ZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVu +dHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1l +dHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZv +bHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBs +ZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5p +c2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZl +bGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMg +aWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1 +cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0 +IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVn +ZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1v +ZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2 +ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2Vt +cGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlz +IGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRl +bXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0g +c2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2 +YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4g +dHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNz +ZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1 +bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1 +cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1 +c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVz +ZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIs +IG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0 +IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVs +bGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxh +Y3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwg +bW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVu +dGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVz +IHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4g +TWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNp +IG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29u +dmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3Ig +cGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNs +IHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxp +c2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2Eg +ZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJh +Yml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRh +ZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxp +dCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGll +biwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQs +IGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNj +aXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0 +b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29u +ZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWdu +YS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlx +dWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJj +dSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBR +dWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2 +ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25l +YyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBj +b25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRp +cywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Ig +b3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBs +b3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNt +b2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1 +cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGlu +LiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwg +cGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyBy +aXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1h +ZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNl +ZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQg +dmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5k +aXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEs +IG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1 +dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVn +ZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5h +dGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3Jl +ZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQg +YWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQg +c29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0 +dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhp +Y3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1 +cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBl +dSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBh +YyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1l +dHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUs +IG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQs +IGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUg +bWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVu +aW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVz +IGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2Vz +IHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29u +Z3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0 +dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNh +cGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0 +LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5j +IHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVp +IHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBp +YWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxh +bmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3Nh +IG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3Iu +IE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBj +b252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBh +dCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1h +ZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMg +YWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVp +c3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5p +c2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0 +IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBh +IHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3Qs +IGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFl +LCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUg +dmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBv +cnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVj +ZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBE +dWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBl +cmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2 +ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1 +dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJt +ZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVy +dXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVl +IHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBp +cHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQs +IGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJp +Y2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBs +b2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0 +YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxl +bnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwg +ZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1 +cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlz +IHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFy +Y3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVh +biBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhh +c2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBj +b25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoK +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wg +cmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFt +IGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3Is +IG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1 +c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQu +IFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4g +QWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lz +LCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1 +bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVp +IG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRh +IHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBz +ZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3Vz +Y2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1 +Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2Nl +IGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRl +bXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3Ji +aSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVp +cyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2ls +aXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUg +bGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2Nl +IGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJv +cyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0 +cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5k +dW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1l +dCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVt +IGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhh +cmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1 +cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVu +dHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGln +dWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMs +IGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJp +cyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1 +cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1 +bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBk +YXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFz +IGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1h +ZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVs +dW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNp +bGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4g +TmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2Ug +YWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBt +aS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVz +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVu +YyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1w +b3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBm +YWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3Ig +YXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBF +dGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5p +YSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVz +dCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xl +c3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50 +IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBv +cnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRp +cyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMg +bW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMg +bGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2 +dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxp +Y2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1 +ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBx +dWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlv +LiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxh +IHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1w +ZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIg +aWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBV +dCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxs +YSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0g +c29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0 +aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlw +c3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0 +LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1w +ZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQ +cmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUu +IEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4g +RnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFs +aXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3Vl +IGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8g +YSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRp +cyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVu +dCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMu +IE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFj +dXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVl +dCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2ku +IEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3Us +IHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lk +dW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBq +dXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1 +ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4g +b3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZh +bXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBD +dXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywg +bnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMg +YWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBw +b3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBp +ZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMg +bWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGli +dXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4g +Vml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4g +TnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBt +ZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0 +IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRh +IGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVu +aW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBv +c3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24g +ZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBN +b3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2 +ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2lu +IHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxl +bWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWku +IFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVz +IGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5p +YmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxs +ZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERv +bmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9z +IHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1 +c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNx +dWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1 +Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJh +ZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlz +LiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQg +YWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQg +bWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVz +IHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdl +dCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFBy +YWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBG +dXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1 +cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4g +Q3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1 +cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25l +YyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlx +dWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50 +IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNv +bW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0 +IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVs +ZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQg +ZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBn +cmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBl +Z2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJp +cyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5h +IGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUg +cG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVj +aWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1 +bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxh +Y3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRl +bGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1 +dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1 +Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlx +dWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBt +b2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1 +c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMg +cHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0 +dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9k +IG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFt +ZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQg +bmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVs +dHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1 +cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlh +IGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVy +YXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBz +b2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEg +dGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxh +Y3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRh +dGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEg +bG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZp +dGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0g +bnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1 +ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBl +bGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxh +IGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUs +IG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFi +aXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVu +ZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVy +bmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0 +IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVy +YXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwg +ZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEg +bnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFj +aW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQg +bWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVh +bSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBl +Z2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3Bl +bmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBE +dWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBF +dGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZl +bGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVy +dXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQg +YW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRp +cGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBo +ZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJo +LiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQg +bnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9y +ZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVh +bSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBs +dWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhl +bmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFs +aXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25l +YyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJp +c3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVn +ZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4g +ZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVk +ZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUg +YWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRp +dG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIElu +dGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3Vs +YSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0 +cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25z +ZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4g +U3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlz +LiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBt +YXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhv +bmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVs +bGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3Ig +ZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0 +dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBl +cmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBh +YyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1 +IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5p +YSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxl +bnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBt +ZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBl +ZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNl +cXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJp +Y2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xv +ci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRl +bXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBl +dCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWdu +YSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBk +dWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBl +cm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxp +cy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4g +TWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50 +ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9u +IHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25z +ZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMg +YXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGlu +Y2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVz +ZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3Rp +YnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVu +ZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVk +ZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBx +dWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUu +IE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3Rl +dHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlz +bCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNz +YS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlz +IHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmlu +YXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5v +biBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmlt +LCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0 +aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxl +bnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlw +c3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBz +b2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlz +bW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1 +cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdl +dCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5v +biBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1 +Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUg +dXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRp +ZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVy +IHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZl +bGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGlj +aXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0g +bmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlz +IG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3Rh +cyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50 +IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUg +ZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1h +dXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2 +ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1v +ZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBk +aWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0 +dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNj +aXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0g +YWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUg +bmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3Jw +ZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCklu +IHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGln +bmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0 +IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2Rp +byBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFy +Y3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxs +ZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1 +cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVz +dCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9y +dGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0 +aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBm +YXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVj +IHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBh +IGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVy +bmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVs +LCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVt +LiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwg +ZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBo +YXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQg +YW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJk +aWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBk +b2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFl +c2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMs +IHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2 +ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8g +YWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJt +ZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4g +VXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVs +aXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxh +bmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1 +aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50 +IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJs +YW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50 +dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1v +cmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNp +ZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBk +aWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xl +c3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIg +YW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFj +LCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRy +dW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3Qg +ZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRy +ZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCBy +aXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29s +bGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxs +ZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9z +IHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0 +IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFz +IHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNl +ZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFs +aXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUg +YSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxp +dC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0 +IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFy +aXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBt +aS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlz +IHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFt +IHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlz +aSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1 +cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZl +bGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBp +biwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWku +IEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNp +ZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0 +IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0 +aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4g +UGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpO +dWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVl +IGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxh +Y3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVx +dWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBh +bGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxh +IG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBx +dWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8s +IHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24s +IG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmli +aCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVu +ZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFi +aXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3Jl +bSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVx +dWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVj +dG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFu +dGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEg +ZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4g +UHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNh +Z2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxp +Y2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1 +aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5p +bSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1 +dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRl +bGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rp +by4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9y +dG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4s +IHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVz +dG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5h +ci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRp +c3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBv +cm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11 +cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29k +YWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBh +YyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxh +LCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8u +IER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNl +ZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRl +LCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNp +bmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlz +IHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3Ug +ZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFt +LiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNv +bW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVz +dC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4g +UHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVs +bGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBs +ZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBp +biBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVz +dGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFs +bGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3Jh +dmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVy +IGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJp +c3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3Vs +YS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBp +c2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0 +aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVz +IHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3Nh +IG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMg +bm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVy +IG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBl +dSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBs +ZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBk +aWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRv +bG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNp +dCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIElu +dGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0 +IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRl +cmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFs +bGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8s +IG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25h +IHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkg +dGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEu +IEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVl +dCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVn +aWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3Vz +LiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQ +cmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQg +bGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxl +bWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBv +cm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxl +bywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVz +dC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1 +bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBB +bGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9z +dWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNz +YSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2Vz +IG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNl +cyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0 +aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMg +ZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jh +dmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNp +IHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0 +b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGll +LiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2 +aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVt +LCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFj +dXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlh +bSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBh +ZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBN +YXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVu +dGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBw +b3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1 +bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNp +ZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZl +cm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVz +IGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVh +biB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlh +bSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENy +YXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0 +dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxl +bnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUg +bG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMg +ZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0 +YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBw +b3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEu +IFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBh +bWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0g +bm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBw +b3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0 +ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1 +ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMg +c2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBm +cmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMg +dXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVz +cXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29u +ZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBh +ZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2Fn +aXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBs +YWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2lt +IHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBw +bGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlz +IHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUu +IE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4g +TWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1w +dXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxh +Y2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBu +b24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIElu +IGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMg +dml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1 +cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZl +c3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4g +U2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFz +IHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxs +YSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1 +cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBD +dXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1 +bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVz +IGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1 +bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBq +dXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1 +cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVy +aXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVj +IHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4g +U2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1 +cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFs +aXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVz +LiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBt +YXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2Vt +LiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEs +IGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBu +b24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlz +IHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1 +cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0 +IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50 +dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1 +bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQg +bWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21t +b2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50 +ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmlj +ZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmli +ZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBw +bGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBh +bGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQg +ZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9s +bGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1 +bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFu +dGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVz +LCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVt +IGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNp +dCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0u +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyBy +aG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBh +Y2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51 +bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3Np +bSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0 +aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoK +TnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGlu +Y2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNv +bGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMg +aWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNl +ZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyBy +aXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2 +ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFt +ZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGli +dWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3Vt +IGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBu +b24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBj +dXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9y +Y2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwg +c29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZh +dWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1 +bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBs +YWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBp +cHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4g +QWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1 +bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xs +aXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxs +YW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3Rp +YnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jhdmlk +YSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2Vs +ZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5j +LiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4g +TnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0 +ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1 +bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2 +YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxl +bWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRp +cy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMg +aW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWws +IHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2Ug +cXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxp +cyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJh +ZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlv +IG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUg +c2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxh +bSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4g +QWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5p +c2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVk +ZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2lu +ZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVs +dW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVu +dGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1 +cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNz +YS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVs +bGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4K +ClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEg +YXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQg +dGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVz +LiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1 +cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMg +aW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xs +aXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBj +b25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5l +bmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUg +ZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jh +dmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQ +cm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJp +cy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBO +dWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBs +ZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8g +bm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBl +dCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNp +bmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51 +bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVt +IGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0 +cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNl +ZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBk +YXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0 +dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJp +Y2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0 +ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGlj +aXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1 +cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBl +cmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwg +dmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBj +b25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQg +dXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBh +dWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIg +ZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkg +ZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVu +dHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1l +dHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZv +bHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBs +ZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5p +c2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZl +bGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMg +aWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1 +cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0 +IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVn +ZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1v +ZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2 +ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2Vt +cGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlz +IGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRl +bXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0g +c2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2 +YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4g +dHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNz +ZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1 +bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1 +cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1 +c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVz +ZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIs +IG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0 +IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVs +bGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxh +Y3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwg +bW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVu +dGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVz +IHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4g +TWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNp +IG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29u +dmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3Ig +cGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNs +IHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxp +c2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2Eg +ZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJh +Yml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRh +ZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxp +dCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGll +biwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQs +IGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNj +aXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0 +b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29u +ZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWdu +YS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlx +dWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJj +dSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBR +dWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2 +ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25l +YyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBj +b25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRp +cywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Ig +b3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBs +b3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNt +b2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1 +cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGlu +LiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwg +cGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyBy +aXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1h +ZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNl +ZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQg +dmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5k +aXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEs +IG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1 +dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVn +ZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5h +dGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3Jl +ZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQg +YWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQg +c29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0 +dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhp +Y3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1 +cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBl +dSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBh +YyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1l +dHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUs +IG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQs +IGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUg +bWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVu +aW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVz +IGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2Vz +IHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29u +Z3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0 +dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNh +cGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0 +LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5j +IHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVp +IHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBp +YWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxh +bmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3Nh +IG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3Iu +IE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBj +b252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBh +dCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1h +ZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMg +YWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVp +c3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5p +c2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0 +IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBh +IHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3Qs +IGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFl +LCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUg +dmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBv +cnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVj +ZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBE +dWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBl +cmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2 +ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1 +dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJt +ZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVy +dXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVl +IHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBp +cHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQs +IGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJp +Y2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBs +b2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0 +YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxl +bnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwg +ZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1 +cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlz +IHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFy +Y3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVh +biBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhh +c2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBj +b25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoK +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wg +cmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFt +IGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3Is +IG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1 +c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQu +IFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4g +QWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lz +LCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1 +bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVp +IG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRh +IHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBz +ZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3Vz +Y2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1 +Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2Nl +IGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRl +bXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3Ji +aSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVp +cyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2ls +aXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUg +bGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2Nl +IGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJv +cyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0 +cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5k +dW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1l +dCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVt +IGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhh +cmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1 +cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVu +dHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGln +dWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMs +IGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJp +cyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1 +cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1 +bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBk +YXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFz +IGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1h +ZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVs +dW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNp +bGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4g +TmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2Ug +YWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBt +aS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVz +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVu +YyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1w +b3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBm +YWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3Ig +YXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBF +dGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5p +YSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVz +dCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xl +c3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50 +IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBv +cnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRp +cyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMg +bW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMg +bGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2 +dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxp +Y2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1 +ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBx +dWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlv +LiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxh +IHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1w +ZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIg +aWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBV +dCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxs +YSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0g +c29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0 +aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlw +c3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0 +LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1w +ZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQ +cmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUu +IEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4g +RnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFs +aXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3Vl +IGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8g +YSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRp +cyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVu +dCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMu +IE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFj +dXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVl +dCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2ku +IEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3Us +IHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lk +dW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBq +dXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1 +ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4g +b3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZh +bXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBD +dXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywg +bnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMg +YWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBw +b3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBp +ZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMg +bWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGli +dXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4g +Vml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4g +TnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBt +ZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0 +IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRh +IGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVu +aW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBv +c3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24g +ZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBN +b3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2 +ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2lu +IHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxl +bWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWku +IFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVz +IGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5p +YmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxs +ZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERv +bmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9z +IHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1 +c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNx +dWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1 +Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJh +ZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlz +LiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQg +YWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQg +bWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVz +IHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdl +dCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFBy +YWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBG +dXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1 +cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4g +Q3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1 +cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25l +YyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlx +dWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50 +IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNv +bW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0 +IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVs +ZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQg +ZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBn +cmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBl +Z2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJp +cyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5h +IGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUg +cG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVj +aWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1 +bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxh +Y3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRl +bGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1 +dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1 +Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlx +dWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBt +b2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1 +c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMg +cHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0 +dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9k +IG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFt +ZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQg +bmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVs +dHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1 +cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlh +IGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVy +YXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBz +b2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEg +dGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxh +Y3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRh +dGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEg +bG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZp +dGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0g +bnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1 +ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBl +bGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxh +IGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUs +IG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFi +aXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVu +ZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVy +bmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0 +IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVy +YXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwg +ZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEg +bnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFj +aW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQg +bWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVh +bSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBl +Z2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3Bl +bmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBE +dWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBF +dGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZl +bGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVy +dXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQg +YW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRp +cGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBo +ZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJo +LiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQg +bnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9y +ZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVh +bSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBs +dWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhl +bmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFs +aXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25l +YyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJp +c3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVn +ZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4g +ZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVk +ZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUg +YWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRp +dG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIElu +dGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3Vs +YSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0 +cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25z +ZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4g +U3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlz +LiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBt +YXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhv +bmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVs +bGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3Ig +ZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0 +dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBl +cmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBh +YyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1 +IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5p +YSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxl +bnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBt +ZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBl +ZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNl +cXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJp +Y2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xv +ci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRl +bXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBl +dCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWdu +YSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBk +dWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBl +cm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxp +cy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4g +TWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50 +ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9u +IHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25z +ZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMg +YXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGlu +Y2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVz +ZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3Rp +YnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVu +ZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVk +ZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBx +dWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUu +IE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3Rl +dHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlz +bCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNz +YS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlz +IHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmlu +YXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5v +biBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmlt +LCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0 +aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxl +bnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlw +c3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBz +b2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlz +bW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1 +cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdl +dCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5v +biBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1 +Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUg +dXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRp +ZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVy +IHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZl +bGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGlj +aXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0g +bmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlz +IG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3Rh +cyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50 +IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUg +ZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1h +dXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2 +ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1v +ZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBk +aWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0 +dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNj +aXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0g +YWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUg +bmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3Jw +ZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCklu +IHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGln +bmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0 +IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2Rp +byBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFy +Y3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxs +ZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1 +cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVz +dCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9y +dGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0 +aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBm +YXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVj +IHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBh +IGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVy +bmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVs +LCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVt +LiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwg +ZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBo +YXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQg +YW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJk +aWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBk +b2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFl +c2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMs +IHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2 +ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8g +YWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJt +ZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4g +VXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVs +aXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxh +bmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1 +aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50 +IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJs +YW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50 +dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1v +cmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNp +ZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBk +aWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xl +c3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIg +YW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFj +LCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRy +dW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3Qg +ZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRy +ZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCBy +aXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29s +bGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxs +ZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9z +IHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0 +IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFz +IHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNl +ZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFs +aXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUg +YSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxp +dC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0 +IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFy +aXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBt +aS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlz +IHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFt +IHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlz +aSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1 +cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZl +bGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBp +biwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWku +IEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNp +ZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0 +IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0 +aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4g +UGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpO +dWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVl +IGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxh +Y3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVx +dWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBh +bGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxh +IG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBx +dWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8s +IHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24s +IG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmli +aCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVu +ZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFi +aXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3Jl +bSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVx +dWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVj +dG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFu +dGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEg +ZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4g +UHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNh +Z2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxp +Y2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1 +aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5p +bSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1 +dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRl +bGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rp +by4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9y +dG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4s +IHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVz +dG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5h +ci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRp +c3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBv +cm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11 +cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29k +YWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBh +YyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxh +LCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8u +IER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNl +ZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRl +LCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNp +bmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlz +IHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3Ug +ZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFt +LiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNv +bW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVz +dC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4g +UHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVs +bGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBs +ZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBp +biBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVz +dGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFs +bGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3Jh +dmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVy +IGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJp +c3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3Vs +YS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBp +c2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0 +aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVz +IHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3Nh +IG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMg +bm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVy +IG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBl +dSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBs +ZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBk +aWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRv +bG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNp +dCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIElu +dGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0 +IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRl +cmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFs +bGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8s +IG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25h +IHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkg +dGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEu +IEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVl +dCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVn +aWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3Vz +LiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQ +cmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQg +bGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxl +bWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBv +cm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxl +bywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVz +dC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1 +bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBB +bGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9z +dWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNz +YSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2Vz +IG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNl +cyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0 +aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMg +ZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jh +dmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNp +IHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0 +b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGll +LiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2 +aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVt +LCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFj +dXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlh +bSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBh +ZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBN +YXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVu +dGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBw +b3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1 +bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNp +ZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZl +cm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVz +IGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVh +biB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlh +bSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENy +YXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0 +dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxl +bnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUg +bG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMg +ZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0 +YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBw +b3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEu +IFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBh +bWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0g +bm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBw +b3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0 +ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1 +ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMg +c2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBm +cmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMg +dXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVz +cXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29u +ZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBh +ZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2Fn +aXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBs +YWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2lt +IHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBw +bGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlz +IHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUu +IE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4g +TWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1w +dXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxh +Y2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBu +b24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIElu +IGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMg +dml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1 +cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZl +c3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4g +U2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFz +IHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxs +YSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1 +cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBD +dXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1 +bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVz +IGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1 +bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBq +dXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1 +cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVy +aXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVj +IHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4g +U2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1 +cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFs +aXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVz +LiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBt +YXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2Vt +LiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEs +IGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBu +b24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlz +IHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1 +cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0 +IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50 +dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1 +bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQg +bWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21t +b2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50 +ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmlj +ZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmli +ZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBw +bGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBh +bGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQg +ZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9s +bGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1 +bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFu +dGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVz +LCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVt +IGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNp +dCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0u +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyBy +aG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBh +Y2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51 +bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3Np +bSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0 +aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoK +TnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGlu +Y2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNv +bGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMg +aWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNl +ZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyBy +aXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2 +ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFt +ZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGli +dWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3Vt +IGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBu +b24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBj +dXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9y +Y2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwg +c29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZh +dWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1 +bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBs +YWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBp +cHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4g +QWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1 +bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xs +aXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxs +YW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3Rp +YnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jhdmlk +YSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2Vs +ZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5j +LiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4g +TnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0 +ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1 +bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2 +YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxl +bWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRp +cy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMg +aW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWws +IHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2Ug +cXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxp +cyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJh +ZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlv +IG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUg +c2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxh +bSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4g +QWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5p +c2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVk +ZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2lu +ZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVs +dW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVu +dGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1 +cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNz +YS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVs +bGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4K +ClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEg +YXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQg +dGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVz +LiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1 +cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMg +aW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xs +aXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBj +b25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5l +bmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUg +ZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jh +dmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQ +cm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJp +cy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBO +dWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBs +ZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8g +bm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBl +dCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNp +bmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51 +bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVt +IGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0 +cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNl +ZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBk +YXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0 +dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJp +Y2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0 +ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGlj +aXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1 +cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBl +cmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwg +dmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBj +b25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQg +dXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBh +dWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIg +ZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkg +ZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVu +dHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1l +dHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZv +bHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBs +ZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5p +c2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZl +bGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMg +aWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1 +cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0 +IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVn +ZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1v +ZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2 +ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2Vt +cGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlz +IGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRl +bXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0g +c2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2 +YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4g +dHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNz +ZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1 +bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1 +cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1 +c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVz +ZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIs +IG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0 +IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVs +bGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxh +Y3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwg +bW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVu +dGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVz +IHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4g +TWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNp +IG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29u +dmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3Ig +cGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNs +IHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxp +c2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2Eg +ZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJh +Yml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRh +ZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxp +dCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGll +biwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQs +IGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNj +aXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0 +b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29u +ZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWdu +YS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlx +dWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJj +dSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBR +dWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2 +ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25l +YyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBj +b25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRp +cywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Ig +b3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBs +b3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNt +b2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1 +cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGlu +LiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwg +cGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyBy +aXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1h +ZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNl +ZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQg +dmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5k +aXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEs +IG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1 +dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVn +ZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5h +dGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3Jl +ZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQg +YWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQg +c29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0 +dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhp +Y3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1 +cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBl +dSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBh +YyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1l +dHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUs +IG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQs +IGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUg +bWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVu +aW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVz +IGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2Vz +IHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29u +Z3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0 +dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNh +cGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0 +LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5j +IHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVp +IHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBp +YWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxh +bmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3Nh +IG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3Iu +IE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBj +b252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBh +dCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1h +ZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMg +YWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVp +c3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5p +c2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0 +IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBh +IHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3Qs +IGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFl +LCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUg +dmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBv +cnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVj +ZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBE +dWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBl +cmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2 +ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1 +dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJt +ZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVy +dXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVl +IHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBp +cHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQs +IGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJp +Y2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBs +b2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0 +YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxl +bnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwg +ZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1 +cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlz +IHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFy +Y3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVh +biBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhh +c2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBj +b25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoK +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wg +cmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFt +IGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3Is +IG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1 +c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQu +IFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4g +QWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lz +LCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1 +bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVp +IG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRh +IHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBz +ZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3Vz +Y2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1 +Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2Nl +IGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRl +bXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3Ji +aSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVp +cyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2ls +aXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUg +bGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2Nl +IGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJv +cyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0 +cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5k +dW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1l +dCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVt +IGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhh +cmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1 +cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVu +dHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGln +dWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMs +IGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJp +cyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1 +cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1 +bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBk +YXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFz +IGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1h +ZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVs +dW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNp +bGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4g +TmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2Ug +YWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBt +aS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVz +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVu +YyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1w +b3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBm +YWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3Ig +YXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBF +dGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5p +YSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVz +dCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xl +c3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50 +IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBv +cnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRp +cyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMg +bW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMg +bGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2 +dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxp +Y2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1 +ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBx +dWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlv +LiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxh +IHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1w +ZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIg +aWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBV +dCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxs +YSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0g +c29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0 +aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlw +c3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0 +LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1w +ZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQ +cmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUu +IEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4g +RnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFs +aXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3Vl +IGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8g +YSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRp +cyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVu +dCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMu +IE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFj +dXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVl +dCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2ku +IEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3Us +IHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lk +dW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBq +dXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1 +ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4g +b3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZh +bXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBD +dXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywg +bnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMg +YWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBw +b3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBp +ZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMg +bWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGli +dXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4g +Vml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4g +TnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBt +ZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0 +IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRh +IGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVu +aW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBv +c3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24g +ZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBN +b3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2 +ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2lu +IHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxl +bWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWku +IFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVz +IGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5p +YmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxs +ZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERv +bmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9z +IHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1 +c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNx +dWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1 +Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJh +ZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlz +LiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQg +YWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQg +bWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVz +IHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdl +dCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFBy +YWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBG +dXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1 +cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4g +Q3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1 +cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25l +YyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlx +dWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50 +IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNv +bW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0 +IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVs +ZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQg +ZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBn +cmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBl +Z2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJp +cyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5h +IGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUg +cG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVj +aWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1 +bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxh +Y3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRl +bGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1 +dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1 +Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlx +dWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBt +b2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1 +c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMg +cHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0 +dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9k +IG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFt +ZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQg +bmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVs +dHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1 +cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlh +IGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVy +YXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBz +b2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEg +dGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxh +Y3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRh +dGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEg +bG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZp +dGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0g +bnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1 +ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBl +bGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxh +IGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUs +IG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFi +aXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVu +ZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVy +bmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0 +IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVy +YXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwg +ZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEg +bnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFj +aW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQg +bWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVh +bSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBl +Z2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3Bl +bmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBE +dWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBF +dGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZl +bGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVy +dXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQg +YW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRp +cGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBo +ZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJo +LiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQg +bnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9y +ZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVh +bSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBs +dWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhl +bmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFs +aXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25l +YyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJp +c3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVn +ZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4g +ZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVk +ZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUg +YWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRp +dG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIElu +dGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3Vs +YSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0 +cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25z +ZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4g +U3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlz +LiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBt +YXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhv +bmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVs +bGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3Ig +ZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0 +dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBl +cmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBh +YyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1 +IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5p +YSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxl +bnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBt +ZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBl +ZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNl +cXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJp +Y2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xv +ci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRl +bXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBl +dCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWdu +YSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBk +dWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBl +cm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxp +cy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4g +TWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50 +ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9u +IHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25z +ZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMg +YXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGlu +Y2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVz +ZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3Rp +YnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVu +ZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVk +ZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBx +dWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUu +IE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3Rl +dHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlz +bCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNz +YS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlz +IHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmlu +YXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5v +biBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmlt +LCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0 +aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxl +bnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlw +c3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBz +b2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlz +bW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1 +cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdl +dCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5v +biBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1 +Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUg +dXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRp +ZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVy +IHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZl +bGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGlj +aXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0g +bmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlz +IG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3Rh +cyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50 +IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUg +ZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1h +dXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2 +ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1v +ZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBk +aWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0 +dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNj +aXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0g +YWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUg +bmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3Jw +ZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCklu +IHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGln +bmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0 +IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2Rp +byBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFy +Y3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxs +ZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1 +cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVz +dCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9y +dGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0 +aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBm +YXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVj +IHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBh +IGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVy +bmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVs +LCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVt +LiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwg +ZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBo +YXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQg +YW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJk +aWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBk +b2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFl +c2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMs +IHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2 +ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8g +YWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJt +ZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4g +VXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVs +aXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxh +bmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1 +aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50 +IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJs +YW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50 +dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1v +cmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNp +ZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBk +aWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xl +c3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIg +YW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFj +LCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRy +dW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3Qg +ZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRy +ZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCBy +aXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29s +bGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxs +ZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9z +IHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0 +IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFz +IHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNl +ZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFs +aXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUg +YSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxp +dC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0 +IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFy +aXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBt +aS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlz +IHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFt +IHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlz +aSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1 +cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZl +bGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBp +biwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWku +IEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNp +ZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0 +IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0 +aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4g +UGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpO +dWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVl +IGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxh +Y3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVx +dWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBh +bGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxh +IG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBx +dWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8s +IHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24s +IG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmli +aCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVu +ZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFi +aXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3Jl +bSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVx +dWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVj +dG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFu +dGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEg +ZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4g +UHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNh +Z2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxp +Y2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1 +aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5p +bSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1 +dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRl +bGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rp +by4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9y +dG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4s +IHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVz +dG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5h +ci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRp +c3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBv +cm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11 +cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29k +YWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBh +YyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxh +LCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8u +IER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNl +ZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRl +LCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNp +bmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlz +IHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3Ug +ZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFt +LiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNv +bW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVz +dC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4g +UHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVs +bGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBs +ZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBp +biBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVz +dGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFs +bGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3Jh +dmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVy +IGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJp +c3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3Vs +YS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBp +c2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0 +aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVz +IHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3Nh +IG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMg +bm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVy +IG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBl +dSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBs +ZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBk +aWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRv +bG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNp +dCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIElu +dGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0 +IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRl +cmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFs +bGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8s +IG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25h +IHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkg +dGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEu +IEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVl +dCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVn +aWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3Vz +LiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQ +cmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQg +bGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxl +bWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBv +cm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxl +bywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVz +dC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1 +bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBB +bGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9z +dWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNz +YSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2Vz +IG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNl +cyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0 +aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMg +ZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jh +dmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNp +IHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0 +b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGll +LiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2 +aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVt +LCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFj +dXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlh +bSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBh +ZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBN +YXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVu +dGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBw +b3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1 +bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNp +ZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZl +cm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVz +IGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVh +biB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlh +bSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENy +YXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0 +dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxl +bnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUg +bG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMg +ZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0 +YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBw +b3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEu +IFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBh +bWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0g +bm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBw +b3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0 +ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1 +ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMg +c2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBm +cmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMg +dXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVz +cXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29u +ZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBh +ZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2Fn +aXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBs +YWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2lt +IHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBw +bGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlz +IHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUu +IE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4g +TWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1w +dXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxh +Y2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBu +b24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIElu +IGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMg +dml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1 +cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZl +c3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4g +U2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFz +IHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxs +YSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1 +cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBD +dXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1 +bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVz +IGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1 +bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBq +dXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1 +cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVy +aXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVj +IHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4g +U2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1 +cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFs +aXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVz +LiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBt +YXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2Vt +LiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEs +IGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBu +b24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlz +IHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1 +cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0 +IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50 +dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1 +bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQg +bWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21t +b2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50 +ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmlj +ZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmli +ZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBw +bGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBh +bGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQg +ZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9s +bGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1 +bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFu +dGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVz +LCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVt +IGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNp +dCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0u +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyBy +aG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBh +Y2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51 +bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3Np +bSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0 +aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoK +TnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGlu +Y2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNv +bGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMg +aWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNl +ZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyBy +aXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2 +ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFt +ZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGli +dWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3Vt +IGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBu +b24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBj +dXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9y +Y2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwg +c29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZh +dWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1 +bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBs +YWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBp +cHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4g +QWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1 +bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xs +aXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxs +YW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3Rp +YnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jhdmlk +YSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2Vs +ZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5j +LiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4g +TnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0 +ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1 +bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2 +YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxl +bWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRp +cy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMg +aW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWws +IHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2Ug +cXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxp +cyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJh +ZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlv +IG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUg +c2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxh +bSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4g +QWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5p +c2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVk +ZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2lu +ZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVs +dW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVu +dGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1 +cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNz +YS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVs +bGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4K +ClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEg +YXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQg +dGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVz +LiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1 +cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMg +aW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xs +aXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBj +b25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5l +bmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUg +ZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jh +dmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQ +cm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJp +cy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBO +dWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBs +ZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8g +bm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBl +dCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNp +bmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51 +bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVt +IGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0 +cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNl +ZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBk +YXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0 +dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJp +Y2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0 +ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGlj +aXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1 +cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBl +cmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwg +dmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBj +b25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQg +dXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBh +dWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIg +ZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkg +ZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVu +dHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1l +dHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZv +bHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBs +ZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5p +c2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZl +bGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMg +aWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1 +cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0 +IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVn +ZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1v +ZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2 +ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2Vt +cGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlz +IGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRl +bXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0g +c2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2 +YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4g +dHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNz +ZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1 +bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1 +cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1 +c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVz +ZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIs +IG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0 +IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVs +bGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxh +Y3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwg +bW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVu +dGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVz +IHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4g +TWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNp +IG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29u +dmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3Ig +cGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNs +IHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxp +c2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2Eg +ZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJh +Yml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRh +ZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxp +dCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGll +biwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQs +IGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNj +aXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0 +b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29u +ZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWdu +YS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlx +dWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJj +dSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBR +dWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2 +ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25l +YyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBj +b25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRp +cywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Ig +b3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBs +b3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNt +b2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1 +cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGlu +LiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwg +cGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyBy +aXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1h +ZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNl +ZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQg +dmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5k +aXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEs +IG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1 +dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVn +ZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5h +dGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3Jl +ZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQg +YWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQg +c29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0 +dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhp +Y3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1 +cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBl +dSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBh +YyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1l +dHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUs +IG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQs +IGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUg +bWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVu +aW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVz +IGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2Vz +IHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29u +Z3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0 +dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNh +cGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0 +LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5j +IHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVp +IHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBp +YWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxh +bmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3Nh +IG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3Iu +IE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBj +b252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBh +dCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1h +ZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMg +YWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVp +c3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5p +c2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0 +IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBh +IHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3Qs +IGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFl +LCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUg +dmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBv +cnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVj +ZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBE +dWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBl +cmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2 +ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1 +dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJt +ZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVy +dXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVl +IHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBp +cHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQs +IGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJp +Y2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBs +b2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0 +YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxl +bnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwg +ZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1 +cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlz +IHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFy +Y3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVh +biBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhh +c2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBj +b25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoK +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wg +cmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFt +IGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3Is +IG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1 +c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQu +IFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4g +QWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lz +LCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1 +bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVp +IG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRh +IHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBz +ZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3Vz +Y2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1 +Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2Nl +IGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRl +bXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3Ji +aSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVp +cyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2ls +aXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUg +bGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2Nl +IGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJv +cyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0 +cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5k +dW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1l +dCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVt +IGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhh +cmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1 +cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVu +dHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGln +dWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMs +IGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJp +cyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1 +cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1 +bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBk +YXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFz +IGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1h +ZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVs +dW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNp +bGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4g +TmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2Ug +YWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBt +aS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVz +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVu +YyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1w +b3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBm +YWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3Ig +YXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBF +dGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5p +YSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVz +dCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xl +c3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50 +IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBv +cnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRp +cyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMg +bW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMg +bGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2 +dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxp +Y2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1 +ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBx +dWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlv +LiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxh +IHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1w +ZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIg +aWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBV +dCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxs +YSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0g +c29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0 +aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlw +c3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0 +LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1w +ZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQ +cmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUu +IEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4g +RnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFs +aXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3Vl +IGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8g +YSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRp +cyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVu +dCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMu +IE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFj +dXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVl +dCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2ku +IEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3Us +IHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lk +dW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBq +dXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1 +ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4g +b3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZh +bXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBD +dXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywg +bnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMg +YWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBw +b3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBp +ZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMg +bWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGli +dXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4g +Vml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4g +TnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBt +ZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0 +IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRh +IGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVu +aW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBv +c3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24g +ZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBN +b3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2 +ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2lu +IHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxl +bWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWku +IFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVz +IGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5p +YmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxs +ZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERv +bmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9z +IHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1 +c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNx +dWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1 +Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJh +ZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlz +LiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQg +YWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQg +bWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVz +IHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdl +dCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFBy +YWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBG +dXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1 +cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4g +Q3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1 +cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25l +YyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlx +dWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50 +IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNv +bW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0 +IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVs +ZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQg +ZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBn +cmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBl +Z2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJp +cyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5h +IGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUg +cG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVj +aWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1 +bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxh +Y3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRl +bGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1 +dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1 +Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlx +dWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBt +b2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1 +c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMg +cHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0 +dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9k +IG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFt +ZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQg +bmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVs +dHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1 +cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlh +IGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVy +YXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBz +b2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEg +dGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxh +Y3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRh +dGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEg +bG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZp +dGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0g +bnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1 +ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBl +bGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxh +IGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUs +IG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFi +aXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVu +ZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVy +bmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0 +IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVy +YXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwg +ZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEg +bnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFj +aW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQg +bWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVh +bSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBl +Z2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3Bl +bmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBE +dWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBF +dGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZl +bGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVy +dXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQg +YW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRp +cGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBo +ZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJo +LiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQg +bnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9y +ZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVh +bSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBs +dWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhl +bmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFs +aXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25l +YyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJp +c3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVn +ZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4g +ZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVk +ZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUg +YWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRp +dG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIElu +dGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3Vs +YSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0 +cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25z +ZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4g +U3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlz +LiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBt +YXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhv +bmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVs +bGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3Ig +ZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0 +dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBl +cmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBh +YyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1 +IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5p +YSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxl +bnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBt +ZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBl +ZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNl +cXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJp +Y2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xv +ci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRl +bXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBl +dCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWdu +YSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBk +dWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBl +cm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxp +cy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4g +TWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50 +ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9u +IHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25z +ZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMg +YXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGlu +Y2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVz +ZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3Rp +YnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVu +ZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVk +ZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBx +dWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUu +IE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3Rl +dHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlz +bCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNz +YS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlz +IHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmlu +YXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5v +biBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmlt +LCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0 +aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxl +bnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlw +c3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBz +b2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlz +bW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1 +cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdl +dCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5v +biBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1 +Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUg +dXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRp +ZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVy +IHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZl +bGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGlj +aXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0g +bmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlz +IG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3Rh +cyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50 +IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUg +ZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1h +dXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2 +ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1v +ZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBk +aWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0 +dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNj +aXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0g +YWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUg +bmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3Jw +ZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCklu +IHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGln +bmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0 +IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2Rp +byBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFy +Y3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxs +ZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1 +cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVz +dCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9y +dGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0 +aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBm +YXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVj +IHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBh +IGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVy +bmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVs +LCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVt +LiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwg +ZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBo +YXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQg +YW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJk +aWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBk +b2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFl +c2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMs +IHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2 +ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8g +YWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJt +ZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4g +VXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVs +aXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxh +bmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1 +aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50 +IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJs +YW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50 +dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1v +cmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNp +ZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBk +aWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xl +c3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIg +YW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFj +LCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRy +dW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3Qg +ZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRy +ZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCBy +aXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29s +bGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxs +ZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9z +IHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0 +IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFz +IHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNl +ZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFs +aXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUg +YSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxp +dC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0 +IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFy +aXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBt +aS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlz +IHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFt +IHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlz +aSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1 +cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZl +bGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBp +biwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWku +IEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNp +ZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0 +IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0 +aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4g +UGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpO +dWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVl +IGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxh +Y3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVx +dWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBh +bGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxh +IG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBx +dWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8s +IHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24s +IG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmli +aCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVu +ZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFi +aXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3Jl +bSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVx +dWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVj +dG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFu +dGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEg +ZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4g +UHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNh +Z2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxp +Y2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1 +aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5p +bSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1 +dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRl +bGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rp +by4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9y +dG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4s +IHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVz +dG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5h +ci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRp +c3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBv +cm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11 +cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29k +YWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBh +YyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxh +LCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8u +IER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNl +ZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRl +LCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNp +bmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlz +IHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3Ug +ZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFt +LiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNv +bW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVz +dC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4g +UHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVs +bGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBs +ZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBp +biBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVz +dGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFs +bGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3Jh +dmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVy +IGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJp +c3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3Vs +YS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBp +c2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0 +aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVz +IHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3Nh +IG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMg +bm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVy +IG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBl +dSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBs +ZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBk +aWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRv +bG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNp +dCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIElu +dGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0 +IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRl +cmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFs +bGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8s +IG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25h +IHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkg +dGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEu +IEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVl +dCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVn +aWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3Vz +LiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQ +cmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQg +bGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxl +bWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBv +cm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxl +bywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVz +dC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1 +bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBB +bGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9z +dWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNz +YSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2Vz +IG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNl +cyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0 +aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMg +ZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jh +dmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNp +IHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0 +b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGll +LiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2 +aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVt +LCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFj +dXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlh +bSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBh +ZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBN +YXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVu +dGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBw +b3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1 +bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNp +ZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZl +cm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVz +IGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVh +biB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlh +bSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENy +YXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0 +dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxl +bnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUg +bG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMg +ZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0 +YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBw +b3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEu +IFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBh +bWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0g +bm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBw +b3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0 +ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1 +ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMg +c2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBm +cmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMg +dXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVz +cXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29u +ZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBh +ZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2Fn +aXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBs +YWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2lt +IHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBw +bGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlz +IHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUu +IE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4g +TWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1w +dXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxh +Y2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBu +b24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIElu +IGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMg +dml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1 +cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZl +c3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4g +U2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFz +IHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxs +YSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1 +cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBD +dXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1 +bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVz +IGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1 +bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBq +dXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1 +cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVy +aXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVj +IHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4g +U2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1 +cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFs +aXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVz +LiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBt +YXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2Vt +LiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEs +IGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBu +b24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlz +IHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1 +cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0 +IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50 +dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1 +bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQg +bWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21t +b2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50 +ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmlj +ZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmli +ZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBw +bGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBh +bGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQg +ZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9s +bGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1 +bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFu +dGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVz +LCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVt +IGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNp +dCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0u +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyBy +aG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBh +Y2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51 +bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3Np +bSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0 +aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoK +TnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGlu +Y2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNv +bGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMg +aWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNl +ZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyBy +aXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2 +ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFt +ZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGli +dWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3Vt +IGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBu +b24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBj +dXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9y +Y2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwg +c29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZh +dWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1 +bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBs +YWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBp +cHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4g +QWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1 +bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xs +aXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxs +YW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3Rp +YnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jhdmlk +YSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2Vs +ZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5j +LiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4g +TnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0 +ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1 +bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2 +YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxl +bWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRp +cy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMg +aW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWws +IHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2Ug +cXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxp +cyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJh +ZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlv +IG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUg +c2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxh +bSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4g +QWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5p +c2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVk +ZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2lu +ZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVs +dW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVu +dGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1 +cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNz +YS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVs +bGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4K +ClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEg +YXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQg +dGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVz +LiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1 +cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMg +aW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xs +aXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBj +b25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5l +bmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUg +ZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jh +dmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQ +cm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJp +cy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBO +dWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBs +ZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8g +bm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBl +dCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNp +bmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51 +bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVt +IGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0 +cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNl +ZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBk +YXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0 +dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJp +Y2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0 +ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGlj +aXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1 +cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBl +cmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwg +dmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBj +b25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQg +dXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBh +dWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIg +ZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkg +ZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVu +dHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1l +dHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZv +bHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBs +ZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5p +c2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZl +bGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMg +aWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1 +cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0 +IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVn +ZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1v +ZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2 +ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2Vt +cGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlz +IGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRl +bXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0g +c2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2 +YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4g +dHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNz +ZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1 +bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1 +cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1 +c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVz +ZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIs +IG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0 +IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVs +bGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxh +Y3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwg +bW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVu +dGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVz +IHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4g +TWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNp +IG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29u +dmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3Ig +cGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNs +IHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxp +c2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2Eg +ZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJh +Yml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRh +ZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxp +dCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGll +biwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQs +IGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNj +aXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0 +b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29u +ZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWdu +YS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlx +dWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJj +dSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBR +dWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2 +ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25l +YyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBj +b25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRp +cywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Ig +b3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBs +b3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNt +b2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1 +cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGlu +LiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwg +cGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyBy +aXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1h +ZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNl +ZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQg +dmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5k +aXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEs +IG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1 +dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVn +ZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5h +dGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3Jl +ZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQg +YWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQg +c29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0 +dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhp +Y3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1 +cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBl +dSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBh +YyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1l +dHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUs +IG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQs +IGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUg +bWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVu +aW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVz +IGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2Vz +IHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29u +Z3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0 +dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNh +cGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0 +LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5j +IHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVp +IHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBp +YWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxh +bmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3Nh +IG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3Iu +IE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBj +b252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBh +dCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1h +ZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMg +YWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVp +c3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5p +c2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0 +IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBh +IHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3Qs +IGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFl +LCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUg +dmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBv +cnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVj +ZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBE +dWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBl +cmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2 +ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1 +dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJt +ZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVy +dXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVl +IHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBp +cHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQs +IGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJp +Y2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBs +b2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0 +YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxl +bnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwg +ZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1 +cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlz +IHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFy +Y3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVh +biBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhh +c2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBj +b25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoK +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wg +cmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFt +IGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3Is +IG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1 +c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQu +IFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4g +QWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lz +LCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1 +bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVp +IG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRh +IHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBz +ZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3Vz +Y2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1 +Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2Nl +IGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRl +bXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3Ji +aSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVp +cyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2ls +aXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUg +bGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2Nl +IGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJv +cyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0 +cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5k +dW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1l +dCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVt +IGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhh +cmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1 +cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVu +dHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGln +dWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMs +IGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJp +cyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1 +cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1 +bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBk +YXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFz +IGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1h +ZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVs +dW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNp +bGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4g +TmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2Ug +YWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBt +aS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVz +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVu +YyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1w +b3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBm +YWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3Ig +YXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBF +dGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5p +YSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVz +dCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xl +c3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50 +IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBv +cnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRp +cyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMg +bW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMg +bGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2 +dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxp +Y2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1 +ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBx +dWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlv +LiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxh +IHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1w +ZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIg +aWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBV +dCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxs +YSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0g +c29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0 +aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlw +c3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0 +LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1w +ZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQ +cmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUu +IEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4g +RnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFs +aXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3Vl +IGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8g +YSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRp +cyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVu +dCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMu +IE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFj +dXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVl +dCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2ku +IEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3Us +IHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lk +dW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBq +dXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1 +ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4g +b3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZh +bXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBD +dXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywg +bnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMg +YWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBw +b3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBp +ZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMg +bWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGli +dXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4g +Vml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4g +TnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBt +ZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0 +IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRh +IGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVu +aW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBv +c3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24g +ZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBN +b3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2 +ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2lu +IHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxl +bWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWku +IFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVz +IGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5p +YmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxs +ZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERv +bmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9z +IHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1 +c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNx +dWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1 +Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJh +ZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlz +LiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQg +YWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQg +bWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVz +IHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdl +dCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFBy +YWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBG +dXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1 +cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4g +Q3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1 +cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25l +YyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlx +dWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50 +IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNv +bW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0 +IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVs +ZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQg +ZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBn +cmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBl +Z2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJp +cyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5h +IGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUg +cG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVj +aWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1 +bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxh +Y3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRl +bGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1 +dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1 +Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlx +dWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBt +b2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1 +c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMg +cHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0 +dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9k +IG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFt +ZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQg +bmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVs +dHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1 +cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlh +IGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVy +YXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBz +b2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEg +dGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxh +Y3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRh +dGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEg +bG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZp +dGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0g +bnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1 +ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBl +bGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxh +IGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUs +IG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFi +aXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVu +ZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVy +bmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0 +IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVy +YXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwg +ZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEg +bnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFj +aW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQg +bWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVh +bSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBl +Z2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3Bl +bmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBE +dWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBF +dGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZl +bGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVy +dXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQg +YW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRp +cGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBo +ZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJo +LiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQg +bnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9y +ZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVh +bSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBs +dWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhl +bmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFs +aXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25l +YyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJp +c3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVn +ZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4g +ZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVk +ZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUg +YWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRp +dG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIElu +dGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3Vs +YSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0 +cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25z +ZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4g +U3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlz +LiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBt +YXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhv +bmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVs +bGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3Ig +ZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0 +dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBl +cmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBh +YyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1 +IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5p +YSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxl +bnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBt +ZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBl +ZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNl +cXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJp +Y2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xv +ci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRl +bXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBl +dCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWdu +YSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBk +dWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBl +cm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxp +cy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4g +TWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50 +ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9u +IHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25z +ZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMg +YXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGlu +Y2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVz +ZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3Rp +YnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVu +ZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVk +ZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBx +dWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUu +IE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3Rl +dHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlz +bCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNz +YS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlz +IHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmlu +YXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5v +biBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmlt +LCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0 +aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxl +bnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlw +c3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBz +b2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlz +bW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1 +cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdl +dCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5v +biBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1 +Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUg +dXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRp +ZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVy +IHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZl +bGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGlj +aXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0g +bmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlz +IG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3Rh +cyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50 +IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUg +ZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1h +dXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2 +ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1v +ZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBk +aWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0 +dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNj +aXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0g +YWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUg +bmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3Jw +ZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCklu +IHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGln +bmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0 +IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2Rp +byBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFy +Y3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxs +ZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1 +cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVz +dCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9y +dGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0 +aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBm +YXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVj +IHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBh +IGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVy +bmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVs +LCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVt +LiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwg +ZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBo +YXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQg +YW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJk +aWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBk +b2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFl +c2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMs +IHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2 +ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8g +YWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJt +ZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4g +VXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVs +aXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxh +bmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1 +aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50 +IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJs +YW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50 +dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1v +cmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNp +ZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBk +aWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xl +c3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIg +YW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFj +LCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRy +dW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3Qg +ZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRy +ZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCBy +aXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29s +bGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxs +ZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9z +IHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0 +IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFz +IHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNl +ZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFs +aXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUg +YSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxp +dC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0 +IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFy +aXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBt +aS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlz +IHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFt +IHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlz +aSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1 +cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZl +bGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBp +biwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWku +IEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNp +ZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0 +IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0 +aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4g +UGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpO +dWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVl +IGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxh +Y3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVx +dWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBh +bGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxh +IG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBx +dWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8s +IHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24s +IG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmli +aCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVu +ZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFi +aXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3Jl +bSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVx +dWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVj +dG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFu +dGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEg +ZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4g +UHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNh +Z2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxp +Y2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1 +aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5p +bSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1 +dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRl +bGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rp +by4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9y +dG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4s +IHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVz +dG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5h +ci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRp +c3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBv +cm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11 +cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29k +YWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBh +YyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxh +LCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8u +IER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNl +ZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRl +LCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNp +bmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlz +IHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3Ug +ZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFt +LiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNv +bW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVz +dC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4g +UHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVs +bGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBs +ZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBp +biBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVz +dGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFs +bGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3Jh +dmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVy +IGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJp +c3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3Vs +YS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBp +c2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0 +aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVz +IHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3Nh +IG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMg +bm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVy +IG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBl +dSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBs +ZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBk +aWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRv +bG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNp +dCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIElu +dGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0 +IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRl +cmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFs +bGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8s +IG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25h +IHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkg +dGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEu +IEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVl +dCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVn +aWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3Vz +LiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQ +cmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQg +bGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxl +bWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBv +cm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxl +bywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVz +dC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1 +bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBB +bGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9z +dWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNz +YSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2Vz +IG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNl +cyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0 +aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMg +ZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jh +dmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNp +IHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0 +b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGll +LiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2 +aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVt +LCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFj +dXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlh +bSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBh +ZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBN +YXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVu +dGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBw +b3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1 +bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNp +ZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZl +cm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVz +IGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVh +biB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlh +bSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENy +YXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0 +dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxl +bnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUg +bG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMg +ZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0 +YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBw +b3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEu +IFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBh +bWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0g +bm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBw +b3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0 +ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1 +ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMg +c2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBm +cmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMg +dXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVz +cXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29u +ZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBh +ZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2Fn +aXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBs +YWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2lt +IHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBw +bGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlz +IHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUu +IE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4g +TWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1w +dXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxh +Y2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBu +b24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIElu +IGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMg +dml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1 +cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZl +c3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4g +U2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFz +IHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxs +YSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1 +cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBD +dXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1 +bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVz +IGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1 +bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBq +dXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1 +cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVy +aXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVj +IHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4g +U2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1 +cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFs +aXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVz +LiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBt +YXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2Vt +LiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEs +IGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBu +b24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlz +IHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1 +cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0 +IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50 +dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1 +bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQg +bWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21t +b2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50 +ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmlj +ZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmli +ZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBw +bGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBh +bGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQg +ZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9s +bGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1 +bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFu +dGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVz +LCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVt +IGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNp +dCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0u +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyBy +aG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBh +Y2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51 +bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3Np +bSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0 +aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoK +TnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGlu +Y2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNv +bGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMg +aWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNl +ZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyBy +aXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2 +ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFt +ZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGli +dWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3Vt +IGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBu +b24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBj +dXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9y +Y2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwg +c29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZh +dWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1 +bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBs +YWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBp +cHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4g +QWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1 +bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xs +aXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxs +YW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3Rp +YnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jhdmlk +YSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2Vs +ZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5j +LiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4g +TnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0 +ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1 +bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2 +YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxl +bWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRp +cy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMg +aW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWws +IHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2Ug +cXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxp +cyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJh +ZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlv +IG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUg +c2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxh +bSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4g +QWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5p +c2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVk +ZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2lu +ZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVs +dW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVu +dGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1 +cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNz +YS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVs +bGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4K +ClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEg +YXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQg +dGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVz +LiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1 +cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMg +aW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xs +aXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBj +b25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5l +bmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUg +ZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jh +dmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQ +cm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJp +cy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBO +dWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBs +ZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8g +bm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBl +dCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNp +bmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51 +bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVt +IGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0 +cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNl +ZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBk +YXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0 +dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJp +Y2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0 +ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGlj +aXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1 +cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBl +cmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwg +dmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBj +b25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQg +dXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBh +dWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIg +ZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkg +ZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVu +dHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1l +dHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZv +bHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBs +ZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5p +c2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZl +bGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMg +aWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1 +cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0 +IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVn +ZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1v +ZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2 +ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2Vt +cGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlz +IGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRl +bXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0g +c2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2 +YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4g +dHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNz +ZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1 +bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1 +cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1 +c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVz +ZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIs +IG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0 +IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVs +bGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxh +Y3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwg +bW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVu +dGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVz +IHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4g +TWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNp +IG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29u +dmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3Ig +cGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNs +IHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxp +c2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2Eg +ZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJh +Yml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRh +ZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxp +dCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGll +biwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQs +IGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNj +aXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0 +b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29u +ZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWdu +YS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlx +dWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJj +dSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBR +dWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2 +ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25l +YyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBj +b25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRp +cywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Ig +b3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBs +b3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNt +b2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1 +cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGlu +LiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwg +cGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyBy +aXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1h +ZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNl +ZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQg +dmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5k +aXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEs +IG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1 +dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVn +ZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5h +dGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3Jl +ZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQg +YWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQg +c29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0 +dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhp +Y3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1 +cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBl +dSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBh +YyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1l +dHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUs +IG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQs +IGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUg +bWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVu +aW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVz +IGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2Vz +IHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29u +Z3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0 +dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNh +cGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0 +LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5j +IHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVp +IHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBp +YWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxh +bmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3Nh +IG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3Iu +IE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBj +b252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBh +dCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1h +ZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMg +YWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVp +c3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5p +c2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0 +IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBh +IHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3Qs +IGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFl +LCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUg +dmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBv +cnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVj +ZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBE +dWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBl +cmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2 +ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1 +dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJt +ZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVy +dXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVl +IHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBp +cHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQs +IGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJp +Y2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBs +b2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0 +YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxl +bnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwg +ZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1 +cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlz +IHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFy +Y3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVh +biBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhh +c2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBj +b25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoK +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wg +cmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFt +IGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3Is +IG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1 +c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQu +IFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4g +QWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lz +LCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1 +bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVp +IG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRh +IHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBz +ZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3Vz +Y2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1 +Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2Nl +IGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRl +bXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3Ji +aSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVp +cyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2ls +aXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUg +bGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2Nl +IGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJv +cyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0 +cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5k +dW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1l +dCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVt +IGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhh +cmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1 +cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVu +dHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGln +dWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMs +IGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJp +cyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1 +cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1 +bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBk +YXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFz +IGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1h +ZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVs +dW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNp +bGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4g +TmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2Ug +YWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBt +aS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVz +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVu +YyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1w +b3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBm +YWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3Ig +YXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBF +dGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5p +YSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVz +dCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xl +c3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50 +IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBv +cnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRp +cyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMg +bW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMg +bGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2 +dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxp +Y2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1 +ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBx +dWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlv +LiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxh +IHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1w +ZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIg +aWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBV +dCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxs +YSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0g +c29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0 +aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlw +c3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0 +LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1w +ZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQ +cmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUu +IEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4g +RnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFs +aXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3Vl +IGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8g +YSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRp +cyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVu +dCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMu +IE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFj +dXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVl +dCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2ku +IEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3Us +IHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lk +dW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBq +dXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1 +ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4g +b3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZh +bXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBD +dXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywg +bnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMg +YWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBw +b3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBp +ZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMg +bWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGli +dXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4g +Vml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4g +TnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBt +ZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0 +IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRh +IGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVu +aW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBv +c3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24g +ZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBN +b3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2 +ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2lu +IHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxl +bWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWku +IFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVz +IGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5p +YmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxs +ZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERv +bmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9z +IHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1 +c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNx +dWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1 +Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJh +ZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlz +LiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQg +YWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQg +bWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVz +IHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdl +dCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFBy +YWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBG +dXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1 +cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4g +Q3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1 +cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25l +YyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlx +dWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50 +IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNv +bW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0 +IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVs +ZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQg +ZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBn +cmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBl +Z2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJp +cyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5h +IGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUg +cG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVj +aWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1 +bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxh +Y3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRl +bGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1 +dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1 +Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlx +dWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBt +b2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1 +c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMg +cHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0 +dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9k +IG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFt +ZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQg +bmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVs +dHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1 +cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlh +IGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVy +YXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBz +b2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEg +dGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxh +Y3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRh +dGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEg +bG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZp +dGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0g +bnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1 +ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBl +bGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxh +IGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUs +IG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFi +aXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVu +ZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVy +bmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0 +IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVy +YXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwg +ZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEg +bnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFj +aW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQg +bWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVh +bSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBl +Z2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3Bl +bmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBE +dWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBF +dGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZl +bGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVy +dXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQg +YW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRp +cGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBo +ZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJo +LiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQg +bnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9y +ZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVh +bSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBs +dWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhl +bmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFs +aXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25l +YyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJp +c3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVn +ZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4g +ZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVk +ZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUg +YWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRp +dG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIElu +dGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3Vs +YSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0 +cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25z +ZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4g +U3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlz +LiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBt +YXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhv +bmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVs +bGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3Ig +ZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0 +dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBl +cmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBh +YyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1 +IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5p +YSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxl +bnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBt +ZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBl +ZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNl +cXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJp +Y2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xv +ci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRl +bXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBl +dCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWdu +YSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBk +dWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBl +cm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxp +cy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4g +TWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50 +ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9u +IHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25z +ZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMg +YXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGlu +Y2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVz +ZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3Rp +YnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVu +ZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVk +ZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBx +dWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUu +IE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3Rl +dHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlz +bCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNz +YS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlz +IHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmlu +YXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5v +biBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmlt +LCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0 +aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxl +bnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlw +c3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBz +b2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlz +bW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1 +cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdl +dCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5v +biBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1 +Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUg +dXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRp +ZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVy +IHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZl +bGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGlj +aXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0g +bmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlz +IG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3Rh +cyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50 +IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUg +ZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1h +dXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2 +ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1v +ZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBk +aWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0 +dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNj +aXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0g +YWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUg +bmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3Jw +ZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCklu +IHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGln +bmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0 +IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2Rp +byBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFy +Y3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxs +ZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1 +cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVz +dCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9y +dGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0 +aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBm +YXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVj +IHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBh +IGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVy +bmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVs +LCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVt +LiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwg +ZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBo +YXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQg +YW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJk +aWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBk +b2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFl +c2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMs +IHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2 +ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8g +YWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJt +ZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4g +VXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVs +aXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxh +bmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1 +aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50 +IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJs +YW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50 +dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1v +cmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNp +ZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBk +aWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xl +c3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIg +YW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFj +LCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRy +dW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3Qg +ZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRy +ZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCBy +aXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29s +bGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxs +ZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9z +IHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0 +IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFz +IHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNl +ZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFs +aXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUg +YSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxp +dC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0 +IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFy +aXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBt +aS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlz +IHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFt +IHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlz +aSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1 +cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZl +bGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBp +biwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWku +IEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNp +ZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0 +IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0 +aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4g +UGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpO +dWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVl +IGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxh +Y3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVx +dWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBh +bGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxh +IG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBx +dWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8s +IHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24s +IG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmli +aCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVu +ZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFi +aXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3Jl +bSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVx +dWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVj +dG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFu +dGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEg +ZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4g +UHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNh +Z2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxp +Y2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1 +aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5p +bSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1 +dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRl +bGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rp +by4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9y +dG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4s +IHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVz +dG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5h +ci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRp +c3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBv +cm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11 +cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29k +YWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBh +YyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxh +LCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8u +IER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNl +ZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRl +LCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNp +bmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlz +IHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3Ug +ZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFt +LiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNv +bW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVz +dC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4g +UHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVs +bGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBs +ZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBp +biBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVz +dGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFs +bGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3Jh +dmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVy +IGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJp +c3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3Vs +YS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBp +c2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0 +aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVz +IHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3Nh +IG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMg +bm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVy +IG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBl +dSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBs +ZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBk +aWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRv +bG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNp +dCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIElu +dGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0 +IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRl +cmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFs +bGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8s +IG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25h +IHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkg +dGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEu +IEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVl +dCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVn +aWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3Vz +LiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQ +cmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQg +bGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxl +bWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBv +cm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxl +bywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVz +dC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1 +bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBB +bGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9z +dWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNz +YSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2Vz +IG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNl +cyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0 +aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMg +ZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jh +dmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNp +IHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0 +b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGll +LiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2 +aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVt +LCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFj +dXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlh +bSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBh +ZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBN +YXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVu +dGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBw +b3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1 +bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNp +ZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZl +cm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVz +IGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVh +biB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlh +bSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENy +YXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0 +dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxl +bnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUg +bG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMg +ZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0 +YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBw +b3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEu +IFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBh +bWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0g +bm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBw +b3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0 +ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1 +ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMg +c2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBm +cmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMg +dXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVz +cXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29u +ZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBh +ZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2Fn +aXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBs +YWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2lt +IHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBw +bGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlz +IHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUu +IE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4g +TWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1w +dXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxh +Y2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBu +b24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIElu +IGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMg +dml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1 +cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZl +c3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4g +U2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFz +IHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxs +YSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1 +cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBD +dXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1 +bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVz +IGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1 +bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBq +dXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1 +cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVy +aXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVj +IHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4g +U2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1 +cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFs +aXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVz +LiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBt +YXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2Vt +LiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEs +IGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBu +b24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlz +IHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1 +cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0 +IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50 +dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1 +bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQg +bWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21t +b2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50 +ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmlj +ZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmli +ZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBw +bGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBh +bGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQg +ZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9s +bGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1 +bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFu +dGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVz +LCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVt +IGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNp +dCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0u +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyBy +aG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBh +Y2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51 +bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3Np +bSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0 +aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoK +TnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGlu +Y2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNv +bGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMg +aWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNl +ZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyBy +aXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2 +ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFt +ZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGli +dWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3Vt +IGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBu +b24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBj +dXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9y +Y2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwg +c29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZh +dWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1 +bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBs +YWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBp +cHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4g +QWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1 +bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xs +aXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxs +YW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3Rp +YnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jhdmlk +YSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2Vs +ZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5j +LiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4g +TnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0 +ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1 +bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2 +YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxl +bWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRp +cy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMg +aW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWws +IHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2Ug +cXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxp +cyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJh +ZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlv +IG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUg +c2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxh +bSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4g +QWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5p +c2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVk +ZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2lu +ZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVs +dW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVu +dGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1 +cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNz +YS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVs +bGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4K +ClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEg +YXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQg +dGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVz +LiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1 +cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMg +aW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xs +aXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBj +b25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5l +bmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUg +ZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jh +dmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQ +cm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJp +cy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBO +dWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBs +ZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8g +bm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBl +dCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNp +bmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51 +bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVt +IGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0 +cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNl +ZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBk +YXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0 +dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJp +Y2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0 +ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGlj +aXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1 +cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBl +cmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwg +dmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBj +b25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQg +dXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBh +dWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIg +ZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkg +ZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVu +dHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1l +dHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZv +bHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBs +ZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5p +c2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZl +bGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMg +aWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1 +cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0 +IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVn +ZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1v +ZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2 +ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2Vt +cGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlz +IGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRl +bXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0g +c2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2 +YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4g +dHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNz +ZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1 +bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1 +cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1 +c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVz +ZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIs +IG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0 +IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVs +bGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxh +Y3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwg +bW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVu +dGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVz +IHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4g +TWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNp +IG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29u +dmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3Ig +cGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNs +IHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxp +c2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2Eg +ZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJh +Yml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRh +ZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxp +dCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGll +biwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQs +IGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNj +aXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0 +b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29u +ZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWdu +YS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlx +dWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJj +dSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBR +dWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2 +ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25l +YyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBj +b25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRp +cywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Ig +b3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBs +b3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNt +b2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1 +cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGlu +LiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwg +cGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyBy +aXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1h +ZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNl +ZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQg +dmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5k +aXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEs +IG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1 +dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVn +ZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5h +dGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3Jl +ZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQg +YWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQg +c29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0 +dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhp +Y3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1 +cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBl +dSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBh +YyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1l +dHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUs +IG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQs +IGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUg +bWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVu +aW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVz +IGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2Vz +IHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29u +Z3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0 +dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNh +cGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0 +LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5j +IHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVp +IHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBp +YWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxh +bmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3Nh +IG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3Iu +IE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBj +b252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBh +dCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1h +ZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMg +YWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVp +c3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5p +c2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0 +IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBh +IHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3Qs +IGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFl +LCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUg +dmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBv +cnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVj +ZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBE +dWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBl +cmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2 +ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1 +dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJt +ZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVy +dXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVl +IHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBp +cHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQs +IGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJp +Y2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBs +b2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0 +YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxl +bnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwg +ZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1 +cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlz +IHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFy +Y3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVh +biBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhh +c2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBj +b25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoK +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wg +cmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFt +IGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3Is +IG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1 +c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQu +IFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4g +QWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lz +LCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1 +bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVp +IG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRh +IHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBz +ZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3Vz +Y2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1 +Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2Nl +IGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRl +bXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3Ji +aSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVp +cyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2ls +aXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUg +bGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2Nl +IGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJv +cyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0 +cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5k +dW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1l +dCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVt +IGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhh +cmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1 +cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVu +dHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGln +dWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMs +IGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJp +cyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1 +cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1 +bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBk +YXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFz +IGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1h +ZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVs +dW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNp +bGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4g +TmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2Ug +YWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBt +aS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVz +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVu +YyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1w +b3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBm +YWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3Ig +YXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBF +dGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5p +YSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVz +dCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xl +c3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50 +IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBv +cnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRp +cyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMg +bW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMg +bGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2 +dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxp +Y2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1 +ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBx +dWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlv +LiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxh +IHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1w +ZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIg +aWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBV +dCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxs +YSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0g +c29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0 +aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlw +c3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0 +LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1w +ZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQ +cmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUu +IEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4g +RnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFs +aXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3Vl +IGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8g +YSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRp +cyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVu +dCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMu +IE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFj +dXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVl +dCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2ku +IEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3Us +IHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lk +dW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBq +dXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1 +ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4g +b3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZh +bXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBD +dXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywg +bnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMg +YWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBw +b3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBp +ZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMg +bWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGli +dXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4g +Vml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4g +TnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBt +ZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0 +IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRh +IGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVu +aW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBv +c3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24g +ZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBN +b3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2 +ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2lu +IHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxl +bWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWku +IFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVz +IGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5p +YmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxs +ZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERv +bmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9z +IHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1 +c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNx +dWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1 +Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJh +ZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlz +LiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQg +YWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQg +bWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVz +IHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdl +dCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFBy +YWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBG +dXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1 +cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4g +Q3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1 +cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25l +YyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlx +dWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50 +IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNv +bW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0 +IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVs +ZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQg +ZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBn +cmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBl +Z2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJp +cyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5h +IGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUg +cG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVj +aWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1 +bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxh +Y3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRl +bGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1 +dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1 +Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlx +dWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBt +b2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1 +c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMg +cHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0 +dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9k +IG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFt +ZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQg +bmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVs +dHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1 +cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlh +IGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVy +YXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBz +b2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEg +dGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxh +Y3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRh +dGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEg +bG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZp +dGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0g +bnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1 +ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBl +bGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxh +IGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUs +IG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFi +aXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVu +ZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVy +bmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0 +IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVy +YXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwg +ZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEg +bnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFj +aW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQg +bWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVh +bSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBl +Z2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3Bl +bmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBE +dWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBF +dGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZl +bGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVy +dXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQg +YW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRp +cGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBo +ZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJo +LiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQg +bnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9y +ZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVh +bSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBs +dWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhl +bmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFs +aXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25l +YyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJp +c3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVn +ZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4g +ZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVk +ZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUg +YWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRp +dG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIElu +dGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3Vs +YSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0 +cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25z +ZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4g +U3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlz +LiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBt +YXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhv +bmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVs +bGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3Ig +ZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0 +dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBl +cmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBh +YyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1 +IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5p +YSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxl +bnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBt +ZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBl +ZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNl +cXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJp +Y2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xv +ci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRl +bXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBl +dCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWdu +YSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBk +dWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBl +cm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxp +cy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4g +TWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50 +ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9u +IHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25z +ZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMg +YXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGlu +Y2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVz +ZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3Rp +YnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVu +ZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVk +ZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBx +dWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUu +IE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3Rl +dHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlz +bCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNz +YS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlz +IHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmlu +YXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5v +biBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmlt +LCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0 +aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxl +bnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlw +c3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBz +b2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlz +bW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1 +cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdl +dCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5v +biBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1 +Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUg +dXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRp +ZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVy +IHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZl +bGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGlj +aXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0g +bmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlz +IG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3Rh +cyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50 +IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUg +ZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1h +dXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2 +ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1v +ZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBk +aWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0 +dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNj +aXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0g +YWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUg +bmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3Jw +ZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCklu +IHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGln +bmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0 +IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2Rp +byBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFy +Y3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxs +ZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1 +cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVz +dCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9y +dGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0 +aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBm +YXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVj +IHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBh +IGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVy +bmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVs +LCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVt +LiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwg +ZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBo +YXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQg +YW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJk +aWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBk +b2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFl +c2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMs +IHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2 +ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8g +YWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJt +ZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4g +VXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVs +aXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxh +bmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1 +aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50 +IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJs +YW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50 +dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1v +cmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNp +ZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBk +aWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xl +c3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIg +YW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFj +LCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRy +dW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3Qg +ZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRy +ZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCBy +aXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29s +bGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxs +ZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9z +IHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0 +IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFz +IHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNl +ZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFs +aXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUg +YSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxp +dC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0 +IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFy +aXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBt +aS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlz +IHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFt +IHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlz +aSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1 +cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZl +bGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBp +biwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWku +IEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNp +ZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0 +IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0 +aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4g +UGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpO +dWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVl +IGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxh +Y3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVx +dWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBh +bGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxh +IG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBx +dWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8s +IHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24s +IG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmli +aCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVu +ZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFi +aXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3Jl +bSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVx +dWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVj +dG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFu +dGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEg +ZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4g +UHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNh +Z2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxp +Y2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1 +aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5p +bSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1 +dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRl +bGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rp +by4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9y +dG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4s +IHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVz +dG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5h +ci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRp +c3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBv +cm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11 +cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29k +YWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBh +YyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxh +LCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8u +IER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNl +ZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRl +LCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNp +bmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlz +IHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3Ug +ZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFt +LiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNv +bW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVz +dC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4g +UHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVs +bGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBs +ZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBp +biBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVz +dGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFs +bGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3Jh +dmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVy +IGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJp +c3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3Vs +YS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBp +c2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0 +aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVz +IHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3Nh +IG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMg +bm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVy +IG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBl +dSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBs +ZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBk +aWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRv +bG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNp +dCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIElu +dGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0 +IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRl +cmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFs +bGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8s +IG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25h +IHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkg +dGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEu +IEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVl +dCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVn +aWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3Vz +LiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQ +cmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQg +bGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxl +bWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBv +cm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxl +bywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVz +dC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1 +bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBB +bGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9z +dWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNz +YSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2Vz +IG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNl +cyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0 +aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMg +ZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jh +dmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNp +IHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0 +b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGll +LiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2 +aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVt +LCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFj +dXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlh +bSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBh +ZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBN +YXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVu +dGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBw +b3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1 +bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNp +ZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZl +cm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVz +IGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVh +biB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlh +bSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENy +YXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0 +dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxl +bnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUg +bG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMg +ZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0 +YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBw +b3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEu +IFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBh +bWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0g +bm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBw +b3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0 +ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1 +ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMg +c2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBm +cmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMg +dXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVz +cXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29u +ZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBh +ZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2Fn +aXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBs +YWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2lt +IHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBw +bGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlz +IHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUu +IE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4g +TWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1w +dXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxh +Y2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBu +b24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIElu +IGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMg +dml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1 +cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZl +c3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4g +U2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFz +IHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxs +YSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1 +cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBD +dXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1 +bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVz +IGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1 +bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBq +dXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1 +cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVy +aXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVj +IHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4g +U2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1 +cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFs +aXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVz +LiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBt +YXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2Vt +LiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEs +IGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBu +b24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlz +IHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1 +cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0 +IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50 +dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1 +bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQg +bWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21t +b2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50 +ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmlj +ZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmli +ZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBw +bGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBh +bGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQg +ZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9s +bGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1 +bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFu +dGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVz +LCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVt +IGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNp +dCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0u +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyBy +aG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBh +Y2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51 +bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3Np +bSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0 +aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoK +TnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGlu +Y2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNv +bGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMg +aWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNl +ZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyBy +aXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2 +ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFt +ZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGli +dWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3Vt +IGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBu +b24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBj +dXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9y +Y2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwg +c29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZh +dWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1 +bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBs +YWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBp +cHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4g +QWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1 +bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xs +aXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxs +YW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3Rp +YnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jhdmlk +YSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2Vs +ZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5j +LiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4g +TnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0 +ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1 +bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2 +YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxl +bWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRp +cy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMg +aW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWws +IHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2Ug +cXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxp +cyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJh +ZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlv +IG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUg +c2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxh +bSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4g +QWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5p +c2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVk +ZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2lu +ZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVs +dW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVu +dGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1 +cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNz +YS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVs +bGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4K +ClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEg +YXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQg +dGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVz +LiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1 +cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMg +aW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xs +aXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBj +b25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5l +bmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUg +ZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jh +dmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQ +cm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJp +cy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBO +dWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBs +ZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8g +bm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBl +dCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNp +bmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51 +bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVt +IGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0 +cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNl +ZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBk +YXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0 +dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJp +Y2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0 +ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGlj +aXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1 +cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBl +cmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwg +dmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBj +b25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQg +dXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBh +dWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIg +ZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkg +ZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVu +dHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1l +dHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZv +bHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBs +ZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5p +c2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZl +bGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMg +aWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1 +cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0 +IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVn +ZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1v +ZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2 +ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2Vt +cGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlz +IGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRl +bXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0g +c2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2 +YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4g +dHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNz +ZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1 +bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1 +cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1 +c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVz +ZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIs +IG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0 +IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVs +bGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxh +Y3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwg +bW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVu +dGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVz +IHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4g +TWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNp +IG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29u +dmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3Ig +cGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNs +IHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxp +c2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2Eg +ZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJh +Yml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRh +ZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxp +dCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGll +biwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQs +IGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNj +aXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0 +b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29u +ZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWdu +YS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlx +dWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJj +dSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBR +dWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2 +ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25l +YyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBj +b25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRp +cywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Ig +b3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBs +b3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNt +b2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1 +cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGlu +LiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwg +cGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyBy +aXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1h +ZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNl +ZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQg +dmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5k +aXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEs +IG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1 +dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVn +ZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5h +dGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3Jl +ZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQg +YWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQg +c29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0 +dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhp +Y3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1 +cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBl +dSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBh +YyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1l +dHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUs +IG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQs +IGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUg +bWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVu +aW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVz +IGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2Vz +IHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29u +Z3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0 +dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNh +cGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0 +LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5j +IHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVp +IHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBp +YWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxh +bmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3Nh +IG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3Iu +IE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBj +b252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBh +dCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1h +ZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMg +YWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVp +c3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5p +c2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0 +IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBh +IHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3Qs +IGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFl +LCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUg +dmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBv +cnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVj +ZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBE +dWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBl +cmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2 +ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1 +dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJt +ZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVy +dXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVl +IHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBp +cHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQs +IGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJp +Y2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBs +b2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0 +YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxl +bnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwg +ZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1 +cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlz +IHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFy +Y3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVh +biBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhh +c2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBj +b25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoK +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wg +cmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFt +IGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3Is +IG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1 +c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQu +IFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4g +QWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lz +LCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1 +bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVp +IG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRh +IHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBz +ZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3Vz +Y2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1 +Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2Nl +IGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRl +bXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3Ji +aSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVp +cyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2ls +aXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUg +bGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2Nl +IGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJv +cyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0 +cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5k +dW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1l +dCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVt +IGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhh +cmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1 +cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVu +dHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGln +dWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMs +IGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJp +cyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1 +cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1 +bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBk +YXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFz +IGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1h +ZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVs +dW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNp +bGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4g +TmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2Ug +YWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBt +aS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVz +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVu +YyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1w +b3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBm +YWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3Ig +YXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBF +dGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5p +YSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVz +dCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xl +c3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50 +IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBv +cnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRp +cyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMg +bW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMg +bGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2 +dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxp +Y2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1 +ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBx +dWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlv +LiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxh +IHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1w +ZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIg +aWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBV +dCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxs +YSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0g +c29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0 +aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlw +c3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0 +LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1w +ZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQ +cmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUu +IEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4g +RnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFs +aXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3Vl +IGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8g +YSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRp +cyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVu +dCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMu +IE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFj +dXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVl +dCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2ku +IEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3Us +IHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lk +dW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBq +dXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1 +ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4g +b3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZh +bXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBD +dXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywg +bnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMg +YWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBw +b3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBp +ZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMg +bWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGli +dXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4g +Vml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4g +TnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBt +ZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0 +IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRh +IGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVu +aW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBv +c3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24g +ZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBN +b3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2 +ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2lu +IHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxl +bWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWku +IFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVz +IGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5p +YmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxs +ZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERv +bmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9z +IHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1 +c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNx +dWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1 +Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJh +ZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlz +LiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQg +YWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQg +bWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVz +IHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdl +dCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFBy +YWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBG +dXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1 +cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4g +Q3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1 +cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25l +YyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlx +dWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50 +IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNv +bW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0 +IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVs +ZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQg +ZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBn +cmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBl +Z2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJp +cyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5h +IGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUg +cG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVj +aWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1 +bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxh +Y3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRl +bGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1 +dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1 +Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlx +dWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBt +b2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1 +c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMg +cHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0 +dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9k +IG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFt +ZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQg +bmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVs +dHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1 +cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlh +IGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVy +YXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBz +b2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEg +dGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxh +Y3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRh +dGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEg +bG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZp +dGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYw==
diff --git a/core/src/test/resources/org/ldaptive/io/base64-76.txt b/core/src/test/resources/org/ldaptive/io/base64-76.txt new file mode 100644 index 0000000..0238d1a --- /dev/null +++ b/core/src/test/resources/org/ldaptive/io/base64-76.txt
@@ -0,0 +1,18397 @@ +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +IENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFj +LCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1 +cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0g +cmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRp +biB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMs +IHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlx +dWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVk +aW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1 +cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBs +ZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5v +biBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGli +ZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2Nl +IGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVs +bHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlh +Y3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkg +YWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVu +ZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBo +YXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMg +cGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8g +bmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2Eg +bnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFt +dXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2Vk +IGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2ku +IFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJl +cm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIg +Y29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBs +aWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBm +ZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1 +cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwg +bW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9y +YmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBz +dW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBz +ZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwg +Y3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1 +cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0 +YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8s +IGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBv +cmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFk +YSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGli +ZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNl +bSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5l +YyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1 +ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVx +dWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUg +c2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3Rp +YnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQg +bmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVy +dXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJp +Y2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2Npbmcg +aXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFy +ZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQu +IFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBu +b24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNl +cyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBT +ZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1w +ZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRp +Y3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVs +dW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0 +YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQg +bG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFu +IGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBm +cmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBt +YXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9k +aW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1 +cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMg +bGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBl +cmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0 +dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVt +cHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxs +YSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVj +ZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNp +cyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVu +LiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1v +bGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGln +dWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCBy +aXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9u +LCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQg +aWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0 +IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1 +LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVy +b3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxl +Y3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBp +c2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1 +bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2Vu +dCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9u +ZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJp +Y2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlz +dGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11 +cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2Rp +byB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhp +bWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNl +bGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJk +dW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBt +b2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2ls +aXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lh +dCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9s +bGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQu +IFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJv +LCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRh +ZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1 +YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0 +cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMs +IHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBt +YXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3Mu +IFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZl +bmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNx +dWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFy +dHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRp +cyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRl +c3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNp +dCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRp +bmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxp +YmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1 +ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2Vs +bHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2 +aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQs +IHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhl +bmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4g +TWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25h +IGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0 +LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0 +IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2lu +aWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3Mg +YXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9z +dHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4g +Q3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1 +cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1 +IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0 +aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVt +IHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxh +LiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMu +IENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBp +YnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVs +dW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBp +cy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4g +Y3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlk +IGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxh +Y3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQ +cm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNz +IGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJu +YSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFz +IG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxv +cmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1 +dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlm +ZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBh +bWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlz +aXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1h +bGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0 +IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2ku +IE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1h +bGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRh +IGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNp +ZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBs +aWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRp +dW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGli +dXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0 +b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVu +ZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdl +ciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIu +IER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVj +IG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBw +b3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4K +ClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQs +IGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBF +dGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9y +LCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlz +IHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0 +LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxs +YSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZl +aGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVy +aXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3Vt +IHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBo +YWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1 +bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNv +Y2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBu +YXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZl +c3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2 +ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1 +dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0 +b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJk +aWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGli +dXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0 +LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVz +dGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBl +bmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJj +dS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlz +cXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlz +aS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBu +b24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBE +b25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFy +Y3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2Vs +bHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlh +bSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5l +cXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGlu +IHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBz +b2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9u +IG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmli +aC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVs +aXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBp +cHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3Vs +aXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMg +dml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlz +LiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWdu +aXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVt +LCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBW +ZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1h +bGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRp +Z25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxv +Ym9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3Vz +Y2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwg +ZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1 +bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVp +cywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFl +IG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0g +bGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFt +ZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0 +ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBz +dW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8u +IFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBp +cHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMg +cXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBw +b3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4g +VXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVj +dHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3Rp +ZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMu +IFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1 +cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRp +cywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNs +LCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4g +RG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRh +dGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4g +dmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFl +LCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBk +aWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEs +IHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2 +ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1 +cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0 +b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1 +dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0 +IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBk +dWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVx +dWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1 +cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMg +ZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMg +dmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVy +bWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlx +dWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBk +aWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9u +IHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMg +ZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZp +dmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJk +aWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMg +b2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMu +IFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBs +aWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBz +ZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNp +IGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVz +dCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwg +bG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBG +dXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9s +ZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmli +ZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNp +bmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0 +IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMg +bmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBj +b25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxp +cyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29s +bGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFy +Y3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBz +ZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBt +b2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVu +dHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9s +b3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEg +ZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlx +dWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVs +ZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUg +Y29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBD +dXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMg +c29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBu +aWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xv +ci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8s +IHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1 +ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQg +c2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWdu +aXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkg +c2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVs +ZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2 +YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRh +ZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1w +ZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxp +dCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGll +bi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0 +cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1 +cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2Vz +IHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZl +cm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1l +cyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0 +LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0 +cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFu +dGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVl +ciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBs +dWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVu +YyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVk +aW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4g +U2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBu +dWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1 +cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFt +IHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBw +ZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1 +bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4g +UXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2lu +IHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1 +YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3Vs +YSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lz +LiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBt +YXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQ +cmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwg +anVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVs +bHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29u +dmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENy +YXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVs +aXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEs +IHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVl +IHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4K +Ck51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0g +ZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0 +b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3Jl +ZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBv +ZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRl +Z2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0 +aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBB +bGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1 +bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZl +dWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlx +dWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBp +ZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3Vy +YWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBl +Z2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1 +cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9s +b3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFy +dHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51 +bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29u +Z3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwg +ZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4g +cGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBh +YyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1 +ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNp +dHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3Rv +ciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2Ug +ZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBh +bnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRy +YSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0 +b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51 +bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFs +aXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0 +cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1 +ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhh +c2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xv +ci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIElu +dGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBw +b3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNx +dWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVu +ZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVz +Y2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNl +ZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVu +dHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVt +IHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1z +YW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1 +ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24g +Y3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxh +Y3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBs +ZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5l +YW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBy +dXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhh +YyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBh +dCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVz +dG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0 +cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBt +YXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1 +bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVl +IHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFn +bmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxh +LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFz +LCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQg +bGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZp +dGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZl +c3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJh +dCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdl +dCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVl +IGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11 +cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVs +bGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2lu +ZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVy +byBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVt +IGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRp +cyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBs +YWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0 +cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQs +IGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4g +dHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZl +cnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBz +ZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlx +dWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBv +c3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZh +bXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwg +ZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2Vy +YXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2 +ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1 +ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4g +QWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNp +ZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2 +aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2ku +IFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4g +QWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0 +ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2Fn +aXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9y +dG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVs +bGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3Ji +aSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9k +LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBt +b250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVs +bGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1 +cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBw +cmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5p +c2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5j +LiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVy +dXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZl +bCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBu +aXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMg +ZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBz +aXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1 +YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0 +LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVu +YyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNl +bGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlz +LCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBl +cmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0g +dml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNs +LCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2Nl +IHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQu +IERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGlu +Y2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFu +dGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRl +c3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1 +YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBl +c3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMg +ZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBT +ZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBh +YyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29u +c2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQg +bmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBp +c2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0g +bmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBl +bGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2 +ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVs +dW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJv +IHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFy +aXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIs +IG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwg +aW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVz +LCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUs +IHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSBy +aG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFt +IHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0u +IERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVz +IGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0 +IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVu +dHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwg +cHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2 +ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlz +c2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2Vs +bHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwg +Y3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBl +dSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBt +YWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBs +aWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQg +dmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1h +dXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1l +dHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQg +bGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFs +ZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFk +YSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMg +YXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50 +ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVx +dWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9y +IGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBh +cHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0 +cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlz +cXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVz +cXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlz +IGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNv +Y2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRv +cyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlz +LiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVy +cmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBz +dXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVz +IG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9y +dG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0g +ZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5l +YW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBk +aWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMg +dml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9y +dG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJh +ZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRp +cGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRv +cnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJ +bnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNp +bGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBs +b3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2 +ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJp +c3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRp +cyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1 +cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVz +IGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3Nh +LCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4g +U2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRp +c3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0 +dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMg +YSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVz +IGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFs +ZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4g +TWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVl +IGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVh +bSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEg +aGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3Bl +bmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmlj +aWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFt +IGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1 +aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxh +LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVz +IGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFt +IGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0g +dmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFs +bGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNh +Z2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1 +cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGlu +Y2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBh +dWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVy +aXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51 +bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVz +dC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVz +IGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZl +cm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNj +ZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRp +Y3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3Iu +IFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRp +bWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJw +aXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1h +dXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2li +dXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRl +c3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBu +ZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2 +ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3Vt +IGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJp +dHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQg +ZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVu +YyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2Vk +LCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNj +ZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBs +dWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVs +dW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBN +YWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBo +ZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1z +YW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0 +IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1 +cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lp +cyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNj +ZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlz +IHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNp +YnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wu +IEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4g +TnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVz +IHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMg +ZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5v +biwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0 +IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBk +dWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlz +c2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGlj +dHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRy +ZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9k +aW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBv +ZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2Vs +bHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVz +dC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1 +cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFz +ZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVn +ZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGln +dWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0 +IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywg +ZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZp +dmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIElu +dGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21t +b2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJ +bnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVy +aXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVu +dCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3Ji +aSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBp +cyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNl +cy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBm +ZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERv +bmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1 +YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMg +ZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlx +dWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1 +cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQg +bWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2Ug +cXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEu +CgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVz +IGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5p +bSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFt +dXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4g +Q3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRv +ciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJo +IGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0 +aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBE +dWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMg +ZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51 +bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNp +YnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBs +b3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBh +dCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxp +c2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5l +dHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2ll +cyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMg +cXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBl +bGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0 +LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMg +ZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxp +cXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhh +Yml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFt +ZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBN +YXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVt +IGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1 +cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBv +ci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2Vj +dGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xl +c3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVy +aXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2Vu +YXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBt +b2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVs +aXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFl +LCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGli +ZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRy +YSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVh +dCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJh +Yml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBz +ZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1 +bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3Vs +YSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVh +bSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVu +dHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMg +Y29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3Bl +bmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1 +bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8g +ZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5l +YyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVs +bGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0s +IGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRl +c3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBw +YXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlz +IG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxl +by4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUg +bWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2Nl +bGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50 +dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBh +dWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJp +Y2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBW +ZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVu +YyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4g +UGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNp +ZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBB +bGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBl +dSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJz +dXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1 +ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRl +bXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMg +c29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNt +b2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJv +cyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwg +c2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBT +ZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVz +LCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xs +aWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBl +Z2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFu +dGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1v +bGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11 +cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1 +Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBl +cm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4g +TnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxl +cyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxs +YSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBp +cyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBu +ZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoK +SW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1 +LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQu +IE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBw +ZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9i +b3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQ +cm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1l +dHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9u +ZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9y +dG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0g +bnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBu +ZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUg +ZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFt +ZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3Vz +IHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51 +bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3Nh +LiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3Jl +bSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBl +cmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3Vy +YWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1l +dHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5p +bS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0 +b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +RXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFt +ZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVu +dCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQg +bWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywg +aGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFs +aXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQg +Y29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2lu +IGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0 +IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1h +bGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFt +IG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywg +cmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4K +ClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMg +ZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBV +dCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlz +IHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50 +ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBu +ZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25n +dWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFs +aXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFk +aXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZl +c3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxl +bnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFu +ZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0g +cGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1z +YW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNp +ZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBz +ZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0 +IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1 +bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3Vz +cGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBl +cmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVl +dCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mg +c2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMg +aWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2li +dXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBt +YXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVj +dHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQg +cHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQg +bWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFt +IGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBh +cnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1 +bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVy +bywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywg +bmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBt +YXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5k +IHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBp +c2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVu +ZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBl +dCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUg +bWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2Vy +YXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQg +YW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2 +aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1 +cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1 +bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFt +IGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHBy +ZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFj +LCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEu +IFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVs +dW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1 +cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywg +YXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2 +ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFt +IGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlz +bCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEg +ZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9y +Y2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBN +b3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11 +cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3Uu +IEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1 +ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERv +bmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1 +cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0 +LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwg +cGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51 +bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9u +LCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0 +IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29u +c2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZl +bGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFj +LCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJy +YSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNp +LiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBz +ZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0 +YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBz +dXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNh +biBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQg +cmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50 +IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0 +ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMg +bWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1 +ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZh +dWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21t +b2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwg +ZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMg +dGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNl +bS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNv +bnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNl +ZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEg +cG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlh +bSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0 +ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBz +dW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmgu +IE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1 +bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBN +YXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlz +LCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNt +b2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBh +Y2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNp +IGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFl +c2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFy +IG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBh +YyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVj +dHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNp +IGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFt +IGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBv +cmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0g +bm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVy +aXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRh +cGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9y +ZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVu +dCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWdu +YS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQ +ZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBD +dXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFj +LCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJp +cyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBW +ZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1 +bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4g +TWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBw +ZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFl +IGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEg +YWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBB +ZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQs +IGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlz +dGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4g +QWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9u +ZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBE +b25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlz +aSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNz +YS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlz +aSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50 +ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBh +cmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFt +IHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3Rl +dHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEg +ZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1 +bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEg +bmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBz +ZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFBy +YWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNl +ZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlx +dWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVz +dWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRl +LiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1 +aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJh +dCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmli +aCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBh +cmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVz +IGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGln +dWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUg +bHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4g +bmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZp +dGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxs +ZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNl +Y3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0 +aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUs +IHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMg +ZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBz +b2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBp +dCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlx +dWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFn +bmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9y +dG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJh +IGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRh +ZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZh +cml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRv +ciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2 +YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBl +dCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNs +IHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFj +dWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQs +IHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVs +cHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlh +IG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBw +bGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1 +bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMg +b3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0 +YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVz +dC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0 +YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8g +aWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2Nl +bGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3Vs +YSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29u +dmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBz +ZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1 +ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +RXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBo +YWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4g +UXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNv +bnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxh +IGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9u +IGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEs +IGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVy +IG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4K +CkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRv +cnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0 +IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQg +YW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0u +IEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2Np +cGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0g +ZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwg +ZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVz +dWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVs +bHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVz +IGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0g +YWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3Jl +bS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNj +ZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxp +cXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3Vz +LiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBh +IGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1 +cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEg +cXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8u +IFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQs +IGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVs +dHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNl +ZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0 +IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJp +bmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1 +bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMg +bmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9k +aW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4g +TnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBh +dCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3Vz +IG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2 +aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1h +Z25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBt +YWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJp +bmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1 +cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVs +bGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0 +b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVn +dWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNz +aW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxs +dXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4K +CkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBx +dWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmlt +LCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVz +Y2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVs +ZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRv +cnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0 +YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3Is +IGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIg +anVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4g +Vml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVy +byBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xv +ciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQg +bWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1v +cmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQs +IGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBz +ZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZp +dmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVl +IG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUs +IHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0 +LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVn +ZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwg +ZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBw +bGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBz +b2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxh +IG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUu +IEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVk +ZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVy +ZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBu +ZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9p +biBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3Vt +IGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50 +ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5k +aXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZp +dGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGlu +dGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRv +bG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1 +c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNs +LiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1 +bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVo +aWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxp +cyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBv +cnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlz +c2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNl +bGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0g +ZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNl +bSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNz +ZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZh +dWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlz +Y2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNh +Z2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0g +YW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2lt +LCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxh +LCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBs +aWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21t +b2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwg +ZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBx +dWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFj +aW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFz +LCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywg +dXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNv +ZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBw +cmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0g +YWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0 +byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1 +c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZl +c3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0 +cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxp +Z3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBv +cm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVy +IGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0 +aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxv +cmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVl +ciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxs +YSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxp +cXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3Uu +IFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4g +U2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8u +IFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1v +bGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0 +aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBp +cHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJz +dXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUg +dGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNp +dGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29k +YWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZh +dWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMu +IE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRl +bXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQg +anVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBN +b3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBt +b2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxp +dC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2Eu +IFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNh +Z2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1 +YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVz +dWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxs +dXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVs +aXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2Vy +YXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9u +IHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQu +CgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWws +IHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3Jl +bS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVu +ZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFl +IHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBz +YXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51 +bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFu +IGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3Vt +IGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVy +IHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5l +bmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZl +c3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVz +cXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3Nh +IHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0g +c2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0 +cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0 +aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQg +dGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNp +bGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVl +ciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9u +IGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJo +b25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2 +ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMg +YSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQg +dmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFt +Y29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMu +IER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1 +ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9u +IGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVz +ZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVu +dGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVj +aWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVz +IGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNl +ZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVs +bGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVu +dGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMg +cXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVo +aWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSBy +aXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQu +IEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0 +ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWku +IEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0 +b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIElu +dGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5p +bSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJh +dC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQg +bW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBv +cnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBR +dWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBs +ZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVs +dHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRp +ZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVl +ci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxp +cy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFt +IGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1v +cmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRh +ZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBt +YWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNp +bGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxp +dCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11 +cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1 +ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNl +bGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVz +dGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEg +dGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVz +ZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGll +IGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNv +bGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2Ug +dWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQs +IHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVs +bGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25j +dXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxl +Y3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0 +aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1 +cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlh +bSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lz +IHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1 +cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBm +ZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRl +Z2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxv +cmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQs +IGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2Vt +IHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4g +RG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMg +ZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1 +Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEg +YXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVl +IGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMg +cXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJl +cm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmlt +LiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwg +ZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3Jl +bS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBl +cmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVp +cyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1 +cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBD +cmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1h +ZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZl +bmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQg +dXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vt +c2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxl +byBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIElu +dGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZl +bCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51 +bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFw +aWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxv +cmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNl +ZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4K +CkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMg +aWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1 +bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQg +dml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEg +ZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUg +bWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJk +dW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQg +bnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3Vt +IHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1Ymls +aWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0 +LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVs +IG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNv +bnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNj +aW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNx +dWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1 +bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0 +b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBw +bGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBj +b25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2Rp +byB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1h +ZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBj +b252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNp +dGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdl +dCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0s +IG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmgu +IER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVu +ZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBp +bnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQg +bmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9y +ZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5h +cyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRv +ciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBl +dCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2Vk +IGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1 +Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVy +dXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRp +cyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3Vs +aXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1 +c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUs +IGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVs +cHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1 +ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRl +LiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUg +c2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBi +aWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGlj +dHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBz +aXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0 +IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0 +LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNv +bnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBD +cmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVj +LCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9s +bGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0 +LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3Rv +IGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFl +LCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5p +YmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5n +aWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENy +YXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5l +cXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNh +biB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4g +UGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3Bl +bmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVy +ZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252 +YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBz +ZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5n +aWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBh +bWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5k +aXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxv +Ym9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5l +YywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVz +dGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRp +YW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFu +IGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBo +aW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVy +aXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5v +biBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEg +bmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3Rv +LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVz +IGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVk +aW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1 +cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9y +dG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxs +YS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFn +bmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdl +dCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVt +IGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMg +bGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNl +bmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1 +c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4s +IHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBp +cHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMg +dGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1w +ZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUg +c2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVz +IGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBt +b3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1 +cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3Rh +cyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1 +cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGlu +IGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBl +dSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVy +IG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFj +IG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBm +ZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0 +ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBu +aXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9k +byBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMs +IGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1 +cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFj +dWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBx +dWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMg +ZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBv +cnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVs +dmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVh +bS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0 +LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVt +IHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNl +ZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRv +ciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQg +bnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywg +ZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRl +bGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZl +bGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJo +LiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFj +aW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBz +b2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBs +YWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBF +dGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZl +bCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVz +LCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBw +aGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0 +LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFt +IGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1 +aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVt +IHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBt +YXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1 +cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBh +IGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9s +b3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZh +bXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0u +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251 +YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBl +bmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3Vl +LiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBl +bGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMu +IEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBm +cmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxp +cyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBO +YW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZh +Y2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBw +dWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0 +byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1h +c3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3Ig +bmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVy +byBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1 +cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlz +IHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZl +c3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUg +cGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGlj +dWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVt +IG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBN +YXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2Vj +dGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21v +ZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1 +YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNv +bmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQ +cm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVt +LCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRp +YW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0 +LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBD +dXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBz +Y2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50 +ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBh +dCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0 +IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFt +IGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRv +cmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBG +dXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGln +bmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0s +IGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJv +cy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3Rl +bnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50 +ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1 +c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlz +aXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlz +IHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2li +dXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1 +cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBs +YW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0 +bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNv +bmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVh +dCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVu +ZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0 +b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +U2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252 +YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJp +c3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUs +IGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFn +bmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1h +dXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0 +dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4g +cXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBu +aXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFt +IHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVn +dWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1h +bGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBu +b24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVu +ZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJv +IHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFz +IHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVs +bGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4g +U3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlz +Y2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8g +bmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rp +by4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWdu +aXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9y +YmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2 +ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0 +ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJh +LCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBV +dCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGlu +Y2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNl +bGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVs +dW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0g +c2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9u +ZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVz +LiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZv +bHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBl +ciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWdu +aXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVs +dHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMg +ZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kg +ZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVy +cGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3Ig +cXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBx +dWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVj +LCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1 +cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxp +dCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBO +dWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1 +ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wg +c2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25j +dXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9y +IGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVj +IGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1 +cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRv +bG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2Npbmcg +anVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBx +dWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVy +by4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBz +ZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVy +IGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBm +YXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRp +Y3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJh +dC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRp +Y3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1l +dHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4g +RXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3Nl +IHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZl +bCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBs +aWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUs +IGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRp +c3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGlu +IGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRv +ciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0 +aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBG +dXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUs +IG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQg +cG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5j +aWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlw +c3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0g +aWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpW +aXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1 +bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0 +dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlz +IGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2Qg +dGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVz +LiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIg +bGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +TnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVz +Y2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +U2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0g +YmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNj +dW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxh +LCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBt +YXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVz +LiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxp +cywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVy +aXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRp +biB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0 +b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2Vy +YXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4g +ZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVu +Yy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFt +LiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBt +YWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2Rv +IG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1 +cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1 +dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVz +IHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQg +bWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBx +dWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1 +IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVu +dHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFs +aXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlh +IGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQs +IHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVy +IHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVj +dHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBh +cmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRv +ciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZh +cml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4K +ClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNv +bW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFu +ZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBn +cmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0 +cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdp +dHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0g +cG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0g +bm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlz +IHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFt +ZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMg +bmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBv +cm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJt +ZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRp +cyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwg +dWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2Vy +IGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBT +ZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERv +bmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBz +ZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2 +YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxs +YSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0 +dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9y +bmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVj +dHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxp +cyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJk +aWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQs +IGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRl +IG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWku +IEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1 +cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50 +dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1l +dCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHBy +aW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1 +IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2Vt +IHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVz +IGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVj +dHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwg +bWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFl +c2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBl +bGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVl +ciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlz +IHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVu +ZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdl +c3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVl +LiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHBy +aW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBl +cmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJp +ZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2Ug +dWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0 +LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGku +IEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2 +ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9y +IGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0 +IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNj +aW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEg +YXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJl +dHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29t +bW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlh +bSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBs +YW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGli +dWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFk +YSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0 +ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVu +ZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwg +bm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBl +cmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVy +by4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQg +bW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4g +RHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4g +TnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMg +ZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVt +LCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZp +dmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUg +b2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0 +YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFs +aXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3Rp +cXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUg +cGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGlj +dWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBu +aXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEg +ZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9u +IGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0 +dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5h +bSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1 +cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2Nl +bGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMg +bmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3Np +bSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1 +cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVy +YXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMg +ZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxp +Y2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGlt +cGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQu +IFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0 +LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMu +IFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkg +dml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMu +IFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25h +IGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVs +dHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNh +Z2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVj +ZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1 +IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZp +dmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZl +bGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4g +Q3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZl +bGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4g +RXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVz +dC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBi +bGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywg +dGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZh +Y2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBT +ZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlz +LCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBk +aWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3Ju +YXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQg +dHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0 +ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlz +dXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMg +c2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3Rp +YnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25z +ZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3Nh +IGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlz +IGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1 +YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVz +IGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0 +dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMu +IFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlk +IGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8g +c2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNl +bnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMg +ZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJh +dCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1 +ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRh +LCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMs +IGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBO +YW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxh +Y2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRl +c3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0 +dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBk +aWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwg +cmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdp +bGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBz +dW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0 +dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNl +bSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0 +aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2lu +ZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRp +biBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2ls +bGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlz +aSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0 +IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9k +byBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFw +aWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVl +IGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11 +cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVz +IGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMg +bG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERv +bmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1 +cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lk +dW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMg +bGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxh +IHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1 +cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1 +bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywg +cGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1 +cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBT +ZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlk +IGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxp +cXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBi +aWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUg +b2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFt +IGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpO +YW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29u +c2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3Vl +cmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1 +cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0 +IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFy +Y3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUg +c2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQ +aGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0 +cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3Jl +bSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2Vk +IGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBj +b25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZl +dWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1w +ZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1 +dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVv +IHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2li +dXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xv +ci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxp +c2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51 +bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQg +dHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdp +bGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0 +YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBz +aXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1v +ZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNp +ZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBh +cmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGlu +dGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2Ug +aWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1 +cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBl +bGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNl +bXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQs +IGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFy +Y3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0 +cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGll +dCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBt +b2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFt +IGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJo +LiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2Vt +LgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0 +aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1 +cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVz +IGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEs +IGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51 +bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxs +dXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVj +IGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9y +YSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1 +c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVs +aXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxp +dC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1 +ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIg +Y29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1 +dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFBy +b2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4g +TnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1 +bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRp +c3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFs +ZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0 +aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJp +Y2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBh +bGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUg +bWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1 +aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRv +ci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZp +dmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdp +bGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBh +bnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxp +cyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBR +dWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVz +IGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlz +cXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9y +dG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQg +ZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2Vu +YXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJp +bWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQs +IHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQ +ZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxv +Ym9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRp +YnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBt +dXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhp +Y3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1 +bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9k +aW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51 +bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVt +IGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxv +Ym9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0u +IEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEg +aW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZv +bHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNz +YSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVh +bSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMg +ZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1 +ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNp +IGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1p +LiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGli +dWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQg +bGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGli +ZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJp +c3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1 +aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3Jw +ZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0 +IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50 +IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBh +cmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZv +bHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1 +YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBw +ZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBp +cyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxp +Z3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1 +cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0g +bWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxp +YmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0s +IHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRh +LCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBz +aXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0u +IEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1 +bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmlt +LiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVz +Y2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlk +LCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2Nl +bGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlh +bSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2li +dXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFt +IHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWku +IFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBk +aWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBs +b3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBp +biwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywg +YWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMg +ZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBp +c2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVs +bGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNl +bnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRl +Z2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8g +ZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFl +c2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNp +LCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNx +dWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQ +aGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlm +ZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxh +bmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVy +IHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJh +dCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1 +ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMg +c2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwg +bW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBl +dWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGlj +dHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBv +cnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRh +IHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQ +cm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJo +IGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVy +cGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxl +cmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBw +b3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0 +LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFy +ZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1 +cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBt +YXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMg +ZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4g +VXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMg +ZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlx +dWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5h +bSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVy +ZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRp +cGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1 +ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNp +LiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1 +YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZp +bmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMg +ZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRp +cy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBz +ZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVy +b3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0 +aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3Nl +IHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlk +IG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBv +cm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4g +dXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywg +cG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4g +TnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRp +cyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQg +bGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9y +YmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1 +bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2Fu +LiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxp +cyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBz +aXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlk +IG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4g +U2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1 +cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNp +dCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEu +IE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4g +VmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlk +IGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0 +IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1 +cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQ +cmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBh +ZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2Nl +IGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBp +ZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVt +cG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVy +IG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNp +ZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVn +dWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11 +cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQs +IGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBk +aWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVy +IGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBm +YXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJv +cyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVj +ZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50 +IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBu +ZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25l +YyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1h +Z25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xs +aWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVy +YXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVz +cXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwg +ZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1 +ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlk +aWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1v +bGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBO +dW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxs +dXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBl +bGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBG +dXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBl +bGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJp +cyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMg +Y29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyBy +aXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQg +bm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2 +b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1v +cmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1p +LiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBh +IG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3Nh +IHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNh +cGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0 +IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVs +bGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9y +Y2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9u +IHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmlu +Z2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZl +bCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMu +IERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdp +dHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVt +cG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50 +dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJh +dCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1 +bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0 +IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUg +YXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3Jl +bS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGlu +LCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9k +aW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3Mu +IEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3Vt +IHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBz +dW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVz +LiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmlt +IGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJv +aW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGlu +Y2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFl +LCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJl +dHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJw +aXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1v +cmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVy +cGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1 +ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxh +dGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5k +aXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNv +ZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGlu +IG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4g +QWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQg +b2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBs +ZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMg +YXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFw +dGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3Ry +YSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVu +Yy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVs +aXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0 +aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxl +bnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwg +ZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3Bl +bmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1 +cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBk +aWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFy +LiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBw +bGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwg +YWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVy +aXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0 +cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBl +Z2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBl +bGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNl +bnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBo +ZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQu +IEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0 +LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBl +cm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJp +c3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lw +aXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRp +bWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJp +cyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNh +cGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEu +IEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxw +dXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNx +dWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNl +ZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBv +c3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9y +ZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1 +cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZl +dWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0 +dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50 +dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGlu +Y2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBh +YyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRv +ci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywg +bmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVl +IHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRp +Y3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1 +ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBt +YXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1 +cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQs +IGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2Vz +IGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1j +b3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlz +c2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBs +aWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51 +bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBk +dWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQg +ZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMg +dG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xs +aWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2Np +cGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBj +b25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVu +Yy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJp +dCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMg +bGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMg +dWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFk +YSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlz +IHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0 +IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVz +dWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEs +IHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlk +IGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmlu +YXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFt +IGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2Vt +cGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdp +YXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNl +cyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNp +dHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1w +dXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdl +c3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMg +ZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBE +dWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQs +IGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBN +b3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVu +YyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVz +IG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBx +dWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlz +IG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlh +IGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEg +ZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmli +aC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlh +bSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNv +bW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRv +cnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9y +LiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVs +dmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMu +IENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxs +YW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0 +IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxp +cyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQg +bHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9y +IGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBk +aWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxs +ZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3Ig +bGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBT +dXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0 +aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wg +bm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0g +bmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5n +aWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2Vk +LCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2Fu +IG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4g +TnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rp +by4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50 +ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBh +dWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1 +bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBB +bGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZl +bmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8g +YWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVt +cHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1 +cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmli +ZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMs +IHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVz +ZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQg +cHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNl +bGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9y +LCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBk +aWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1 +cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdl +c3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEs +IGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNp +dCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVp +c21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRy +ZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1 +cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0 +YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVy +ZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5l +YW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNl +bmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0 +dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBs +ZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVk +aW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0g +dXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJv +aW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4g +U2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBO +dW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVt +IG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVy +dXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxp +cyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBp +biwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRy +aXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMg +dGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVj +aWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2Vu +YXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQu +CgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVy +ZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlk +LCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2Rp +byBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRp +Z25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBp +cHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVs +bGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVj +ZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25p +c3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBx +dWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJp +bWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25k +aW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMg +cGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBj +b25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVu +YyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1 +bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNl +bnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2Fu +LCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9y +IHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFt +LiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFt +IGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1 +bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2Rv +IGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFi +aXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVz +IHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50 +ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5h +ci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBl +cm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0 +YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGku +IEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGln +dWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMg +ZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxp +cXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhh +cmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25h +IGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEg +bWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJp +bmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJw +aXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJh +ZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50 +dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxp +cXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBs +ZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4u +IE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVt +IGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0 +cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBs +ZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0 +aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJp +Y2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBW +ZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0g +dHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEg +c2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1 +bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBl +ZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVy +cmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNs +IG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBm +ZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0 +IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBk +aWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBk +dWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmlj +ZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1 +bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVz +dG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29u +dmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25h +IGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1h +ZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJp +bWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoK +TW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIElu +IGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVp +c3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxp +cXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9y +dGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0u +CgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxl +bWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFl +bmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxl +bWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3Vz +IGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0 +cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEg +cG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxs +dXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNp +IGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1 +Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0g +c2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxs +dXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRv +cnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJp +YmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBu +ZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQg +aWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2Fn +aXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlh +bSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5n +IG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlz +IGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1 +IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0 +aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRy +aWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1 +bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBh +dCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVy +IGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0 +cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUs +IHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRl +c3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVs +aXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxh +LiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBs +ZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0 +LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBh +bWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxh +LiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZp +bmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1 +aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0 +IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3Vl +LCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVl +IGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEg +ZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBl +bmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZl +bmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFj +aW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0 +aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJh +IGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZv +bHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBu +ZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRh +ZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4g +TWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBE +b25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxl +by4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRl +c3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVn +ZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4g +TWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVs +dW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2Npbmcg +bGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQs +IGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFz +ZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlk +IHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJh +Yml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVp +c3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVz +IG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25l +YyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0 +IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVy +aXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlz +IGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVn +dWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFu +dGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1 +cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFj +LCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxs +YW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5l +cXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50 +ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVt +cHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1 +aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0s +IGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdl +dCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBp +dC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQg +ZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBz +ZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmli +ZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2 +aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxp +YmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1 +bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNl +bGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVz +IGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlv +IHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBp +YnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1 +YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4g +ZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBE +b25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1 +bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0 +IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1 +c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0 +IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBk +aWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGlu +Y2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRp +biBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5k +aXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVo +aWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1 +cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0 +IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBj +b25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVu +ZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMu +CgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2Vx +dWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVz +dGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0 +ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVu +dCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1 +ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJp +YmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBp +cHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNv +bW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3Vt +LiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1l +bnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVt +IGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jh +dmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1 +ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQg +YW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZp +dGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBh +bWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJh +dC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVu +dHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFt +Y29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3Nl +IG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBu +b24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVy +aXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJh +ZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZv +bHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZl +cm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVy +YXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxh +LiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIg +YWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhh +c2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFt +IGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVz +dG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9y +LiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1 +ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVu +dGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5k +LCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEs +IGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJu +YSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9u +Y3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMg +aW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBx +dWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQ +cm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQs +IG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxs +dXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3Vz +LiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVu +YyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMs +IGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwg +cXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlz +IGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBl +ciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxh +IGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBN +YWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4g +dG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJv +aW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVo +aWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJp +Y2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxs +YW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFi +aXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1 +aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdy +YXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5h +bSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZl +cm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVs +bGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZp +bmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2Fu +IGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1 +cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVz +LiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFt +IGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFl +bmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2 +ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRl +Z2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMg +aWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2Vu +YXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0 +IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUg +cmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5l +YywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMg +c2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQu +IERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxp +dCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMg +bW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMu +IEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNw +ZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZp +bmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2ll +cyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEg +c3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVk +ZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVj +ZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVs +bGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlx +dWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlz +LgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJo +b25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMg +ZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBu +aXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlz +LCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1h +Z25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0 +dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9p +biBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0 +LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwg +Y29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRp +bmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRp +cyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJl +cm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xl +c3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29u +ZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11 +cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVz +dGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxp +cXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGlj +dHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBE +b25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUg +bmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBh +bWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2Vk +IGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9z +LiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRp +cyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQ +cmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVl +IGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJk +aWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVl +IG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lk +dW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5k +aXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZp +dGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFv +cmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGlu +LCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRh +ZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2Vy +YXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxl +cyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVl +IGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5h +bSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBu +ZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4g +Q3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVz +LCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2Nl +IGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJp +c3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1l +bnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Ig +c2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVz +IGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0 +dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1 +cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9u +ZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBu +aXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJp +IHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJl +cm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdl +c3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVs +IG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBl +dSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFy +IG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51 +bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGlu +Y2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50 +dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0u +IE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFt +ZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0 +dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwg +bnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGlu +IHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxp +cy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBl +c3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0 +by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVp +ZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFj +LCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9i +b3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1 +cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhp +Y3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2 +aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1 +bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVt +IGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4g +SW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQs +IGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwg +aWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMg +YW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5k +aXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xl +c3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFt +LiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3Vz +cGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBh +IG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1 +bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlx +dWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBl +Z2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9y +ZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENy +YXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBl +bGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBz +aXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlz +dXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1 +dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZl +c3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFt +IGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4g +ZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlz +IGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0 +dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBp +bXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJv +IHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVs +ZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVz +LiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3Vs +aXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNj +dW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlz +c2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNl +bGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhh +cmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVj +LCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVs +bGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMg +dWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNv +bnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBo +YXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8u +CgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29u +dWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1 +bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxp +cywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBu +b24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9s +ZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMg +ZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0u +IEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0u +IEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vy +c3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBl +dCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRl +IGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJp +YmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNp +LiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUg +aGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJv +IG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwg +ZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBl +c3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1 +dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUu +IEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2Vk +LCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVs +dW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0 +dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMu +IEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2Vz +IHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBz +dW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRy +YS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFBy +YWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24g +ZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBt +aS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQg +ZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJk +aWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1 +bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0g +YXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUs +IGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9y +ZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNv +bnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmlu +Z2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVy +aXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8u +IFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBp +cyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGli +ZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRp +ZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlz +IHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVz +LiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwg +dmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5h +cyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2 +aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBN +YWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVz +dGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxh +LCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1 +cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1 +bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQs +IGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxl +byBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBl +bmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3Mg +bGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1 +cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2Np +bmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVt +LiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBs +dWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMg +dXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2ll +cyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlx +dWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2 +ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2 +ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUg +YWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVu +YWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1 +cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0g +ZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xl +c3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNp +LgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0 +aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlz +IGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNl +ZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0 +aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBm +ZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRh +LiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEg +dXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1 +YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVy +aXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1 +aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQg +aWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUg +bGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVy +aWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBq +dXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1 +ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBh +bWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNp +ZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVy +bywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQg +bWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVz +IGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5h +ciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRp +bmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRy +ZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1 +cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVs +ZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBF +dGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNl +ZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVu +ZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEg +ZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0 +ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJh +LCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3Jh +cyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1 +cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1 +YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUg +cG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNl +ZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBD +cmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENy +YXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVz +IHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0g +YW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9z +dWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4g +Vml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vy +c3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFu +dGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3Vz +IHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9p +biB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFw +dGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3Ry +YSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwg +c2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9y +Y2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVt +IG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwg +ZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5k +IGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0 +LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMg +dXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVz +dWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZl +cm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51 +bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVz +dWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVs +aXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVu +dCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJl +cm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0g +cG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMg +ZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3Ig +bG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlz +c2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBp +ZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1 +aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5v +biB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1 +ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNl +ZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVz +dC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEg +dG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlh +bSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBs +YW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRl +bXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQ +ZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBm +YWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGlj +dWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMg +cGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNj +ZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMg +aGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBh +YywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lp +cyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNj +ZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3Rp +YnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwg +bWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0 +b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0 +IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMu +IFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBu +ZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGli +dWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmlt +IG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3Bl +bmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4K +Ck5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVl +IHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4g +UHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24g +YXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25l +YyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3Uu +IEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVz +IGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBh +bnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVl +IGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZl +bGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2Rh +bGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1l +dHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4g +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +IEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1 +bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMu +IEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0 +YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBE +dWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNz +aW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBv +cm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0 +aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVz +dWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25p +c3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9y +dGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lw +aXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxl +aWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBz +b2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywg +Y29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9k +aW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGli +ZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQs +IG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1 +ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0g +cHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1 +c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1 +bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVp +cyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1 +ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQg +Y29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVz +IHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0 +aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJp +Y2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBv +cmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0 +aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJp +Y2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFi +aXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywg +dGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1 +dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9u +ZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUg +bWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVs +LCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBt +b2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWdu +aXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZl +bmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0 +aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4g +RXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3Iu +IFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBl +bGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5l +dHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWks +IGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUg +bWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4K +ClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQg +dWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVs +IHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVu +dHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFt +IHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFt +IG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNj +ZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVp +IGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVy +cmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0 +LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2Rp +byBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNl +ZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJl +cm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1w +ZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGlu +IGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBh +YyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9i +b3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNj +ZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0 +aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5k +dW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlh +IG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGlt +cGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmli +aCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25k +aW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2 +ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGlj +aXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3Uu +IEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0g +cnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xs +aXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVt +IHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3Ig +bWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVp +LCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFt +IHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVl +ciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1l +bnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29u +ZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJh +Yml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29s +bGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJo +IHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4g +QWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZl +bmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1 +bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2Fw +aWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNz +aW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2Vt +LCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlm +ZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJp +dXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2 +aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJk +aWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBl +cm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4g +TmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBv +c3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1l +bnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRh +bnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBh +Y2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEg +c2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUu +IEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBz +b2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0 +dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBu +b24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4g +ZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2Vk +IGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxs +YS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZp +dGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5h +dGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVz +IG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVp +c3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBv +c3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0g +c2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBi +aWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJ +bnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0 +aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFl +c2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVz +dG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVz +IHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFs +bGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMg +bWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMu +IEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBv +cnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNl +bmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51 +bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9s +b3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0 +b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQs +IGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlv +LiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2Vy +IGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1 +cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVz +LiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlx +dWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4K +CkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdp +YXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFt +IHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBz +YXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJp +dHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0 +IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4g +U2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3Ig +YSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVy +aWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMg +ZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3Vl +LiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9s +b3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVk +ZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBu +aXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBk +aWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVk +aW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBx +dWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlh +bSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRl +LiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1 +cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0 +b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxh +LiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1 +YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBl +dSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2Vs +bHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4g +UGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVn +ZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1 +ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUu +IFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5h +dGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2Ug +dGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCBy +aG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVt +IGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRp +bmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4u +IFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBx +dWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vy +c3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3Vz +LiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0 +dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4g +dXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRy +dW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBo +YWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwg +dGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8u +IE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmlj +aWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVy +aXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZp +bmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1 +c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEs +IHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBB +bGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBt +ZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGli +ZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFl +IG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3Rp +YnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBz +dXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBl +bmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVn +ZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBt +YXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEg +ZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBv +ZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBj +b25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGlu +IGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBx +dWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNp +bmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0 +IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxl +Y3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVy +cGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJh +IGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0g +bmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUg +bm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFu +dGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3Vl +cmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVz +IGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVp +LiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQg +aWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJy +YSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIg +bnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVu +ZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMg +bGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRh +ZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNl +ZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxp +cXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1w +dXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0 +aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9y +LiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFt +Y29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBl +dWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBD +dW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250 +ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFt +IGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBu +b24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0 +aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kg +bnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJ +bnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMg +c2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBh +dWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNp +IGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9s +b3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQg +YW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0g +dWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBW +ZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBt +YXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1 +cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBl +c3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0 +IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0 +YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBj +b21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNl +bSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERv +bmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lk +dW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUg +aWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1 +ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRh +IGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3Qu +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQg +dWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQg +c2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBw +dXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmli +aC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2Np +bmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVx +dWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxl +bnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhp +Y3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0g +YW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9z +dWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNp +dCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVz +IGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9k +aW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1w +ZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBv +cmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZp +dGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9u +Y3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1 +YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERv +bmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFk +aXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFt +ZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVt +IHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVs +dmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0 +aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2lt +IHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVz +IHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vy +c3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwg +bHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxl +c3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJl +cm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVu +ZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJp +cyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVz +LiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVv +LiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1 +YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2 +aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJj +dSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNx +dWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUg +dXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFj +LCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEs +IHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVl +IGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVl +IGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNv +bmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBo +aW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBT +dXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEg +cHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNj +aXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5p +YmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9y +LiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxl +aWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3Vz +cGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4g +YXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFt +IGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0 +YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9y +IGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNl +bnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlz +Y2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRv +ciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRl +Z2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlz +aXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3Jl +bSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhp +Y3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1 +ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBp +cHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlz +LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBj +b25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2Vk +IGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3Nl +IG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlz +LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBt +b250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0 +ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlk +LCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMu +IEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFl +Y2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFj +LCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0 +aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVu +ZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRp +c3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVz +LiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1 +c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMs +IGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQ +ZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGlu +IG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFy +aXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlz +IHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0 +dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBt +YWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lk +dW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1 +ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMu +IEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxh +bSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4g +UHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNv +bW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1l +bnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBo +ZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1 +bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBl +bGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVu +dHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMg +dXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJp +cy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMg +cHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1 +ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMg +bmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxp +dCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEg +bGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVy +IG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdl +dCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBj +b25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBi +bGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxl +cmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0 +dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0g +YW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9z +dWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVj +ZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5k +cmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4u +IEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5l +YywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywg +dmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBu +YXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1 +ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBv +cnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVz +IGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIElu +IHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVs +bGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZp +dmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0 +IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwg +dGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1p +IGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWku +IFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1 +bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJp +bGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2Ug +Y29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVt +IGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJp +dCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8s +IGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlv +LCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVz +IG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4g +SW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBl +dSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxs +dXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIg +dXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxh +IGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFj +Y3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxl +aWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVy +cmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVn +ZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2Rv +LCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRl +Z2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNx +dWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBj +b21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0 +cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBl +Z2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4K +ClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJt +ZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVj +IHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQg +cGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVp +IHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUg +ZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2 +aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFz +c2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVp +cyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQ +ZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBl +dCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMg +dmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3Jh +cyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBz +aXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNv +bnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1 +ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlz +IGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlh +bSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxh +LiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVz +LCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3Jl +bS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBz +ZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lz +LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVz +IGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBw +b3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVh +bSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0 +LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBs +YWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJp +bmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVh +bSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0 +YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVy +aXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVn +ZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBt +b2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4g +TnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0 +dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3Rp +ZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMg +cmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMg +bW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xl +c3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQg +bGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBh +bnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJv +LiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBx +dWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBp +ZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0 +dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQs +IG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBj +b25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwg +Y3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBl +cmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVt +IHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29t +bW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRp +c3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlz +LiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdl +dCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBt +YXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFt +IGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNp +dGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFs +aXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1 +ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0 +dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51 +bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4g +U2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFz +c2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVy +aXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0g +bmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0 +b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2Vz +LCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0 +aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBl +bGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhh +c2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMg +ZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlx +dWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwg +YmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMg +bmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1 +bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1 +cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29k +YWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2Qu +IEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBz +ZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0 +IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQg +ZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBl +cmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNp +dHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0 +LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUu +IENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVz +dGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBz +ZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lh +dCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9z +LCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVs +bGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2 +aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBh +dCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2 +aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMg +bG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50 +ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBT +ZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51 +bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxs +ZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0 +aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9p +biBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVz +LCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMg +dmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9y +LiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVu +Yy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9s +b3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQs +IGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVy +bmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxh +IGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBO +dWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2 +aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0 +IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJp +dHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVz +IGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4g +Vml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3Jh +IHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRp +YW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBl +dCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1 +cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVu +ZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1 +YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29u +ZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGlu +IG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZl +bGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVz +dWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1h +c3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlz +dXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBl +bGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQg +bWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBp +bnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZl +aGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdl +ciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1 +ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUg +ZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1 +YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBp +c2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3Rp +YnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRl +c3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0 +LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVk +ZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4g +YXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMg +c2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQg +dXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZl +bGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBj +b25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVu +ZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0 +LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBl +Z2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2Vt +IHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQg +ZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0 +cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMs +IG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVy +aXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVz +LiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVy +dXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGlt +cGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQs +IGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywg +aWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFz +Y2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNz +YSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZp +dGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Np +bmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5h +dGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwg +c3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFn +bmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQu +IEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1l +dCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRh +IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4g +TWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxh +bWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFj +IGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRp +dW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBw +b3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFBy +YWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0g +bmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4g +VXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJj +dSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxp +dC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNv +bnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwg +c2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFj +aWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kg +ZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3Ji +aSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBt +YWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0 +aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBl +Z2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVj +aWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVj +IHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVz +IG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBt +ZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVs +bGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMg +dXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBm +YWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFt +ZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2Vj +dGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlz +IGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBz +b2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBh +dCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQ +ZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQg +dGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUg +ZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNj +aXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBt +YWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlz +dXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1 +aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBz +dXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0 +dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJl +IGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNp +YnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2Rv +LiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5p +bSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVp +cyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVs +bHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4g +TnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNl +cXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBs +YW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9y +dGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBl +bmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1 +ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0g +ZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51 +bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQg +dmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVy +aXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2 +ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2Qg +bmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1 +bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1 +cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2Vu +dCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5v +biwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBs +ZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVz +IHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFj +IHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVs +aXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNp +LiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9u +LCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNx +dWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGli +dXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0u +IE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwg +ZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4g +UHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxs +ZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1h +bGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJh +Yml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBu +dW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBh +cmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0 +aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxh +bWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFl +Y2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxs +ZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVy +YXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNj +dW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5l +YW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFy +Y3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlx +dWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxp +cXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMg +ZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25l +YyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBh +IG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4g +TnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2 +ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNx +dWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1 +LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBv +c3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVl +ciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0 +IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQg +ZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmli +aCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0g +c2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVz +ZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwg +bmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFt +LCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFk +YSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBW +ZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMs +IGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2 +b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBv +ZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1 +LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxh +IHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVj +dHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVx +dWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFl +LCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50 +ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3Rl +dHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMs +IHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNv +bGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5p +bSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xs +aWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBm +ZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFt +IGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEg +ZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9y +LiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFj +LCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBs +YWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1 +cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1 +bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11 +cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwg +ZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNh +Z2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxp +cyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVs +bGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0 +YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1h +Z25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0 +ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQu +IEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3Ju +YXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMg +YXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4g +TnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUg +YXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQg +cGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVy +aXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2 +ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFs +bGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0s +IGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBw +b3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRp +YW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVp +c3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZh +bGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJp +YmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRp +YW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRh +cGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5v +biwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNy +YXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRv +ciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVs +aXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1l +dCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIElu +dGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0 +LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQg +bmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0 +IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFk +YSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVz +LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNj +dW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4g +SW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0 +aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVh +bSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQ +cm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFy +Y3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBk +b2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVp +cywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNl +ZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVz +dC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJp +Y2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBj +b21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVy +YXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdp +bGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRy +aWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlz +aS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8g +ZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVs +bGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwg +Y3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1v +bGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZl +cnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25h +IHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWdu +YS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdp +bGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBh +YyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVu +dGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3Ig +aWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUu +IENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0s +IG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMs +IHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFl +bmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlz +IHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBm +ZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ug +dml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlm +ZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRv +ciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMg +dWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFs +aXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVz +dG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2 +YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBp +bnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0 +ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFs +ZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJp +IGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1 +Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFt +dXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5l +cXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNh +cGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBj +dXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIg +ZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGln +bmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFj +ZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xs +aWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9y +bmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFl +bmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4g +RG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBu +b24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1 +ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBl +Z2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxh +Y3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4g +U2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNz +ZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFl +LCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVy +ZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9y +IGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3Rv +IGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBW +aXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQg +c2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1 +bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBt +YXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRh +IGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2Ug +cG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1 +cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVy +bWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwg +dmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBh +ZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNp +YnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2lu +ZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0 +dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50 +ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBu +aXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBu +b24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1 +bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2Rv +IGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9s +b3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlz +IHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5p +YSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBs +ZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQg +ZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFs +ZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0 +aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRp +cGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBx +dWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2Nl +IHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3Rp +YnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmlj +ZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3Vs +YS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5h +cmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRp +Z25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMg +ZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVt +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBw +b3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBl +dSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVh +bSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNl +ZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2Vk +IHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0 +IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVz +dGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5j +aWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1 +bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMg +bWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVt +cHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkg +c29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2Vw +dG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxl +cyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNp +YnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51 +bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1 +cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVz +dG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3Ji +aSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xs +aXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4g +VmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFBy +b2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0 +dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0g +cXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFk +YS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMg +dGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQu +IFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQg +cHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNl +bSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpN +YXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRp +bmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4g +UHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlz +c2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1 +dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBp +ZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxh +bSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVn +ZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRv +bG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1 +bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0 +aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3Rp +YnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVl +LiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZh +cml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2Vk +IGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlz +dGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMs +IHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVs +bHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlz +aXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBt +ZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlw +c3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25j +dXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5l +bmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBt +YWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVs +aXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29y +cGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1 +aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGlu +LCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFy +Y3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50 +IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVz +cXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1 +cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlk +IHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBz +ZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFt +Y29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVz +cXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVp +cyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1 +bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1 +cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIElu +IG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxs +dXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIElu +IG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0 +b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVn +ZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBt +YXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9u +dGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0 +aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlz +cXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0 +dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJp +Y2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQg +bHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4K +Ck1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4g +TWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVn +ZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJp +IGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwg +bGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxl +c3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlz +aXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBz +ZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0 +dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBh +dWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1 +cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGli +dWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVt +cHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50 +IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFj +LCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxp +Y2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0 +cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZp +dmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVu +dGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMg +cGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1 +cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVt +LCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVz +LCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBu +aXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNl +ZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFi +aXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJt +ZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2Vy +IGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVt +IHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVu +aW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1 +cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9u +ZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdl +c3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1 +cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJj +dSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEg +ZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVp +cyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8s +IGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBO +dWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9s +b3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4g +U2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0 +LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBq +dXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBl +dSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFz +IG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNl +bmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQg +dGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJu +YSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2Fu +IGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBx +dWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVn +ZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwg +c2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxh +bSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1 +cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVt +IGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2 +ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFl +bmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQs +IGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlz +IHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0 +YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxl +aWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0 +dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0g +YmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVu +YyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHBy +aW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBw +b3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5l +cXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNl +Y3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5n +IG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUg +ZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlz +LgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0 +b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFj +ZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25z +ZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2 +b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNl +bmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252 +YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkg +c29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2Vw +dG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBu +aXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5p +c2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1 +aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlz +c2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRl +cmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVx +dWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0s +IHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBl +dCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBm +ZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBs +aWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGlt +cGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3Rv +ciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMu +IE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBt +YXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMg +YSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2Nl +IG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxh +Y3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0 +YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBs +ZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBN +b3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2Vk +IHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJl +bmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVt +IGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQg +YW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1l +dHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBW +ZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNl +Y3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFz +IGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0 +ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlz +LiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBw +aGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0 +IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0 +cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmgu +IFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxs +YSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMg +dG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVl +IHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2 +ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhh +c2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRp +c3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGll +dCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxs +aXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQg +b3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxs +YSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0 +IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNz +ZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9y +dGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywg +cGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGli +dWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0g +ZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNv +bnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1 +IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1l +bmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNx +dWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBk +aWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlz +aSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQ +ZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4u +IE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBz +b2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9y +IG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4g +QWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEg +YXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBl +bGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlk +LCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFj +aW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVj +dHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3Bl +bmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRv +cnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1 +bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVt +cHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIu +IFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2Vk +LCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxv +cmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3Ji +aSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBp +cyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBh +dWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4K +CkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1 +c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBk +b2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5p +YmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1h +c3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxp +cy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1w +b3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNp +LiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBk +aWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlh +Y3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBp +cHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxp +cyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlz +IG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxl +bWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRh +IGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmlu +YXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4g +TnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBE +dWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJp +c3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBz +ZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2 +aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVu +Yy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxl +bWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1 +cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0 +LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBF +dGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5p +YSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xs +aWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNl +cmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlh +bSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwg +dXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBs +YWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFy +ZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBw +ZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVy +YXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBx +dWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHBy +ZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNz +YSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBz +aXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVz +dCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3Ig +cHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVz +IGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENs +YXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251Ymlh +IG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0 +aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBE +dWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0 +IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFl +bmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmlu +Z2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBt +aSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0g +aW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2ls +aXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2 +aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2 +ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3Nh +LiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVj +LCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBj +b25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1 +dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZp +dGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3Rp +YnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1 +cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5l +cXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVy +aXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0 +dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwg +bWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0g +ZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1 +ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9p +biBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBw +b3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0u +IEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBw +cmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJh +Yml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2Vs +ZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNx +dWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwg +bmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxp +YmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRp +Y3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEg +dG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNj +ZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlz +c2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1 +IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4g +TmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdl +ciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2Nl +IGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMg +dWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRl +bGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMg +b3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1 +cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9y +ZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywg +aW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1 +ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBp +biwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJl +cml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3Jh +IHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2Vk +IHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxs +aXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3Rp +cXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNv +bmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEg +dXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJp +cyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMs +IHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVh +bSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNs +LiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRv +cnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUu +IFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVz +dWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24g +bnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5h +dGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0 +IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZp +dGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEg +ZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3Vz +cGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2lu +ZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVj +IG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4g +Vml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNz +aW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkg +bWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5l +bmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50 +IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBw +ZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2 +ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lk +dW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1 +cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0g +cnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0 +IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMg +bW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBN +b3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0 +cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVu +YyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBk +aWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMg +ZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJp +Y2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVp +LCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQg +bWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlz +LiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVp +cywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlz +IGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBj +b252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBh +dCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBh +dCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxs +YSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1 +bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2Nl +bGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMg +ZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxp +Z3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEg +bWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1 +cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9y +LiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVz +dG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlz +IG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4g +SW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0u +IE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVy +b3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVj +aWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNv +bnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1 +bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4g +QWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1 +bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVz +IGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRp +YW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBv +dGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwg +cGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJl +cm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRp +Y3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3Nl +IGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxp +Z3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1 +dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRv +ciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNj +ZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51 +bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9y +dGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1 +bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3Vt +IGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQg +c2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVz +IGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZh +bXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxh +bWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFk +aXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGlu +Y2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBB +bGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFj +aW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVu +YyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2Ug +cHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2Vk +IGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxh +bmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1z +YW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBk +b2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVy +aXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBB +bGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywg +YWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMg +ZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1 +dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0 +b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQg +dGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGln +bmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4g +VXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBW +ZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9y +YmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxl +c3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5v +biwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMg +aW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFl +OyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlz +IG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1 +bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRl +bXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0 +dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFt +LiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxp +YmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVt +IHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1 +ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1 +LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZh +cml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNv +ZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVz +LCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1 +LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwg +cGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1 +cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBo +YXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1v +ZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0 +IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2 +aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEg +ZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRp +cyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9z +dWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9u +IHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNj +ZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQg +c3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmli +aCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5h +cmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50 +dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBw +dXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0 +cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0g +ZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlk +IG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQg +ZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVj +IGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0u +IEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11 +cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBw +cmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJw +aXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFy +ZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVz +LCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1 +dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0 +IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxh +Y2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1h +dXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIElu +IHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1 +bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3Bl +bmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0g +bmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBu +ZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1p +cyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3Vy +YWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZl +bGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZl +bCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0 +IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVz +IGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1 +cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2Vu +dCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxl +bnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBv +ZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZp +dGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFu +IGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3Rh +cyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBT +ZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1p +cyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3Vy +YWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRp +ZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxs +YW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQ +ZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIElu +dGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWws +IHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGlu +IHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNv +bW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5n +IG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQs +IGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJh +LiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9k +byB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBp +bnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9y +ZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1 +bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUg +aGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxs +dXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5h +dGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9u +IGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRp +ZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9u +dGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVp +cyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVu +YyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJh +dCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBh +dWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFt +dXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2Rp +byBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBw +cmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1 +YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVl +IHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVu +YXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1 +cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNp +IGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdl +dCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVs +ZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMu +IFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBw +dXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBp +ZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVy +aXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVx +dWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwg +ZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4g +Q3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQg +bm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFj +aWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0 +dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVy +ZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNl +ZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1 +cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0 +IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2 +ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBl +bGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0 +IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJp +Y2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0 +dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5h +cyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1 +dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFt +dXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0 +IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3Vy +YWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlz +IGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRp +YW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4g +RXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFu +ZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGlu +Y2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2ls +aXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQg +ZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBt +ZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWdu +aXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJl +LiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVy +cGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1w +b3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMg +bm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0 +IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVs +dW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1 +YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVn +ZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlh +Y3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0g +aW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFj +IG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIg +dWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFBy +b2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVy +b3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2Vt +cGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQg +dml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJv +cy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBl +Z2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBu +b24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1 +bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJp +bGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0 +ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlk +IHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0g +cGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2Vy +YXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1 +ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0 +b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9y +Y2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0 +dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhv +bmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxh +IHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0u +IFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlz +LCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBp +ZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMg +ZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBl +cmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBt +b2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEg +ZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBz +aXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5l +cXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBl +dCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1 +cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFj +Y3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBx +dWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0 +IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1 +c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9y +ZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVj +IHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4g +VXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50 +IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVj +dHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBl +ZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4g +QWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4g +TWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhh +cmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4g +Q3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQg +Y29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNv +bnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVh +bSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJl +bmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rp +by4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlk +IGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0g +anVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2Vj +dGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUg +aWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBp +cy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFs +aXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3Ug +cHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFz +ZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMg +aW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFl +OwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVt +IGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBp +cHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhl +bmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25z +ZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdp +YXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIg +dmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1 +bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNh +cGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMg +b3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4g +SW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNp +dGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2ku +IEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMg +bmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxh +LCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUg +ZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQg +YW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8g +bWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVu +dCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1 +LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVy +ZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQg +YXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBz +aXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxl +bnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBl +ciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVs +ZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3Us +IGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmlj +ZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0 +b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xl +c3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJp +YmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBO +dWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoK +U3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVt +IGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFi +aXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGlu +LCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxh +Y2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMg +bmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMs +IHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1 +Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0 +b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2Nl +IHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMs +IGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4g +TWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGlu +LiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29u +dWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBs +b3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2lu +IG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVs +bGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0 +dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3Nl +IGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMg +ZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2Vz +IHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlx +dWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFn +bmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMg +dmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4g +RnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVy +cmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxh +IHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRl +IHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBu +b24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlz +cXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZl +bGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVl +IHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9y +LiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVp +LiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMg +cHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRy +aXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxs +ZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9y +dGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVz +IGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +CgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3Vs +YS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2 +ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8u +IEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxh +IHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1 +aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9y +dGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1 +cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4g +cXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0 +cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwg +cG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBl +Z2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdl +c3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4g +Q3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxh +Y3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBB +bGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1 +bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFj +dXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJv +LiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1 +ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMg +cGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIg +bWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdy +YXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEg +ZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1 +IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0 +cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0g +cmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxs +ZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBz +ZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3Vs +YSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4g +TmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFz +c2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVy +byB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNl +ZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBs +YWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQg +YW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1 +cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1 +dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBT +dXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2Ug +dmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCBy +aXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVy +aXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBs +YWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMg +b3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZl +aGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1 +c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0 +dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3Jl +bS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwg +bnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxp +cXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlz +IHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Np +bmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEg +ZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQg +bGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2Vy +IGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlh +bSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2Vu +dCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBp +bXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUg +Y29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFz +ZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5k +IGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0 +dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRp +dCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNv +bGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBz +aXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJl +LCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2Fw +aWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9s +ZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlz +bW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVt +c3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRh +LiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVs +dHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9p +biBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRp +YW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlz +LiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlz +cXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0 +dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2 +b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRy +YSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4g +TW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0 +aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBl +bGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQg +bWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQg +aGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdl +c3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFt +IHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBw +b3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBv +cmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlz +Y2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBt +YXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQ +cm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0g +c2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFy +LiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdl +c3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4g +UHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQg +dmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3Mg +dmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMu +IE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZp +dGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5l +cXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5h +cmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQg +bGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9y +dHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVs +bGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBp +biwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVv +IHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMg +ZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBl +cm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBE +b25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBz +b2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQg +YW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1h +Z25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2Vk +IG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBl +dCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBh +bWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51 +bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVz +dGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZl +bGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZp +dGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBt +YXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFl +c2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlw +aXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVu +aW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4u +IEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9y +IHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5p +c2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVu +dCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUs +IHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBh +dWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxh +b3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFt +IHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxh +b3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVj +aWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBk +b2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5h +cyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1 +aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1 +ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBh +dCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25h +IGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNp +dHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVl +IGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVp +c21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBw +ZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1 +bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVz +dGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5j +IHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMg +aW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0 +LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNj +ZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxl +bnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2 +ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29u +Z3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1 +cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9u +LCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1 +dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJp +IG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQ +cm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9k +aW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1 +aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGll +bi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVy +YXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEu +CgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kg +YW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJp +c3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2ls +bGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBk +dWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERv +bmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRp +cyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9y +IHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0g +ZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2 +ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwg +bWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxh +Y3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVn +dWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4g +RHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBl +cmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8g +c2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIElu +IHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNp +dCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0u +IFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBD +cmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1 +Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4g +ZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lk +dW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBm +YWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJh +IHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMu +IFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlz +IGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQg +cXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVh +IGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQg +c2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFs +ZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5p +c2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVu +ZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2Rp +byBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8g +cG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQs +IGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVu +dCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwg +cGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4g +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +IEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMg +dml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRl +c3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVp +c21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRp +c3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBp +cHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0 +dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBW +ZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFj +ZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRp +cGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQg +bGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlz +dGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxl +bnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQg +bG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5k +cmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1 +cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBl +bmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBz +aXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9z +LiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3Vz +LiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQg +YWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVu +dHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBx +dWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGll +biwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIElu +dGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRh +dGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUg +dXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBu +dW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3Vl +cmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0 +LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBx +dWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdp +YXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVy +IHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0g +bGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lk +dW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBw +dXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4g +VmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFz +Y2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBl +bmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwg +cmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNz +YS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlz +IGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVz +LiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNv +bnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxh +Y2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3Jw +ZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2Ug +dG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJl +cm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMg +YSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWku +IFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQg +b2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9y +dG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNp +dHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0 +IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25z +ZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4g +U2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwg +cmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFj +dXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxs +YW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwg +cGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBv +cnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1l +dHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFk +YSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBv +c3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxv +Ym9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIg +cmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1 +cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVy +IHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQs +IHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1 +bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVk +aW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMg +bmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3Rh +cyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFw +aWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlz +IGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVy +b3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3Ji +aSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBv +cm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1h +c3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFt +LiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5v +biwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVz +dC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9s +b3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4g +TnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBu +b24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1v +ZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRv +ciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBD +cmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmlu +YXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENy +YXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1j +b3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5l +cXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBh +dCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVj +dHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNv +bW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFt +IGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50 +ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFj +dXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMg +bmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9u +IGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVj +IHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxs +YSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBw +aGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1h +dHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVs +bGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4K +ClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBp +biBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0 +b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEg +bG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlx +dWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQg +bm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMg +bGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVz +IG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBp +ZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5k +dW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNh +Z2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50 +IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJl +dGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1 +cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBu +aXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWdu +aXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBt +b2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rh +cy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNv +bnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBh +bWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21v +ZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJp +dCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlz +IHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUg +bnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVt +LiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4g +Y29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFz +IHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlz +IGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8u +IFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4g +YSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQg +bnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4g +dmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2Vk +IHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5j +IGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1l +dHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMg +c2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBx +dWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwg +aW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0 +aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVt +cG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1 +cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMg +YSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpO +dWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGll +dC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBw +dWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBl +Z2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25p +c3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1 +bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFt +Y29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5h +cyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3Np +bSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlz +LCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1l +bnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVk +ZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25k +aW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBs +YWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEg +ZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQg +aWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBh +bnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZl +bGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBO +dWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVy +YXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSBy +aXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRh +cGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1 +ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZp +dGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJk +dW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4K +CkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9z +LiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUs +IHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1 +cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxh +LCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9s +b3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVh +bSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0 +cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0 +IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1 +cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdp +bGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMg +cXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNl +bnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0g +bGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVh +bS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0 +dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51 +bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFs +aXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0 +LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0 +dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2Vz +IHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0 +aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJp +c3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0 +IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBw +cmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUs +IGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEg +dmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1h +dXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxp +cy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRl +bXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWdu +aXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkg +cGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMg +dWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwg +dmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8s +IHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFs +bGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVz +dCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNl +bmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9y +YmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFy +Y3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1 +ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVh +bSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlz +IHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJ +biBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVu +dHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVh +biBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVu +dHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVu +aW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVt +IGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9z +dWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMg +dmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVu +aW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3Vl +LiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2Vk +IG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMg +Z3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRv +ciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVu +ZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMg +YW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQg +ZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0 +aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBj +b25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51 +bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxl +byBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNh +cGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFt +IGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNp +ZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwg +ZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBl +bGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNv +bmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmlj +aWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNh +Z2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1 +ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQs +IHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBO +dWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0 +dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBs +aWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0 +IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBT +ZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFy +LiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBz +YXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVy +bmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBm +cmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhh +Yml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFt +ZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmlt +IHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVu +YXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5p +YSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMg +bWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFj +Y3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0 +cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1 +ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwg +bmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1 +cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25l +YyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4g +TnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1 +ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQs +IGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1 +cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0g +bHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVv +IHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZy +aW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxs +dXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRl +bGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0 +dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1 +ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1l +dHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBh +IGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0 +LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQg +ZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhl +bmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUg +c2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUg +dGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlz +IGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBt +YXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0g +b3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVl +LiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJk +dW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVz +LCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBl +Z2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVy +YXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBt +YXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4g +RHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxl +bWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0g +dWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5k +dW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRh +ZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVy +byBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBu +aWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1 +cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFu +dGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1 +aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVz +IHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0g +dWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25l +YyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNh +biBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1v +bGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3Bl +bmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVu +aW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0 +dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lk +dW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBm +YXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQg +ZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1 +bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1 +cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFt +ZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25z +ZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBv +ZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpO +YW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0 +IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGll +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBl +ciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxs +dXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBh +YywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBp +biBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVu +ZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1 +bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1v +ZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBO +YW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1 +bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVu +aW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3Jhdmlk +YSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBt +YXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50 +ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFl +IHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0 +IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4g +Vml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVt +IG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29y +cGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1h +Z25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24s +IHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMg +aWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNl +bnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0 +cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1l +bnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQg +bG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBE +dWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2Vs +bHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1 +cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8g +ZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBF +dGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBt +YXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVz +cXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBw +dXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGlu +IHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0 +cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3Vz +LCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4g +cHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFt +IGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9p +biBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5p +c2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMu +IENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQ +cm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBs +YWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxl +byBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVp +cyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRv +bG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBs +YWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1 +aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVj +ZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9y +dG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4g +bnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1 +bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2Vz +IHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1j +b3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1 +ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMg +bWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZp +ZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBj +b25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1l +bnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFt +Y29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFy +IGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVn +ZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBB +ZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGlu +dGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVh +biBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWws +IGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2Vy +IGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQg +YXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMg +Y29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZh +dWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlz +dXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywg +YWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2Vt +cGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERv +bmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBw +b3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9s +bGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIElu +IHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5k +aXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFy +IGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBj +b25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3Vz +Y2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwg +ZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5h +cyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVu +dGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFt +IGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoK +RG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25j +dXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdl +dCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNp +IG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBu +aWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25h +LiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0s +IGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBy +dXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBD +dXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29u +dmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNp +ZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBx +dWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8g +aW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3Rp +ZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGlt +ZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBj +b25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGli +dWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVh +bSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVt +LiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25l +YyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVj +LCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0 +IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdy +YXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBR +dWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBw +dXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFl +c2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEs +IG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0 +IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5v +biwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50 +LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQu +IERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFl +IG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVl +dCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBp +bnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBl +cm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQg +YWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBj +b25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGlu +LCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBj +b25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMs +IGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3Jh +cyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBk +aWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxv +Ym9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1 +ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1 +bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0 +IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFs +aXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRp +bi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBl +dCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMg +c2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNs +LiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNh +cGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8u +IERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3Rh +cyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1l +dHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBt +YWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1h +c3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxh +IGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lk +dW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0g +ZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1h +dXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQg +bGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBl +ciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0g +dmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVs +bGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNl +bXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4g +SW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3Qs +IGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4g +UHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVu +ZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBh +bGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0 +aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBp +bXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3Vs +YS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRh +ZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxh +bWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVz +dC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50 +ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFy +Y3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFj +dWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50 +ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQg +ZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3Rp +ZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVu +ZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5p +c2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2 +dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUg +cG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0 +LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0g +aXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMg +YWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVp +ZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQg +YW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMg +bWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwg +ZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3Rp +YnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVy +YXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVp +c21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1 +cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMg +aWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBl +cmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0 +IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1l +bnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQ +cm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMg +bW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1z +YW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2Ug +cG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1 +cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0 +cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBm +YWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEs +IHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0 +cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNl +cXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNl +bGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpD +bGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEg +dml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywg +dmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24g +bGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0 +aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdl +c3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFl +bmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFs +aXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3Vz +IHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBu +aXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVs +ZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVu +ZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBO +dWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1l +cyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1h +dHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQg +c29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qg +c3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBl +bmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1 +c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBu +dWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0u +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMg +ZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIElu +IGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1 +c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0u +IFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4g +UGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVz +ZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVs +aXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4g +UHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlh +bSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0 +LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBt +b2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVn +dWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRp +YW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0u +IERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZh +bGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2ls +bGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMg +ZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0 +IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBl +dCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJv +LiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQg +b2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRp +bmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBE +b25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVo +aWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBl +dCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRh +ZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVj +ZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGll +LCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBl +dSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4g +UGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRy +aWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNv +bnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBu +ZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmlt +LiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVv +LCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4K +Ck51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2Npbmcg +ZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBE +b25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0 +dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQg +bWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBp +cHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUu +CgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhp +Y3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwg +ZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQg +bGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQg +bW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0 +aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJp +bmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3Rp +ZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoK +RnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5j +aWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0 +LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1 +dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5j +aWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxp +cy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQ +cm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJu +YS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0u +IE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMg +ZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNx +dWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQs +IG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGln +dWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0 +byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBj +b25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0 +LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVu +dCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywg +dml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFz +c2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNv +bW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBs +dWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNp +ZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJp +dCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlz +IHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1l +bnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlh +bSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwg +dGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlz +c2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUs +IGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50 +IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBw +ZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2 +aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywg +ZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0u +IEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9y +dGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBl +cmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFz +IGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMg +c29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNh +cGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50 +ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVy +ZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2 +YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3Vz +LCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUu +IENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNl +bSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2 +ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVu +dCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwg +cGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2Vt +cGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2ku +IFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51 +bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVp +LiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1 +aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBz +dXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJu +YSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFk +YSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1l +bnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxh +IGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFk +YSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQg +ZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwg +bnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8s +IGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9y +dHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGlj +dHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9i +b3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2Ug +cG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBh +dWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMg +bmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2 +ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJl +IHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBs +ZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4g +TW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9y +cXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBz +ZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9y +ZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBv +ciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxs +ZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNp +bGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxh +LiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVs +bGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxl +cmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFi +aXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywg +ZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBu +YXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1 +ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVs +dW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFz +c2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4g +TnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3Iu +IFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5v +biwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNl +ZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1 +ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1 +bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5l +YyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRp +c3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5h +bSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZh +cml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJh +ZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVn +dWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBm +ZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFl +bmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1 +IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRl +LiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1 +Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0 +LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVz +IGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVz +LiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9y +ZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBs +YWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUg +ZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlz +IGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0g +Y29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5h +cmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1 +bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFk +YSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3Np +bSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlz +IGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQu +IFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZl +bmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2Rh +bGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29u +ZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8g +cG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJv +IG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1p +LiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIg +YWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJp +bWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3Bl +bmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBk +b2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBw +ZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJl +IGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29t +bW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNl +bXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2Vz +IHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNp +IHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2Vz +IHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3Bl +bmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1 +ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVs +bHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0 +cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMg +cHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0 +dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBt +b2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xs +aXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNz +aW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVu +YXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1 +bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRp +YW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNl +ZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0 +LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVz +IGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZl +dWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFz +c2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZl +c3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0 +cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRl +bXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVt +IHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNl +ZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5v +biB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxl +cmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZl +dWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEu +IE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBj +b21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBm +ZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBq +dXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8u +IEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIs +IGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxp +Z3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBz +YXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0 +aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBj +b252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUg +cXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0g +bGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1h +c3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVy +ZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBl +Z2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1l +bnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxp +dCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1 +ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0 +aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0 +cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMg +YXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1 +bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkg +bm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBt +YXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZl +aGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1 +bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGlt +ZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0 +dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGlj +aXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZl +c3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxp +cXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVu +YXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRy +aWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVu +LCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0g +aWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBj +b21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5k +IGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMg +dml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZl +cnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0 +IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9z +LCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFt +IGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoK +VmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1 +bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFu +dGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3Vl +cmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1 +bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1 +bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2Vt +LiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFs +aXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2Rh +bGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMg +ZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24g +ZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdl +dCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVn +ZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4g +VmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1 +bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFl +IHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGli +dXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1 +ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3Vl +cmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2Vk +LCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJl +bmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRl +Z2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMg +bGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2Vu +dCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8u +IFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1 +bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlz +IHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFn +bmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIElu +dGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0 +aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVj +dHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMg +ZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Ig +c2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3Iu +IEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVs +aXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQ +cm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNv +bmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBW +aXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFt +IGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0 +aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQg +YWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZl +aGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBp +ZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVy +IHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVy +bmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2Vk +IHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBl +cmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVu +dCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxl +aWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBN +YWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3Ig +YW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4K +ClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNs +IHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWdu +aXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4s +IGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFt +LCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0 +b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBE +dWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5h +LiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Ig +b2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBO +dW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0g +YSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJ +biBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwg +bGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVz +IGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhh +c2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIg +ZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJl +IHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1 +c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlz +IGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGlu +Y2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9u +Y3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxp +YmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNp +ZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNl +ZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlz +IGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3Vz +IHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBE +dWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMu +IFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQg +YXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0g +ZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGlu +Y2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1h +ZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVz +IHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMg +bG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFy +LiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2Np +cGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNv +bGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlx +dWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1 +cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJv +LCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9k +aW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVs +dW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNj +aXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmlt +IGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0 +YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0 +aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQg +bWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlv +IHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25n +dWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFs +aXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFt +IGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlh +IG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0 +dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJs +YW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1 +cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlz +LiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNv +bnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlz +bCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9u +LCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUg +aXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUg +Y3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZl +bGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBE +b25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQs +IG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwg +bWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVu +YywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFu +IGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFj +aW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBu +aXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBu +ZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVh +bSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMu +IE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMg +bm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBV +dCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29y +cGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlz +bW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0 +IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24s +IHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVt +IGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVu +YywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRl +Z2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2Vk +IHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0 +b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0 +IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3Iu +IEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1l +dCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxs +YW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0 +aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNz +YSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBz +YXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3Qu +IFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZh +dWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUg +bGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21t +b2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBt +ZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVj +IHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50 +LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFj +dWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZh +bWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZl +c3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0 +cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2Vk +IHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1 +cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0 +dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4g +TWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2Npbmcg +aW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUg +cXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRl +c3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3Vs +YSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50 +ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVy +ZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBh +bWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFs +aXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8g +ZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJk +aWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNp +IHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFl +IGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3Vz +IGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0g +Z3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVj +IGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBp +c2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQg +dmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZp +dGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmlu +YXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1 +bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBs +YWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHBy +ZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3Vz +IHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVj +dHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3Vh +ZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8g +bWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5h +dGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBz +b2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQ +ZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBW +ZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRh +IHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRh +ZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwg +c29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUg +aWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQg +bmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0 +cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQg +dGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBl +ciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFj +Y3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGlu +LCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1 +ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1 +IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1l +bmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNw +ZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVs +dmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBp +dCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmgg +dHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBE +b25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZl +bmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVu +ZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQg +b2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRp +Y3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUg +bG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZl +dWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQg +c29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2lu +ZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBs +b3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2Vy +IG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMg +YmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBl +cm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3Vs +YSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2 +dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1 +bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25n +dWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNv +bnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5v +biBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBD +dW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250 +ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxs +dXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBm +cmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0 +aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2Vu +YXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBj +b25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5j +aWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJl +cml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3Nl +IGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBE +b25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3Rv +LiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlh +Y3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxs +ZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1h +bGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5l +cXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVz +IGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNp +dCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlz +IGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxl +c3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50 +IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBl +dCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0 +YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFs +aXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBl +dWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJv +aW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1v +ZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1 +bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5k +cmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBl +Z2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxl +bnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVt +LCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQg +ZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4g +RG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVy +dXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwg +ZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVx +dWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBs +ZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGli +ZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51 +bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwg +cXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25z +ZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFu +ZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlz +cXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMu +IFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50 +ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVy +ZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5h +cyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVy +aXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1 +cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywg +dnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFy +aXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRv +cXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciBy +aWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0 +aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFu +dGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRl +bXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEg +aWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVy +cmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVn +ZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVt +cG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFj +IGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZl +c3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBw +cmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlh +IEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29u +c2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1 +Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwg +ZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEg +aW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2 +aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1h +dXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4g +aGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBh +dWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMg +YXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQg +YXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlk +IGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vt +c2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZl +bmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEg +bmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIg +b2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1 +cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2Vy +IGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUg +aWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21t +b2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlz +dGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClBy +YWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50 +dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1 +dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxh +Y2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1 +aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9s +b3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRh +ZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2Eu +IE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyBy +aXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxs +ZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1h +bGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBm +ZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVo +aWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBs +YWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQg +YW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZh +bGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4g +RG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVn +ZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwg +YXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBT +dXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBh +bGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4g +TnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQs +IG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQ +ZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0 +dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBl +Z2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQ +ZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1 +cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdp +bGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBp +bnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50 +IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMg +dHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMg +dm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQg +ZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xs +aXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVs +bGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVy +IG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1 +dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhv +bmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9s +bGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3Rp +ZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGli +ZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRl +LiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQ +cm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlz +LCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwg +aWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIg +YXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1h +dXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25k +aW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vy +c3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0 +IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNl +ZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9k +byBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3Nl +IHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJ +bnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBl +cmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNz +YSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlw +c3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkg +c29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2Vw +dG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1 +ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBs +aWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJp +ZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMs +IHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2Vk +IGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2Eu +IE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNx +dWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVj +LCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3Iu +IFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCBy +aG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1 +bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVp +ZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2Vs +bHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdl +dCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFt +IGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxh +bmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlz +bCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRy +aWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4g +Q3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxl +cyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1 +c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQg +bGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFt +ZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxp +dCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0 +LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVk +aW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0 +ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENy +YXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGll +IHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQg +b3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwg +dGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBp +ZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEg +ZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRh +ZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwg +ZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRh +ZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9i +b3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdl +ciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQg +dmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxh +IGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50 +ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMg +b2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBl +bGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBz +ZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVs +IHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBG +dXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4g +UGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBl +dCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3Ig +ZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFy +Y3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEg +ZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVy +b3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxs +YSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRh +ZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVy +IHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVy +YXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2 +YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0g +ZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNv +bnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwg +bGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlz +IHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJl +cml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0g +bWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGlt +ZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1h +c3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlz +IGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFk +YSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3Nh +IG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMu +IEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxl +bnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRl +cmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGlj +dWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBl +dSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4g +U2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUs +IGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0g +bGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2Np +bmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVs +dW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1 +ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBz +YXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwg +bmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJj +dSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2Fn +aXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJu +YSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlz +IHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25z +ZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlz +c2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBO +dWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2Vz +dGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0 +IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9s +b3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1h +c3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMs +IHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBO +dW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMg +bGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlz +IGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVy +ZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVy +b3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQg +YWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0 +dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBz +YXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFl +LCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcg +c29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlz +IHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3Vz +Y2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEg +c2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFs +aXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBk +aWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNv +bnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1 +cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNv +cnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVy +b3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0g +bWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0 +YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVz +ZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVj +LCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQg +ZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBk +aWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4g +TnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNl +Y3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2Fn +aXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxp +c2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVy +bWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBs +YW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWdu +YSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFt +IG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0 +LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1 +cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZp +dGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1h +c3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1 +cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVu +dGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJu +YS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNp +bGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQg +YXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0 +dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRv +bG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2Rh +bGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwg +dmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxs +ZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGlu +Y2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJp +bmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBp +dCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxl +c3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMg +cXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMs +IHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNj +aXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMg +bmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJp +YmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVz +IHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBD +dXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBl +bGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBk +YXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVz +LCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVs +bGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVh +dCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9y +ZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEg +dGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmlt +IGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIu +IE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlh +bSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxh +bSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVs +LCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMg +bmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhp +Y3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2Qgbmli +aC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNh +bi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1 +cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBt +YXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwg +bGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8u +IE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNl +ZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRl +bGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQg +YWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBT +dXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2 +dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUg +dWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMg +Y29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1v +cmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJv +cyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJh +ZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50 +ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0 +dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5j +LiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1 +IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1 +bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNv +cnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2Vu +YXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50 +ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQg +bG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1z +YW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4g +bWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3Uu +IERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUg +YSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVh +bSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVy +bWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBh +bGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1h +c3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVs +bGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwg +anVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUu +IFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBi +bGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3Vl +cmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1 +bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVz +dCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0 +IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBh +dCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2Vk +IG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50 +IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVx +dWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBs +b3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBh +cmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0 +aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZh +Y2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1 +dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlv +LCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1 +aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVz +LCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUu +IFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0 +aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNx +dWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVl +ci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1 +YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxp +Y2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBl +dSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNp +dHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxp +cyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEg +dGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQg +b2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBG +dXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBw +dXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1 +cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0 +b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRy +aWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBh +bnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVs +aXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0 +dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBh +dCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFt +Y29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRl +LCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25h +LCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEg +ZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0 +aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJl +IHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQs +IGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVs +bGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJj +dSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVs +bGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNx +dWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWws +IG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlz +LCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNv +bW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0 +dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0g +bWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1 +ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxp +cyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVu +ZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0u +IERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGli +dXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwg +c29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMg +bmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBp +bnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQu +IE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBx +dWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVn +ZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBl +cmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmli +aC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFj +IGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBl +bGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1z +YW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4g +YWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5j +aWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBm +ZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9p +biBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3Ug +aW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xv +ciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywg +cGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBx +dWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4g +QWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2Vz +IHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21t +b2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQs +IGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxh +IHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNl +cyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4g +TWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUg +cmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEg +dml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vy +c3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVz +dGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJh +LiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBl +bGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4g +UGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxh +LCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBl +bGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVz +cXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQs +IGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENy +YXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5p +c2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1 +aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVh +biB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRl +bGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVn +aWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0 +YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5k +LCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBu +ZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0 +cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1 +ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8u +IE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11 +cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRl +cmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1w +b3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1 +YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFj +Y3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3Rv +ciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1 +cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMg +dXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVl +IG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGll +bi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJz +dXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUg +b2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlz +c2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJh +dCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNp +dHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFy +ZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVh +biB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9u +ZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24s +IGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwg +Y3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0 +IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3Vz +LCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2Vk +IG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBs +dWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVt +IHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFj +IHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNv +bmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZh +bXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2Vk +LCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEg +c2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNz +YS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlk +LCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90 +ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBk +b2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVu +dHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVz +dGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlw +aXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVz +IHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBu +b24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlz +LCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwg +c2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNs +IHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24g +Z3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEg +YXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxp +YmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3Iu +IE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1 +YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBh +LCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8g +ZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdl +c3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMg +ZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVt +IGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlz +Y2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFt +IGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNp +dCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVs +dW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4g +VmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUg +dXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25p +c3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1 +Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJ +biBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1 +ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBt +ZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBt +YXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBh +IHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1 +YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1 +c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGll +IGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1 +bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBu +b24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0 +dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVz +LiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9z +IGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1 +dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVz +IGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxh +IGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4g +UHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8u +CgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBl +dCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMg +dml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVz +dGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2lu +IG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlz +LCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVh +bSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4g +TnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVs +bHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFBy +YWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVy +dXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBh +bGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVy +aXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNp +ZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJv +aW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2Ug +cmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1 +bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4g +bmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBz +ZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQg +dXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9y +IHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1 +dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMg +YWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVs +dW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBG +dXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1 +cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlw +c3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlx +dWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVy +bmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVz +LiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMs +IHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1 +cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3Vt +IHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMg +bm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0 +aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWdu +YS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQu +IEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVy +IG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMg +dGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBs +ZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3Uu +CgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEg +ZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVl +IGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBu +b24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZv +bHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1w +ZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29y +cGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVl +IG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBm +ZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEg +c29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4g +UGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51 +bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMu +IFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51 +bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3Iu +IEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIg +ZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNz +YSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVz +LCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRv +ciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVl +IHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMs +IHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVj +dHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1h +ZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1 +cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0 +YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxl +Y3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGln +dWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3Vh +ZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMg +dmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0g +c2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJw +aXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0 +b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBw +b3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1 +bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVz +IGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlk +IHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCBy +aG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0 +dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmlj +ZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVy +cmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVz +cXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVk +ZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4g +UGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBl +c3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBp +ZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNs +IHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwg +bmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1 +ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50 +dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNv +bnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNh +cGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0u +IEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVz +IGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMg +cGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3Rh +cyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0 +cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBp +cHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJv +cyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBs +aWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFs +aXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxs +YSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Ig +b3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2Vk +IHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBT +dXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0 +byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwg +cHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5l +YyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFz +IGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGlu +Y2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBp +biB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVz +dC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFt +IHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIg +bGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2Fw +aWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1 +dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4g +RXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZl +bGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhp +Y3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVh +biB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlw +c3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJo +b25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUs +IGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZl +bmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMg +bmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxh +bmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5n +IGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBh +IGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1p +cyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3Vy +YWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0 +YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVl +IGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3Rl +dHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1l +dHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVp +IHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoK +Vml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3Ig +bW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJh +dCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0 +ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1 +dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFz +IGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxs +aXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9z +IGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNs +LiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wg +ZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMg +dWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2Ug +ZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1 +bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUg +aW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBv +cnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBl +c3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJt +ZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1 +bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVy +ZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBm +ZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1v +cmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVy +aXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwg +bGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5l +cXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3Vz +LiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRl +IGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8g +bWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3Ji +aSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1 +YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1 +bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFy +Y3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1l +dCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVz +LCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0 +aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFy +Y3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxs +dXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBO +YW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFy +ZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1 +YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlz +dGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBl +bGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBz +b2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9y +dG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBl +ZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxp +dC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2Vs +bHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3Nl +IGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBx +dWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMg +cGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3Jj +aS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBt +YXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9k +aW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBs +aWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlz +LCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhh +cmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1 +bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1 +Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNl +Y3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFk +IGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFl +b3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUs +IHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFt +LiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwg +Y29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxs +ZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1h +bGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51 +bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2Rh +bGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1h +dXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxp +cXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQg +bmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0 +LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBk +aWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5p +YSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVz +IGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRp +c3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRv +ciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4g +Vml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVz +IHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNl +ZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBj +b25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVt +IGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0 +cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBl +Z2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0 +b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNy +YXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3Rv +IHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xv +ciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmgu +IE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3Nh +LiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4g +Q3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Ig +c2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBN +YXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWdu +aXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3Vs +aXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1 +bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBs +YWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9y +Y2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVu +dHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxh +Y3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIg +bmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVs +bGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlz +IGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3Vz +IG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQg +bWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRh +ZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4g +Q3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVu +dHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywg +dGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBE +b25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlh +bSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwg +bnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNp +dHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0 +IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBu +dWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJu +YS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNp +bmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRy +YSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxs +ZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlz +IGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRp +dW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBk +YXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQg +YW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBp +biBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVs +dmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0 +IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNz +IGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1 +cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVz +LiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlz +IGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZl +c3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVh +biBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2ls +bGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwg +ZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1w +ZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNp +LiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5h +ciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwg +dmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBF +dGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBi +bGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25n +dWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwg +c29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFl +LCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVs +dW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRp +YnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBt +dXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVl +IHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMg +bGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVy +IHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFn +bmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQg +dG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBs +YWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBu +b24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1 +ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFs +aXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0 +aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0 +dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJp +c3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUg +YXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlz +bC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVy +bywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1 +bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9y +cXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBn +cmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2lt +LCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBv +cnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFt +IGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBW +aXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBh +bGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZh +dWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0 +cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1 +cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2 +YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0 +LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4g +ZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBk +dWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwg +dGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0 +IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBv +c3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMg +cXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVl +IG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRp +bWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQg +bmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBs +YWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRl +bGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBs +ZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQ +cmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRv +ci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0 +IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFk +YSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVs +bGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlz +LCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxp +Z3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFl +IGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGlj +dHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVu +ZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBj +b25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1h +Z25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2 +YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0g +Y29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFs +ZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0 +aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIg +aW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwg +bG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50 +IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBh +bGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0 +cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFt +ZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9s +bGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3Ji +aSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0 +IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBs +b3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWdu +aXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlz +IHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2Vz +LCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBp +ZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFz +c2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJ +biBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywg +YWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVs +aXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252 +YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBl +cmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBh +cmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBx +dWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxh +bWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVy +aXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJp +bmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3Vs +YS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWku +IFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBk +aWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBW +aXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8g +ZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51 +bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50 +ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51 +bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3Mu +IFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1 +cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNl +Y3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0 +LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxp +cXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0 +LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEg +bGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0g +aWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVu +dGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxh +Y2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8u +IE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1 +bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0 +IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3Vs +YSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBt +aS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2 +aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1 +cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMu +IEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEg +ZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQg +cXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRv +bG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2Vt +LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVz +IGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNv +cnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFk +aXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBp +c2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lk +dW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlx +dWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5p +YSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBz +aXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJl +dGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhl +bmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRp +dCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4g +bW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xv +ciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMu +IEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlx +dWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRp +cGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxp +dCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwg +bWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3Iu +IEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVt +cHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlz +c2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQg +dGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0 +aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMg +ZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3Vh +ZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwg +dWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4g +ZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBN +YXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1h +bGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBz +YXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1 +cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMg +dmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBN +b3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVy +byBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNl +ZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQg +ZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBj +b25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1 +cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFs +ZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2 +ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQ +aGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxh +Y2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBu +aXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNl +bGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8g +ZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1 +bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRh +LCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJh +dCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBs +b3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVy +ZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJp +c3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxl +cmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3Vz +Y2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBw +dXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUs +IGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0g +bGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1 +cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmlj +ZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9s +b3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5p +c2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUg +c2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFs +aXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFs +aXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBx +dWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0 +aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMu +IFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBh +dCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0 +ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBt +aS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZp +dGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2lu +aWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJp +cywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNj +ZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRy +aWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRp +c3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVj +LCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1 +ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBp +biBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7 +IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9y +Y2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlz +IHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBu +aXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5l +dHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVs +aXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlz +LiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBl +cm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRl +c3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlv +LiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFl +LCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1 +c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBp +ZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQg +cHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBp +biBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7 +IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQu +IEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1j +b3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxs +ZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVn +ZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRl +bGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRl +bGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1v +ZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9y +Y2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNv +bmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBE +b25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0 +dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRl +cmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0 +IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBk +aWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1l +cyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMg +aW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlz +LCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZl +cm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQg +YXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVz +LCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBj +b25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBl +bGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBu +dW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1 +ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMg +c29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBj +b252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0 +aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0g +bWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBv +cnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRp +YnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBt +dXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVn +ZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBh +ZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1l +bnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFBy +YWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1 +cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwg +ZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNx +dWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUg +aWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdl +c3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3Vy +YWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9u +IGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxp +c2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRp +biBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGll +dC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBs +aWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5h +LgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBs +YWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJy +YS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxl +bnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRp +YW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2ll +cyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlz +IGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBj +b25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1 +bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMg +bWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlk +IG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJp +dHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRp +YW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0g +cGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRp +YW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0 +IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lk +dW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNp +cyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJv +cyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1 +cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNz +aW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBW +aXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlz +IGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Ig +dml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9u +IG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFt +ZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0g +cGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQs +IGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQg +ZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3Vs +aXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4g +ZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5p +YmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0 +cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2lu +IGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3Mu +IERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVy +IGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0 +YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4g +TnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2Vz +dGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24g +bWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBw +cmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlh +IEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxs +dXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNh +Z2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVs +bGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQg +bGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBs +aWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Ig +bm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kg +bHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0g +dGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1 +cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZl +bCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZp +dmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBx +dWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2 +ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJp +bmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0 +IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xl +c3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFw +aWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQg +YW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVl +LiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwg +YXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBv +ZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vt +c2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlz +IGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1h +Z25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3Bl +bmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0s +IGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0 +IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQg +YXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZl +bCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVz +LiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUg +c29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVu +ZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1 +cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0 +cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3Vy +YWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29u +dmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNl +Y3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBl +bGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1 +bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4g +RG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZl +bGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVz +dG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0 +dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQs +IGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4g +TnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1 +YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVy +dXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0 +dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxs +dXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4g +ZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoK +SW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxh +b3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1 +bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRy +ZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0 +ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQg +ZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVs +aXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBj +b25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGll +biBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50 +ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkg +c29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2Vw +dG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1 +cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlz +aSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlz +LiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBv +ZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJv +cy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1l +dCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0 +dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwg +c2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1 +dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVt +IGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVn +dWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQg +YW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRl +c3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciBy +aG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlm +ZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFs +aXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMs +IGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0 +b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3Rp +ZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVu +ZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxs +YSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3Vz +cGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRv +bG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1 +ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBw +dXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2lu +aWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVj +IGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRp +bmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1 +cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0 +IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxh +Y2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1 +cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBD +bGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3Jl +bSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5v +biBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFt +IG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJw +aXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJp +YmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVs +aXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBv +c3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0 +IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEu +IE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVs +aXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVz +Y2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEg +c2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZp +dmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNl +bSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24s +IGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVl +IGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlz +LCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNp +dCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBD +cmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBF +dGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJl +dGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +UGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0 +aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50 +ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlz +IG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0 +IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpT +ZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4g +TmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWws +IG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFs +aXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNl +bSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNt +b2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlz +IG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFi +aXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVh +bSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0 +IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9y +dHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0 +IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rh +cy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3Jh +cyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3Vz +LCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlx +dWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1 +dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMg +YWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBD +cmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4g +SW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhh +cmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFz +c2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZp +ZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJv +cyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVn +ZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0 +IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhv +bmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50 +ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1w +ZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwg +aWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFt +IGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2Eu +IERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2 +aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBz +dXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1 +cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1l +dCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFi +aXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0 +ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNw +ZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVs +aXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1 +cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNx +dWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNp +bmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGlj +dWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3Bl +bmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0g +dmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4g +VXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVs +bGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVl +dCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBh +cnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcg +dml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFj +aWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFj +aW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZh +Y2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBh +dCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBh +IGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBl +cmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29u +dmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxs +dXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFu +dGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMg +ZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBt +YXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxp +Y2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQg +YW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBk +aWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVu +LiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0 +aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9k +IGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3Qu +IE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBN +YWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJp +Y2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBm +ZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0g +YWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQ +aGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVl +IGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0 +b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1 +dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBl +cmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9y +YmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMg +YXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxl +bnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVu +ZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3Rh +cyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZl +bGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1 +ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNp +LCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2lu +ZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNz +YSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9p +biBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2Fw +aWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBG +dXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rh +cy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJh +ZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVs +aXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVs +IGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51 +bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFl +IG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVl +LiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUs +IGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGli +ZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRp +dG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEg +cG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwg +bG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0 +IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdl +c3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9z +IHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25l +YyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2Rh +bGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1l +dCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25h +IHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5l +cXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBu +ZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0 +IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxh +IGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGli +dWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlz +IGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFl +LCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNz +YSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2Vu +dCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNj +aW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0g +aXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIElu +dGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNp +dCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wg +bmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBh +YywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVs +dHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0 +b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3Jl +ZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNl +ZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3Jl +ZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1 +cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xv +ciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBu +b24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNt +b2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2 +aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBh +bnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNv +bmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVk +aW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9s +dXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBl +ciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlk +IHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21v +ZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5h +dGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVz +IG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGll +LCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZl +bmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4g +dG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBz +YWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2 +b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRl +c3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhp +Y3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3Vl +IGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBu +aXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBj +b21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1h +dXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9p +biBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8g +bm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMg +c2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4g +UHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQg +dXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpR +dWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50 +ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3Vz +LiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEg +aW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWku +IERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVj +IGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBx +dWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZl +bGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVy +bWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5l +bmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFn +bmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3Vz +LiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUs +IGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVp +cyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0 +LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2Vt +IHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNl +bXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBh +bWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBl +bGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFz +IHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3Rv +ciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFw +aWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50 +IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNp +bGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBv +cnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNl +ZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRy +aXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVn +ZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVp +cywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRp +Y3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2Fw +aWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMg +dmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wu +IEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFu +IGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBh +bGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9z +dWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNv +bnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9y +ZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIElu +IG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0 +YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1 +ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21v +ZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3Nl +IG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1 +bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0g +dGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0 +aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJh +dCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlz +Y2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGli +ZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlx +dWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFz +LiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRl +c3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9y +ZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVy +aXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFi +aXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmlt +LiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQg +YW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBE +b25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBN +YXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxp +cXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVt +LCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlz +IHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwg +cG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVn +ZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUu +IEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQg +ZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5j +IGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUg +dmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBt +YXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFt +LCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQg +dGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRl +bXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGli +ZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50 +LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1 +cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVz +dGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0 +dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0 +aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlz +dXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4g +UHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRp +cyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBT +ZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNl +cXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2lu +aWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIg +dWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9y +dG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8u +IEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBt +YWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNl +ZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2Rp +byB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9y +IGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVk +aW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1 +YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0 +ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2Vk +IGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlz +dXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMs +IG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1j +b3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVk +ZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0 +aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVz +LCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwg +bGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3Vl +cmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9y +dGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlz +dXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1 +cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1 +aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZh +cml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBh +bnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1 +ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4g +ZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVj +LCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2 +aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1 +cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1 +Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3Mu +IERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBl +bGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5h +cmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3Nh +IHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBO +YW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwg +ZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4g +U2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3Ig +YWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVs +bGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24g +ZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8g +bWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwg +YWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFz +IG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIg +YXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMg +c2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3Jw +ZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVl +IGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBz +b2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVz +IGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1v +ZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGlu +IGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNx +dWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMg +Y29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5k +aXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVx +dWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxl +Y3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRl +bXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBz +YXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFy +ZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRp +cyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEg +bmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBo +YXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBs +aWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3Ig +ZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9y +ZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFt +IGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9u +LCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVj +dHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1h +dXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBs +YWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0g +c2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0 +dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0 +IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1 +bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0 +aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNs +IGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNz +aW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xl +c3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVl +IHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4g +U3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZh +bGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0 +IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBl +c3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBp +biwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJo +b25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVu +Yy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQ +cmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29u +c2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHBy +ZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1 +LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFBy +b2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwg +bGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVu +YyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFy +aXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBs +YWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlk +IGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVz +LiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2Vk +IG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlz +IGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1w +ZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1 +ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9y +IGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4g +U2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBt +YXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxs +YW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4g +Q3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2 +aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0 +IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3Np +bSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBx +dWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29y +cGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBp +bXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBn +cmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBk +aWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +RHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1 +bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwg +YSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1l +bnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNp +bmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQg +bnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQg +dXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRl +IG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0 +IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxs +YSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1 +cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGli +dXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2 +ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFl +LCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0g +anVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFl +bmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQ +cm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNx +dWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBv +cnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFi +aXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBj +b25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3Ig +bGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwg +bGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEs +IHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNl +bS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlz +IHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxh +IGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVh +bSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQg +dnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFj +aW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4g +TnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMg +cG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxh +bSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1 +YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBt +YXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMg +c2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBv +c3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1 +bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3Rp +cXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFt +ZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0 +aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEg +c2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVs +LCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJp +cywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4g +VmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1 +cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNz +aW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhh +cmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0 +cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVs +aXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNl +ZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlz +IG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBk +aWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFz +IHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +UGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkg +dGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3Uu +IFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2 +ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBt +b2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRl +bXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBz +ZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVt +IGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBl +Z2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVt +IHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0u +IEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxh +Y3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVy +ZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVo +aWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0s +IGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQ +cm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5p +c2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jh +dmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwg +b3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVt +IGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50 +ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1 +Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMg +bGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25z +ZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMs +IGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBl +dWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGll +biwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZl +cm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMg +aWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJh +dCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0 +LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1 +ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVz +IG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0 +dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwg +dmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNp +dCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxs +YSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMs +IGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1 +bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5p +c2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQg +ZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBO +dWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBp +ZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEu +IER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmlu +Z2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0 +YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMg +YWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZl +bCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRp +cyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBh +ZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1 +cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vt +c2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0 +IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBk +dWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVx +dWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlz +IHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2 +YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVs +bGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBx +dWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRh +cGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlz +IG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVj +dHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNp +dCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5n +aWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMg +cXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1 +cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIg +bm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0 +aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVz +LCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFy +Y3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCBy +aXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdl +dCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRy +ZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2Fn +aXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVt +cG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0 +IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0 +aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3Jj +aSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBD +cmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0g +dmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBt +YXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0 +IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQg +anVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNz +YS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVp +cyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVu +dHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0 +cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0u +CgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwg +cGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBq +dXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJo +LiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBp +ZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUg +c2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMg +dml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZl +bGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0 +cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2li +dXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyBy +aG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBl +dCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVz +dGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRp +c3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0g +bm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1z +dC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50 +IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVj +aWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVp +IGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEg +dG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1 +dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQs +IGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1 +YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlv +LCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0g +YWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNl +bSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBj +b251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMu +IE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywg +bnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBl +cmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVt +IHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4g +RXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8g +dG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0g +dmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBt +b2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0u +IFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwg +YXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVy +aXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBl +dSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBo +YXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1 +dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2 +YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5p +YmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVy +IGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25h +IGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRl +bGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFj +dWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQg +ZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0 +IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1 +bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9i +b3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlz +IGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlz +Y2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVz +IGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1 +cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQg +ZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlh +bSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNz +YS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVl +IGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1 +cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVs +dHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlz +dGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBs +YWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVy +dXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxh +Y3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBu +aWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2ku +IFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENy +YXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9p +biBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNp +bmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBh +YyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBi +aWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9y +LiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNp +bmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwg +Y29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5h +cyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9y +IHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVs +bGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEg +bWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVs +bGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3Jw +ZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBw +aGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0 +dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEg +ZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25z +ZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1 +bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29y +cGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNv +bmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQs +IGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5l +YW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVy +ZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBh +dWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1 +Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFj +IHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVn +dWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29u +ZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNp +YnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMg +ZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxp +cXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVy +IGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVj +IGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0 +YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlz +IG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1 +aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNz +ZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVn +ZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25k +aW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lw +aXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVp +c21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBl +cmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVz +cXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVy +YXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9u +ZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMg +ZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBh +dWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5l +YyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJo +IG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBW +aXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVs +ZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRy +dW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJh +Yml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFs +bGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVu +dCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlz +LCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4g +ZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0 +b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50 +dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25k +aW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1 +bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBl +bGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBF +dGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBl +dCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBh +ZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGlt +cGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZp +ZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlz +cXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1 +cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2Vu +dCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5p +YmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxv +Ym9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwg +aW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBT +ZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERv +bmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1h +dHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBu +aXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRl +cmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9z +IGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRp +cGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25z +ZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBt +b2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25z +ZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZl +cm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBh +YyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWdu +aXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9y +dGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBl +cm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0 +ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFt +ZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1 +ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4g +VmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1 +bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2Fw +aWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBD +dXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGll +biBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERv +bmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBh +dWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVz +IGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxl +c3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3Nh +IG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFj +IGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50 +IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVs +aXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJp +cyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFj +dXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBj +b251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFy +aXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEg +bm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBl +ciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50 +ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFj +Y3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJv +aW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4K +ClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlx +dWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMu +IEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBl +cmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4g +TWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBu +ZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNv +cnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4g +UGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdl +ciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3Uu +IFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxp +cyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4g +TnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQs +IGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2 +aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxs +ZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlz +c2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wu +IEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxw +dXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9z +dWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBj +b25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxp +cXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVu +ZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1l +dCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFz +c2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVp +LiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVs +dW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21v +ZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1 +cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQg +YXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRp +ZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5p +c2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1 +bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9p +biBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9s +bGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4g +ZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90 +ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBw +b3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEu +IENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNp +bGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNl +bXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmlj +aWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVh +dCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1 +cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFz +cyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBu +b3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0 +YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVs +IHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGli +ZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUg +ZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rh +cy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVh +biBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1 +YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZl +bCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNs +LiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlm +ZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVt +IHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxs +YW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRh +bnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRp +cyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29k +YWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3Vz +Y2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmlt +IGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2Nl +IHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxs +YS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBl +bGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQg +bWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEg +ZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2Np +cGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0 +IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVs +bGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50 +IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMu +IEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJv +aW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBp +cHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBl +bGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xs +aXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUg +ZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0u +IE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERv +bmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxp +cyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEu +IFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxh +dGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJh +dCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVs +ZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBu +aXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBT +dXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2Rp +byBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNp +ZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25l +YyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1 +bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBw +dXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwg +bG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5h +cyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBz +YXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBz +YWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhh +c2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNl +cyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZh +bGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1 +ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBD +cmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBw +b3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51 +bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5p +bS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25l +YyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMu +IEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFn +bmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1 +bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpB +ZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3Vs +YSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlh +bSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0 +b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9u +dGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5j +aWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdp +bGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBt +YWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVz +Y2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1 +bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBz +b2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBl +cmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1 +bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4g +UGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9p +biB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4g +SW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1h +dXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9s +b3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUg +bWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5p +c2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxh +LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBt +b250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2 +ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25n +dWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBj +b252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwg +ZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2 +ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Eg +dml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1v +ZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0 +dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVu +dCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1 +dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZl +aGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1 +bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0 +ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGlu +Y2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2Ug +cG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1 +Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRh +Y2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIg +aW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRh +ZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5p +bSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1 +c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEg +ZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0 +LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFs +aXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29k +YWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGll +biwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11 +cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBu +dW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENy +YXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwg +dWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwg +YXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVy +IGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZl +c3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxh +LCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBW +aXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2 +ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNj +aXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2 +aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBl +dSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1 +bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJp +YmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBn +cmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0 +IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVu +YyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVn +ZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRp +dG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVt +LiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0 +aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90 +ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1 +ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlz +bC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxp +dCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZl +bGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8g +bmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9y +YmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVl +bnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1w +ZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0 +IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBt +YWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50 +ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlz +aS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQ +aGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVu +dGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlz +cXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRh +c3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVp +c21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRv +cXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciBy +aWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0s +IGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2Eu +IE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVs +bGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNl +ZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwg +bG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBu +dW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4g +TWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4g +Vml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBh +cmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3Nl +IHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBu +b24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1 +cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNl +bnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUg +Y29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxp +cyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVh +biBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBl +ZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJ +bnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1 +cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBV +dCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFu +dGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBW +ZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0g +aXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhh +YyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNp +bmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhh +YyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0 +LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZl +dWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29u +ZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUg +cXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVt +IHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBp +ZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBv +ZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1 +Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1 +aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQg +YWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVz +IGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGlt +ZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9z +dWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51 +bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBR +dWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRp +cGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRp +c3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRl +IG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVy +YXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9k +byBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBl +ciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBv +c3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1 +c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBv +c3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRp +c3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBx +dWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVz +IHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlz +dGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVs +dmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMu +IEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xl +c3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMg +c2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0g +bWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRp +cyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVt +IGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0g +Z3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBs +YW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQ +ZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdp +YXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2Es +IHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3Rp +YnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmlj +ZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBv +ciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNl +bSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBs +aWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2 +b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlz +cXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdp +YXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1v +cmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21t +b2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxp +cywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0 +byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0 +aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVy +b3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3Vs +YS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBp +ZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMg +dmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252 +YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVp +cywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFj +aW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3Nh +IHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGll +dCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2Vz +dGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1 +bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwg +dXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGlu +IGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFt +IHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVt +IGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJj +dSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1 +dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9u +IHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0 +aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGlj +dWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBv +ZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50 +dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIg +ZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1 +ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3Rp +YnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVh +bSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRp +cyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNl +cywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBp +biBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQs +IHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21t +b2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1 +aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0 +YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJh +IHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZl +bGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBl +dWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFj +Y3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVz +dGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRy +aWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUg +aXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUg +Y3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4g +UGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9y +YmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNh +biBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJ +bnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1 +YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVz +LiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUs +IGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxp +dCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwg +dWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0 +YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVz +dGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRy +aWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1 +YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMg +ZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4g +RHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBp +biBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUu +IFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2 +dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1 +bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2Vy +IHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGln +dWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBl +bmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNl +ZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1 +dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVs +bGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEg +c2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVn +ZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRv +ciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVz +IGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQg +bWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0 +IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIElu +dGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQg +bnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9p +biBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRp +bWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZh +bXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRh +cGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFt +IHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMs +IHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGlj +dWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4u +IEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZp +dGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEg +bGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNl +ZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0 +LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBt +b250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZl +bmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVj +ZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50 +ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0 +IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVs +dHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNz +aW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVs +aXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBx +dWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0 +b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlz +IGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBN +YWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2Rp +byBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5j +IGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBu +aWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBp +YWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFj +aW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZh +dWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2Vs +bHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGln +bmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1 +YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3Bl +bmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVn +ZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lk +dW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3Vz +IHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVy +byBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVu +dCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0 +ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRh +cGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1 +YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlz +IGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFBy +b2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVn +dWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQs +IHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lk +dW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNl +bmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1 +dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9i +b3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBT +ZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0 +LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxp +Y2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFt +IGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBz +aXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBl +dSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8u +IFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0u +IEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBp +dC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1 +Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMg +ZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMu +IEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0 +dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJp +c3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUg +dGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1 +ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFu +dGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9k +aW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMg +ZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5k +aXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBl +cm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQ +aGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZh +bGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2 +aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBw +b3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBz +dW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlz +IG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25l +YyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5l +cXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFz +c2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywg +ZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEg +cHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5p +YSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNs +IGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMg +dXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBl +Z2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5h +bSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9u +LCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBu +dW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVy +IGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9k +IGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29j +aWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5h +c2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1h +Z25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZv +bHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRp +Y3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywg +cGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2Vy +IHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVs +dHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3Ig +bnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFy +Y3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIElu +IG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwg +bWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1j +b3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1 +bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBi +bGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBp +ZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0 +IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNp +YnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVv +IGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2Rv +IGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1 +cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1 +bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBG +dXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxp +cyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJp +dGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVz +IGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3Rp +YnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmlj +ZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZl +bGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBz +YWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVy +IGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFl +Y2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1w +ZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVp +cyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1 +ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBt +YXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0 +IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBl +ciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1 +ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUg +cHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0 +IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZv +bHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJp +YmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFy +Y3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3Jh +dmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZh +Y2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2Np +bmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVs +aXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFl +LCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIg +ZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVt +IGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNl +cmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRp +dW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNl +ZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVz +IHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEs +IHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFz +c2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlz +IHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xs +aWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxs +ZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0 +aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1 +cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwg +bGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29k +YWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQg +dmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlz +bC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlz +dGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFj +aXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vt +c2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBz +ZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2 +ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFk +IGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFl +b3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5k +aXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmlu +YXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBh +bGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJp +c3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25l +YyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQg +c2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlz +c2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rp +by4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1 +bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9y +ZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdp +YXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29k +YWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1 +cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3Jl +bSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9y +bmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmli +ZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9z +IGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBs +YWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxw +dXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBh +bGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0 +aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJp +Y2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUg +ZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNl +cXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBh +dWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMg +dml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmlu +Z2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFt +IGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMg +cG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25z +ZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1 +bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0 +IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEg +bmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25l +YyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBW +ZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3Vs +aXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50 +ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVl +IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhl +bmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBh +bWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVs +ZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3Vh +ZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZl +c3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBw +dXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNz +ZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1 +YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlz +bW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4g +dml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8u +IFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBj +b25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVy +aXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2Vz +dGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRl +c3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBp +cHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxp +dC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9u +ZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMu +IEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlh +bSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUu +IFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0 +dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJv +LiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMg +YXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVh +bS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1 +YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0 +IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVl +IHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0 +IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBp +bXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQg +ZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFi +aXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVs +cHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVz +IGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVl +IHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRp +Y3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRv +ciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUg +dml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1 +cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQg +bWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEg +ZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQg +bmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9y +IGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxl +byBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3Rp +YnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2Vx +dWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3Vl +LCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVs +aXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50 +ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZl +cnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJp +cyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1 +ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQg +ZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJj +dS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZy +aW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2Fu +IG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQg +c2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVx +dWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2Rp +byBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5h +LiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRp +Z25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQs +IGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2Rv +IHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlx +dWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFz +LiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVz +ZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0g +bGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1 +bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2Vy +YXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMg +bmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3Ig +YXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwg +dWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5h +bSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1 +cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50 +ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxp +cyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1 +bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1 +cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1l +dCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxp +cyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9u +ZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0 +YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQg +YWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNw +ZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlx +dWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVu +YyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5p +YmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxs +ZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1h +bGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0 +b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0 +IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxs +ZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBz +ZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxh +IHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRl +cmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1v +cmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVy +cGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9s +dXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxp +dC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMg +dGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEg +bGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5v +biwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwg +dmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1 +cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlz +IGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBp +ZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJv +LCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBG +dXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9p +biB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2 +ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFj +dWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJj +dSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJp +cy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1l +bnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3Vz +IGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZv +bHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwg +bHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBw +ZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBv +dGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRl +Z2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0 +LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBl +dSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3Vt +LiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9z +IGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQg +dXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJl +cm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZh +cml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRp +Y3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51 +bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUg +dnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBj +b252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZl +c3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9u +Y3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVt +IGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVu +ZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVz +IHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwg +bWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFj +IGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRp +dCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBy +dXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNp +ZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3Jh +cyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBh +bGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2Nl +IG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFv +cmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQg +dml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBt +YWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBW +aXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4g +ZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1w +b3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMg +bm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBs +YWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3Jj +aSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVs +bHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBw +dWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFj +aWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwg +Y29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxl +aWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBj +b252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0 +aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBu +dW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVz +dGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdy +YXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNx +dWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2Rp +byBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0 +LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1w +ZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1 +cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNj +ZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVs +bGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBt +YWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9s +b3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3Uu +IEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdl +dCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3Ms +IGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0 +cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2 +ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0 +cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNp +dCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQs +IGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11 +cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdl +dCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNl +Y3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFj +aW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZp +dGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0 +IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFn +bmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50 +dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3Nh +LiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0 +IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBz +aXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9k +aW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFs +aXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRl +c3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1 +YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1 +bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxh +IG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBs +YWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2Vk +IHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhl +bmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVj +dHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2Npbmcg +ZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0g +ZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBt +YXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBp +ZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVj +IHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2 +ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0 +aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBh +IHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNl +bXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1 +YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2Ug +YWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxs +YSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFz +LCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRl +bGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3Ig +ZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoK +TnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3Nh +IG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNl +ZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5j +IG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFj +aW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRp +cyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGll +dC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQg +bW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3Mg +YSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxp +cXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0 +b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIg +cmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBp +ZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0 +b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29k +YWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRl +bXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lw +aXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2Vk +IGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1 +YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFt +LiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZh +bGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlz +IGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBl +ci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3Mg +YXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0 +dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBl +dCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50 +IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0 +ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9s +b3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFt +IHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVu +YyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3Rl +dHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0 +aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2ku +IEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVu +dHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9y +ZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBl +bmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1p +IHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBs +aWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBv +cmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFl +IG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3Nh +LCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4g +QWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVz +cXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4g +SW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlz +aXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJj +dSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVy +IHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9y +IGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVz +IGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVu +ZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50 +ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lk +dW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdp +bGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBz +Y2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3Vh +ZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVp +cyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNv +bGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBp +dCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVj +IG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVu +ZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1 +bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJh +Yml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0 +IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBp +YnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBu +ZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFt +IHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBw +cmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0 +IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVt +cG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlk +IGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1v +cmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBm +ZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBk +aWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBv +cmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVj +IGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3Vs +YSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4g +Vml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4g +SW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBk +b2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0 +aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFj +aW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1h +dXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBk +dWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1 +cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRp +cGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNw +ZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxw +dXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0 +cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29u +ZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJp +IG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBk +aWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNl +bnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFk +YSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIg +YW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBO +dW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1 +bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVt +IHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBl +ciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMg +c29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNx +dWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9i +b3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4g +YmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkg +YXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERv +bmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwg +c2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2 +ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVu +dHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlx +dWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3Nh +IGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFt +IHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVz +dG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBo +YXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFu +ZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUg +cHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRy +aWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBz +ZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxh +Y2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBw +dXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9k +aW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxh +Y3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUu +IE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3Jl +bSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1 +LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1 +bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2ls +aXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBh +dC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBh +dWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0 +aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJp +Y2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMg +bWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBs +b3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1 +aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5j +aWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUg +bGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4K +CkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0g +bm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0 +dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBw +dXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVk +aW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1 +dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVs +bHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rp +by4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNj +ZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1 +cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2 +ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0 +b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNl +cyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRl +IHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMu +IFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlz +IG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwg +dmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29y +cGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBs +b3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBx +dWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGlj +dHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFt +IGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRl +bXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNv +bW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEg +ZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBh +YyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVu +dGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUg +ZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1v +bGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBl +c3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1v +ZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0 +b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0 +dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBu +aWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBu +ZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVt +LCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERv +bmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMg +bm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29s +bGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVj +IGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRl +cmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51 +bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFt +IHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIg +dXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0 +IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4g +Vml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJp +YmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0 +IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0 +aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJp +Y2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4g +cGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxp +cXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1 +bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVn +aWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBh +cmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4g +dmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwg +YmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVk +ZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFt +IGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxp +cXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBl +ZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2Rv +LCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEg +dmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVs +dHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBz +ZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFl +Y2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlz +dXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0 +YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3Vz +IGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGll +LiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBN +YXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxl +bnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVs +bGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0 +b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0 +LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVl +IGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNv +bmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMg +dXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wg +ZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMg +dGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2 +ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1 +cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0 +IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUg +bnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBl +c3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMg +ZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmlj +ZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQg +ZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1h +ZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBs +dWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1 +bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3Ig +ZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRh +IGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vt +c2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBl +dCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBl +dCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQg +cGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1h +dXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4g +RG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMg +dmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2Rp +byB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2lt +IHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBp +bnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVk +aW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBs +aWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2 +ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMg +cGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZl +dWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vy +c3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVz +dC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1 +bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1h +dXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3Rl +bnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0 +dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNv +bGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1 +cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRp +bWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVz +IGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBw +cmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2Vk +LCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4g +SW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0 +ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50 +aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xv +ci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVt +IHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGli +dWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNj +aW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZp +dmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24s +IHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBq +dXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0 +IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0 +IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3Jh +dmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQg +bWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVy +byBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5h +bSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0g +YXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBm +ZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdl +dCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3Rh +cyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5p +bS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZh +dWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2lu +Zy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJp +YmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBh +bWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0g +YW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9z +dWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVz +dGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQs +IHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3Np +bSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2li +dXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBo +YWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJl +IG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1 +cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVy +aXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVy +bmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0g +bWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3Rv +IGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGlu +LCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQs +IGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24g +YW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlz +LiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBB +ZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhp +bWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwg +c29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlw +c3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVn +ZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJh +ZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpB +bGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBp +cHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2 +ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGli +dWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5l +YyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBl +cm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1 +dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVu +YyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVz +IGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVz +ZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMu +IERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlx +dWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMg +aW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVu +dCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4g +YSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2Ugcmhv +bmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBw +cmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVx +dWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0u +IEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJu +YS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNp +dCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0 +ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRp +cGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0g +bmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNj +ZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBl +bGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3Vt +LiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUg +YWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEg +YXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBN +YXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVy +bmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywg +ZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRp +bmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9u +LCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMg +bm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4g +U3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIElu +dGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1h +dXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVs +bHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8g +ZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpO +dWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVs +aXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1 +Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24s +IGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0 +cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIg +bWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVy +IHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5v +biBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxp +cyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29s +bGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVs +bGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMg +bGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxh +IG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIElu +IHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGln +bmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwg +ZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNv +Y2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBu +YXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBw +dXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZv +bHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVs +dHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBl +bGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVz +LiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNl +bmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlz +IHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMu +IE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1 +cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxh +LiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEu +IEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFy +aXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0 +IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMu +IFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3Iu +IE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0 +YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBh +YyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1 +c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1 +cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9u +Y3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRp +biwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMg +Y29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEg +YSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVl +IHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBz +aXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhh +c2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3Qg +ZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0 +ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRv +cnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmli +aC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0 +ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0g +ZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNl +cXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGll +biwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1 +cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZy +aW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVk +ZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBl +bmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlz +dGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1 +bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBl +dSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJl +cm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1 +YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBs +b2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3Jj +aSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBo +YXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNw +ZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBj +b25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJl +dGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyBy +aXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVz +dCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lk +dW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0 +dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4g +VXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1 +bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVj +dHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVu +LiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCBy +aXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRp +YW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlz +LCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3Vs +YSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0 +b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3Vt +LiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25j +dXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRh +cGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQs +IGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlz +bCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRp +dC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVs +aXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlw +c3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBp +biBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7 +IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBp +ZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFj +Y3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVl +ciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVz +LiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0 +IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2 +YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9s +bGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBl +bGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1 +ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBh +dCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhl +bmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMg +Y29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhp +bWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBT +dXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlh +bSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxs +YW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdl +dCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwg +ZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4g +bmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0 +aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3Qg +ZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50 +dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEg +ZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGll +dCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJt +ZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJp +IGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMu +IFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFj +aW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVl +IHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJ +biBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGlu +LCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0 +dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBw +cmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0g +c2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBp +YWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3Ug +aW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBt +YWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0 +ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1 +bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVl +ciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3Ug +bnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMu +IFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0g +dml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRy +YSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0u +IFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlx +dWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxl +bnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xs +aWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9y +LiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUg +YWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4g +U3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVz +IG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFs +aXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlz +LCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVk +ZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4g +TnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVy +aXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8g +c2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJl +cm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBs +aWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0 +cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBz +aXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2li +dXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3Rl +dHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxp +dG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZl +bGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBW +aXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29t +bW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50 +ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMg +YmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVz +IG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJp +cywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVh +bSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVx +dWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQ +aGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWdu +aXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBz +b2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0 +IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3Nl +IHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0 +b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2 +YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBv +c3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBw +aGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25z +ZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlk +IHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlz +dGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2Vz +dGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Ig +b3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMg +dGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0 +IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2 +ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1v +cmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJ +biBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3Vy +YWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0 +IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVy +aXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNz +aW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMg +bmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4g +U2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNp +bmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kg +bmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVt +IG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3Vz +IG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVj +LCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFt +IG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVs +ZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5v +biBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFz +c2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBs +aWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3Vy +YWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVt +IGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGlu +Y2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25l +YyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBn +cmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVu +YyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVk +aW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5l +YywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxs +YSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4g +RG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlh +IG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBk +aWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50 +ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9s +dXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxp +Z3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0g +cG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBp +YnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1l +dCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBw +dXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmlu +YXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRp +YW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFw +dGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3Ry +YSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBO +dWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZh +dWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3Rp +YnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBs +aWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEg +b3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVp +c21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJk +aWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBO +dWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBp +biwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVs +aXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlh +bSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFu +ZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUg +ZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29k +YWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBs +b2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0g +ZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVz +IGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZp +dGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVv +IGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNl +ZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEg +bnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9y +dG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1 +cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24g +bWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJl +IHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1 +YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVt +IHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIg +ZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1 +ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVn +dWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4g +QWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywg +dWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBt +aSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVl +bnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2 +aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBs +aWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0 +aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1 +Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZh +bXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlx +dWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNp +YnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmlj +ZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBu +b24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJp +dXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2 +ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGlj +dHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkg +c2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVt +cG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVs +aXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3Vl +cmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVp +cywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1l +dHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVu +dHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlz +aS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1 +cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1 +cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8s +IGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFl +c2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4g +UHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNv +bW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBt +aSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEu +IFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBt +aSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3Vs +YS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVs +aXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVt +IG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlz +c2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25z +ZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25h +IGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11 +cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29u +Z3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1 +YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMg +c2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0 +aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5j +ZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9y +ZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNp +dCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlx +dWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVt +IHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQg +YW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlz +IGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBx +dWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1 +cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3Jl +bSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNz +aW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBh +cnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBu +aWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBp +YWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2Eu +IEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBz +b2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxp +cXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQg +aWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxs +aXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0 +LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1 +LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlz +IG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNv +cnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNx +dWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdp +bGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4g +RXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZl +c3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0 +dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZh +bXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJp +bmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMu +IEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdl +ciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxh +bSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNl +ZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBh +bnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVh +bSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoK +TnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGln +dWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQg +bmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGku +IE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2Vy +YXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51 +bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBh +dCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxl +Y3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1 +dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4g +RnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRh +ZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5h +IG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1 +c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxp +dCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVp +cywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9y +IHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1 +Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBl +ciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBp +c2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2Np +bmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50 +IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFt +IGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBt +YXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQg +YW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1 +bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRy +ZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0 +cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9s +bGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBt +aSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1 +cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFt +IHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlz +Y2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBh +cmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWku +IERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFs +aXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVz +LCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2lt +IGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVt +cG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1 +bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdl +c3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEg +ZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0 +cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVy +aXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVz +dWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBp +ZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4g +RnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVu +ZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3Ji +aSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBl +dCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwg +dWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdl +c3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25k +aW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBh +LCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMs +IG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwg +cnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFz +ZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2Vy +YXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNp +LiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1 +cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUs +IGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1 +dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBx +dWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwg +YXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3Jl +bSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwg +ZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3Vz +LiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlz +cXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lw +aXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1 +cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFy +Y3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGli +ZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBh +IGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMg +YWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Ig +c2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wu +IFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2Vt +IGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1 +YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1 +YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlz +IHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVt +IHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBo +YXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwg +bnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxs +dXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4g +U2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFl +LCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEg +ZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywg +dGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxl +cmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNp +ZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3Nl +IHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBm +YXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4g +QWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5h +bSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kg +bHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNl +ZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNs +LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVz +IGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQs +IHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBE +dWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9z +LiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1 +ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBE +dWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2 +ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3Rv +IG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwg +c2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJl +dGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1 +c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1 +bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3Jw +ZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50 +ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIg +ZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1 +cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1 +cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8g +YWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kg +c2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1 +ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25l +YyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJw +aXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1 +bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5v +biwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0 +dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRh +bnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4g +ZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5n +IGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBs +ZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1l +bnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVn +dWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNv +Y2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBu +YXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25n +dWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVp +ZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5j +LCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4g +TmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29s +bGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252 +YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVt +LiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0 +dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRh +LiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVz +IGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQg +ZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlw +aXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1 +bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVz +ZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBz +YXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlh +bS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUs +IGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQg +dXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3Rh +cyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJp +dHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVs +ZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lz +IHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBv +ZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4g +QWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJl +cm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoK +RXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNl +cmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4g +UGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRl +c3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0g +dml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBx +dWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhl +bmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25z +ZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBk +b2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0 +dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5l +cXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVy +IHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0g +Z3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhh +cmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0g +b3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJs +YW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50 +IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBv +ZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBl +c3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4g +TW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0u +CgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZh +bXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1 +Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2 +ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5p +YmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQs +IGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhh +cmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVy +YXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9s +b3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMg +bWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlh +bSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmgu +IE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmlj +ZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNv +bnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERv +bmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1 +c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUg +cmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVs +bGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFz +IHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFz +c2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMg +dXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0 +dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVu +dGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVv +LCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1 +bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9u +LCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVs +bHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBx +dWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwg +YWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFt +dXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFt +IHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxp +dC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdp +bGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1 +aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3Rp +ZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1 +cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1l +dCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBE +b25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVn +dWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlv +LiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2Fu +IHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlw +c3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRp +c3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlh +Y3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFy +Y3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJj +dS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwg +cGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJ +bnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29s +bGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFu +IG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlz +IG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEg +bmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJp +dHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFs +bGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3Rl +dHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0 +IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1 +dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9u +ZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlz +LiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8u +IERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVy +IG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGlt +cGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVs +bGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMg +c2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMg +c3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50 +ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3Jl +ZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBk +b2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJp +dCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1 +ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9s +b3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQg +c2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25z +ZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBu +ZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdl +ciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9z +IGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFi +aXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBh +bGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQ +ZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlv +IHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4g +UHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBt +b2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMg +bnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2Fw +aWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBt +b2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0 +LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUu +IE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1l +dCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1 +ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9u +Y3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5k +IG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1 +ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRv +bG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3Is +IGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBw +dXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVt +IGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBw +cmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVu +ZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9y +LiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBu +dW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1 +cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEg +bmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVy +YXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNp +ZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBs +dWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVu +dCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVz +dCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2lu +aWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlz +IGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFz +cyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBu +b3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBk +aWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBt +YWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5v +biBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMg +aW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVu +ZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMg +bHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFu +dGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3Vl +cmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZl +aGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51 +bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQu +IERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2Ug +dXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2Vt +IHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVy +cmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBu +b24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxh +b3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1 +cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBm +ZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBh +bWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFz +IG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlh +bSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1 +bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhh +c2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1 +ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNx +dWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1h +dXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1h +Z25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQg +YWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFt +IGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51 +bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBh +dWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2Qs +IHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9y +Y2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1 +ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBz +b2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVz +dCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRp +dG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5l +cXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVl +IHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4g +VmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBp +biBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBs +b2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFt +IGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBs +ZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRp +cGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFz +IHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50 +ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0 +cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2Eu +CgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEg +bGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBz +aXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQg +ZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1 +cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1 +cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNx +dWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIg +cGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQg +dm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVs +ZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERv +bmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRh +ZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNj +aXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBh +dCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBz +b2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1 +ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBo +ZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5k +aXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQg +ZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4g +RHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUg +c2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlh +IHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxh +IG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRp +c3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVs +LCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQg +bGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEu +IFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBl +dCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2 +ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxp +c2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5p +YSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2ls +aXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0 +ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxp +YmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRp +ZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFs +bGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMg +cmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUu +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQg +dWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0 +aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0 +dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1l +dCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFt +IG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQ +ZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUg +c2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1 +LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51 +bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVj +ZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2Vz +LiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxp +cy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNj +dW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFz +ZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFj +LCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3Ig +ZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBh +dCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0 +LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkg +bmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQs +IG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRl +c3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1 +YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJl +cml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBz +b2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0 +IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJl +LCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBu +b24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBu +aWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwg +YXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBt +b2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVu +IGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNj +ZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVl +IHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4g +U3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNl +bnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQg +cmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVy +YXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMg +cXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1p +LiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBO +dWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1 +Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJv +LiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9y +IGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9y +dHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9i +b3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNh +cGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rh +cy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0 +IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBz +dXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVz +IGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBh +bGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBo +YXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVl +LgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5p +c2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1 +IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1 +bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0 +IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBj +dXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwg +cG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBz +aXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5n +IGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBz +dW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVn +ZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBh +bWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVj +IHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywg +dGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJp +Y2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3Ig +bWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQg +aW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBk +dWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQu +IEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2 +ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwg +Y29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24g +dG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2Qg +cGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRh +ZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRl +LiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1 +ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4u +IFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRw +YXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBj +b251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZl +bGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBl +dCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGli +dXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11 +cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBs +dWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVu +YXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9y +dG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdp +dHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1 +dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1 +ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3Vs +YSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVs +ZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNs +IHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21t +b2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4K +Ck51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJp +cyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBh +YyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9u +IG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2Fw +aWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJv +aW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQg +YW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlz +cXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBw +ZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBD +cmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4s +IGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERv +bmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZl +bGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlz +LCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0 +IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVu +dHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0 +aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEg +bmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBW +aXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVs +ZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBw +ZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBO +YW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNj +ZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBl +ciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0 +IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxl +bnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZl +aGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBt +YXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1 +cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVs +aXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlz +aXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0 +aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBz +b2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0 +aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywg +c2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1 +bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVu +IGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVs +LCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1 +cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVn +ZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlx +dWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVy +ZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZh +bGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNp +dGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0g +aXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1l +dHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUs +IGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4g +RXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBl +Z2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5v +biBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2 +aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVs +bHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1 +bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBz +aXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2lu +ZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJv +LiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUg +c2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBD +dXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1 +ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0u +IERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQu +IFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1 +ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJ +bnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1l +dCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25l +YyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVy +aXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVh +bSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBm +ZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1 +YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9y +dHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIg +cXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0 +aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9s +b3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxh +Y2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVu +ZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNz +YSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBp +biBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVt +cHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBv +ci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJv +LiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBl +cmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4g +RHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGli +dWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0 +b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIg +cmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1 +cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVz +LiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMg +cmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJv +aW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBw +YXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQg +bm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVh +dCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEg +ZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0 +cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9y +IGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFs +aXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWdu +YSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0 +b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0 +aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEg +bGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4g +YWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0g +bm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1 +ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRv +bG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMu +IFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1h +dHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3Jw +ZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBh +IHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRv +ciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCBy +aG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGln +dWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUg +c2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlz +IHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMg +bGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBs +b3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMs +IHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1 +cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRl +IGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJl +IGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1 +Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBj +b25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRh +ZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBw +ZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3Vl +IGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERv +bmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVp +ZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUg +YXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNl +bSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0g +bmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5p +bS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2Vk +IHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRp +cGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEg +c2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5p +bSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1 +cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxp +cXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5p +c2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQs +IG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2Vk +IHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIg +bGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlk +IG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xs +aWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxv +cmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8s +IG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFy +Y3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUg +c2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29u +c2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNz +ZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUs +IHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1 +cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1 +cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBp +ZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRy +YSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBl +cmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlz +bCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNl +bGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1 +bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJp +bmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0g +dml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVu +aW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2 +ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVz +LiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJp +cy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNp +bmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2Fw +aWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlz +IHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51 +bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0 +ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5j +aWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEg +dGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0g +YW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3Rp +ZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNl +bmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3Vz +cGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxp +cyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1 +Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3Qg +ZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwg +bGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25j +dXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4g +UHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFl +c2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2Vx +dWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRp +dW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2 +ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2lu +IG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGln +dWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBm +ZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVz +IGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNl +cmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxl +by4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJ +biBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1h +c3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZl +bGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJk +aWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwg +bWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1 +c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2Vk +IGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNz +YS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0g +dHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3Vy +YWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5h +ciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRv +cnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwg +bGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlz +IG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVy +IHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBl +cmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2 +aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWdu +aXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVp +cyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwg +anVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBw +b3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1 +bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlh +IGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVu +YyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJu +YS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5p +Ymggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1 +IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2 +ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9s +dXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBp +bXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMu +IE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhp +Y3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBt +b2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVz +dG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVh +biBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9p +biBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUg +ZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0 +aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1 +ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25z +ZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGln +dWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGln +dWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJp +c3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4g +SW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNv +bGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFk +aXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwg +bGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVs +cHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5p +YSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVs +bGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9y +dHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBm +ZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0s +IHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVy +aXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2Vt +cGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFu +dGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3Vl +cmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVt +IGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVl +IG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQs +IGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVt +LCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2Vt +cGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBj +b25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywg +Y3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVz +dGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBs +ZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0u +IE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0 +cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmlj +ZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQg +c2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBp +bnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1h +Z25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0 +dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRl +bXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhh +c2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVt +cG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBo +YXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxp +dC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xl +c3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1 +cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQg +bGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNv +bnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2Vz +dGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZp +dGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1 +cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3Vz +LiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwg +bWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1 +bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVs +ZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9p +biBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wu +IE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3Jhdmlk +YSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3Ju +YXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlw +c3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBu +b24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lh +dCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFj +dXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0 +ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1 +IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlz +bW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwg +dGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1l +bnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFj +dWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBw +dXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBO +dWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4g +SW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5p +YmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlz +IHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVs +aXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBh +bWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBm +YWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNv +bnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEu +IFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kg +ZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdl +dCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxs +YW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4g +cmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1 +aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2ls +bGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50 +IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMg +dHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBs +b3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBp +ZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlw +aXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlz +IHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2Fu +LiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZp +dGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWks +IHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUu +IE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1 +dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJp +dXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFt +IG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlz +LCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGli +dXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1h +Z25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVz +LCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBh +bWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxs +YSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVp +cyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4g +SW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9u +IG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5j +aWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBj +b25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3Uu +IEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1 +cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwg +dWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJp +dCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0 +aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9y +IHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1 +cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMg +YSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBh +cmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFz +IG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVs +LCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVy +aXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxp +Z3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVz +dG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4g +VmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBs +YW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVt +IHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmlj +ZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQ +cm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVk +ZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0 +byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBD +dXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBp +cHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2Vt +cGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2 +ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0 +IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmlj +ZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMg +b3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9u +Y3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwg +YWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGll +IG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3Nl +IGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9u +IG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +TWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1h +dXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1 +cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0 +IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9y +dG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwg +dml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJs +YW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQs +IHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBu +b24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMg +bmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBx +dWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251 +YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51 +bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVu +Yy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0 +IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBs +YWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRp +YW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9y +dG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVs +IHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xs +aXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZl +c3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJj +dSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMs +IHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2 +ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJl +dHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1 +bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11 +cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmgu +IFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlw +c3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxv +cmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1 +cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxp +cyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVp +c21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5l +cXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBw +dXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0 +aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGlu +IG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2lu +ZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1 +IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBw +dWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJh +dCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBl +Z2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4g +VXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlk +IG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBp +ZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJp +Y2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlx +dWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1 +cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMu +IE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3Vz +LCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJo +IGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNl +ZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMg +Z3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBv +cmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlh +IHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2 +dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJl +bmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBE +b25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlh +LiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29u +ZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBz +Y2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBl +bGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEu +IE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0 +dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFt +Y29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIg +ZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFy +ZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMg +YWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdl +dCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1 +YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2 +ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVy +IGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1 +ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNv +bmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWdu +aXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4g +cGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVt +IHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1 +ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3Rv +ciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZl +bGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUg +bW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGlt +ZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVz +IGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGln +bmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVl +dCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRv +bG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFj +Y3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBl +cmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1p +IG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMg +bWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBz +b2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0 +YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1l +bnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQg +Y29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21v +ZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0 +IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVl +IG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQg +bWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMg +bWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxp +dC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1 +ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBm +ZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51 +bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZh +bXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1l +bnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0g +bWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0 +dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlz +IGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2 +ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1 +bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVp +c21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0 +b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0g +dHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1l +bnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBu +dWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0 +IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlh +bSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBs +ZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlw +aXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVy +ZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEg +bmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVl +IGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4K +Ck51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBl +cmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmgu +IFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9y +dGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1w +ZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQg +dmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVj +IGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRp +cyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNp +IHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1 +bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxh +b3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlz +Y2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1 +YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xl +c3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1 +YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1l +bnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0 +dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNz +aW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlz +LCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9z +LCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxs +dXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQg +b2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVz +dGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRy +aWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVu +IGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJh +Yml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBl +c3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVj +IHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1 +ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlk +IGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3Vh +ZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51 +bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVy +YXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNv +bmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMg +bmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2 +ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251 +YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVz +IGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9u +IG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBu +aXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdl +ciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vt +c2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4g +cGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZl +c3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFt +IGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIElu +IG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRp +ZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1 +cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1 +ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBl +ciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVs +bGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBp +cHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBo +YXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2 +ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVs +bGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxp +Z3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRh +ZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50 +ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ug +c2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFl +bmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRh +dGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVy +ZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25k +aW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0g +ZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVl +dCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBl +dSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBx +dWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2Es +IHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBE +b25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0g +bmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9s +dXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBh +dWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBl +bGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVj +dG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQg +bWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kg +YmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBz +YWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBs +aWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlz +LCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVp +IGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50 +aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0 +YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENy +YXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlz +aXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBl +ciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVz +IGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBs +YWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1 +bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBh +cHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0 +cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUg +Y29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVs +dHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJv +LiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQs +IHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVl +IHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4g +Vml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBu +ZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0g +aWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwg +ZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBE +dWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5k +IG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNh +Z2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0g +ZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1 +bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxl +cyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lw +aXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEg +ZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1 +cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4g +U3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxl +bnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFs +ZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVs +aXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0 +IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1 +aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVu +dGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZl +dWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIElu +IGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4g +bWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1 +bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0 +LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMg +bWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5p +bSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1h +dXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVj +IGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBl +cm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBo +YXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVh +IGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwg +YWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlm +ZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNs +IGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNw +ZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBz +aXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVu +dC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBh +bGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEg +c2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1 +cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9i +b3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBt +b2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBp +ZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdp +dHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2Vs +bHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBl +dSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxp +cyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwg +dmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFz +IGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0 +YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxh +bSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4g +U3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBl +dSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFs +aXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEu +IEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBu +ZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5l +YW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBs +b3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBo +ZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3Jh +IHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVz +LCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1 +bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxh +IHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWdu +YSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2Ug +dmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQg +ZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2Rh +bGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0 +LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQg +bmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVs +bGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2 +ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4g +bWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJp +cyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3Is +IHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1 +cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2ku +CgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBD +dW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250 +ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwg +cmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUg +bGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252 +YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5p +bSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJy +YSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0 +YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8g +cXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMu +IE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBu +ZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwg +aW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGlj +dWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBm +ZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1w +dXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lk +dW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90 +ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1 +cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0 +aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5j +ZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBu +aXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBu +dW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2Nl +IGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0 +LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBT +ZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1 +ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxl +cywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwg +ZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1 +bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJp +bGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBl +Z2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5j +IHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMg +dnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0 +cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJj +dS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNp +dGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0 +LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3Rp +YnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBz +b2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZh +bXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwg +bnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBp +dCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRh +ZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwg +dnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0 +dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVu +ZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2 +aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZp +dGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1 +bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQg +dmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9y +IHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBO +dW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMu +IFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50 +aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4g +UHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4g +U3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBz +aXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0 +LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVx +dWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkg +YmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQg +cGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIg +cGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0 +LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxl +c3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNx +dWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4g +UGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFz +ZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVz +cXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVl +IHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3Nl +IHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21v +ZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVl +IHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRp +Y3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVy +b3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1v +cmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEg +bW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBp +cHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9y +ZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5j +IGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1 +cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2 +YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1 +LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBv +dGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24g +bGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBh +bnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQg +ZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29t +bW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1 +cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBk +aWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUu +IEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRl +Z2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBl +bmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0 +aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUg +YSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0 +aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBo +YWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlh +IGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBo +YWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQ +ZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdp +YXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGlt +ZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVp +cywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRp +bmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwg +dWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlv +IHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3Vl +IHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNx +dWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMs +IG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1 +c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50 +dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVy +ZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxh +LCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlz +cXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlz +Y2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +RG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3Nl +IHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBz +aXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1h +dHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQu +IFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBh +cmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2 +aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFu +dGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3Vl +cmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2Np +cGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFu +dGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3Vl +cmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3Nl +IHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlz +IGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0 +IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlx +dWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmlu +YXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1 +cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3Rp +ZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0 +IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWku +IE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBh +LCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1 +aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3Jh +dmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9y +ZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxs +ZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1h +bGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQg +bmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZl +aGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVs +dW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBh +bGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBk +aWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJl +cm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1 +dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVl +IHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQg +ZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJp +IHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2Rv +IG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywg +dmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBt +YXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFt +IHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3Mg +bmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4g +U3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4u +IERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVs +LCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxs +aXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywg +Y29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5p +YSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZl +bCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwg +dGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFz +IG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwg +ZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQg +Z3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVy +YXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRl +bXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1 +aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBl +Z2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0 +ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZl +bGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMg +cXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxh +IHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlv +LiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0u +IFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGlj +dHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGlu +IHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVs +dW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBp +YWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBp +biwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywg +ZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBk +aWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBv +cnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2Rv +IG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1 +dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUs +IGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNh +Z2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0 +IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlz +bW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vt +c2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNl +cyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBz +dW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhh +c2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMg +ZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBz +ZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRl +Z2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0g +c2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBB +bGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNv +bW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBp +YWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxs +YW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMu +CgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNl +cyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0g +YSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQg +bWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVp +cyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBu +ZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxw +dXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBl +c3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZl +c3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxh +LCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmlt +IHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2 +YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0 +ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFt +Y29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2Fw +aWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIg +b3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBl +dCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0 +IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFn +bmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFt +ZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVn +ZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVs +bGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBu +b24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVu +dHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWdu +aXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVz +IHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGli +dXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZp +dGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBs +YWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxh +IGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1 +c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFl +IGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFj +aW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBt +aSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBD +dW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250 +ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQu +IFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5h +cyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBt +YWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1h +bGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJp +Y2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0s +IHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQg +YSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlz +IGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3Is +IGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFu +dGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVj +ZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBl +dWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdy +YXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJo +IG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1 +bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5p +YSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNp +YnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVz +IHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlz +c2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0u +IFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRp +c3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQs +IGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50 +IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZl +bmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBs +aWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBs +b2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1w +dXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGli +dXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0g +bmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1 +aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2lu +IGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUu +IER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1 +cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50 +IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFz +IGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1 +bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0 +aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQg +bmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBE +b25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0 +dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVy +YXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQg +YW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBp +bnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFBy +b2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0 +aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4g +RHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1 +cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxl +aWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIElu +IGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlz +IGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3Vz +IHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVt +cHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQg +c3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUg +ZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8u +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQg +dWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQg +bGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9z +IGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFz +ZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxp +cywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRh +ZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0 +dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0g +cHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51 +bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyBy +aXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVl +LgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2Eg +ZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdl +dCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVy +dXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBh +bnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlk +IGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJu +YSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0 +IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBz +Y2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2 +dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5j +LiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxp +Z3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxh +b3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlz +IG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2Nl +dHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25h +LiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0 +cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1 +bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxh +Y2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRp +bmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJp +Y2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVs +bGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3Ug +aW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1p +IGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFn +bmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3Jw +ZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVt +IGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFu +ZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4g +ZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1v +bGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVz +IHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFj +Y3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0 +LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywg +bGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1 +dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNj +ZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBk +dWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFu +dCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFj +IHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVs +dW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0 +IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdp +dHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFk +aXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2Vu +YXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJk +aWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBs +aWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0 +ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNz +YSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1 +bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJp +bGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBl +ZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBj +b251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQg +ZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJl +dGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVs +aXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0 +cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVu +ZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3Uu +IFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3Jhdmlk +YSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2ls +aXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2Npbmcs +IGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQu +IE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBt +ZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdl +dCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNv +bnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0 +IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0u +IER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwg +ZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0 +LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1 +cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2Eg +dXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNl +bXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNp +dHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50 +ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1 +bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVz +LiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFv +cmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxl +cyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVs +aXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4K +Ck1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlx +dWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRp +IHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNl +cHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2Fu +LiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1w +ZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhp +Y3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxp +dG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3Mu +IE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNz +ZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIu +IERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlx +dWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3Rp +cXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBs +YWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2Fn +aXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9y +Y2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2Ug +dmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4g +RHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBm +YXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0g +ZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQg +c2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxl +cywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5h +LCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwg +ZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFy +ZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5k +dW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxh +b3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNp +bmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRh +dGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlx +dWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2Vz +IHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdl +dCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVh +dCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1 +ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29j +aWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5h +c2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0 +YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2ls +bGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGlt +cGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9y +dGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1 +YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQg +bWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1 +cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlz +aS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2 +aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0 +aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMg +cXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFk +YSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVs +dHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRy +ZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0 +LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1l +bnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEg +dm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3Rp +YnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1 +cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBw +bGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0g +aW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9k +LiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0 +YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBo +YXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25n +dWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQg +ZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFz +IG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1 +ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1 +bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4K +ClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMg +ZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1 +cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2 +ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZl +c3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMg +dHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBW +ZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJj +dSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4g +Q3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQg +b3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNp +dCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1 +aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1 +IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1 +bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJp +bGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBl +cmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdl +dCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1 +ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0 +YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVn +ZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBl +bmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1 +bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0 +YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBj +b25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFz +c2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0 +LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmli +aC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVn +ZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBl +dWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVs +dW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMg +aW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFl +OyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0 +LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBh +YyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMg +cXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJk +dW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJh +IHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBw +ZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4g +U2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5p +bSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4g +RG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5n +aWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1l +dHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2Vk +LCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUg +YSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBl +bGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBF +dGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25p +c3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNv +bW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1 +cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUg +c2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBF +dGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50 +IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGln +dWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBh +cmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQs +IG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlz +bC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQg +dGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxs +YW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0 +ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBl +dCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFk +YSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBz +Y2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEu +IEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4g +U2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBk +aWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2 +YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMg +bWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMs +IGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNj +dW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5k +aXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFt +IHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBk +b2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmgu +CgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50 +ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3Ig +anVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1 +aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50 +ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0g +Y29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJp +c3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1 +bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlz +IGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRw +YXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4g +UHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGlu +Y2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFj +dXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwg +bWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVu +ZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBm +ZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRp +YW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwg +ZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2 +ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNj +ZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0 +b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxp +dC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxp +cyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBu +aXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4g +UXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1 +bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVn +ZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0 +cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVj +dHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxs +ZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVu +dGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2Vy +IGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBN +YWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBl +bmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBV +dCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhp +bWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQs +IHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8u +IEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1v +bnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1 +cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1 +bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxh +IGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVs +cHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252 +YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3Rp +YnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3Vz +IG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJp +YmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0 +dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBl +ZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFn +bmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFu +dGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBl +dCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRy +dW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMu +IE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBj +dXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlx +dWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5p +c2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVl +dCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2 +ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWdu +YSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZh +bXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlh +bS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3Ig +Y29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9u +IHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNl +cmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBs +YWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVz +IGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2 +aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxp +c2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29u +ZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZl +bmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252 +YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMg +ZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5j +LiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGli +dWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZp +ZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUg +YWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBl +cm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJ +bnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIg +YWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBp +cyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBt +aS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxl +c3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3Is +IGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBl +bGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdy +YXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlz +dGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxp +dCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBh +bWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1 +Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBo +ZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBl +bGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5p +YSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFl +IG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNl +ZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEg +dml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0g +dGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBF +dGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxl +byBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQg +YW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8s +IHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1 +YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1 +ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRh +IGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBm +ZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5p +c2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1 +cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNl +bXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRy +ZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVz +LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxp +dC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFj +aWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0 +aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4g +ZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNh +Z2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwg +bnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMs +IGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRl +bGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBl +ciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQu +IFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMg +dG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBm +YXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBp +cHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1 +cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdl +dCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVs +bGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1h +bGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBm +cmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9y +bmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5p +YSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBw +YXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9u +dGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBl +Z2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVl +dCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1 +ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlk +aWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4s +IHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0 +b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxl +cyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1 +cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQg +YSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZl +bGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0g +cmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBO +dW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxp +cy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0 +IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4g +UGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQg +YXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlz +IGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwg +dGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0 +IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1w +b3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3Iu +IE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZl +aGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBj +b25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVl +ciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMg +dml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIElu +IHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVt +IHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0 +IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmlt +LCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1 +cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1 +bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNp +IGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9y +Y2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBl +dWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVu +ZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVl +IGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50 +ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMg +dml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBp +bXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZl +c3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVn +ZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdy +YXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5h +dGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNx +dWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50 +IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxh +IGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2Vs +ZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEu +IE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1 +cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxp +Y2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwg +bW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9k +aW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVt +LiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZp +bmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0 +dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1 +c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVz +LCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMg +dGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZv +bHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0 +aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVz +dCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9y +LCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVy +b3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJp +IHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVn +aWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFt +IHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNp +LiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxl +by4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBh +LCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2 +YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4g +aW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xv +ciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMg +dmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5p +YSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJp +cyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWku +IFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4g +VXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlz +Y2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5k +aXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRh +dGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmlj +aWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGlt +ZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5v +biBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFt +IGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQg +bm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUg +aGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50 +ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5j +IHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1 +dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1 +cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBn +cmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29s +bGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUg +YXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0 +aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmli +ZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJj +dSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVj +IGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2Vt +cGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwg +bmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVt +IGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0 +IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxv +Ym9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZl +c3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8u +IE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNl +bGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0 +IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVs +dmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNp +ZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQg +bmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2lu +aWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1 +cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8g +cGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3Vz +IGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1h +ZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBy +dXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2 +ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVt +IG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNp +cyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4g +UGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0 +b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2Vz +IHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFz +c2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3Jl +bSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNx +dWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1 +bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGli +ZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1 +c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9u +IHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRp +biBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1 +cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4g +ZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0 +dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVz +IGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4g +SW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBq +dXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4g +TnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwg +bGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3Iu +IFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBv +cm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVy +bmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1v +bGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFy +aXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVy +IHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3Jl +bSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlz +IHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVt +c3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1 +IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1 +cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1v +ZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFj +aWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBu +dWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVz +cXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVp +IGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVz +dGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3Qg +dXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8g +ZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3Ig +ZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9y +Y2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlz +IHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxh +dGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJo +IHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMs +IGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBk +dWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVj +IG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9u +LCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGlj +aXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRv +bG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1 +bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxh +bSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNp +dCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJu +YS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1 +cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2 +YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVu +ZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1h +Z25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2Vz +IHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVk +ZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVl +dCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQg +YWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0 +IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1 +LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVs +aXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxh +bmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4g +SW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxl +bywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVh +bSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUu +IE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0 +dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVz +dGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJp +Y2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQs +IGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2Vu +YXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMu +IEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUg +bmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1 +LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBO +dW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVy +aXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRl +c3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVu +dGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0 +b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBN +YXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFj +IGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRp +bWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQg +ZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQg +ZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVt +cHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwg +c2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4g +TnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNl +ZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVs +bGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3Qg +bmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9s +b3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMg +bmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFw +aWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNl +bmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0 +dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBw +b3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGln +bmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1 +Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2Fu +LiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwg +b3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBu +ZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVk +ZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJp +cywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9u +ZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVs +LCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2 +aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNl +ZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRl +cmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4g +cXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1 +bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhp +Y3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxh +Y2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdp +YXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3Vz +IGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4K +CkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRy +aWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJp +cy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRp +LiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMg +dml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxp +Y2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVz +LiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVu +dHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxv +Ym9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0 +aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2 +YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4g +YXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxs +dXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4g +U2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4g +VXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNj +ZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1 +bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5n +IGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVy +cmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNv +bGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0 +byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFt +ZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxh +Y2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3Jhdmlk +YSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkg +dmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBz +aXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBm +YWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQg +bWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVn +aWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBh +bGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBh +dWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4g +RG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNp +YnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4g +RHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVu +ZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0 +IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50 +ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVy +ZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGli +dWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1 +YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBt +YXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMg +YXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMg +aGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1h +dXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBl +dSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMg +aWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEu +IE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0 +dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1 +c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBq +dXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlw +c3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50 +ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQ +ZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5l +YW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUg +YWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVu +YWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29k +YWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3Vt +LiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQg +bWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNl +bnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlx +dWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1 +bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJy +YS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1 +bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBm +ZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9z +IHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBu +dW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBz +YWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVs +ZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50 +IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERv +bmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0 +IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4g +bWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBx +dWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBs +YWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1 +cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0 +aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUg +c2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1 +c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4g +U3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBh +bWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBs +ZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlz +Y2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVx +dWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBt +YXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVt +ZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBO +dWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxp +cXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVn +dWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVy +aXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEg +ZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQg +cnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNp +ZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBj +b25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9u +LCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3Vz +cGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVn +ZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJp +cyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVz +LiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9s +b3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxs +YW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMg +bW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1 +cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGlu +dGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0 +IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFn +bmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNl +bS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBx +dWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBz +aXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGlj +aXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVu +dGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFj +dXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3Bl +bmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5p +c2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNl +ZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlz +c2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJp +bmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lp +cyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNj +ZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1 +cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0 +cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJp +Y2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxl +bnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBG +dXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFz +IG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0 +IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51 +bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2 +ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBN +YWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIElu +dGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVz +IHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFt +ZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1 +c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1h +ZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBu +dW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBt +aS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3Rv +IHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBp +cy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3Vz +IHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwg +c2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29u +c2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwg +bW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNl +bS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQg +YW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2Vs +bHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdl +dCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1w +b3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRv +ciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4g +UHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1w +b3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdl +dCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVh +dCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwg +cmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFi +aXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5n +aWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4g +RXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmlt +IG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlx +dWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBh +dCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBs +aWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8u +IEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0g +dGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2Jv +cnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBt +YWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJl +dHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5k +aXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25n +dWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1 +bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1 +cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBm +ZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50 +LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJw +aXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQg +cGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1 +dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVz +IGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBR +dWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1 +cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0g +YSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBs +dWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBi +aWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0 +b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBN +YWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMu +IE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGli +dXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1 +c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBh +dCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4g +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +IEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3Vt +IHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFl +bmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwg +aGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vt +c2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBh +YywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBO +dW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNl +bS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11 +cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlz +IGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0 +IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIs +IGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBs +aWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRy +ZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29u +dmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUg +YWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVu +YWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNw +ZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBz +YWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1j +b3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBu +dW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJp +bmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVx +dWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRv +ciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdl +dCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0g +cHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQg +YW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBm +ZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50 +dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZl +cm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBo +YXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5p +YSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1 +YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBs +b2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBo +ZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMs +IHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0 +aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2Fn +aXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1 +bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4g +ZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWdu +YSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1w +b3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVt +IHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVu +YywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNl +ZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0 +YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBu +ZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFBy +b2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUg +YWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRl +c3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNp +dHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJ +biBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNj +dW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3Vz +cGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5v +biBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1 +YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2 +ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBh +dCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVu +YyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMu +IERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2Vk +IG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8g +aXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1 +bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEg +ZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQg +YW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMg +ZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVl +ciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9y +YSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1 +aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0 +IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZh +bXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9k +byBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFk +YSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxh +bmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1h +dHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywg +YmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBz +Y2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUu +IFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFz +ZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNz +aW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2Rh +bGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5l +dHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBl +bGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0 +b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11 +cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3Vl +cmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFy +ZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1 +YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJp +c3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlx +dWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFz +LiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3Jj +aS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVt +cG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51 +bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5l +bmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJp +IGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBh +Y2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJp +dHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFt +ZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMg +aXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0g +bnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVj +LCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2Vk +IGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlh +IGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVj +IHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5p +c2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5l +YyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBs +b2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1v +bGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1l +bnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBw +ZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Eg +dml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJl +cm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJp +dHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVn +ZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lk +dW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBj +b252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2 +aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBu +aWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4g +b2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywg +Y29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBt +ZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9u +ZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5l +YywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWdu +aXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNx +dWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRw +YXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3Vs +YSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9y +dHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVz +IHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBs +YWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1 +cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIg +bGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0u +IEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVu +dCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwg +cGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxs +YSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNp +YnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVs +dW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1 +bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3Ju +YXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21v +ZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0 +IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxs +YW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwg +ZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQg +c2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0 +aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0 +IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1 +Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxl +cyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2Jv +cnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdl +c3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0 +IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBo +YXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFl +IHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxv +cmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwg +ZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVs +bGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9y +LiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBh +YyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0 +dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1 +aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0g +ZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNp +dCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdl +dCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4g +UXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUg +cXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxp +cXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0 +cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBp +biBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQg +cGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRh +IGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1 +bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRv +ciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rv +ci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVz +IG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFt +IHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVz +IHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMs +IGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24g +ZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0 +dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMg +bWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxp +dCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVt +IGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2Vk +IGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9y +IHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQu +IFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUu +IE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywg +dmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVz +LiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVt +IHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4g +Q3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywg +bWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4g +SW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxv +Ym9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2Vu +dCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJh +ZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1v +ZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwg +cG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1 +c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBw +ZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4g +Q3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQg +ZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9y +Y2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2Ug +cG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1 +YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRh +cGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBp +bXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3Vl +LiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRh +IGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2Vk +LCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBz +b2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0 +b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0u +IE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBh +bWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0 +LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNl +bXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50 +ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxl +byBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlz +IGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBp +cyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBs +b3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0s +IHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJo +IHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1 +bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFs +aXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2Rh +bGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVl +dCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQg +bWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMg +cXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQ +ZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBO +dWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51 +bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBl +ciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUg +ZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxh +LiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRp +YW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3Rp +YnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0s +IGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVz +IG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdp +bGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIElu +dGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0 +ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2 +ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBz +b2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRl +LiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVl +ciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5j +IG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBl +cmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVs +bGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxh +IGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlz +bCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1v +cmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQg +ZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxh +IG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwg +cHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1 +cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBm +ZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVz +Y2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwg +cXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5p +c2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2Nl +IHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBx +dWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywg +ZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNp +dCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0 +aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJp +Y2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1 +cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBw +b3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2Np +bmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2Npbmcu +IFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZl +bGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEg +bGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVy +aXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9y +Y2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1l +dCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBt +ZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9y +Y2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJp +dC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlz +dGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlz +LgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1 +bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFi +aXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1 +bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2lu +ZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1 +LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERv +bmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1 +YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBs +YWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNv +bnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9y +IHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVt +IHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rh +cy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdl +dCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmlj +aWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2li +dXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMg +ZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFk +YSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4g +ZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVz +Y2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5h +dGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSBy +aG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0 +ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxs +YW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3Rh +cyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1l +bnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBw +b3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9k +aW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0 +cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxs +dXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQg +dmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBO +dWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBp +cHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRp +YW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0 +ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFt +IHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQg +cGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1 +dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlh +bSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBV +dCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVl +IGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQg +ZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBu +b24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ug +c2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJv +LCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVs +aXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMs +IGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0 +IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1 +aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEg +cGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0g +bWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0g +cHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRl +bGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNv +bGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNl +bGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVu +Yy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMg +YXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2Vk +IGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBh +bnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQs +IHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVt +cHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlz +cXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMg +bmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBv +dGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVj +aWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVj +aWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBl +dSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0 +b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQ +ZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBo +YXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlz +IGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBW +ZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBu +aWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlz +IGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxp +dC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5l +cXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2Vt +LiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1 +bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVj +aWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2Nl +IHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywg +bmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIg +bmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNx +dWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVs +aXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4g +SW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBt +YXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxp +cXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2Vt +IHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBu +ZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBl +dSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMg +bm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBw +ZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwg +cmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0s +IHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQg +bW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0 +dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlh +bS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVs +aXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8g +YWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1 +bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUg +cXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lp +cyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNj +ZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUg +ZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVu +ZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBt +YWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFt +IHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGlj +aXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxs +aXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBO +dWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlz +IHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBE +b25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0 +IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIElu +IG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxp +dCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNj +aW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBs +YWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50 +IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBp +ZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4g +UXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxv +cmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJu +YS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1 +dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVy +IGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1l +bnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNl +bSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlv +IHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8g +bGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRp +YW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0 +IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhh +c2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1 +ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2 +ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlz +LCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRy +ZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0 +ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xv +ciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlz +IGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVl +IGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVs +bGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3Jh +dmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0 +cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3Ju +YXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5k +aXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1 +LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlv +IGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3Qs +IHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9y +Ymkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQ +ZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVz +IGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3Rv +ciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJy +YS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmgu +IEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVn +ZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0 +cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQg +ZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3Iu +IFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0 +dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2 +ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51 +bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMg +aXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNl +Y3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVj +IHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3Rv +LCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlz +dXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEg +dmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNl +bSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2Eu +IFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMg +aW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFl +OyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQg +YXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlz +IGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVz +cXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBl +bGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEg +bGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBl +cmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVz +IGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVz +IGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlz +LCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxp +cXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMg +bGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1 +cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4g +SW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxh +LiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMg +dmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4g +TnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4g +TnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0 +ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25l +YyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUu +IFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBO +YW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZh +cml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3Vt +LiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBk +aXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3Nl +IHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3Vs +aXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3Ug +cmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4g +UGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhh +cmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRl +Z2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGlj +aXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1p +LgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5l +YyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVj +LCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVy +IGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlz +IGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVl +ciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5p +c2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwg +YWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMg +cXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBN +YXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERv +bmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5v +biwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVy +ZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEg +cGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJp +bmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2Vk +IGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQg +bmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3Vz +Y2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2li +dXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdl +ciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQu +IFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBs +aWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIs +IGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3Is +IGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0 +IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1 +YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMg +cHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0 +dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBm +YWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhp +bWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1 +ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlx +dWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxs +ZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNl +bSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJh +ZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xs +aXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVs +bGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVu +IGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xs +aXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBj +b25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1h +dXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwg +c2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBl +cmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3Vz +IGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5l +YywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQg +ZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9y +IHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1 +aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1 +cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVn +ZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0 +aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlz +c2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBO +dW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5j +IGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4g +Vml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVj +LCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQu +IFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVu +dCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0 +dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBw +ZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBl +dCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEg +cXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVn +ZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBh +cHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0 +cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWdu +aXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWdu +YSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBh +cmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4g +bGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVt +IG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVj +dHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUg +aXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUg +Y3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGlj +dWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxh +IGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERv +bmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQg +c2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZp +dGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEs +IG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24g +bmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3Jl +ZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1 +cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJt +ZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0 +IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9k +aW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBu +ZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBz +b2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2Vs +bHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBz +aXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUg +anVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJp +cy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRp +cGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFu +dGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxh +LiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0g +ZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1 +ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJp +c3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2ku +CgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBj +b252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xs +aWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBz +ZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9y +IHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVl +LgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNl +bmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVz +dGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBk +b2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2Jv +cnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0 +IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0 +dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlz +Y2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1 +cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdl +ciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEg +bWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpF +dGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGln +dWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQg +YW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9s +b3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVz +IHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBu +aXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUg +YmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVs +bGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9s +dXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlm +ZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVj +IHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2 +aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBp +dCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBj +dXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2Rh +bGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBw +bGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5k +cmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNz +ZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9s +b3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVp +cyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2Vk +LCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJo +b25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0 +dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1v +bGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3Nl +IG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBs +ZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVv +IGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1 +aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwg +bmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJy +YSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2ku +IFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBs +ZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNp +cyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxs +dXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVy +by4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQg +bm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlz +LgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhv +bmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZl +c3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0 +cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMg +b2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRp +biwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBk +dWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9k +aW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxs +ZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2Vk +LCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBo +ZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxh +IGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5h +cyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBD +cmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4g +SW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1z +YW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxs +dXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1 +cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9s +b3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBp +ZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBV +dCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmli +aCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1p +LiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1 +ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRh +IGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0 +LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2Rh +bGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNl +bSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBs +YWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24g +ZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJo +LiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVj +dG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xl +c3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0 +IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBz +aXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNl +bmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3Vz +cGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQg +YmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhv +bmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQu +IEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVp +cyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBW +ZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxs +YW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3Vl +IHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQ +aGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEs +IHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRp +dG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0 +aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGll +biB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVl +IHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4g +QWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVy +bmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNj +aXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlh +Y3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlx +dWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJl +dHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoK +UGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBl +dCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2ku +IFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1l +dHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBp +ZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFu +dGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJz +dXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9y +dHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQg +YW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGlt +cGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0s +IHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIg +YSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0 +LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJp +c3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVt +cG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2ll +cyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0 +dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4s +IGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWku +IFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFl +bmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWws +IGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29u +Z3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9y +dG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxh +Y2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBv +cmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBO +YW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0 +b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNl +ZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251 +YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0 +LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwg +bnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMg +ZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4g +UHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0 +dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRp +cyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9y +IGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRp +cyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBh +dCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBh +YywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBw +bGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1l +bnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNp +dCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2Rv +IHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51 +bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBs +YWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBw +dXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1h +Z25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVu +IHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4g +bnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50 +ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVl +IHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxs +ZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFz +IGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRp +Z25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVj +IGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlz +IGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBu +aXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFs +aXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVt +IG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMu +IFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlz +aSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZh +bXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1l +bnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRl +IG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0g +c2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxl +cmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBn +cmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVs +aXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRl +c3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGlj +dWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNz +YSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBu +ZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQu +IEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMg +dXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRv +ci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2Rh +bGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1 +ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMu +CgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2Nl +bGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0 +LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFj +IGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBt +b2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFi +aXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQg +ZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0 +IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBk +YXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxp +cyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkg +c29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2Vw +dG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBz +dW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVz +IHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxp +Z3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRp +YW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0 +LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBq +dXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRh +ZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVz +LiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVt +IGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQg +YW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBh +LCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBN +YXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJh +Yml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBz +ZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERv +bmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZl +c3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBu +aWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRl +Z2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwg +Y29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2 +ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMg +cGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBp +cHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxp +cyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0u +IFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRp +dG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVp +cyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFt +IG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3Ig +dmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2lu +aWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5h +dGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBw +b3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBh +ZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVz +IHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4g +QWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBD +dXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0 +IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVp +cyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1 +bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1 +ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlk +aWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBN +YWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlz +dXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4g +YSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0 +dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9u +IHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBk +aWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxp +dC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmlj +aWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRv +bG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1 +YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2 +dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0 +b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5j +aWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFj +dXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxp +cXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9u +IHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIu +IFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9y +IGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZp +dmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRp +cyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIg +dmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1 +bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBh +dWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9u +Y3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxh +LiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2Vk +LCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNv +ZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGln +dWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3Jl +bSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNv +ZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBz +ZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlw +c3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1 +YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lh +dC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25z +ZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwg +YWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRl +IG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFy +Y3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVj +IHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVu +ZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJj +dSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwg +c29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVx +dWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4K +Ck51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRp +bmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlz +Y2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2Vk +IG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2 +ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlz +LiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVl +dCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wg +bmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51 +bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBl +ZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGli +ZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51 +bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNp +dHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVt +IGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5p +c2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3Uu +IEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2Fn +aXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2Vj +dGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBw +bGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNl +ZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBm +YXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1 +bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4g +ZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSBy +aG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0 +LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBt +aSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1 +cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEu +IFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdp +bGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0 +YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0g +bGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxp +dC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBT +ZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4g +TmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlh +IGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVu +IG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1 +aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxh +IGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxs +dXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1 +bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGlu +Y2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50 +ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBj +b25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVj +dHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVu +ZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2 +ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3Rv +ciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVs +aXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFj +aW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMg +bGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJh +ZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2Vu +dCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0 +IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0g +YW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5l +bmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1h +Z25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxh +LiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVn +aWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVz +dCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0 +LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4g +QWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBj +b25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3Nh +IHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlz +LiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0 +IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1 +cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3Rv +LCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGlu +IHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4g +UGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVy +cGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJp +dHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBp +biwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRv +ci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGln +dWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1h +c3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1 +aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRp +ZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRh +IGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNz +aW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBw +ZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVz +dG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0 +YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2 +aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFu +dGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2 +ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4g +SW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmgg +c2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVy +YXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwg +ZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRw +YXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBl +cmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1h +dXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3Vs +YSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xs +aXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8u +IEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBl +bGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBu +ZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1 +Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRv +ciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBh +YyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0 +ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxh +LCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxh +LiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3Vz +IGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4g +aGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxp +Y2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBp +c2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFj +aW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0 +YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBw +dXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEg +Y29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRp +dG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxp +cyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNh +cGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMg +aXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVy +IGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUg +aXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUg +Y3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0 +IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1h +c3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFk +aXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBt +aSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVy +IG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25z +ZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vy +c3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGli +dWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0 +dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1h +ZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEg +bHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMu +IE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2Vk +IHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRl +cmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25h +LiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0g +bWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBv +ciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2Vs +bHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9y +IGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNl +bGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4g +U2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3Rp +ZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBu +aXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVj +dHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZh +bGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFz +IGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFl +LCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFi +aXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBB +bGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkg +cmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEg +c2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlm +ZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBj +b25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51 +bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBw +cmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJl +IG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3Vt +IGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24g +ZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBw +cmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMg +dmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1 +ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZh +cml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9k +IHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVt +cG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1 +bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxp +cy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1 +cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxs +YSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4g +YmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmgu +IENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZp +dGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQg +aW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0 +IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNp +bGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZh +bGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNl +ZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFw +aWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBl +cmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0g +aW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhv +bmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMg +c2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEg +bm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1v +cmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVy +cGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3Jl +bS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwg +Y29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNj +aW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1 +aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBN +b3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFl +LCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNh +Z2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51 +bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1 +bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMg +c2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51 +bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBt +YXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMg +dml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25h +LiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBh +Y2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0 +IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBl +Z2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBu +dWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50 +ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1h +Z25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1 +bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25n +dWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIElu +IHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4g +UHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxs +YW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBk +aWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMg +bG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBv +c3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVz +LiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwg +bGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1 +LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51 +bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBt +YXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMg +bWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3Vs +YS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8g +cG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVz +dGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9y +ZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNl +bS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMg +c2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9p +biBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4g +UXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0 +aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJh +Yml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1 +bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVy +IG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJy +YSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVy +YXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMg +Y29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3Vz +IHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRp +cGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1h +dXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEg +anVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1h +c3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1 +cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJp +cyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4g +U3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVy +bmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9y +LiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2 +ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5k +aXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1 +YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24g +ZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlz +aSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlz +IG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENs +YXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251Ymlh +IG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxh +IGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4g +TnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZl +cm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNl +cmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0g +bWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9y +IHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJp +c3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMg +ZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3Rp +YnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBu +ZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZp +dGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxp +dCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJh +IHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBp +cHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBj +b25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFBy +b2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3Vt +IHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVt +LCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4g +RnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBw +dWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21v +ZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVl +LCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1 +cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMg +cG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5p +c2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBl +bGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZl +bGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2 +aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBz +ZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0 +IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQg +dWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1h +Z25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBw +bGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2ll +cyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUg +dGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBl +cm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51 +bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBv +cm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1 +aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0 +cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jh +dmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNp +LiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZl +c3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxw +dXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1 +bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25l +YyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBD +dXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGlt +ZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2Vs +ZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxl +bnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51 +bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMg +aW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29y +cGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVy +bWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRy +YSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxp +cXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwg +dmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQg +YWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWws +IGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1 +Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBu +dWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRp +bWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMg +ZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhh +cmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNl +bSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4g +UGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2 +ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0 +IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9s +bGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50 +dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFk +aXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlz +c2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2 +ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9y +LiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vt +c2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0 +LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5v +biBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkg +aW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xs +aWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMu +IFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1 +bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29u +Z3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBz +ZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZl +bGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5l +Yywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFn +bmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWku +IE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4g +UGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4g +TWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxp +cy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMg +c29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVz +IGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1 +bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFz +c2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIg +cHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFj +LCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhp +Y3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRy +aWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21v +ZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Ig +b3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVy +cGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1 +bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxs +YSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0 +IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2 +ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8u +IFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNj +aW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGll +dCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmli +aCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1 +aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51 +bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0 +IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZp +dmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlz +LiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJk +aWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVs +IGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNv +bmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBj +b25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZl +bGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBl +dSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3Jl +ZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2lu +Zy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQg +bWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3Rp +ZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQg +ZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1 +bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJw +aXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0g +bmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBu +dW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBh +YyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMg +c2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNv +bnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rp +by4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGli +dWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNl +cyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxl +Y3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0 +dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3Qs +IHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRp +bmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4g +RG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVz +dCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEg +YmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMg +ZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQu +IFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRp +bWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVx +dWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwg +cHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENs +YXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251Ymlh +IG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxh +Y3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9y +bmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNp +IGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBh +IHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2Fu +IGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVk +ZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3Rp +YnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0 +LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1p +LiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQg +bGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlz +IHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBl +bGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBl +cmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVu +dGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1 +bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNl +bGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWws +IGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEg +bnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3Vs +YS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwg +ZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNx +dWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2Fw +aWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVh +biBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUg +aXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4g +UGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1l +bnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9s +b3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBt +YXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwg +dWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFt +LiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZl +aGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25l +YyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVj +LCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRw +YXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1 +ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0 +IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9y +IHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFn +bmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxh +bmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdp +dHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1 +bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBu +aXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0 +IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +VXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4g +UGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMg +bGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMg +aW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBl +dCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFs +aXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1 +cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxh +bWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEs +IHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29u +ZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJp +Y2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQ +cmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZp +dmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNl +bmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2 +YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMg +bGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQg +bGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxl +bWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlz +IGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51 +bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0 +dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUg +ZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9y +YmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRy +aWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBs +aWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQg +bG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVs +aXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBp +cyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3Vz +cGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRl +c3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1 +YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMu +IEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5p +c2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMg +bWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVz +cXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdp +YXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhl +bmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFs +ZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwg +dWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBN +b3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFn +bmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwg +dWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJp +cyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxp +YmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9z +IGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNl +bGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRp +Y3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRp +cGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5k +IGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhl +bmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5k +aXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQg +YW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4g +TnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlx +dWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2Vk +LCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4g +TWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0 +aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xs +aXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4g +ZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRp +cyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVz +IG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwg +c2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBz +ZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVu +ZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlk +IGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBx +dWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBi +bGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3Vz +cGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0 +ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1 +YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0 +aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMg +ZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4g +c2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3Jl +bSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5k +cmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRv +cnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNv +Y2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBu +YXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQg +ZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRp +bmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBs +ZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVs +IHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVs +aXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVz +IGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJ +biBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVj +LCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVu +dGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhp +Y3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0 +dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBh +YyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNv +ZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlz +IGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpB +ZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlz +dXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGli +ZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxs +aXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBh +IGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBl +Z2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUg +anVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVh +bSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1h +dXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMs +IGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1w +ZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxh +IG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJt +ZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMg +dHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50 +IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50 +aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2 +ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBz +b2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0 +b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNs +LgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5j +IG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVy +b3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBT +dXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQg +ZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQg +c2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywg +bmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQg +dWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBw +cmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlh +IEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0 +IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVy +bmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVs +cHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmlj +ZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4g +TmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkg +c29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2Vw +dG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBz +ZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVs +dW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xs +aWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVz +IHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVu +Yy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBz +ZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBs +ZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVs +cHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJw +aXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVt +IGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRh +LCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFl +IGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRy +aWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFy +aXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRv +cnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5j +IGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBo +YXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +UHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJh +ZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3Vz +cGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQg +YW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBD +cmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUs +IHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxh +bmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVy +IGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVs +bGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBm +YXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3Vh +ZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUg +cHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhh +c2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxs +dXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVl +IG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNv +ZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBs +YXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBl +Z2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBl +bmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3Vs +dXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3Mg +ZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJp +IGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9s +bGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1 +bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0u +IFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFy +Y3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlz +IGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11 +cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBO +YW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVu +dGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGli +ZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRl +IGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxl +aWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9k +byBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5h +LCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0 +dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1 +c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2Vy +IG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmlt +LgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5j +aWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBk +b2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1 +bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0g +ZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlh +Y3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJp +dGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxs +ZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQg +YWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50 +dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywg +cGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNp +ZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxs +YW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0 +IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZl +bCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUg +ZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9y +bmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3Rv +IHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0g +dmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBh +ZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBh +dWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVl +IG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2lu +ZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZh +dWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9u +ZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZl +bCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQg +YW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRp +cyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFBy +YWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1 +IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZl +cnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUg +aXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUg +Y3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0 +IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUg +aXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUg +Y3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBv +dGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVy +YXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFs +aXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUg +cGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIg +bGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFi +aXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBx +dWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFt +ZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51 +bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBw +b3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBl +dCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3Jhdmlk +YSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0 +IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50 +ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVj +LCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGlj +dWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0g +YW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9z +dWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlx +dWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFt +IGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8g +bm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBh +dCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBl +ZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxl +bWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1 +YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5v +biwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFy +aXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNz +YSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZh +cml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3Mgbmli +aCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3Vz +cGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERv +bmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBu +aWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMg +bGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29u +ZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBk +dWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBh +dWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVs +bHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1h +Z25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVp +IHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3Jh +dmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQu +IERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1 +cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwg +dml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0 +IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwg +cmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0 +LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVp +cywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1 +cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5n +IGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBB +ZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1 +aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVt +IHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJp +c3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0g +Y29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1 +bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwg +c2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVp +IGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWdu +aXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0 +aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5l +Yywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBu +aXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdy +YXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0 +dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVs +aXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9k +IHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2Fu +IGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1 +bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0g +cHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2Vs +bHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdl +c3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQs +IHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2Vy +IGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlx +dWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1v +ZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1 +bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1j +b3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJ +bnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1 +bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1 +cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2 +ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1 +ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3Bl +bmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRh +dGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3Qu +IE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3Rp +YnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBz +aXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZl +bGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJp +dXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBw +dWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29y +cGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVu +LCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3Jj +aSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwg +ZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5l +dHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEu +IFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIg +bWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEg +cGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24g +dmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVt +IG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMg +ZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBs +YWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMg +YmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFl +IHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNl +cmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlw +c3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2Nl +IGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVy +b3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5p +YSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBl +Z2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0g +c29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMs +IG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZl +c3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBm +YXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxl +c3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVz +dWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2ll +cyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBv +c3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBw +ZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNv +bnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVs +ZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUu +IE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5h +cyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlz +bW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZp +ZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5v +biB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlz +IGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBh +YywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVz +IGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZl +bCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2lt +IG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1 +aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3Nl +IHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxh +Y3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFu +dGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVu +YXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJl +cm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2Jv +cnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMg +dml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMg +c2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVx +dWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNt +b2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGlu +IHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1 +aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBp +cy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxh +dGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1 +LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFj +IGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBv +cmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMg +ZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVj +IG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25l +YyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRp +biB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQg +dm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1l +dCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRl +cmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2lu +IGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFt +IGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVp +cyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBi +bGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZl +bmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFs +aXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1 +Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNl +ZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVz +LiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3Vz +Y2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUg +bWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZl +c3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0 +cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFj +dXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZl +cm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxs +dXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywg +bnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBz +YXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0 +b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJp +bWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMs +IG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1 +cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoK +U3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdl +dCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBw +b3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMg +c2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRl +LiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1 +c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBz +ZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5p +YmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2Vs +ZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxw +dXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBE +b25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3Vs +YS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3Jl +ZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBD +dXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0 +IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4g +TnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2Vy +YXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNp +ZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2Vz +IGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEg +aXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1w +ZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFy +Y3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEu +IEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIg +bnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRh +cGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0 +IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0 +LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVz +dGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNv +bGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vt +c2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBp +bnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFv +cmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0 +ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBh +bGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWks +IG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBt +b3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1 +cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0g +YW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9z +dWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVs +dHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRp +cyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBp +c2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMg +dHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0 +LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1 +bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1w +dXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwg +aWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBw +cmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlh +IEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUu +IENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251 +YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5p +bS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1 +bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQg +bWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0 +IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVt +IHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNl +ZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBz +YXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNp +cy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVz +dCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1v +cmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1 +cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwg +dGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNl +Y3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9k +aW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1 +aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVs +aXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCBy +aXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBp +cyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQg +cXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBl +ciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVk +aW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNx +dWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVt +IGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBD +cmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVl +dCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBl +dSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQu +IEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1v +cmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUg +aW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNv +Y2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRv +cyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBE +b25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIg +dmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3Vs +YS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9y +YSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51 +bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2 +aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERv +bmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFt +LiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVl +IGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNp +bmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0 +aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kg +bHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVs +IG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVp +cyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVj +aWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJp +bmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2Fn +aXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywg +bGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2 +aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxl +aWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBs +ZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0s +IG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3Jl +ZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlh +LiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUg +dXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0 +IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBv +c3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwg +Y29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBu +aXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4g +SW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlz +IG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2Nl +dHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUg +ZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEg +dmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVy +ZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEg +dGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQg +dXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWku +IEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVz +LiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4g +RG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZl +cnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1 +bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVp +cywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUg +aGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJp +Y2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJp +dC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBm +YWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1 +bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9s +dXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVs +dW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBp +bnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0 +ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50 +ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBB +ZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUg +bGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNl +bGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUg +bGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5p +bSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1p +LiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0 +aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBt +ZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClBy +YWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFw +aWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFi +aXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxp +dCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3Rp +YnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJp +c3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0 +aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwg +ZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3Vy +YWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3Jj +aSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBh +bWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMs +IGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1h +dXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBw +cmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlh +IEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRp +ZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwg +aGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBp +biBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRl +IGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQs +IGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0 +aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRy +aWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUg +bWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25n +dWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2Eu +IERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBO +YW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4g +TnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQs +IG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlz +bW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4g +ZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQ +ZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBs +ZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0 +ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVp +cyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0g +b3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZl +bCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRl +LCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0 +YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2Vk +IGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBh +YyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9u +ZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxs +YSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVz +IGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0 +ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBt +YXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0 +LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlh +bSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3Np +bSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1v +ZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVz +LiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlh +bSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlh +Y3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxh +LCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1 +IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51 +bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4g +UHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVs +bHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1j +b3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1w +b3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBt +aSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUg +aGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2Vs +ZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIElu +dGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2Vk +IHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFt +IGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJp +dXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFs +ZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1 +c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1z +YW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNz +ZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNp +dCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xv +ciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpR +dWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFk +YSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVz +dG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBh +bGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNx +dWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29u +dmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3Vz +LiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBw +dWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRy +aXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVn +ZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQg +YmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJh +ZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lk +dW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMg +dHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1 +cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5h +dGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxp +cyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0g +bmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxl +bWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5l +bmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBu +dW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0 +b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4g +RHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBp +ZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNp +LCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVp +c3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBs +b3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQs +IGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0 +LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVz +IHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50 +ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGku +IFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVn +ZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVj +ZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmlt +IG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBv +ZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUg +YWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVu +YWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRl +bXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1 +bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRl +cywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1 +dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBs +b3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZh +Y2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0 +YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxs +aXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVs +dW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5v +biwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVu +ZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJw +aXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUg +bmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEu +IEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUu +IENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwg +cGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0g +cXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1h +ZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJz +dXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFt +IG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2ku +IFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBz +b2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJy +YSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwg +c2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVz +IGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4g +Q3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29u +c2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1 +cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0 +LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNp +bmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGlu +IHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5h +ciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2ku +IE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGlt +ZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQg +bmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxs +aXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVp +IGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBV +dCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1 +bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEg +ZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxp +cXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9z +IHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRl +Z2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMs +IHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2 +aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4g +TnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVz +cXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3Vh +ZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxh +b3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhh +YyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0 +LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZp +ZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlx +dWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBl +Z2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBG +dXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0 +IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1 +cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5k +cmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBl +ciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0 +LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVl +ciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBz +aXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1p +IGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwg +ZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0 +YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVt +cHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlh +bSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBs +YW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1l +dCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNv +bGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0g +YmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZh +bWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJt +ZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kg +ZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBp +biBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBl +ciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJp +dCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBM +b3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4g +Vml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxp +c2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMu +IEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQg +dWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0 +dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVs +bGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1 +Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1 +cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0 +cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNl +ZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9y +dG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVj +aWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1 +bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4g +UGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBz +YXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEg +aWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVz +dWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmlu +Z2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFy +ZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBm +cmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0 +dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3Vt +IHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVz +LCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2Vz +dGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBt +ZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBw +ZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1 +bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNv +ZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3Iu +IERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBk +b2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBh +dWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwg +dGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlz +LiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhv +bmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5j +IHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4g +Q3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1 +Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVs +bGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJj +dSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxl +by4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGlu +Y2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1h +dXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3Ig +YXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1h +ZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGlj +dWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25n +dWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwg +dWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0 +YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZh +cml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRl +bGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlw +c3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBw +b3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVz +LCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEu +IEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1 +Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kg +ZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlz +bW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFu +IGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGlu +LCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdl +ciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0 +YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBl +cmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3Rp +YnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQg +ZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZp +ZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlz +IHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUg +ZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZl +c3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZl +bGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJp +c3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51 +bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5h +LiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0 +dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9s +ZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8g +cG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBE +dWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFy +IHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIg +ZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2Np +cGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBv +ZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGlu +Y2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0 +cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVt +IGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1 +cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBs +b3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3Mu +IEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNj +ZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0 +IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVy +bmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJ +bnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4g +TnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBj +dXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11 +cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1w +ZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwg +dmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVz +dGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBz +aXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBp +bXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNl +ZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQg +bWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2lu +ZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNz +ZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUg +ZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVz +LiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50 +dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBl +cm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRp +Y3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9u +IGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1l +cyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBu +dWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNh +Z2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0 +ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBp +cyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2 +aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGlj +aXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVn +dWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMg +ZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5k +dW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwg +c2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFs +aXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVy +IGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlz +aS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJp +YmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNl +bSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9y +dGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3Rp +YnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1h +ZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1 +cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1 +aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmlu +YXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMs +IG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlz +aS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEg +aWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBw +b3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVs +bGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxh +Y3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNl +bmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRy +dW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwg +ZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1h +dXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBu +b24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVs +bGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3Ig +ZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBv +c3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2Eu +IEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBs +aWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUg +ZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQg +cXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJv +LiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2Nl +IG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNh +Z2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBh +ZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2 +ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJp +bmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJw +aXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0 +IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4g +YXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0 +byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVs +bGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVv +IGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1 +c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5h +cmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEs +IGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3Bl +bmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxp +cy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVz +IGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNl +ZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBh +dCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1 +dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3Qu +IER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1 +cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBk +aWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8g +ZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxp +c2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxs +YSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVl +IG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxp +YmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGll +IHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQg +ZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFj +aWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJv +cyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kg +bHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJp +c3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVh +IGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRl +bGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxp +Z3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkg +bnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1h +c3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBp +cHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1 +ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9y +LiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBs +YWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBx +dWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBh +bWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4g +Q3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBp +cyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11 +cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVt +IGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25h +IHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBv +c3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBj +b25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2 +YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxp +cXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZy +aW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBW +ZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQg +dml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRp +dCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50 +ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywg +cG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBt +b2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1v +cmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJw +aXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGli +dWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2Vz +IG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZl +cm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMg +aGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIElu +IG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVx +dWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0 +b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5j +IG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMg +YmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1 +ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVz +cXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3Ig +bmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVy +aXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFu +dGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVu +dHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJv +cyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFj +aWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVz +IGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2Vt +IGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVu +YyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwg +dWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEu +IERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVx +dWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3Iu +IERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmli +aC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1 +cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFz +IGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMg +bG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1 +ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlz +c2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3Vl +IG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBT +ZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3Jj +aS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1 +cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4g +RG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywg +aW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMg +aXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2 +ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRh +ZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwg +dmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1 +bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVp +cywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEg +ZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3Vs +YSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2Vy +YXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQg +dml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVn +ZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1 +c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNp +ZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4g +U2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBO +dW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0 +YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0 +dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBT +ZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVt +IHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9y +dGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVt +IGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJp +dXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJj +dSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMu +IERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2Vk +IGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQg +ZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxl +cmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBu +ZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxh +Y2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEs +IGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxp +Y2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBh +dCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQg +cG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2lu +aWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBs +aWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVz +dGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQg +YW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNp +bGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0 +dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0 +IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlx +dWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1 +ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9u +ZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVz +LiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVp +cyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVt +IGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5p +c2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1 +bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0u +IE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVy +aXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJj +dS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFi +aXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJp +cy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBv +cmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQg +ZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51 +bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMs +IGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3Rv +LCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0 +by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3Vt +IGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4g +TnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxs +ZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4g +aW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQg +bGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxl +cyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBW +aXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0 +dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQg +Y29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFt +IGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4g +TWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4g +Q3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBz +dXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxp +cy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRl +bGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5j +LiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdp +dHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlm +ZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZh +cml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVj +IHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1h +dHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0 +dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlz +LCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1 +cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBl +cm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVt +LCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2Vk +IGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2Nl +IHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3Vz +cGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0 +LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0 +dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2lu +ZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUu +IE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0 +aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50 +dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxs +YW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVh +bS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUg +YWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMg +ZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUg +dmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0 +cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVu +dCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25n +dWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBw +ZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVu +ZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIg +aGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBx +dWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBO +dWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3Ig +ZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0g +YWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9s +bGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBl +c3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVy +ZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFj +Y3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEg +c2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4g +U3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFt +IHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQg +YW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1 +ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVz +cXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMs +IGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRp +c3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ks +IGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBh +dWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2lt +LiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdp +bGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBu +YXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1 +ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBh +IG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0 +IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2Vz +IG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRl +c3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNj +ZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5l +YyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5p +c2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMg +ZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxp +dCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVj +ZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVn +ZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRl +bXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQg +ZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3Bl +bmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNl +bmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5j +IG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4g +TWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZl +bCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4g +TWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZp +dGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2Fn +aXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2Vx +dWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9s +bGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4g +RG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1l +dCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVz +IHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBz +ZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3Ig +cGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwg +YWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJv +aW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3Ig +YWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwg +YWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2 +ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhv +bmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1 +ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxs +YSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRp +YW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5l +YyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUs +IGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBm +ZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1 +bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFs +aXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGlu +Y2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRp +cywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxl +c3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJh +IG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNz +ZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUg +c29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBl +dSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBh +dCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxp +cywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBs +b3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMg +aGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhh +cmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0 +ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1 +Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlz +cXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBu +b24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBm +ZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0 +dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJl +bmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3Ig +ZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVj +ZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51 +bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMg +ZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3Rv +IHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBw +dXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9y +ZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIElu +dGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVs +dHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVj +aWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVh +biBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVu +ZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2Fu +IGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywg +bW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5j +IHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4g +U3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBw +aGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1 +aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1 +Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1 +aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJl +cm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJp +dCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFs +bGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQg +bGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5k +aXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdp +dHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3Jw +ZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5j +LiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdp +bGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUg +dmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBl +Z2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBt +YXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVy +dXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50 +ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxp +cyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0u +IER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1l +bnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNl +bGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBp +ZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0s +IHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2Jv +cnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5k +cmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNh +Z2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVt +IGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0 +aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlz +IHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0 +LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBu +b24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3Ig +YWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNp +dCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywg +aGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBw +aGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUg +cGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMs +IHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2lu +IG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMs +IGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1 +ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVk +aW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBh +ZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1z +YW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVu +ZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBt +YXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0g +ZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5l +bmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBt +YXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBw +dXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERv +bmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1h +Z25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBz +dW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEu +IER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUs +IGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1l +dCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVs +aXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBs +YWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0 +b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMg +ZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9y +Y2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVz +IGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBj +b25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUg +aGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRp +dCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRp +cy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxh +bmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2Vs +ZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1 +aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxs +dXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0g +aW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVz +LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVz +IGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxl +bnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3Ig +bWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBx +dWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUg +bnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRy +YSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQg +bm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3Vz +IHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUg +c2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBG +dXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4g +TWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9y +IGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxh +IGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0 +aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZh +dWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1 +bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVy +IGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQs +IHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBz +dW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVs +bGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0 +aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0 +IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxl +Y3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJp +c3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2ku +IEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBh +bnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2Jv +cnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxp +cy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1 +bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRl +LiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0 +YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8g +dm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVy +IHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQs +IGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50 +IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252 +YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRh +LiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJo +IGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rp +by4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29u +ZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1 +cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMg +dmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywg +dGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNz +aW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUg +dm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQu +IEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBw +b3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRp +dG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRp +bmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1 +cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBz +dXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFv +cmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIElu +dGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVy +IGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWdu +aXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBh +IG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVz +LCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0g +bGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEu +IE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJl +LiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBz +aXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5p +YmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0g +YXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVp +LiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2Fn +aXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5j +aWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEs +IGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2li +dXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBy +dXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRp +cyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3Rh +cyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1h +Z25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNl +bGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVy +bmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVt +LCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJv +cy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEg +ZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBW +aXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBl +bGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMg +YXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMs +IGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxp +dCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBh +bWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBx +dWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVp +c3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVh +bSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVh +bSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmlj +ZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBm +ZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVy +IGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRh +cGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEg +bm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBu +dWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4g +TnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1v +bGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1 +bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRl +bXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVy +b3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9s +b3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMg +ZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0 +dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBu +b24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxl +Y3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVs +aXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1 +aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0 +IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBl +ciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1v +cmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVs +aXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBW +ZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1 +aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3Vy +YWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFs +ZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50 +ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9y +dGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBl +Z2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNl +bnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8s +IG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9y +dGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3Bl +bmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRl +IHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3Vy +YWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdl +dCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kg +ZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90 +ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQg +ZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGli +dXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBl +cmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBO +YW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRp +Z25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBw +aGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Np +b3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3Mg +aGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51 +bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0 +LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBE +b25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBl +ciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2 +ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBh +dCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRv +bG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBh +IG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3Jl +bSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZl +bGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmll +bnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZl +bCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlz +IGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVz +IG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2 +aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkg +bHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVp +cywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxs +ZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxs +YW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMu +IFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBs +aWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJp +bmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBO +dWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0g +cXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVs +dW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdy +YXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1h +dHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxh +IG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVn +ZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1w +b3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwg +cmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2Rh +bGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBO +dWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5l +YyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0 +LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFt +IGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRh +cGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBx +dWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJp +IHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdl +dCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51 +bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVy +dXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4K +ClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxp +cyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2Ug +bWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVh +bS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ks +IHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNl +ZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlz +IGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1 +Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBh +bWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1 +bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2Vz +IHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBs +b2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1 +ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2Npbmcg +ZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNl +ZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlz +LiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGli +ZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMg +YXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kg +bHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBt +YWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1 +cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kg +bHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4g +TnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlx +dWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoK +RHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxh +bWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1 +ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1 +dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBh +YywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBw +cmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVj +IGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0g +bmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1 +cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNl +Y3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRy +aXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBv +cnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVl +IHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4g +RG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwg +bmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVz +IHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMg +b3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVp +c21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBu +dW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdl +dCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2Ug +aGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlz +IGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9u +Y3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxs +dXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1j +b3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1 +cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1 +bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0 +dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8g +YXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVt +IHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMg +aW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVs +LCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxs +YSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1 +bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0u +IFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBv +cmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1 +aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhh +cmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBs +b3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBx +dWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBm +ZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZl +bGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVp +c21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24g +bGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0 +IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBh +IGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQu +IE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1 +Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFt +ZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNx +dWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVk +ZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0 +dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVs +dmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1 +cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxp +Y2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1 +cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4K +ClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVn +dWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFy +Y3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRl +LiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBl +ZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVz +IHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVl +LCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVx +dWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVu +dGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1 +cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVh +bSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1 +cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBw +ZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVz +IGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0 +b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxs +ZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1h +bGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJl +dHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRh +cGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0 +aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJo +IGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxl +Y3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4g +Q3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVl +LCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJ +biBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBz +Y2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1 +cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0 +IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFz +Y2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmli +aCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUg +YXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMg +bGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50 +ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0 +aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVh +bSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZp +dGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMs +IGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBt +YXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9u +IHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRl +IGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhv +bmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVs +bGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9y +YmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJw +aXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4g +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +IE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMg +dGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBu +dW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVp +cyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBu +YXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1 +ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGlj +dHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBw +ZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxl +c3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZv +bHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1 +ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMg +YmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxs +YSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZl +bmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25l +YyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1h +Z25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5l +YyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBw +b3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5n +IHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1 +cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1 +Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4s +IHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVp +c3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVt +IHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4g +U3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwg +bHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1 +cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1 +bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBu +aWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1 +aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVh +bSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFj +dXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0g +YXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1 +bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2Vs +bHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBw +b3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJy +YSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBj +b25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJp +dCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1 +ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwg +c2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1 +c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFs +aXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFt +Y29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3Jhdmlk +YSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEg +dGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJl +IHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQg +dHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBy +dXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGlu +IGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBl +bGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkg +c2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxs +ZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1 +IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBt +aSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4g +UGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0 +aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0 +YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEu +IFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxp +dCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1 +c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMu +CgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwg +ZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxh +IGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBz +dW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3Rl +dHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZl +bmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBu +b24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMg +Y29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVo +aWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwg +cXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNl +ZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4g +ZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBW +aXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVj +dG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFy +Y3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVl +LCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVp +ZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGli +ZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0 +LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEg +dG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBw +aGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVl +dCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVj +dHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBp +cyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4g +bmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQ +cm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVs +aXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVs +bGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVs +bGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxs +dXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBl +c3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0 +IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0g +dWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1 +cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBN +b3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMg +cGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZl +bCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMg +cXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3Ugcmhv +bmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVs +bGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0 +cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2Vy +IHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1 +ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoK +TnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBt +ZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBz +Y2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0 +IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRv +bG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBw +bGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kg +aWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRp +cGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVp +cyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVy +aXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVj +IHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwg +bWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGll +dCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVk +ZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdp +bGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVy +YXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0 +dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lw +aXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMg +b3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBz +ZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNl +ZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBz +aXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1 +bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRv +bG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0 +IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFt +ZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQs +IGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVy +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMg +ZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNp +bGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUg +YWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVu +YWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBj +b25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0 +IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50 +ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBw +b3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNl +bnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMg +bW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEg +YXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVn +ZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMg +ZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25n +dWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJp +cyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2Fw +aWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0 +LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxl +Y3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywg +ZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQs +IGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNl +ZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNt +b2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBu +b24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0 +YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVt +IG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2Ug +YWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5j +IGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVy +YXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2 +YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBu +dW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNl +ZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBh +YywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMg +bGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIg +Y29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBl +bmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVp +cywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQg +b3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEs +IHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNz +aW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1 +dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1 +IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVv +LgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9k +aW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVz +IG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBz +dW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxh +IG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0 +IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVj +IG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2Fw +aWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFl +IHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9k +aW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlz +aS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQg +YWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywg +c2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50 +dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVz +dCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8u +IE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMg +bmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xs +aWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQg +YW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVz +dG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4g +TWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBk +aXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlz +Y2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUg +c2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBR +dWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJh +dCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwg +cGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3Vz +LiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpT +ZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252 +YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNp +dHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQg +c2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNl +ZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoK +TWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVj +dHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGli +dWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xv +ciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRp +cyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5l +cXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMg +YWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2lu +ZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVz +LiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBh +IGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0 +dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlh +bSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxh +LiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1l +dCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3Iu +IFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0 +IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNs +LiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmli +ZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVu +dGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRw +YXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5k +IG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZp +dmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZl +cnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBs +ZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJz +dXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVz +IG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFj +ZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVy +aXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBw +b3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3Is +IGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1 +cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBu +aWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25j +dXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMg +ZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVz +dGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51 +bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8u +IER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRv +bG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNx +dWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmli +aC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQg +bW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBk +b2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFBy +YWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0 +dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBv +cm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMu +IE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4g +SW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9u +LCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoK +UXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1 +cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3Rp +YnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmlj +ZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rp +by4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwg +bWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWku +IFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8g +bWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50 +ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBu +dWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5k +cmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVs +ZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBx +dWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFz +IGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4g +aWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4g +dGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMg +b3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5h +LiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3Ig +ZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwg +cmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0 +ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBk +b2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBD +cmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZh +bWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBN +b3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVz +LCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBu +b24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1 +cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVp +c21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBE +b25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9y +IGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3Rp +ZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRl +bGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQg +YW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVj +dHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVu +ZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmli +ZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1 +cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1 +c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBs +YWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0 +aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0g +c2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNh +cGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFz +ZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBo +YXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9y +IHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMg +dmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0 +ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNl +bmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVu +ZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEu +IFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBp +dCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3Vs +aXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0 +IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJh +IG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVs +bGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBt +YWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0 +IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVz +LiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBz +ZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUg +b3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMg +cXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRp +dG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1l +dCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVy +ZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVs +dHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1 +cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBm +ZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3Vz +LiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9y +IGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2 +ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMg +YSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNv +bnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZp +dmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVh +biBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxv +cmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3Vl +IGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9y +IG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2Vy +YXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNp +IG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0g +bGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0 +b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBh +Y2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENs +YXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251Ymlh +IG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBO +YW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVu +Yy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQg +bWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJh +ZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMg +c2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBw +ZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVn +ZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBh +YywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBt +ZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywg +bW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFj +ZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1 +bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBh +bWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZp +dGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxh +IGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1 +cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1 +cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25h +IHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVs +bGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVs +bGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBs +YWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZl +bmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50 +ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVn +ZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25p +c3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNv +bnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVy +b3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNs +LiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1 +ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1h +dXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZl +c3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1 +bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVz +IHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1 +bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9y +Y2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2Fn +aXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlz +cXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2 +aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQu +IEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1 +ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxh +LCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwg +dmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1 +ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1 +c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQs +IHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4g +TWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVz +IHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBz +ZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQ +ZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVy +aXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBO +dWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFu +dGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xs +aXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1 +ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJv +cy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNv +bnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBp +YnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBz +aXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9z +IGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0g +ZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVy +bmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3Vs +YS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0g +cXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0 +b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0 +byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0 +ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQ +cm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFy +Y3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1l +dCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBh +bGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVy +aXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0 +dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0 +dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQg +bnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVj +IHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3Rp +YnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJo +IGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2Vy +IHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29u +c2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwg +bmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhh +cmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1 +bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBt +aSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1 +aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9y +IGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBl +cm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5l +YyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVs +IHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEg +YWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlz +LiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0 +dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlw +aXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1 +YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxp +cXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJh +Yml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNl +bSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBl +bGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2 +ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBw +ZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1 +bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBt +YWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVj +ZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMg +ZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0 +ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJp +ZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBl +ZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0 +dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4K +Ck1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVz +IGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9y +LCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0g +c2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxw +dXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3Iu +IE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1 +bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMg +c2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVh +bS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1 +cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1 +c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVz +dCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFt +dXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBz +ZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVu +ZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZp +bmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1 +ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3Vz +IGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBT +ZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBt +YXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFs +ZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxh +IGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1 +dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFs +ZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQs +IHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3Vt +IHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1Ymls +aWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4K +ClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1 +YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNj +dW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5v +biBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3Us +IGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZp +dGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwg +bG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwg +YWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29s +bGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUg +cXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51 +bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNp +ZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2lu +ZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5p +c2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwg +ZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJ +biB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBl +dCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVx +dWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxh +LiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUg +bmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJv +LiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMg +ZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVk +aW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlw +c3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wg +b2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1 +cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0 +aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0 +dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFj +ZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2 +ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVj +aWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxh +bWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxp +dCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9u +Y3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBO +YW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwg +ZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBk +YXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBl +bGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxh +LCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUg +bWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFj +dXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4g +VmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQg +bW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFt +IG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFj +Y3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5p +YmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMs +IHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlk +IHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMu +IE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQg +cGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lk +dW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBk +aWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25z +ZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVz +IGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlz +c2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWws +IHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBy +dXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMg +cXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5p +YSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFj +aW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNl +bnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBh +YyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRl +bGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50 +ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0 +aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25h +IGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBN +b3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0 +IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBx +dWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBO +dWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxp +cXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25z +ZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZh +cml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBB +ZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1 +LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlz +IGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBh +dCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRv +cnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVs +bGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlz +LiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVy +IGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwg +dGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4g +SW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxh +IG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3Nh +LiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMs +IHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQu +IEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxl +Y3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0g +dmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxs +ZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8g +ZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBu +dW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRh +ZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUg +aW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0 +aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50 +ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2Fn +aXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQu +IFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5p +bSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQu +IFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRp +ZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJp +cyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBs +ZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMg +aW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1 +cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVp +ZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMg +ZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lh +dCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBl +dSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBt +YXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1 +ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0 +aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQ +aGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxl +Y3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFj +IGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0 +dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2Np +bmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5p +YSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRl +IHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1 +cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29u +Z3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9y +IGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBk +aWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGll +bi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBz +dW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxl +Y3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBz +dW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9k +aW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3Nh +IHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBp +c2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBu +ZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1h +Z25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0 +ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3Vz +IHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1 +bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMu +IENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNl +bmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVj +dHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1h +ZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBs +YWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1 +bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBO +YW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWks +IHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2 +dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVz +IGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxp +YmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1 +cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2Vk +IGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2 +aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNp +LiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVz +LiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxp +cywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRh +cGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBj +b21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1 +ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlx +dWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlz +dXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2Vt +LiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5k +IHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25n +dWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMg +ZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0 +aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5v +biwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGlu +IG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0 +IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0 +aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVs +aXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIg +c2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1 +cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZl +bmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9y +IGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1 +bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4g +RHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBt +b2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2 +aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmli +ZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENy +YXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFl +LCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4g +cG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1 +dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlz +aS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxp +cyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBj +b25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1 +cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0 +IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1w +ZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1 +cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2Vk +IG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9u +LCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJp +IHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlz +IGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4g +UGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29u +ZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5n +LCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMg +cmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3Ji +aSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBu +aXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0 +dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxh +IHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBy +dXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2Nl +bGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMg +bmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVy +aXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0 +YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBB +bGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1 +bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1h +Z25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0 +LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxs +YSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdl +ciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25h +IHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQg +cGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUg +c2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNl +bSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJh +ZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1j +b3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFt +LgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9i +b3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3Vl +cmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBE +b25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVv +LiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBk +aWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMg +ZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNz +YS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1 +cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4g +SW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9y +dHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGli +dWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0 +LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4g +SW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2Fn +aXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBk +dWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVp +c3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5j +aWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0 +dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBw +b3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5p +c2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSBy +aG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQg +dmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29u +ZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBs +dWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNj +ZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlz +Y2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJp +cy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVz +dG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3Nh +LgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlz +IGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBp +biBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3Vz +cGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEu +IE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBE +b25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJy +YSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQg +c3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0g +YWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxl +aWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBh +dCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9y +Y2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNz +IGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRp +YW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVu +YyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1l +bnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0 +LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0 +dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZp +dGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3Vz +IHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0 +LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVs +dW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMg +Y29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFl +IGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBs +YW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZv +bHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1 +bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25z +ZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2lu +IGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNp +dCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBm +YXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVz +Y2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2 +aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwg +dHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBl +Z2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBh +dCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9z +dWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2ku +IExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0 +LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5h +ciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1w +ZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1 +cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0 +cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25h +IGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFj +ZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBs +ZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVt +cHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9z +IGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMg +dmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5h +cmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwg +cG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlz +dGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3Jhdmlk +YSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBB +bGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3Rp +YnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRh +dGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBv +cmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBl +dCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJh +Yml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50 +dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJp +c3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRl +c3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxh +bSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4g +bnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVy +LiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVu +dHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBz +Y2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVh +bSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVu +ZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRp +cGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdy +YXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3Vl +IGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxs +YS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVu +dHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlz +IHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0 +cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBl +Z2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhh +c2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWws +IG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0 +IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlz +IGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0g +b2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBp +c2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2lt +IGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWws +IG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBT +dXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2Fu +LCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBl +dCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBu +dWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4g +dHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNp +dHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNl +ZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBu +ZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3Vl +IGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1w +ZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlz +LCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywg +b3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEs +IGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5h +bSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhh +c2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFl +Y2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4g +QWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29s +bGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFj +IGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBp +biwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2Eg +ZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVy +dXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBt +YXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3Vs +YS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNp +ZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBz +dXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3Jj +aSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlz +LiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwg +bnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwg +aW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1 +Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhp +Y3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFBy +b2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5n +IHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1 +bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1 +cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNt +b2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMg +aWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1 +cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFt +dXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBV +dCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0 +IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxl +by4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRp +bWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25z +ZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0 +IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwg +dmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQg +bG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4g +UHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1 +cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBh +dCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVp +c21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBl +dSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMg +dXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVj +LCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5j +IGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBw +ZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2Vk +IGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNl +Y3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4g +TWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1 +bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBw +b3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1 +cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIg +dmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHBy +ZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNp +ZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9u +ZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBt +b2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxh +bmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQg +bWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBl +bGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVu +dHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUg +bmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVy +dXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNz +IGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3Vz +LiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFy +ZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRv +bG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRl +bGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlk +LCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4g +TWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVs +dW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBu +aXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBE +dWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGln +dWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNl +ZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVt +ZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0 +LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVz +cXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBs +ZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1 +cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRh +cGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVu +YyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4K +ClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGlj +dHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUg +bWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVu +LiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBt +aS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBz +dW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhh +c2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1 +bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Ig +c2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNz +YSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxs +YW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBD +dXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGlj +dWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBl +Z2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBw +cmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQu +IENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4K +CkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1 +aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZl +c3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEg +ZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRp +dCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRp +cyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEg +bG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNs +LiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1h +dXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQg +bHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhh +c2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVj +dHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4s +IHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwg +Y29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1 +YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBz +ZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNv +cnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQg +dGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBl +ciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGlt +ZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2ll +cyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFl +c2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVy +cmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVj +dHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11 +cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGln +dWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGln +dWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVu +dHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFk +aXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMu +IEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlz +LCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVs +aXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMg +ZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNp +ZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJl +cm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9i +b3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMg +ZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBu +dW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVu +ZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1 +ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRh +IGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIElu +dGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wu +IE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWku +IE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVl +IHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQg +Y29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRy +ZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1 +YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0 +cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3Ji +aSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEu +IER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0 +cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBs +YWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVy +by4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFj +IGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1 +cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1 +bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlz +Y2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxl +Y3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRy +ZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNz +ZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1l +dCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVs +bGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFt +LgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBs +dWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFl +Y2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMg +c2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMg +b2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUg +bW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0 +ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5p +c2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2Vt +LiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQs +IHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5h +dGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1 +aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlz +LCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFu +ZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVu +ZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxs +dXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0g +YWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFt +IGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxp +dC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2Vk +IGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBp +biBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVy +aXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1 +ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lp +cyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNj +ZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVp +IHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNp +ZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0 +dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNl +bSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMu +IE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVn +ZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBk +dWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBw +cmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVz +cXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3Vs +YSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMg +ZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBt +ZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFs +ZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVy +b3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5l +YW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29j +aWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5h +c2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMu +IFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJv +IGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMg +cXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdy +YXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2Vz +dGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVz +dG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2 +ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJp +cyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxp +Z3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJk +aWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5p +c2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50 +dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVy +cGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0 +LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4g +QWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWws +IGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Np +b3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3Mg +aGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoK +TWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1h +bGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3Mu +IEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNw +ZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdl +dCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2Vt +IHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlz +aSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0 +cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRv +cnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEg +cG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0 +YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMg +YXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFt +IGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29j +aW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9z +IGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1w +ZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0g +bG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNp +dHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZl +c3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4g +Q3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQs +IHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0 +dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0 +YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMg +aWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFk +aXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBh +dWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRp +YW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNp +ZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVz +IGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRv +ci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGlu +IGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNl +bGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJh +ZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNl +bnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVu +ZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1l +dCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFz +IHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZh +cml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRp +dC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNv +bnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVu +dGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVj +aWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEg +aXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVy +dXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2Vs +bHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMg +aWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5l +cXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFs +ZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRl +YSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0 +LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0 +aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMg +bXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5p +bSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVs +ZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlz +IGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBl +cm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBl +bGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3Us +IHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNv +bnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBm +cmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0g +aWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGku +IFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJv +IHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlk +IG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZl +bmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBh +dWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBh +dWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0g +bWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2Nl +IGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1v +bGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoK +U2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1 +bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xv +ci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVt +IGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9s +b3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3Vs +aXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFz +c2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50 +ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxp +cXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0u +IFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVs +bGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVu +dCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1j +b3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVu +aW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBs +ZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGln +bmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFy +ZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1 +aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVs +LCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlw +aXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0 +b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9y +Y2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBl +bGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNp +YnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMg +dmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBl +bGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1l +dCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBs +ZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVz +ZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxh +Y2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJh +LiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBz +dW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZy +aW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBz +dW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3Vi +aWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVu +dGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQg +dmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1 +YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVk +ZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFj +dXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1 +ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlz +LCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQs +IHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxh +bSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0 +YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBs +YWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0 +b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRp +bmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNx +dWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFk +YSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBs +YW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxh +IGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50 +ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVy +ZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0 +LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlk +IGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9u +IG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBy +dXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUg +bGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVu +dHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0g +cXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwg +b2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVz +IGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwg +cHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1 +cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0 +aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVu +ZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVj +IG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJo +LiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFv +cmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGlt +ZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWku +IE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1 +ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVz +IGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25h +LiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZp +dGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3Jhdmlk +YSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERv +bmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywg +bWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0 +YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRv +bG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlz +dXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBF +dGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywg +YmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBp +cy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVs +aXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5l +YW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNx +dWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNv +bGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3Vz +IGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29u +c2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlz +IHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2Fn +aXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1 +IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNz +aW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRv +ciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywg +c2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNs +LiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZp +ZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlz +LCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQg +ZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNl +ZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxp +Z3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBh +bnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1 +ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJp +bWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBD +dXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVz +IGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3Rp +cXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rh +cy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRp +bmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGlu +IGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVy +aXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFt +IGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8g +cXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlz +IG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3Jw +ZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRl +Z2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBh +bnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1 +ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5h +IHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlz +IGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhp +Y3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4g +UHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRp +c3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUg +aW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51 +bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVs +dW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQg +YW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0 +LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMu +IE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2 +aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVy +IHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBz +dXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBs +b3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVp +LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVz +IGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNl +ZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNv +bnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFn +bmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhh +cmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVs +aXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5p +c2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlz +IHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNl +cmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmli +ZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZl +bGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0 +IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3Vt +IGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEg +ZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3Mg +aWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBj +b252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0 +IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29j +aWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5h +c2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3Rp +YnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVj +aWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3Vh +ZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFk +YSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBm +YWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3Vl +cmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxs +ZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNl +cXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlm +ZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1h +ZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBp +bXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9k +IGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEu +IE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1 +cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxh +Y2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywg +YWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1 +Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2 +ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1h +dHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNx +dWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZl +bGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3Vz +LiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUg +YSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRp +cywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8g +ZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRp +cy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2 +ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2Nl +bGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUg +dml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2Qg +ZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1 +cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMg +b3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4g +Q3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVh +IGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1 +bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFy +Y3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNp +LiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGlj +dHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51 +bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0 +cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1 +dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9s +dXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBs +b2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1 +bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJs +YW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0 +IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBz +b2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFu +ZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQu +IFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1 +ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1 +cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBs +YWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQ +aGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lw +aXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFz +c2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3Rp +YnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmlj +ZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMu +IFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1l +bnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMg +Y29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVu +YyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBp +ZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3Ig +cnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1v +bGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBt +ZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3Vz +cGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBj +b252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1 +ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2Vk +IHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBT +ZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3Rv +IHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQg +bmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmgu +IE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJp +c3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRh +dGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25l +YyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4g +UGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQg +ZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9x +dWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJp +ZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJh +Yml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZl +bCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVs +bGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQg +ZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVu +dCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZl +dWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBz +dW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJk +aWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3Us +IGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1 +cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVu +YyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGli +dXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNh +cGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBn +cmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGll +IHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxp +Y2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2Fu +IHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRl +cmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVl +dCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBq +dXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlx +dWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5l +YyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3Ji +aSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBp +cyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50 +ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVy +ZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJp +Y2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBm +ZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2Np +bmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVy +cGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBh +bnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEu +IE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMs +IHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQg +YWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENs +YXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251Ymlh +IG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4g +TnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0 +aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFz +c2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJs +YW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVy +bmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBh +dWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBp +ZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4K +ClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBv +ZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJp +IGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4g +U3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVt +cHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3Rl +dHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8u +IE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMg +bGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMu +IE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1 +cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBh +cmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVh +bS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0 +b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4g +c2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUg +c2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhl +bmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFz +IGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBh +YywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwg +ZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIElu +IGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJp +IGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4s +IGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lv +c3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBo +aW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25l +YyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVz +dGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4g +VXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0 +b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxh +bSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRh +ZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVj +IHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBB +bGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVy +YXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlh +LiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMg +bGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5l +cXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBw +ZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1 +cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdp +bGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0 +aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFj +dXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRh +ZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZl +bmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8g +c2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5p +c2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQg +cmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBE +b25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJu +YS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRl +bXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFu +dGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3Vl +cmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29u +dmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNp +IGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4g +ZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5h +dG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVy +IHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0 +IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVs +LCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGll +dCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVt +cG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQs +IGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIElu +IGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBF +dGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9u +ZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJh +LiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVt +IHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywg +b2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1l +cyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2Vz +IHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4g +QWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNp +bGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBq +dXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRw +YXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0u +IE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRl +cmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEg +ZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJk +dW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5l +YW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFj +dXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1 +cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVv +LiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBh +dCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBT +dXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5j +aWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1 +cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVz +ZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1 +cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1 +ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBz +b2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVs +dW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3Rp +cXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1 +bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVp +c21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJp +dHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1 +dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0 +LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRh +cGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJp +cyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmlt +aXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1 +cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQg +cGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVu +ZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBm +ZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0 +LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFj +Y3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1 +cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVz +LiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNl +cyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1 +cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUg +bWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERv +bmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0g +dGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVs +bGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1p +LiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9k +IGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFs +ZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxs +ZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0 +dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1w +dXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2 +b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3Jj +aSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwg +Z3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBj +b21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNz +ZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVy +YXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBq +dXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMg +c2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBw +cmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1 +aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1w +b3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVy +aXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2 +ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBw +bGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBi +bGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8g +bWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJ +biB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0 +dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1 +bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3Vs +aXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBz +aXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1 +aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxh +IHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJv +aW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVz +LiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3Jw +ZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3Iu +IE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBw +cmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1l +cyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJp +c3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVn +ZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVs +bGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1 +aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMu +IFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1 +YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3Rv +IHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4g +ZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBh +cmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBh +bWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBv +ZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlz +cXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUg +aGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8u +IEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlx +dWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUg +bWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFs +bGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJ +biBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2 +aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0 +aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0 +YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxh +bmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNl +bnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50 +LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVy +cGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlz +LiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlz +IGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2 +aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVj +IGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVu +dHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0 +aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5j +LiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3Ig +bmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVp +cyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwg +YW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBm +YWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1 +ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3Jl +bS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxh +Y2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBD +dXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0 +LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNx +dWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBo +YXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQg +dGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5h +cyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1h +bGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlv +LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQg +bGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1 +cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBz +b2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywg +bmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwg +Y29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3Jl +bSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2ls +aXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRl +LiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMg +ZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0g +bGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwg +ZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVt +LCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMs +IGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVx +dWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFs +aXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENy +YXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhh +cmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVh +bS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNl +bmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMg +dmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5p +YmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFBy +b2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xs +aWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBx +dWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2Vt +cGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZl +dWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3Jh +cyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2Vj +dGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBp +cy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQ +cm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlh +IGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZv +bHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBu +ZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1h +ZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50 +dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVj +LCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMg +cGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRp +YW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBw +cmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2 +dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9s +b3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVh +bSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1 +aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2Vy +IHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZv +bHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRh +ZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVs +bGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZlc3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVl +IGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEg +ZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxsZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3Jl +ZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNxdWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBo +YWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxsYW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBR +dWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUuIFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEg +dm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMgZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUg +c29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2Vz +dGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNj +ZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5p +c2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVzLiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2 +ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQgYW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVy +aXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBj +b251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoK +TnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBh +ZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEsIHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQg +YW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4gUHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFj +Y3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVhbSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1 +Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUg +anVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVz +LiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxsdXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1 +bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9pbiBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9y +ZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3UgcHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwg +Y3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwgbnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxp +Y2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlxdWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxh +bmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMgZ3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJp +dGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVz +IGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIgYSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50 +dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVuYy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQg +bnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNlbXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBl +c3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVsdW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBs +dWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBp +ZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBsYWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3Jl +bSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2 +YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlzbC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lz +IHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIElu +dGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4gRHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0 +cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBlbGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlz +IG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNxdWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEu +IENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlkLCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1 +cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9zLiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2 +ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBhdWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlz +dGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJpc3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBl +Z2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxpcXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9y +IGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBTZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1 +cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBs +ZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNjaW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVs +bGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0uIFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBp +ZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFj +dWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFk +YSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBlbGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2ls +bGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVtZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBh +cmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwgZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmlu +Z2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJp +ZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNv +Y2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBu +YXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5hcyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFz +IHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGljdHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1 +cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxsdXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5h +dGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVz +IG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUuIEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFs +ZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0sIGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERv +bmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1vcmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xv +ci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVzdC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1 +ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBhY2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGlu +Y2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2NlbGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBR +dWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRhdGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1 +cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNl +ZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQgZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3Vy +YWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2VtcGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3Vl +IG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4gSW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVu +dGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVzLiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1 +bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3BlbmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4K +CkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwgdmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lk +dW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMgdXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJp +cy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQsIHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQs +IG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5hdGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNl +bmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFyIG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxh +IHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBtYXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUu +IE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0 +cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQgdmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUs +IHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNzYS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1 +cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMsIGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1 +cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEgc2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3Vt +IG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBtaS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1 +ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMgZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBw +cmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBlbGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIElu +IGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1 +cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUg +b3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClByYWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9k +IHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQgaGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZl +bGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1zYW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBz +YXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBzYXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2 +ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRhcGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUs +IHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFlIG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRp +ZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9yZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVs +dW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMgdGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJv +cy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGljaXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEs +IGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVhbSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1 +aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxhIGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdl +c3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVudCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3Rp +YnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBwdXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlz +IGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2kuIE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1 +ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJvcyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMg +dGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBO +dWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwgdGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRp +biBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUsIHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0 +aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBOdWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9z +dWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVjIGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlz +IGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBBbGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1 +cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGln +bmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4gbGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0 +IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3VtIGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlv +IHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2RpbyBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lk +dW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFiaXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0 +IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMsIG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1 +cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVyIGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5h +IGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3Jl +bSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5lbmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0 +aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxl +cmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNvcnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxv +cmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBxdWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEs +IHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3VzLCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRl +Z2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0gZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVs +bGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFwaWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJz +dXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBpYnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBp +bXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxlbnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJk +aWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBtZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVs +IGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGli +dWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMsIHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQg +YW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVzdGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBl +cmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9sZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBm +ZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9ybmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFs +ZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vtc2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBt +ZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmggYmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBp +cHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZlc3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUs +IGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBlZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBD +cmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1hZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0g +YXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhhcmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9z +LiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1 +bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFtIHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxp +Z3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRh +bnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgdmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxs +YSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZlaGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0 +dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRydW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBu +ZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVpcyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0 +ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBjb21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRh +LCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5pYSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1 +ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQgcHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUu +IERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBlcm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJp +bmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0g +ZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBpZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2Vt +cGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1 +ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFj +LCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3JiaSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4K +CkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNvbmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVu +ZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlzIHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBh +Y2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxsYW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlz +IHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVhbSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVs +dW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNl +bmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBm +YXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5lYW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMs +IGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBsb3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIg +bWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1h +dXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBmcmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4g +UXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRvciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFj +dWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVudGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0 +YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBGdXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVu +dGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGluIGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3Vz +LCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGluY2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFz +IHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0g +dmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1hZ25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1 +Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBNb3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJp +cyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24s +IG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVu +dGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdl +dCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVuZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFu +dGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3Vl +cmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1 +cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdldCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1 +bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5jIG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVs +aXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwgYXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVp +cywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4gbGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBB +ZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9y +bmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdlciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0 +dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlw +aXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFByb2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhp +Y3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdp +bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNlZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMu +IEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQgZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRl +bGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBydXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQg +ZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBw +dXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4sIHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFt +IHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFiaXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNv +bmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVuZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3Bl +bmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlhbSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUu +IEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBqdXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFk +aXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwgc29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRp +c3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNzYSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4g +TmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIgZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1 +LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5jaWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwg +YWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFzZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0 +aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1 +bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1 +aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRpbiB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVz +IGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2NpbmcuIFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFt +LiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBub24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdl +dCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJpc3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2ku +CgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4gUHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBj +b252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3VlLCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1h +dHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRpYW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVy +byBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFtLCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0 +LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4gRG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxl +bWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0gZ3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxp +c2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1 +dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3Vz +IHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRp +Y3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1 +cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2NpbmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3Vs +YS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMgZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVu +YyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25hIG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3Nh +IG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1 +bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZlbCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGlu +IGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBldSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBE +b25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENyYXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1 +cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFzIHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlz +IGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVzLiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0 +IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNlbmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3Vy +YWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNlcmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBm +ZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBuZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBj +b25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0gYWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNv +bW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZpdGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZp +dGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxwdXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFu +dGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3Vl +cmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25n +dWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVybyBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJp +dXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBvZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVl +dCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5n +aWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZlcnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0 +aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQcmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2 +ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBEb25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBz +aXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywgcGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdl +ciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGlidXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9z +dWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21tb2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xl +c3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBpYWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJp +IGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFtIHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMg +aW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMgaW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1 +bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBNYXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51 +bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNpdCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1l +bnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUgbG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVu +ZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxlbWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1l +dHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVtIGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUu +IE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwgYmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0 +b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9y +Y2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRpZ25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxh +bmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVtLCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBk +b2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQgZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVl +IGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2FnaXR0aXMgZnJpbmdpbGxhLCB0b3J0b3Igbmlz +aSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBsYWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMg +aWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVuYXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUu +IE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVt +IHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRyaWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBh +dCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVpcyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxp +c2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xlc3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlw +c3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRhZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0 +IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5kdW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBm +YWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMgbnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0 +cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBpcHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERv +bmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9ydHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUg +bG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERv +bmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4gU2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4g +RG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBwb3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywg +ZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25zZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEg +c2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBsb2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9y +ZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZpdGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJl +LiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJkaWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2lt +IGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBuZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1h +Z25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1hdXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQg +bWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBhdWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4g +UGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBl +dCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9u +ZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVsbGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50 +ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGltZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBz +dW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBsYW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxp +dC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlzdXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBs +YWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBsZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFy +aXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNpLiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBl +bGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlzIHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywg +Y29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGlj +dHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRydW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0 +ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVyaXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQg +dnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlzbCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0 +YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMuIEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQs +IHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUsIG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2Nl +IHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlxdWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMg +aWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNhbiB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2Vk +IGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25hLiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5j +IG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBlZ2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUs +IGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBldSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRp +bi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBpYWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQg +dmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNpdCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1 +bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVkZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlz +LiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2VkLCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0 +LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBqdXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMg +aWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNlbnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBl +bGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3JwZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERv +bmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoKU3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0 +IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQg +YXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUuIEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlz +cXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25lYyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMs +IGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBTdXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2lu +aWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRh +cGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlhbSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0 +dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4gTWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0 +cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlzIGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9z +dWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4gZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEg +Y29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRpdG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1 +bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGli +dWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBOdWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1l +dCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlz +aXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMg +bW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkgZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFj +LCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFt +IHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBw +ZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIgbW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMg +YXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBN +YXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kgaW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBk +YXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9uY3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRv +bG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVsIGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wg +dmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGltZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1 +bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJp +bGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxlcmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBt +aSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2luZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51 +bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4gQ3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMg +ZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8uIE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4g +RHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoKTnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRh +c3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNvbnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4g +TWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBlcm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNp +IHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVuZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0 +LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxh +IGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25lYyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVn +ZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBub24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBt +YWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3VzY2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4g +VmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMgZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxp +YmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZlbmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVs +bGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBmZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50 +ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2kuIFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1w +ZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0 +b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0gZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBu +ZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBsYWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZh +bXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMg +bmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBWaXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29u +Z3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlzIGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1 +aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFlIG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1 +cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3Vy +YWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBOdWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNj +aXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0gdXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4g +TWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29uc2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1 +cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFjY3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJ +bnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9yZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRp +cywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5k +IGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBuaXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1 +cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHBy +ZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRp +cy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBhbWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMu +IFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVjaWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBz +Y2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2UgcXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBz +aXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5hci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9z +IG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBv +ZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVy +YXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBsZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZl +bCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVyZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVu +ZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBj +b25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoKQ3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMg +aWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBFdGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBu +aWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1h +dXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIgcGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMg +ZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVzIGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0u +IFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmljaWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0g +ZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlkIGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4K +ClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJhdCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxp +cXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8gcmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQg +bnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVzLiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVz +dGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNvbnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVt +IGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVsIG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBt +b2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUgdml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUg +c2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9ydGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxs +ZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlxdWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlz +c2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBpbXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVu +ZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlxdWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlz +IG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVsdW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxs +YW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUgc29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1 +Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNpIG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNj +dW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBkdWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlz +IGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3Qu +IFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0gdmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVt +IGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vt +c2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2Vt +IHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBkYXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3Vz +cGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVuYy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZl +bCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQaGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1l +dCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVtLiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGlu +IHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2VsZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVl +IGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBpbXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZl +dWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5hdGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3Nl +IHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlzY2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZl +dWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZpZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1 +ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBB +bGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4gTW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxh +IGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVtIG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRv +cXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciBy +aWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEuIEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1l +dHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1 +Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2VsbHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5l +YywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5pc2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1 +ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNlbSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2 +aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNvbnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBs +YWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2RpbyBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wg +dml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2NpbmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQg +ZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNvbW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwg +dGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1hdHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5h +cyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNwZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIg +bWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBsYWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1 +cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBydXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVp +LgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxsYS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRp +c3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVycGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFz +IGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVkaW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5v +biBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBudWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1 +cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBt +YXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFyY3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1 +cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIsIG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFl +LCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0 +aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3JjaS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0 +IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZldWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlz +IG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBkaWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9u +ZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2VsbHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCBy +aXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2VuYXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNv +bGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxpcXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1w +ZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGljaXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVk +ZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxvcmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRp +cGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwgZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4g +bWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdldCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRp +cGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMgdGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxp +cXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVyaXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxp +dCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4gTnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1 +cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMgc2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBj +b21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNjaXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBl +bmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBldCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0g +cGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQaGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBt +YWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVsbGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVy +b3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4gdmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxp +cy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3VlLiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEg +YWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3VsYSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1 +YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2luIGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lk +dW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBvcnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywg +dG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxhbWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3Vh +ZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5hIHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1h +bGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2QgYWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBh +bGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQgbnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29s +bGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBpcywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwg +cGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMgdGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0 +dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBtYXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywg +cGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNlZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3Jl +bS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4gRG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVu +ZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVudHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0 +cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBv +ZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3Vl +LCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVuZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVl +IGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9ib3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24g +bnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJhZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxp +cy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlzLiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMg +YSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwgcmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1 +bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21vZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxp +dCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwgbG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5h +cyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQgbmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxh +IHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUs +IG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1 +cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxsZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1 +cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVuaW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0g +aXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVn +ZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJp +Y2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1 +cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBh +Y2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywgY29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJl +cml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVsIHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxh +b3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRpdW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9s +bGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVudCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZl +c3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMgc2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3Vz +cGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xlc3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFy +ZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRpdCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwg +c2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFnbmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3Rv +ciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxlbnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBj +b252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVtLCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8s +IG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVjIG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBl +cm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMgYWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlz +LiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0 +b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBNYXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNz +ZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBkaWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRp +cyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9yIGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIg +dml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBB +ZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBzdXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxh +IHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFlY2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVz +dGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0gbnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0 +LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNsLiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNz +YSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlzIHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMu +IERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxhLiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBt +b2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBkb2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1 +dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1 +aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBBZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1 +bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVlIHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1 +cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwg +YWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBhdCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVs +dHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGlidXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRp +cyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBwdXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVy +aXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBlbGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0 +dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVtIGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZl +bGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMg +ZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQcmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRv +cnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4gRG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBN +b3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0uIEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24g +bmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2VsbHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMs +IGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBub24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBw +b3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNj +aW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBuZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVu +ZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1jb3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFy +ZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJhYml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVk +ZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxhIHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNv +bGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2VzdGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5p +c2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxv +cmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENyYXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBz +b2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4g +b3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMgbGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlw +aXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3RpYnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4g +ZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlhbSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlz +c2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBzYWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVy +aXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBzZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxl +aWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9yZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0 +aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBFdGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNz +YS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJpcy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1 +cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVjdHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVj +IG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2VsbHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25h +IHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVzLiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0s +IGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1 +aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29uc2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVs +aXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0gb2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBt +YXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQgdXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMg +dmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBlci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1 +cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFj +aWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kg +Z3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBxdWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1 +Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2VudCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25k +aW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEgZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1l +cyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBzb2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBj +dXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxhIHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4g +SW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxhLiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRp +dCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVtIGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJp +c3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBpc2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNx +dWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFsaXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMg +ZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1w +ZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMgbm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQ +ZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRl +c3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMgYWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFs +ZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8gb2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlz +IG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVu +Yy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdlc3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBt +YXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5jLCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9u +LCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlzc2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBv +cnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2Vu +ZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNj +ZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVnZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1 +cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFk +aXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1hZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNv +bmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMg +c3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29uc2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNp +YnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJpdCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNh +biB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRhIGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGlu +dGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmljaWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZp +dmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBtb2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0u +IEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEu +IFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmljaWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5j +aWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNpbmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1h +dXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4KCkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1 +cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFudGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3Vz +IGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBmYWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIElu +IGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRl +LiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2luZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRp +cyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4g +SW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJpdCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4g +TnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBN +b3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBsaWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUg +aXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEgbmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9s +dXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoKRHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1 +cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZl +bGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2VuYXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEs +IGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxs +aXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2RpbyBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJ +bnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9sZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFs +aXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxsdXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4g +RHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kgbmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGlt +ZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBVdCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywg +dm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVs +IGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlzIGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGlu +Y2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBhIGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0u +IERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBsYW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9s +dXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1 +c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlzc2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0 +YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMgdmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9y +LiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMgZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNp +ZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4g +U2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4gUXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNj +aXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVl +dC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBwZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVn +ZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQgYmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNp +dGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMg +ZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5p +c2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZpdGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBk +dWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVudCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGli +ZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMgaWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51 +bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBldSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBT +ZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQg +YW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQsIGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmgg +YXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWkuIE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVn +dWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBN +b3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVlIHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0 +aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBibGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1 +bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1 +cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMu +IE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMgaW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRy +dW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3MsIHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1 +dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4gbmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBw +ZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1 +cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNlZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEu +IFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlkIGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBi +bGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVpcywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4g +TWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZpZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVy +bWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFzIHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZh +bXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8uIE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0 +LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwgbGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQg +ZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBkaWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdy +YXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3VsYS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBs +ZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0 +LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wgaW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFt +IHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0uIE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1 +ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlzLiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwg +aGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBwaGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBs +YWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVuZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMg +aW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFudGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxp +cy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNv +bnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGli +dXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFlY2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9u +IHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVzdWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxs +YSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFsaXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVs +bGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVz +dGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBpcHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZp +bmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1 +cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBhYyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3Mg +YXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmljZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3Iu +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQg +dWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMu +IFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRvci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24g +YWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9zdWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1 +cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRlLiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQu +IFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQsIGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMs +IG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVy +YXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBj +b251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJp +IGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIgbm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQu +IE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9ib3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0 +aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVkaW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMs +IGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3RpYnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJp +dHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3VyYWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1 +YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdl +ciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMuCgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlz +IHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRlIHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0 +IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQgcXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQg +bmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBpc2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1h +Z25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEg +bWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0uIE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRp +c3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMgcG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRp +bmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFudGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJp +dHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4KCk1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBu +aXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxpYmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUg +ZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50 +aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNlbnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxp +dC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQgaW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMg +cHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlzc2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRp +ZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCByaXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0g +YWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25p +c3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFy +ZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3Nx +dSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVzcXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMg +bWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBl +cmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBzdW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25l +YyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMuIFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBu +aWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVzIGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0 +aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQgbmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBl +cm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVlIGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9y +IGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMuIEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1l +dHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwg +dmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0 +LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQg +bW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBh +bGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVu +aW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlmZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0g +ZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVnZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51 +bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9zLCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRh +ZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVj +dHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJob25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywg +Y3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZhbGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50 +ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmluZ2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0g +YWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQgdG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0 +IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1 +bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZpdGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdp +bGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1ldHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxs +YSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQgcG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVp +cyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0g +dGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZp +ZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFsZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRp +cy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFkaXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1l +dHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxpcyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIg +ZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2VkIGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3Ig +bGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQgbGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlz +dXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4gQ3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVz +LiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVsZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxs +YSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlw +aXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBs +b3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMuIER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBD +cmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFu +dGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNxdWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGli +dXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVldCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlz +IGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZl +bGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVudGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwg +dG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBtb2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxh +IGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3JwZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMu +IERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0uIFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClBy +YWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBj +b25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlzc2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFn +bmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4g +VmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMgdHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJo +b25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBkaWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBu +aWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNjaW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRv +bG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Igc2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2li +dXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2kuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0 +LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVt +IGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBv +c3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVsIGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2Jv +cnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJl +LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxp +dC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBh +Y2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBE +b25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2luaWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJv +IHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBDdXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQg +dGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWdu +YSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5naWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBu +b24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVj +dHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVs +bGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUg +bmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVsIG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVp +cyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0gZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNv +cnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBlbGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBp +ZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMgZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0 +ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBtYWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywg +YWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBxdWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0 +aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNvbGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGlt +cGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBzaXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVx +dWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBpbiwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4g +UXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3Rl +dHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0 +aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNpZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRh +IHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNl +bmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9u +ZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9yZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlz +aS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZp +dGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21v +ZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5j +LCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBv +ZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1pIGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVu +ZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRydW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxp +Z3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGlndWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3Vz +IGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVtLiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMg +Y29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVhbSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3Jw +ZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rpby4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5h +LiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBh +LCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVsdmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0 +b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4gQ3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQg +cG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5jaWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNh +cGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlzc2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1w +ZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0 +ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBBbGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBl +dCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVldCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBk +b2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1 +aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNp +LiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4gQWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMg +aW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRpYW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0 +cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBOdWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3Jl +bS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFlIGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFt +IGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBsZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJt +ZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVjIHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlz +LiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFnbmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21v +ZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUgc2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFj +dXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9yLiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFt +ZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMgZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxh +Y2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlhbSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51 +bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmliZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3Vl +LiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQs +IGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuCgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUg +ZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4gbHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2 +dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUgbWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlz +IGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxpY2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmlu +YXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEgZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBz +aXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2VxdWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0 +dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRpbmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBp +cHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBl +bGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlhY3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUg +dm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0gdXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3Ug +ZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBO +dWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2FnaXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUu +IEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBEb25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNp +dCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEgcXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBm +ZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUs +IHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGku +IFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwgY29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBz +ZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3VsYSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBl +cmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBv +cmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRl +LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0 +IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3Ig +dGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNvbW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50 +ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVz +dWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJh +IHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNpZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGli +dXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1 +bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNv +bnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNvbnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1 +cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVpcywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3Jh +cyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1hdHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBz +b2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIgZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBl +dSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2VyIGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2Vs +ZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBv +cmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBl +ZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZhcml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMg +bmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0 +dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3VsYS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBu +b24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJhZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJj +dS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFj +dXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4sIG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdl +ciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMgbm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMg +ZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0sIGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwg +ZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1ldCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFl +IG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBtYWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1 +Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1vcmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNz +YSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5hci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNl +bS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJpc3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlk +IG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNjaXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1 +cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3JlbSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFt +Y29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMg +ZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBiaWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9y +ZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5h +bSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEuIER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVt +cG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5j +IG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQuIFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBu +aXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wgbmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRv +cXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciBy +aWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVt +IG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5kdW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRl +IHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3Vh +ZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNvbmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0 +cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlkIG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGlu +IHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVsaXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxh +bmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQgZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBp +biBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVu +YXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVyYXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBh +dWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBs +aWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVsdW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0 +dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRp +bmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEgZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0 +dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBtaSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3Rv +ciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNpbGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBl +bGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUgZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1 +ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJp +c3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVhdCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3Vz +cGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5kIGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVj +dHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNlbmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1 +cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBlcmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBl +dWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxlY3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJo +IHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1vcmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMg +bGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5hIHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBl +cmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2luaWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMs +IHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxpcXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQg +bmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1 +dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxpdC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVz +IG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRpcyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1 +ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUgbmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBw +ZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25n +dWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJbnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBk +b2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBzZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIs +IGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywgbmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2Vk +IGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQgaXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3Rv +IHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4gVXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1 +ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJyYSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29y +cGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVyaXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBv +cmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGlu +Y2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJpbmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRp +bmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBpcy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVy +cGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3JjaSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRy +dW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3VyYWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFu +dGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxl +bnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRyaWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0 +IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3UuIE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50 +ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBBZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJp +c3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVtLiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSBy +aG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMgYSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVs +bGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlzdGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFt +IG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwgdWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMg +ZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNl +ZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2JvcnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBp +bXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBxdWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3Bl +bmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5kaXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpW +aXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5pc2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxp +dCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2RhbGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGlu +IG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0g +bm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNlZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVl +ci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQuCgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVu +YXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywgYW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24g +YWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29u +Z3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFzZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1 +bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQsIGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVp +cyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2EuIEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBi +aWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1 +Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZh +bXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFByb2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9y +IGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3Ug +anVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29uc2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBt +aSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBsaWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVu +ZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJv +LCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBW +ZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVs +dHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgSW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9y +dG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVzdGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFy +ZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBl +dSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVuZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVz +LiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBj +b25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJlIG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVj +IG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9p +biB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQgYWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQu +IE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNvbGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEg +ZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlzbCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEg +YXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMg +ZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qg +b3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUgYSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRh +cGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBkaWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0 +cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVsbGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBs +ZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJhdC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3Ji +aSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFy +dHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBw +dXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVp +cywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwgbnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1 +cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFtIHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVu +dGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdldCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEg +bm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNl +bXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdpYXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGlu +IGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0gdmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVs +bGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1 +cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNvbmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2Vs +ZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFiaXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVs +aXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBldSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9y +IGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMsIGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFj +ZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGllbiwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQg +bWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlz +Y2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyBy +aXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMg +c2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHByZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1 +cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFz +c2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBuZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBp +biwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4g +TW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxh +LCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBhbGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQu +IFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMg +ZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQg +cXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQg +dGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2llcyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBu +b24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVnaWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQg +YW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEg +c2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlzLiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9y +IGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRlIG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBv +cnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1hdXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQg +aXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVu +aW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNjdW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMu +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQg +dWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlz +aXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQg +bGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVv +cy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVsbGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25z +ZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5jaWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5l +cXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Egc2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNx +dWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5kaXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1 +ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEgbG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQg +dml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9s +bGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4sIGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVj +dG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClByb2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQg +dWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlvIGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJh +dCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVzdCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUg +YSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3VzcGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBl +bmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVzIGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVu +LiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVlciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBT +ZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1hZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1 +cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGliZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdl +c3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5hbSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZh +Y2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4gRXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2 +b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2Qg +Y29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4gSW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24g +ZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMg +aXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2VtIG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1l +dHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMg +bmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRyZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZl +dWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQs +IG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywgdWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11 +cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFjaWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5j +LiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBk +aWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxlY3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywg +cG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVyb3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVv +LiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29u +dWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmlt +IHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBsaWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywg +cGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGlidWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3Jj +aSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQgc29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQg +dGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBl +ciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBpZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0g +dmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBzYXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBl +cm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZl +bCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlxdWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoK +VXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQuIFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8g +dml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBDcmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51 +bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGlndWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0g +cHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVlLiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1h +Z25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxsZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRv +cnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4gTWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5v +biB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxhIHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVu +IHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMuIERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNh +cGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMgaW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8g +YXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBpbnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4g +TnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQgYWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMs +IHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2VkIGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2Vt +IG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kgbWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0g +ZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlzdXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBl +dCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25lYyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5h +bSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4gUHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlz +bCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNp +dHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9y +Y2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1 +Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFsbGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1l +dCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8u +IFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGlnbmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1 +cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMg +cGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2lu +Zy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2Vt +LCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBjb25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlz +cXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBlbGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2 +b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9yIGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVs +bGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNvbmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBT +ZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGludGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQg +dmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlhbSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxs +aXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMgaWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVk +aW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBRdWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2Vt +LiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRvcnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwg +dmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rpby4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1 +cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVz +IGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1 +bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBlbGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBx +dWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxpcXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBl +dSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlzaXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVl +LiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxp +cXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQuIER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBs +aWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1vcmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBN +b3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1 +aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMg +ZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0gdWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBv +cm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4gY29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBB +bGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMuIFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBk +dWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFBy +YWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBBbGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxv +cmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBsZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBW +aXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNwZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5k +dW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVz +cXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBzb2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQg +ZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1v +bGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBmZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVy +cmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBjb25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJh +IHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2RhbGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0 +dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMg +Y29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVlIGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5l +cXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVtIGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJh +dC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21vZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQs +IGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVyIHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3Rl +bnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBsYWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRh +cGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCByaG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5h +IG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGlidXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJo +LiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBjdXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMu +IFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQg +dWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGll +IGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVkZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxh +IGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJlcml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1 +aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxpcy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9y +LCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBlbGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUg +bnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vtc2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9u +dGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBDcmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xv +ci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBwdXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVz +ZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlzLgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMg +c2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5h +cmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVjIGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5h +bSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVsbHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4g +ZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEgZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBi +bGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVp +c3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZhdWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBw +dXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVs +dW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4g +U3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMgYWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkg +dmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMgZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFBy +b2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFs +ZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBkaWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNx +dWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3JhdmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxs +YS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21tb2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVy +aXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1l +bnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQuIFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlz +IG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxl +by4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2VkIG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFj +dWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVs +bHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3Jj +aSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3IgYWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJ +bnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMuIE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUg +dmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhv +bmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFjZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1w +b3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFuZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xv +ciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFsZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFz +IHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJp +dGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVz +IGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxhbWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3Ji +aSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMsIGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1 +cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQgYW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24g +cHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMgcHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBh +dCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBlZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21v +ZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4gcG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25l +YyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBEb25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlk +LCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIgdmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBu +ZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1vcmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1 +cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1l +dCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVz +IGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlz +c2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5k +dW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIgYXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBt +b2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFtY29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2Nl +IGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNtb2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1 +cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1 +bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRhIGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2Vk +IGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGll +biBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJhdCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxs +dXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJl +dHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRp +bmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlvLCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVs +LCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVlIGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1w +dXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVj +dHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFu +IHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFBy +b2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFtIGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBl +bGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMg +aW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlzIGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFy +Y3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBldSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9y +bmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5hciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVu +dGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxl +c3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0 +IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRpdCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBW +ZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQgcG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0g +bm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBBbGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3Ju +YXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlzLCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVp +cywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBGdXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9y +IHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEsIGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBv +cmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRhZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGll +dC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxlby4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJp +Y2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVtIGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5h +LiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMgZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVn +aWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBTZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJ +biBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVxdWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFj +LCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBsZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWws +IGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBh +bnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNpbGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNl +Y3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBwbGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFt +dXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4gQ3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBv +cmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2luaWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVt +LgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJhYml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEs +IGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBuaWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5l +YyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUuIFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQg +bWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNlbGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1h +dHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVsbHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFj +aW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBldWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3Iu +IE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVzdWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1 +bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNz +IGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0g +b2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBzaXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4K +ClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFn +bmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNl +bnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29udmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0 +IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBldCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxs +ZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNpLiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQg +cmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBTZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywg +Y29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQsIGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1 +cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVvIGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9s +bGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9sb3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJh +dCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBhcmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwg +dmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlkIGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0 +IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUsIGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFl +LCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZh +Y2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMgcmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywg +cG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4g +RHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4gQWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBl +bGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFzIGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFt +Y29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVsaXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEu +IFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmguIEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNp +bmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2luIHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVu +YXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNpdHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNx +dWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFtIGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQg +bGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVyIGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3Np +bSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdpYXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZh +bGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBzZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3Ms +IHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBE +dWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4gTnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQg +dHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9pbiBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJp +cy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3Rp +YnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxh +bWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNl +ZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1 +dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0gbmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ks +IGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBwcmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0 +aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhhcmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVl +IGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0gdmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRh +IG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIElu +IG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxwdXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0 +aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3IgaW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBk +b2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwgZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVo +aWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMgcXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBp +biBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJob25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2Nl +IGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRl +bGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBuaXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFl +Y2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFtIG5lYyB0dXJwaXMuIFNlZCBzb2RhbGVzIHZl +c3RpYnVsdW0gbnVuYy4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5l +Y3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuCgpQZWxs +ZW50ZXNxdWUgZG9sb3IgZG9sb3IsIGxhb3JlZXQgZXUsIGFsaXF1ZXQgcXVpcywgc2NlbGVyaXNx +dWUgc2l0IGFtZXQsIGFyY3UuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOdWxs +YW0gY3Vyc3VzIHVybmEgZWdldCBlbGl0LiBRdWlzcXVlIGJsYW5kaXQgc2FwaWVuIGFjIGFudGUu +IFByb2luIG51bGxhIGVyb3MsIGdyYXZpZGEgdm9sdXRwYXQsIHNvZGFsZXMgdmVsLCBtb2xsaXMg +ZXUsIG1hc3NhLiBOdWxsYSB0cmlzdGlxdWUgc29sbGljaXR1ZGluIG5pc2wuIEN1cmFiaXR1ciB2 +aXRhZSBsb3JlbSB2aXRhZSB2ZWxpdCBlZ2VzdGFzIG9ybmFyZS4gQWVuZWFuIGVnZXQgZXJvcy4g +QWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBGdXNjZSBhIHVybmEgaWQgb2RpbyBhbGlxdWV0IGNvbnZh +bGxpcy4gQ3VyYWJpdHVyIHNpdCBhbWV0IG5pc2wgcG9zdWVyZSBsZW8gcG9zdWVyZSBkYXBpYnVz +LiBEdWlzIG1ldHVzIGVyYXQsIGx1Y3R1cyB2ZWwsIHJob25jdXMgYXQsIGNvbnZhbGxpcyBzaXQg +YW1ldCwgZW5pbS4gVml2YW11cyBoZW5kcmVyaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhp +bWVuYWVvcy4gRXRpYW0gZWdldCBlbGl0LgoKTnVsbGFtIGEgbnVuYy4gTG9yZW0gaXBzdW0gZG9s +b3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIG1ldHVzIHVybmEs +IHRpbmNpZHVudCBldCwgbGFjaW5pYSBzaXQgYW1ldCwgbG9ib3J0aXMgdml0YWUsIGxpZ3VsYS4g +UHJvaW4gZXQgbWF1cmlzIHZpdGFlIG1pIGFjY3Vtc2FuIHBlbGxlbnRlc3F1ZS4gRXRpYW0gcXVh +bSBwdXJ1cywgaGVuZHJlcml0IHNlZCwgZmV1Z2lhdCB2aXRhZSwgZXVpc21vZCBlZ2V0LCB0b3J0 +b3IuIFV0IGFsaXF1YW0gbWFnbmEgdml0YWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBqdXN0byB2 +ZWwgdmVsaXQgY29uZGltZW50dW0gdGVtcHVzLiBEdWlzIHRlbXB1cyBpcHN1bSB2aXRhZSB0ZWxs +dXMuIFByb2luIGluIG1hc3NhLiBFdGlhbSB1bGxhbWNvcnBlciBkaWN0dW0gdGVsbHVzLiBQcm9p +biBhbGlxdWV0IGZlbGlzIGF0IGxlbyBsYW9yZWV0IHB1bHZpbmFyLiBWZXN0aWJ1bHVtIGFyY3Ug +cHVydXMsIG1hbGVzdWFkYSBzaXQgYW1ldCwgY3Vyc3VzIGV1LCBwbGFjZXJhdCBzaXQgYW1ldCwg +bnVuYy4gTmFtIG1hc3NhIG9kaW8sIHNvbGxpY2l0dWRpbiBpbiwgYWRpcGlzY2luZyBhLCBhbGlx +dWFtIG5lYywgcmlzdXMuIEFsaXF1YW0gYmxhbmRpdCBoZW5kcmVyaXQgbGliZXJvLiBNYXVyaXMg +Z3JhdmlkYS4KClBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBDdXJhYml0dXIg +YSBuaWJoLiBVdCBpbnRlcmR1bSBmZXJtZW50dW0gbmVxdWUuIFBlbGxlbnRlc3F1ZSBzZWQgbnVu +Yy4gTWF1cmlzIHZlaGljdWxhIG5pc2kgZXQgbnVuYy4gUHJhZXNlbnQgbG9yZW0uIERvbmVjIHNl +bXBlci4gSW50ZWdlciBldSBsYWN1cyBpbiBlc3QgYWxpcXVhbSBoZW5kcmVyaXQuIFZlc3RpYnVs +dW0gZWdldCBuZXF1ZS4gU2VkIHNlbXBlciBsdWN0dXMgdmVsaXQuIEN1cmFiaXR1ciBuaWJoIGF1 +Z3VlLCBjb25ndWUgZXUsIGhlbmRyZXJpdCBpZCwgY29uZ3VlIGV0LCBlbmltLiBJbnRlZ2VyIHBs +YWNlcmF0IGFsaXF1YW0gbGVjdHVzLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gVml2YW11cyB2aXRhZSBlcm9zLiBEb25lYyB2ZWwgbmlz +bC4KCkluIHZlc3RpYnVsdW0gZmFjaWxpc2lzIHVybmEuIFV0IHJpc3VzLiBNYXVyaXMgcGhhcmV0 +cmEuIFBlbGxlbnRlc3F1ZSBtYXR0aXMuIEludGVnZXIgc3VzY2lwaXQgYWxpcXVhbSBpcHN1bS4g +RHVpcyBibGFuZGl0LCBzYXBpZW4gZXQgdWx0cmljaWVzIGNvbmRpbWVudHVtLCBmZWxpcyBtaSBl +bGVtZW50dW0gcGVkZSwgbmVjIHNhZ2l0dGlzIG1ldHVzIG1hdXJpcyBxdWlzIHF1YW0uIFF1aXNx +dWUgYWNjdW1zYW4gYXJjdSB2ZWwgbnVsbGEuIENyYXMgc2VtIHNhcGllbiwgcG9ydHRpdG9yIGlk +LCB1bHRyaWNpZXMgc2FnaXR0aXMsIGx1Y3R1cyBldSwgbnVsbGEuIEludGVnZXIgcXVpcyBlcm9z +LiBNb3JiaSBzZWQgdXJuYSBhIHRlbGx1cyB2ZWhpY3VsYSB2dWxwdXRhdGUuIEV0aWFtIG5lYyBh +dWd1ZSBlZ2V0IGZlbGlzIHNlbXBlciB0cmlzdGlxdWUuIFF1aXNxdWUgdXQgZG9sb3IgdmVsIHJp +c3VzIGRpY3R1bSBjb25zZXF1YXQuIFNlZCBlZ2V0IGRvbG9yIHNlZCBudW5jIGxhY2luaWEgYWxp +cXVldC4gU3VzcGVuZGlzc2UgYWMgdG9ydG9yIGluIGlwc3VtIHBvc3VlcmUgdmVuZW5hdGlzLiBT +ZWQgZWdldCBlcmF0LiBOdWxsYSBmYXVjaWJ1cy4gRHVpcyBsYW9yZWV0LCBtYXNzYSBwb3J0dGl0 +b3IgYWxpcXVldCBlZ2VzdGFzLCBpcHN1bSBsZWN0dXMgcmhvbmN1cyBxdWFtLCBpbiBhZGlwaXNj +aW5nIGVyb3Mgc2VtIHV0IHRlbGx1cy4gUGVsbGVudGVzcXVlIGZldWdpYXQgdGVtcHVzIHF1YW0u +IFZpdmFtdXMgaWQgZG9sb3IgZWdldCBzYXBpZW4gY29uc2VjdGV0dWVyIHRlbXBvci4gQWxpcXVh +bSBlcmF0IHZvbHV0cGF0LgoKTnVsbGEgaWFjdWxpcyBmZXJtZW50dW0gbGliZXJvLiBDdXJhYml0 +dXIgZmF1Y2lidXMsIG1hc3NhIG1hbGVzdWFkYSBjdXJzdXMgdGluY2lkdW50LCBlcmF0IHNlbSBl +bGVpZmVuZCBtYXVyaXMsIHNlZCBmcmluZ2lsbGEgbWkgYW50ZSBhYyBwdXJ1cy4gRHVpcyBlbGVt +ZW50dW0gbGVjdHVzLiBOdW5jIG9ybmFyZSBhcmN1IGV1IHRvcnRvci4gVmVzdGlidWx1bSB2ZWwg +ZG9sb3IgYXQgcHVydXMgbGFjaW5pYSBmcmluZ2lsbGEuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5h +dGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVz +IG11cy4gTmFtIGltcGVyZGlldC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWdu +aXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBNYWVjZW5h +cyB0aW5jaWR1bnQsIGVyb3MgYSBlZ2VzdGFzIHBlbGxlbnRlc3F1ZSwgcmlzdXMgcmlzdXMgZGlj +dHVtIGxpYmVybywgaWQgYWxpcXVldCBtZXR1cyBqdXN0byBpbiBtYXNzYS4gUHJvaW4gYSB0ZWxs +dXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50 +IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gU2VkIHB1cnVzLiBTZWQgbm9uIHBlZGUu +IEFlbmVhbiBtYXNzYSBzYXBpZW4sIHNvZGFsZXMgc2l0IGFtZXQsIGNvbnNlcXVhdCBkaWN0dW0s +IGVsZWlmZW5kIHZpdGFlLCB0b3J0b3IuIERvbmVjIHVsdHJpY2VzIGxhY2luaWEgZWxpdC4KCk1v +cmJpIGFkaXBpc2Npbmcgc29kYWxlcyBkb2xvci4gVXQgdWxsYW1jb3JwZXIgdWx0cmljaWVzIGVz +dC4gSW4gdmVuZW5hdGlzIHRlbXB1cyBhdWd1ZS4gU3VzcGVuZGlzc2UgdG9ydG9yIGRvbG9yLCBh +Y2N1bXNhbiBldCwgc3VzY2lwaXQgYSwgdGluY2lkdW50IHV0LCBsaWJlcm8uIEFsaXF1YW0gc2Nl +bGVyaXNxdWUgbWFnbmEgc2VkIGZlbGlzLiBRdWlzcXVlIHV0IG51bmMgYSBtYWduYSB2dWxwdXRh +dGUgcGxhY2VyYXQuIEFsaXF1YW0gcmhvbmN1cyB2ZWhpY3VsYSBkdWkuIFNlZCB0b3J0b3IuIE51 +bGxhbSBzaXQgYW1ldCBkaWFtLiBOdW5jIHNlZCBlcm9zLiBTZWQgZXQgb2RpbyB0aW5jaWR1bnQg +ZWxpdCBncmF2aWRhIGNvbnZhbGxpcy4gQ3VyYWJpdHVyIHF1aXMgdG9ydG9yIGEgbGFjdXMgc2Vt +cGVyIHZhcml1cy4gTWF1cmlzIGF0IGF1Z3VlIG5vbiBtaSBzb2xsaWNpdHVkaW4gYWxpcXVhbS4g +SW50ZWdlciB1bGxhbWNvcnBlci4gUGVsbGVudGVzcXVlIHN1c2NpcGl0IHF1YW0gbm9uIHB1cnVz +LiBBbGlxdWFtIGFjIGVyb3MgYXQgYXJjdSB1bGxhbWNvcnBlciBjb25zZWN0ZXR1ZXIuIFN1c3Bl +bmRpc3NlIHByZXRpdW0gbWF0dGlzIGxlby4KCkR1aXMgYXQgbnVuYy4gU2VkIGRvbG9yIGVzdCwg +dmFyaXVzIGFjLCBwb3J0YSBldCwgdGluY2lkdW50IGhlbmRyZXJpdCwgcmlzdXMuIFZpdmFtdXMg +dXQgbWFnbmEuIFByYWVzZW50IHV0IG1hdXJpcy4gSW4gcHVydXMgbGFjdXMsIG1hdHRpcyBzZWQs +IHZlc3RpYnVsdW0gbmVjLCB0ZW1wb3IgYXQsIG5pc2wuIENyYXMgdWxsYW1jb3JwZXIgdmVuZW5h +dGlzIHRlbGx1cy4gVXQgZG9sb3IuIE1hZWNlbmFzIG1hbGVzdWFkYSwgcGVkZSBhIHB1bHZpbmFy +IG1hdHRpcywgYXJjdSBkaWFtIHZlaGljdWxhIHJpc3VzLCBxdWlzIHBvcnR0aXRvciBhdWd1ZSBt +YXNzYSBpbiB2ZWxpdC4gTnVuYyBjb25ndWUuIE1vcmJpIHZlbGl0IG1ldHVzLCByaG9uY3VzIGV0 +LCBhbGlxdWFtIGNvbnNlY3RldHVlciwgdWx0cmljaWVzIG1hbGVzdWFkYSwgbGlndWxhLiBTZWQg +dmVsaXQgbmlzbCwgc2FnaXR0aXMgdml0YWUsIHBoYXJldHJhIGEsIHBvc3VlcmUgc2VkLCBtYXNz +YS4gTnVsbGEgZmFjaWxpc2kuIEluIHZhcml1cywgbGlndWxhIGlkIGxvYm9ydGlzIHNvZGFsZXMs +IGF1Z3VlIG9yY2kgZmVybWVudHVtIHRlbGx1cywgZXUgcHVsdmluYXIgcmlzdXMgbGlndWxhIGEg +c2FwaWVuLiBNb3JiaSBsYW9yZWV0IGlwc3VtIG5vbiBtaS4gTmFtIGN1cnN1cyBsb3JlbSB1dCBt +aS4gVml2YW11cyBtYWduYSBlbmltLCBwb3N1ZXJlIG5vbiwgc2VtcGVyIHF1aXMsIHNvZGFsZXMg +ZXUsIGFyY3UuIEV0aWFtIG1pIHB1cnVzLCBwcmV0aXVtIGZldWdpYXQsIHZhcml1cyBzZWQsIHBl +bGxlbnRlc3F1ZSBlZ2V0LCBsaWd1bGEuIEluIGxlby4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHBy +aW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IERvbmVjIHZpdGFlIG9yY2kgZXUgb3JjaSBzb2xsaWNpdHVkaW4gZmV1Z2lhdC4KClBy +YWVzZW50IHB1cnVzIG1hc3NhLCBldWlzbW9kIHZpdGFlLCB0ZW1wdXMgbmVjLCBjb25zZXF1YXQg +aGVuZHJlcml0LCBtZXR1cy4gQWVuZWFuIGZlbGlzIGVzdCwgZWdlc3RhcyB2aXRhZSwgYWNjdW1z +YW4gZWdldCwgcGVsbGVudGVzcXVlIGluLCBzYXBpZW4uIER1aXMgZGFwaWJ1cyBwZWRlIG5vbiBz +YXBpZW4uIE51bmMgdXJuYS4gSW50ZWdlciB2ZWwgbGliZXJvLiBEdWlzIGF1Z3VlIGFyY3UsIGRh +cGlidXMgbm9uLCBmYWNpbGlzaXMgdml0YWUsIHBvc3VlcmUgdXQsIGVyb3MuIERvbmVjIHZpdGFl +IG51bmMgc2l0IGFtZXQgYXJjdSBpbXBlcmRpZXQgZGljdHVtLiBNb3JiaSBlbGVpZmVuZCwgbG9y +ZW0gZXUgY29uc2VjdGV0dWVyIHZlc3RpYnVsdW0sIGRpYW0gbnVuYyBvcm5hcmUgYXJjdSwgYWMg +dGVtcG9yIGZlbGlzIGRvbG9yIGVnZXQgZXJvcy4gUGhhc2VsbHVzIG1hc3NhIHNlbSwgc29sbGlj +aXR1ZGluIGFjLCBzb2RhbGVzIGdyYXZpZGEsIGx1Y3R1cyBhLCBxdWFtLiBOYW0gbmVxdWUgcXVh +bSwgdml2ZXJyYSBhdCwgdmVuZW5hdGlzIHF1aXMsIHNhZ2l0dGlzIG5vbiwgZW5pbS4KCk51bGxh +IGZhY2lsaXNpLiBQZWxsZW50ZXNxdWUgZWdlc3RhcyBsYWNpbmlhIGVzdC4gU2VkIHRpbmNpZHVu +dCwgcGVkZSBzZWQgdGluY2lkdW50IHZlc3RpYnVsdW0sIHVybmEgZG9sb3IgYWRpcGlzY2luZyBw +dXJ1cywgdml0YWUgZnJpbmdpbGxhIGZlbGlzIGVsaXQgaW4gbmliaC4gTnVsbGEgc2VkIG5pc2ku +IE1hdXJpcyBzdXNjaXBpdCBzY2VsZXJpc3F1ZSBhcmN1LiBFdGlhbSBub24gZW5pbSB2ZWwgZXJv +cyBhY2N1bXNhbiBtYWxlc3VhZGEuIE51bmMgdGluY2lkdW50IGNvbW1vZG8gbWF1cmlzLiBJbiB0 +aW5jaWR1bnQgcmlzdXMgcXVpcyB1cm5hLiBOdWxsYSBkaWFtIHRvcnRvciwgYWxpcXVldCBldCwg +dGluY2lkdW50IHF1aXMsIHNvbGxpY2l0dWRpbiBhYywgdG9ydG9yLiBDcmFzIG5pc2wgbmVxdWUs +IHZ1bHB1dGF0ZSBzdXNjaXBpdCwgbW9sZXN0aWUgcXVpcywgcHVsdmluYXIgYXQsIG51bGxhLiBO +dWxsYW0gYWMgbWV0dXMgbmVjIG9kaW8gcG9zdWVyZSB2YXJpdXMuIENyYXMgc2VkIHBlZGUgbmVj +IGR1aSBwb3N1ZXJlIGJpYmVuZHVtLiBEdWlzIGV1aXNtb2QgdWxsYW1jb3JwZXIgbGliZXJvLiBB +bGlxdWFtIGZhdWNpYnVzIHB1bHZpbmFyIHR1cnBpcy4KCkluIHV0IG5lcXVlIGlkIG51bmMgZmV1 +Z2lhdCBjb21tb2RvLiBDdXJhYml0dXIgZGlnbmlzc2ltLCBmZWxpcyBhdCBzb2xsaWNpdHVkaW4g +bGFjaW5pYSwgZW5pbSBlbGl0IHN1c2NpcGl0IG5lcXVlLCBzZWQgbHVjdHVzIGxvcmVtIGlwc3Vt +IGluIGxlby4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgYXVjdG9yIGNvbW1vZG8sIG5pc2wgb2Rp +byBtYXR0aXMgdGVsbHVzLCBuZWMgdGluY2lkdW50IHR1cnBpcyBkaWFtIGluIGFyY3UuIEN1cmFi +aXR1ciBhIHNlbS4gTnVsbGFtIHZvbHV0cGF0IG1hZ25hLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMs +IG5lcXVlIGNvbnNlcXVhdCBwcmV0aXVtIGN1cnN1cywgZG9sb3IgbGFjdXMgY29uc2VjdGV0dWVy +IGFyY3UsIHNlZCBsYW9yZWV0IGVzdCB1cm5hIGV0IG1ldHVzLiBTdXNwZW5kaXNzZSBwbGFjZXJh +dCwgZHVpIGEgcG9ydGEgdGVtcG9yLCBsb3JlbSBkdWkgbG9ib3J0aXMgbmVxdWUsIHNlZCB2ZW5l +bmF0aXMgZGlhbSBlbmltIGlkIGVyb3MuIEV0aWFtIGV0IG5pc2wgbm9uIGxlY3R1cyBmYXVjaWJ1 +cyBjb25zZWN0ZXR1ZXIuIE1vcmJpIHNjZWxlcmlzcXVlLCBzZW0gbmVjIHRlbXB1cyB1bGxhbWNv +cnBlciwgaXBzdW0gZGlhbSBmZXVnaWF0IGxvcmVtLCBhIGZyaW5naWxsYSBzYXBpZW4gZWxpdCBx +dWlzIG5pYmguIE51bGxhbSBkaWFtIHVybmEsIHZpdmVycmEgc2VkLCBwaGFyZXRyYSByaG9uY3Vz +LCB0aW5jaWR1bnQgdmVsLCBvcmNpLiBJbnRlZ2VyIGFjY3Vtc2FuIG1hdHRpcyBlcmF0LiBOYW0g +ZGljdHVtLiBNYXVyaXMgbmVjIGxlby4gTnVsbGEgaWFjdWxpcy4gTnVsbGEgbmlzbCBtaSwgZGFw +aWJ1cyBxdWlzLCB2ZWhpY3VsYSBhLCBjdXJzdXMgZWdldCwgb2Rpby4KClBoYXNlbGx1cyBkYXBp +YnVzIGV1aXNtb2QgbmliaC4gVml2YW11cyBpbXBlcmRpZXQgYW50ZSBpbiBsaWd1bGEuIFBlbGxl +bnRlc3F1ZSBhY2N1bXNhbi4gSW4gaW1wZXJkaWV0LCBkdWkgYSBhdWN0b3IgZnJpbmdpbGxhLCBt +ZXR1cyBuaXNpIGN1cnN1cyBkb2xvciwgdmVsIGx1Y3R1cyBsaWd1bGEgbG9yZW0gdml0YWUgbWF1 +cmlzLiBQcmFlc2VudCBtYXR0aXMgdmVzdGlidWx1bSBlbGl0LiBBbGlxdWFtIGVuaW0gbGFjdXMs +IHB1bHZpbmFyIG5vbiwgbGFjaW5pYSBzaXQgYW1ldCwgZWxlaWZlbmQgbm9uLCB2ZWxpdC4gVmVz +dGlidWx1bSBhYyBsZW8uIE1hdXJpcyBpbXBlcmRpZXQganVzdG8gYWMgbGVjdHVzLiBTZWQgbW9s +ZXN0aWUgbGVjdHVzIHNlZCBkdWkuIFNlZCBmZXJtZW50dW0gdGVtcHVzIG1hdXJpcy4gTmFtIG9y +bmFyZSBvcmNpIGFjIHRlbGx1cy4gVXQgbWFsZXN1YWRhLCBsYWN1cyBpZCBsYWNpbmlhIGFjY3Vt +c2FuLCBkaWFtIGVsaXQgYWRpcGlzY2luZyBtZXR1cywgZXQgYmliZW5kdW0gc2FwaWVuIG5pYmgg +YmxhbmRpdCBvcmNpLiBTdXNwZW5kaXNzZSBpcHN1bSB0ZWxsdXMsIHNhZ2l0dGlzIHF1aXMsIHZl +c3RpYnVsdW0gbm9uLCB2dWxwdXRhdGUgZXUsIGVyb3MuIFByYWVzZW50IGF0IG51bGxhIGlkIHBl +ZGUgc2NlbGVyaXNxdWUgdWx0cmljaWVzLiBDcmFzIGJsYW5kaXQgcHJldGl1bSB0ZWxsdXMuIE1h +ZWNlbmFzIGRhcGlidXMgY29uZGltZW50dW0gYXVndWUuIFBoYXNlbGx1cyB0aW5jaWR1bnQgcGhh +cmV0cmEgbG9yZW0uIE1vcmJpIG5vbiBlcm9zLiBTZWQgdGVtcG9yLCBuaXNsIGEgdGluY2lkdW50 +IHRpbmNpZHVudCwgZXJvcyBkaWFtIGRpY3R1bSBzZW0sIHZlbCBkaWduaXNzaW0gYW50ZSBkaWFt +IHNlZCBtYWduYS4gUHJhZXNlbnQgbm9uIGxpZ3VsYSBpZCBtZXR1cyBtb2xlc3RpZSBjb25zZWN0 +ZXR1ZXIuCgpQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0 +IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2Ug +dmVsIG1pLiBDdXJhYml0dXIgYW50ZSBudWxsYSwgcnV0cnVtIGEsIGNvbnZhbGxpcyB2ZWwsIHZl +aGljdWxhIGFjLCBudW5jLiBOdW5jIHNhZ2l0dGlzLCBlbmltIHNpdCBhbWV0IGF1Y3RvciBydXRy +dW0sIG1hdXJpcyBhcmN1IHZ1bHB1dGF0ZSBuZXF1ZSwgZXQgZXVpc21vZCBlc3QgZmVsaXMgcXVp +cyBhbnRlLiBWZXN0aWJ1bHVtIHR1cnBpcyB0ZWxsdXMsIGhlbmRyZXJpdCBpbiwgbGFjaW5pYSBj +b21tb2RvLCB1bGxhbWNvcnBlciBncmF2aWRhLCByaXN1cy4gTWF1cmlzIHJob25jdXMgbGFjaW5p +YSByaXN1cy4gTWFlY2VuYXMgc29sbGljaXR1ZGluIGVyYXQgdml0YWUgbnVuYy4gUHJhZXNlbnQg +cHJldGl1bSBwZWxsZW50ZXNxdWUgYXVndWUuIERvbmVjIGludGVyZHVtLiBQcmFlc2VudCBhYyBl +cm9zIHZpdGFlIGVyYXQgbG9ib3J0aXMgZnJpbmdpbGxhLiBBZW5lYW4gY29uc2VxdWF0IHRlbGx1 +cy4gTnVsbGEgYWNjdW1zYW4gYmliZW5kdW0gZmVsaXMuIE1hZWNlbmFzIHByZXRpdW0gYW50ZSBp +ZCBuaXNpLiBBZW5lYW4gbWkgYXJjdSwgc2VtcGVyIHNlZCwgbWF0dGlzIGV1LCB2ZW5lbmF0aXMg +c2l0IGFtZXQsIGFyY3UuIERvbmVjIGFsaXF1ZXQgZXVpc21vZCBsZW8uIFByb2luIG1hZ25hIGp1 +c3RvLCB0cmlzdGlxdWUgYSwgc2VtcGVyIGFjLCBzb2xsaWNpdHVkaW4gYSwgbGlndWxhLiBNb3Ji +aSB2ZWxpdC4gQWxpcXVhbSB2ZWwgbmlzaS4KCkluIGEgbG9yZW0gdXQgbnVuYyBmZXVnaWF0IGNv +bmd1ZS4gRG9uZWMgZmVybWVudHVtIGJpYmVuZHVtIGR1aS4gUHJvaW4gdmFyaXVzIGVzdCBxdWlz +IHZlbGl0LiBEb25lYyBhbGlxdWV0IHNlbSBhY2N1bXNhbiBtaS4gU2VkIHBsYWNlcmF0LiBOdWxs +YW0gYWMgbmlzaSBhIG1hc3NhIGxvYm9ydGlzIHN1c2NpcGl0LiBOdW5jIGlkIGxlby4gQWxpcXVh +bSBldCBtYXNzYS4gTnVsbGFtIHZlc3RpYnVsdW0gZWxlbWVudHVtIG1ldHVzLiBJbiBjb25zZWN0 +ZXR1ZXIgbmlzaSB2ZWwganVzdG8uIE1hZWNlbmFzIGVnZXQgcHVydXMgc2VkIG1hc3NhIHZhcml1 +cyBwZWxsZW50ZXNxdWUuIFBoYXNlbGx1cyBmYXVjaWJ1cyBmZWxpcyBxdWlzIGZlbGlzLiBBZW5l +YW4gb2RpbyBhcmN1LCBibGFuZGl0IHF1aXMsIGZhY2lsaXNpcyBpbiwgaW1wZXJkaWV0IGV1LCBs +b3JlbS4gTmFtIHBvc3VlcmUgcHVsdmluYXIgbWkuIEZ1c2NlIHRyaXN0aXF1ZSwgbWF1cmlzIGV0 +IGNvbnNlY3RldHVlciB1bHRyaWNpZXMsIG1hdXJpcyBsZWN0dXMgdGVtcG9yIGp1c3RvLCBhdCBm +cmluZ2lsbGEgZXN0IGVzdCBzZWQgbmlzaS4gUXVpc3F1ZSBmYXVjaWJ1cy4gU2VkIGluIHRvcnRv +ciB0aW5jaWR1bnQgZXN0IGxhY2luaWEgaWFjdWxpcy4gTWFlY2VuYXMgYSBtYXNzYS4gUGVsbGVu +dGVzcXVlIGEgbmliaCBhdCBwdXJ1cyBwb3J0YSBoZW5kcmVyaXQuCgpOdWxsYW0gdHVycGlzLiBG +dXNjZSBhYyBzZW0gc2VkIG9kaW8gcGVsbGVudGVzcXVlIGltcGVyZGlldC4gQ3VyYWJpdHVyIGlu +IGFyY3UuIFByYWVzZW50IGxhY3VzIGxhY3VzLCBmZXVnaWF0IGlkLCBwdWx2aW5hciBpbiwgdGlu +Y2lkdW50IHNlZCwgbmVxdWUuIE1hZWNlbmFzIHZpdmVycmEgb2RpbyBlZ2V0IHRvcnRvci4gSW50 +ZWdlciBhbGlxdWFtLCBsb3JlbSBydXRydW0gdmVuZW5hdGlzIGRpZ25pc3NpbSwgbGlndWxhIG1h +Z25hIG1hbGVzdWFkYSBhcmN1LCB2ZWwgZmV1Z2lhdCBsb3JlbSBpcHN1bSBxdWlzIG1hc3NhLiBN +b3JiaSBhbnRlLiBWZXN0aWJ1bHVtIG1hdXJpcyBsaWJlcm8sIHVsbGFtY29ycGVyIHF1aXMsIHVs +dHJpY2VzIHF1aXMsIGZhY2lsaXNpcyBub24sIG1hc3NhLiBNYWVjZW5hcyBpbXBlcmRpZXQuIEFs +aXF1YW0gZXJhdCB2b2x1dHBhdC4gUGVsbGVudGVzcXVlIGRpZ25pc3NpbSBncmF2aWRhIGxlY3R1 +cy4gSW4gbmliaCBvZGlvLCBhdWN0b3IgZWdldCwgZGFwaWJ1cyBxdWlzLCBkaWduaXNzaW0gdmVu +ZW5hdGlzLCBhcmN1LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9y +Y2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRHVpcyBwZWxsZW50 +ZXNxdWUgbGlndWxhIHF1aXMgbWFzc2EuIEN1cmFiaXR1ciBjb25kaW1lbnR1bSwganVzdG8gZWdl +dCBvcm5hcmUgbHVjdHVzLCBsb3JlbSBsaWd1bGEgc2FnaXR0aXMgcGVkZSwgYSBwb3J0YSBudW5j +IG51bmMgaW4gbmVxdWUuIFF1aXNxdWUgZmVsaXMgbWF1cmlzLCBjb25kaW1lbnR1bSB2aXRhZSwg +YXVjdG9yIHZpdGFlLCB0aW5jaWR1bnQgcXVpcywgcGVkZS4gTnVuYyBsYWNpbmlhIGFudGUgaW4g +bGVvLiBQZWxsZW50ZXNxdWUgbGliZXJvLiBBZW5lYW4gYSBsaWd1bGEgZXQgbnVuYyB2ZXN0aWJ1 +bHVtIGNvbnNlY3RldHVlci4KCkZ1c2NlIG9ybmFyZS4gUHJhZXNlbnQgaWQgdXJuYS4gSW50ZWdl +ciB2ZW5lbmF0aXMsIHF1YW0gbm9uIHNhZ2l0dGlzIGFjY3Vtc2FuLCBhbnRlIG5pYmggc2FnaXR0 +aXMgYXVndWUsIHNvbGxpY2l0dWRpbiBhZGlwaXNjaW5nIGRvbG9yIHZlbGl0IGV1IGVyYXQuIFBy +b2luIHF1aXMgZW5pbSBldSBwdXJ1cyB2ZWhpY3VsYSBhbGlxdWFtLiBOdWxsYSB2ZWwgZW5pbSB2 +ZWwgZWxpdCBzb2xsaWNpdHVkaW4gZnJpbmdpbGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIFNl +ZCBzdXNjaXBpdCBmZWxpcyB1dCB0dXJwaXMuIEV0aWFtIHJ1dHJ1bSByaXN1cyBpbXBlcmRpZXQg +ZXN0LiBBbGlxdWFtIGEgdGVsbHVzIGF0IHRlbGx1cyBjb21tb2RvIGRhcGlidXMuIE1hdXJpcyBy +dXRydW0gbWFnbmEgZXQgb2Rpby4gSW4gYXQgZG9sb3IuIEN1cmFiaXR1ciB2ZWhpY3VsYSBsZWN0 +dXMgaW4gdG9ydG9yLiBGdXNjZSBqdXN0byBwdXJ1cywgbHVjdHVzIHZpdGFlLCBtb2xsaXMgaW4s +IHBoYXJldHJhIGFjLCBwdXJ1cy4gTnVsbGFtIHBvc3VlcmUgaW50ZXJkdW0ganVzdG8uIEN1cmFi +aXR1ciB2aXRhZSBsYWN1cyB2ZWwgbGVvIGNvbmd1ZSBwdWx2aW5hci4KCkFlbmVhbiBlbGVpZmVu +ZCBuaWJoIHZhcml1cyB0b3J0b3IuIFN1c3BlbmRpc3NlIHZlbCBlcm9zLiBQcm9pbiBuZWMgZGlh +bSBhIHRvcnRvciB1bHRyaWNlcyBvcm5hcmUuIEFsaXF1YW0gc2NlbGVyaXNxdWUgZmV1Z2lhdCBq +dXN0by4gVml2YW11cyBhbnRlIHVybmEsIGFkaXBpc2Npbmcgdml0YWUsIHBvcnR0aXRvciBldSwg +c29kYWxlcyBldCwgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEN1cmFiaXR1ciBhYyBtYXNz +YSBpbiBuaXNsIHNhZ2l0dGlzIG1vbGxpcy4gTmFtIHF1YW0gbGlndWxhLCBjb25zZWN0ZXR1ZXIg +ZWdldCwgaWFjdWxpcyBhdCwgdmFyaXVzIGV1LCBsZW8uIER1aXMgZG9sb3IgbGlndWxhLCB0aW5j +aWR1bnQgYXQsIHVsbGFtY29ycGVyIHNlZCwgYWNjdW1zYW4gYWxpcXVhbSwgbGlndWxhLiBQaGFz +ZWxsdXMgdnVscHV0YXRlLCBsb3JlbSBhdCB0aW5jaWR1bnQgcGhhcmV0cmEsIHJpc3VzIGxlY3R1 +cyBsYWNpbmlhIG1hZ25hLCBxdWlzIHJ1dHJ1bSBlbmltIG1hZ25hIGF0IHNlbS4gSW4gaGFjIGhh +Yml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIER1aXMgaWQgc2VtIGEgbWF1cmlzIHNvbGxpY2l0dWRp +biB0aW5jaWR1bnQuIEV0aWFtIGV1IHB1cnVzIGV1IGFyY3UgZnJpbmdpbGxhIGFkaXBpc2Npbmcu +IFZpdmFtdXMgb3JuYXJlIHRlbXB1cyBkaWFtLiBQcm9pbiB0dXJwaXMgcXVhbSwgbGFjaW5pYSBu +b24sIGVnZXN0YXMgYXQsIGNvbW1vZG8gZWdldCwgcGVkZS4gUHJhZXNlbnQgdnVscHV0YXRlIHJp +c3VzIGluIGVzdC4gTnVsbGEgZmFjaWxpc2kuCgpVdCBlbGVtZW50dW0gbGFjaW5pYSBwdXJ1cy4g +UHJvaW4gdml0YWUgYXJjdSBhYyBudWxsYSBjb252YWxsaXMgYWxpcXVhbS4gTnVsbGEgY29uZ3Vl +LCBsaWJlcm8gaWQgcGVsbGVudGVzcXVlIG1hdHRpcywgcXVhbSBsZWN0dXMgcG9ydHRpdG9yIGRp +YW0sIGEgc2NlbGVyaXNxdWUgZHVpIGxpYmVybyBpbiBzYXBpZW4uIE51bGxhbSBmZWxpcyBkaWFt +LCB2ZWhpY3VsYSB2ZWwsIG1vbGVzdGllIHV0LCB2ZXN0aWJ1bHVtIGFsaXF1YW0sIHNhcGllbi4g +RG9uZWMgY29udmFsbGlzLCBlc3QgdXQgZWxlbWVudHVtIHZvbHV0cGF0LCBtYXVyaXMgaXBzdW0g +Z3JhdmlkYSBzZW0sIGNvbW1vZG8gZmFjaWxpc2lzIHNhcGllbiBsZWN0dXMgc2VtcGVyIGxlY3R1 +cy4gUXVpc3F1ZSBwb3J0dGl0b3IgZXJvcyB1dCBuaWJoLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0g +cHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgRXRpYW0gbWF0dGlzIHJpc3VzIHNlZCBvZGlvLiBWZXN0aWJ1bHVtIGV0IG9kaW8u +IEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdHJpc3RpcXVlIG1hc3NhIHV0 +IGxpZ3VsYS4gUXVpc3F1ZSBuaWJoIHRlbGx1cywgdmVoaWN1bGEgc2l0IGFtZXQsIGFkaXBpc2Np +bmcgYXQsIGNvbnZhbGxpcyBuZWMsIGxpZ3VsYS4gVmVzdGlidWx1bSBwcmV0aXVtLCBtaSBuZWMg +ZnJpbmdpbGxhIGJpYmVuZHVtLCBkdWkgbnVuYyBzb2RhbGVzIHBlZGUsIGEgc2VtcGVyIG1hZ25h +IG5pYmggbm9uIGRpYW0uIERvbmVjIG1hc3NhIG51bmMsIHZpdmVycmEgdmVsLCBjb25zZWN0ZXR1 +ZXIgcG9ydGEsIGRhcGlidXMgbm9uLCBpcHN1bS4gRHVpcyBuaXNsIG1hdXJpcywgY3Vyc3VzIHZl +bCwgc2VtcGVyIG5vbiwgc29sbGljaXR1ZGluIGJpYmVuZHVtLCBmZWxpcy4gVmVzdGlidWx1bSBl +dSBuZXF1ZS4KCkNyYXMgbmVjIGRvbG9yLiBEb25lYyBsYW9yZWV0IHRlbXB1cyBsZWN0dXMuIENy +YXMgc2VkIHRvcnRvciBpbnRlcmR1bSBsYWN1cyBlbGVpZmVuZCBkaWduaXNzaW0uIE1hZWNlbmFz +IHNpdCBhbWV0IGVsaXQuIE51bGxhbSBxdWlzIGRvbG9yIHZlbCBkdWkgcGhhcmV0cmEgbHVjdHVz +LiBJbiBzaXQgYW1ldCBxdWFtIHNpdCBhbWV0IHBlZGUgdWx0cmljZXMgdWx0cmljZXMuIE1hZWNl +bmFzIGRpYW0uIEludGVnZXIgdXJuYS4gQ3VyYWJpdHVyIGRpY3R1bSwgdmVsaXQgc2VkIHBsYWNl +cmF0IHN1c2NpcGl0LCBlcmF0IHR1cnBpcyBmZXJtZW50dW0ganVzdG8sIHNlZCBpbnRlcmR1bSBu +ZXF1ZSBzZW0gZXQgbmliaC4gVml2YW11cyBjb25zZXF1YXQgY29udmFsbGlzIG1hZ25hLiBOYW0g +YWxpcXVhbSwgZXN0IGFjIGJpYmVuZHVtIGNvbW1vZG8sIG1hZ25hIGVzdCBkaWN0dW0gbWksIHZp +dGFlIG1hbGVzdWFkYSBlbGl0IG1hZ25hIHZpdGFlIG9kaW8uIE1hZWNlbmFzIHRlbXBvciB2dWxw +dXRhdGUgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9y +Y2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGR1 +aS4gRXRpYW0gYWNjdW1zYW4gcGVkZSBjb25ndWUgdG9ydG9yLgoKTW9yYmkgdGVtcG9yIGxpYmVy +byBhYyBsb3JlbS4gSW4gYWxpcXVldCB2YXJpdXMgbWFnbmEuIEluIGFyY3UuIFBoYXNlbGx1cyBv +ZGlvLiBGdXNjZSB0aW5jaWR1bnQgYWxpcXVldCBmZWxpcy4gUXVpc3F1ZSB2ZWxpdC4gU2VkIGx1 +Y3R1cy4gQWxpcXVhbSBmZXVnaWF0IGZyaW5naWxsYSBtaS4gQWxpcXVhbSBtb2xlc3RpZSB2aXZl +cnJhIHJpc3VzLiBQcm9pbiBhcmN1LiBWZXN0aWJ1bHVtIGxvYm9ydGlzIHRlbXB1cyBuaXNpLiBQ +cmFlc2VudCBhIGFyY3UgaW4gdmVsaXQgdml2ZXJyYSBydXRydW0uCgpJbiBzZWQgbGVjdHVzLiBE +b25lYyByaXN1cyBkb2xvciwgYmxhbmRpdCBzaXQgYW1ldCwgZWxlbWVudHVtIGNvbnZhbGxpcywg +cGhhcmV0cmEgcXVpcywgcGVkZS4gSW50ZWdlciBvcm5hcmUuIEFlbmVhbiBlZ2VzdGFzIGRhcGli +dXMganVzdG8uIFNlZCBxdWFtIGxlbywgcG9zdWVyZSBhdCwgZWxlbWVudHVtIHZpdGFlLCBjb21t +b2RvIGVnZXQsIGVzdC4gQWxpcXVhbSBtb2xlc3RpZSByaG9uY3VzIGVuaW0uIEN1cmFiaXR1ciBp +YWN1bGlzIHVsdHJpY2VzIHBlZGUuIE1vcmJpIGFsaXF1ZXQgcnV0cnVtIGxhY3VzLiBBbGlxdWFt +IHF1YW0uIFNlZCBjb21tb2RvLCB0dXJwaXMgaW4gcGhhcmV0cmEgcG9zdWVyZSwgbWkgcmlzdXMg +aW1wZXJkaWV0IGVyYXQsIGEgdmVzdGlidWx1bSBtYXNzYSB0ZWxsdXMgdmVoaWN1bGEgc2VtLiBN +YXVyaXMgZnJpbmdpbGxhIHVsdHJpY2VzIG51bmMuIE5hbSBuaXNpIGVuaW0sIGVsZWlmZW5kIHNp +dCBhbWV0LCB1bHRyaWNlcyBzZWQsIGZlcm1lbnR1bSBub24sIGF1Z3VlLiBQcm9pbiBjb25ndWUg +bG9ib3J0aXMgbmlzaS4gTWFlY2VuYXMgaGVuZHJlcml0LiBOYW0gc2VkIG5pc2wuIE51bmMgZWxl +bWVudHVtIG9kaW8gZXUgcmlzdXMuIEluIG1ldHVzLiBQaGFzZWxsdXMgZ3JhdmlkYSBwcmV0aXVt +IGxpZ3VsYS4gTnVsbGEgdml0YWUgbmVxdWUuIE5hbSBuaXNpIHRvcnRvciwgb3JuYXJlIG5vbiwg +YmxhbmRpdCBhdCwgY3Vyc3VzIGV1LCB0b3J0b3IuCgpEdWlzIGJpYmVuZHVtIGlwc3VtIGluIG51 +bmMgY3Vyc3VzIG1vbGVzdGllLiBOdW5jIG9yY2kuIE51bGxhbSBuZWMgYW50ZSBub24gZXN0IGRp +Z25pc3NpbSB2aXZlcnJhLiBNYXVyaXMgYmxhbmRpdCwgdmVsaXQgaWQgZmV1Z2lhdCBwcmV0aXVt +LCBlbGl0IG1hZ25hIHBlbGxlbnRlc3F1ZSBkb2xvciwgYXQgc2FnaXR0aXMgbGFjdXMgdmVsaXQg +ZWdlc3RhcyBtYWduYS4gUGVsbGVudGVzcXVlIGN1cnN1cywgZGlhbSBjb25zZWN0ZXR1ZXIgc2Fn +aXR0aXMgZnJpbmdpbGxhLCB0b3J0b3IgbmlzaSBhZGlwaXNjaW5nIG51bmMsIGV1IHZhcml1cyBs +YWN1cyByaXN1cyBhYyBlbGl0LiBNYXVyaXMgaWQgbmlzaSBxdWlzIGxlbyBldWlzbW9kIHZlbmVu +YXRpcy4gUGVsbGVudGVzcXVlIGFjIGFudGUuIE1hdXJpcyBhcmN1IHNhcGllbiwgdGVtcG9yIGF0 +LCBwb3J0dGl0b3IgaWQsIGNvbmRpbWVudHVtIHV0LCBkdWkuIEV0aWFtIGZlcm1lbnR1bSB1bHRy +aWNpZXMgYXVndWUuIENyYXMgdXQgZXJvcyBhdCBqdXN0byB1bHRyaWNpZXMgaWFjdWxpcy4gRHVp +cyBkaWduaXNzaW0sIG5pc2wgZXQgZmFjaWxpc2lzIGZlcm1lbnR1bSwgZXJhdCBwdXJ1cyBtb2xl +c3RpZSB0ZWxsdXMsIHF1aXMgdGVtcHVzIGlwc3VtIGxlY3R1cyBhdCBlbGl0LiBOdWxsYSB2aXRh +ZSBsb3JlbS4KCkFlbmVhbiB2ZWwgc2VtIGV0IGRpYW0gc2VtcGVyIGNvbmd1ZS4gSW4gYmliZW5k +dW0gZGlhbSBxdWlzIHRlbGx1cy4gTnVuYyBmYWNpbGlzaXMgdWx0cmljaWVzIG5pYmguIENyYXMg +bnVuYyBlbmltLCBmZXVnaWF0IHNlZCwgdWx0cmljZXMgdml0YWUsIHNhZ2l0dGlzIHZpdGFlLCBp +cHN1bS4gRnVzY2Ugdml0YWUgbnVsbGEuIERvbmVjIHBlbGxlbnRlc3F1ZSwgdmVsaXQgaW4gcG9y +dHRpdG9yIGVsZWlmZW5kLCBlc3QgbmVxdWUgbG9ib3J0aXMgdmVsaXQsIHNpdCBhbWV0IHJ1dHJ1 +bSBhbnRlIHRvcnRvciBuZWMgZG9sb3IuIERvbmVjIHZlaGljdWxhLiBOdWxsYSBmYWNpbGlzaS4g +U2VkIGVnZXN0YXMgdWx0cmljZXMgbmliaC4gRG9uZWMgZWxpdCBsZWN0dXMsIGNvbnZhbGxpcyBw +b3J0dGl0b3IsIGFsaXF1ZXQgZGFwaWJ1cywgZmV1Z2lhdCBlZ2V0LCBsaWd1bGEuIFNlZCBjb25z +ZWN0ZXR1ZXIganVzdG8uIE1hZWNlbmFzIGEgc2FwaWVuIHNpdCBhbWV0IG5pc2kgZGFwaWJ1cyBs +b2JvcnRpcy4gVml2YW11cyBsdWN0dXMgbG9yZW0gbm9uIG51bGxhLiBTZWQgZWdldCBlcmF0IHZp +dGFlIGxpYmVybyBpbnRlcmR1bSBwb3N1ZXJlLiBDcmFzIHB1bHZpbmFyLiBOdWxsYW0gaW1wZXJk +aWV0LCBkb2xvciB0ZW1wb3IgZGlnbmlzc2ltIGJsYW5kaXQsIGR1aSBzYXBpZW4gcmhvbmN1cyBu +ZXF1ZSwgaWQgbWFsZXN1YWRhIGF1Z3VlIG1hZ25hIHNpdCBhbWV0IHVybmEuIER1aXMgc2VkIG1h +dXJpcy4KCk1vcmJpIGFjY3Vtc2FuLiBTZWQgbWF1cmlzIGF1Z3VlLCBmcmluZ2lsbGEgbm9uLCBh +dWN0b3IgdXQsIGF1Y3RvciBldCwgb3JjaS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRy +aXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVn +ZXN0YXMuIFZpdmFtdXMgdXQgcGVkZS4gRG9uZWMgdml2ZXJyYSBlbmltIHZlbCBsb3JlbS4gUGVs +bGVudGVzcXVlIG5lcXVlIG1hdXJpcywgaW50ZXJkdW0gZXUsIHZlbmVuYXRpcyBpZCwgY29uZGlt +ZW50dW0gZXUsIHNhcGllbi4gRG9uZWMgaXBzdW0gYXJjdSwgbGFjaW5pYSBhZGlwaXNjaW5nLCBs +YW9yZWV0IGV0LCBjdXJzdXMgdmVsLCB2ZWxpdC4gVXQgc2FnaXR0aXMgbWF1cmlzIHF1aXMgcmlz +dXMuIEludGVnZXIgZXUgb2RpbyB2aXRhZSBsYWN1cyB2aXZlcnJhIGFjY3Vtc2FuLiBNb3JiaSBs +ZW8gYW50ZSwgZGlnbmlzc2ltIHNlZCwgdmFyaXVzIHF1aXMsIHZvbHV0cGF0IHZpdGFlLCBuaXNp +LiBOdWxsYSBwbGFjZXJhdCBpbnRlcmR1bSBlbGl0LiBEb25lYyBuZXF1ZSBkdWksIHNhZ2l0dGlz +IHZpdGFlLCBzb2xsaWNpdHVkaW4gcXVpcywgY29tbW9kbyB2aXRhZSwgbmVxdWUuIE51bGxhIHF1 +aXMgbGlndWxhIG9ybmFyZSBsaWd1bGEgZGljdHVtIG9ybmFyZS4gTWF1cmlzIHJ1dHJ1bSBydXRy +dW0gbmVxdWUuIEFlbmVhbiB2ZWhpY3VsYSB0ZW1wdXMgZXN0LiBEb25lYyB2YXJpdXMgc2NlbGVy +aXNxdWUgcGVkZS4gRG9uZWMgcGxhY2VyYXQgdnVscHV0YXRlIGxlby4gTnVsbGFtIG51bmMgbmlz +bCwgcG9zdWVyZSBub24sIGZldWdpYXQgdml0YWUsIHBlbGxlbnRlc3F1ZSBxdWlzLCBtYXVyaXMu +IEluIGR1aSBuZXF1ZSwgY3Vyc3VzIGVnZXQsIHNhZ2l0dGlzIGVnZXQsIGRhcGlidXMgdml0YWUs +IG1pLiBQcm9pbiBlZ2V0IGVzdC4KCkZ1c2NlIHBvcnRhIGVzdC4gTWF1cmlzIG1hZ25hLiBBbGlx +dWFtIGlwc3VtIGxhY3VzLCB1bHRyaWNpZXMgaWQsIHZlc3RpYnVsdW0gbHVjdHVzLCBhY2N1bXNh +biB1dCwgYW50ZS4gU2VkIG1hdXJpcy4gU2VkIGFkaXBpc2NpbmcgbGVvIHNpdCBhbWV0IG1hZ25h +LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBOdW5jIG1hc3NhIGVsaXQsIGZyaW5naWxsYSBlZ2V0LCBl +Z2VzdGFzIHZpdGFlLCBsdWN0dXMgdml0YWUsIGRvbG9yLiBQaGFzZWxsdXMgcXVpcyBudWxsYSBl +dSBuaXNpIGludGVyZHVtIHNvbGxpY2l0dWRpbi4gTnVsbGFtIGlkIHRlbGx1cy4gSW50ZWdlciBp +YWN1bGlzIGRvbG9yIGFjIHB1cnVzLiBTZWQgdmVsIG1pLiBDdXJhYml0dXIgbm9uIG1hZ25hIHNp +dCBhbWV0IGp1c3RvIGNvbmRpbWVudHVtIHZ1bHB1dGF0ZS4gUXVpc3F1ZSB0aW5jaWR1bnQgcGVk +ZSBldSBuaXNsLiBWaXZhbXVzIGxvYm9ydGlzLiBOdW5jIG1ldHVzIG1ldHVzLCBjb25ndWUgc2Vk +LCB0aW5jaWR1bnQgc2VkLCBwcmV0aXVtIGF0LCBvZGlvLiBEb25lYyBhIGFyY3UuIEluIHNlbSBq +dXN0bywgdmVoaWN1bGEgc2VkLCB2YXJpdXMgaWQsIHZvbHV0cGF0IGF0LCByaXN1cy4gUHJhZXNl +bnQgaWFjdWxpcyBtYXNzYS4gSW4gYXJjdSBlbGl0LCBoZW5kcmVyaXQgZWdldCwgdWxsYW1jb3Jw +ZXIgaW4sIHBvcnRhIGlkLCB0ZWxsdXMuIERvbmVjIHNhZ2l0dGlzIGhlbmRyZXJpdCBkaWFtLgoK +U3VzcGVuZGlzc2UgcG90ZW50aS4gU2VkIGV0IGRpYW0gZXQgYXVndWUgc2FnaXR0aXMgbG9ib3J0 +aXMuIFBoYXNlbGx1cyBkb2xvci4gVXQgZXQgYXJjdSBlZ2V0IGFudGUgdGVtcG9yIHBvc3VlcmUu +IEFsaXF1YW0gZmVybWVudHVtIHNjZWxlcmlzcXVlIGR1aS4gTWF1cmlzIGF0IHB1cnVzLiBEb25l +YyBlcmF0IHNlbSwgdmVzdGlidWx1bSBuZWMsIGZhdWNpYnVzIGFjLCBtYXR0aXMgYSwgbGVvLiBT +dXNwZW5kaXNzZSBhZGlwaXNjaW5nIGxhY2luaWEgc2VtLiBOdWxsYW0gb3JjaSBhcmN1LCBkaWN0 +dW0gZXQsIGZhdWNpYnVzIHZpdmVycmEsIGRhcGlidXMgZXQsIG5lcXVlLiBDcmFzIG51bmMgZGlh +bSwgYWRpcGlzY2luZyBub24sIHNvbGxpY2l0dWRpbiBpbiwgaW50ZXJkdW0gdmVsLCBtYXNzYS4g +TWF1cmlzIHNhZ2l0dGlzLCBqdXN0byBhdCB0cmlzdGlxdWUgdGVtcHVzLCBtYXVyaXMgbWF1cmlz +IGFsaXF1YW0gYW50ZSwgc2l0IGFtZXQgcG9zdWVyZSBkaWFtIGR1aSBlZ2V0IGxpZ3VsYS4gSW4g +ZGlnbmlzc2ltLCBuaXNsIHV0IGxhY2luaWEgY29uZGltZW50dW0sIGVyYXQganVzdG8gcG9ydHRp +dG9yIG51bGxhLCBub24gZ3JhdmlkYSBsaWd1bGEgbWFnbmEgZWdldCBtYXNzYS4gVmVzdGlidWx1 +bSB2aXRhZSBsaWd1bGEgYXQgbWkgdmVzdGlidWx1bSBzdXNjaXBpdC4gRHVpcyBsYW9yZWV0LiBO +dWxsYSBjb21tb2RvIGxpYmVybyBzaXQgYW1ldCBsb3JlbS4gVXQgZWxlbWVudHVtIHNlbS4gSW50 +ZWdlciB2ZWwgZG9sb3IuIE5hbSBmYWNpbGlzaXMgbWkgcXVpcyBzZW0gdWx0cmljZXMgc2FnaXR0 +aXMuIFNlZCBxdWlzIHF1YW0gYXQgbWV0dXMgbW9sZXN0aWUgYmliZW5kdW0uCgpQcm9pbiBkdWkg +ZW5pbSwgbGFjaW5pYSBhLCBmZXVnaWF0IGFjLCBwbGFjZXJhdCB2aXRhZSwgcGVkZS4gUXVpc3F1 +ZSBlZ2VzdGFzLCBsZW8gZWdldCBhbGlxdWFtIHByZXRpdW0sIGxpYmVybyBqdXN0byB0aW5jaWR1 +bnQgZXJvcywgdXQgZWdlc3RhcyBhdWd1ZSBwZWRlIGVsZW1lbnR1bSBuaWJoLiBDdXJhYml0dXIg +bW9sbGlzIHNvZGFsZXMgZW5pbS4gRG9uZWMgYXVndWUuIFBoYXNlbGx1cyBpZCBpcHN1bSBwb3N1 +ZXJlIGR1aSBwcmV0aXVtIGZhdWNpYnVzLiBNYXVyaXMgbHVjdHVzIGFudGUgc2VtcGVyIG5pc2kg +aW50ZXJkdW0gYWRpcGlzY2luZy4gRHVpcyBkYXBpYnVzLCBvZGlvIHF1aXMgdml2ZXJyYSByaG9u +Y3VzLCBqdXN0byBxdWFtIGJpYmVuZHVtIGRvbG9yLCBpZCBkYXBpYnVzIHZlbGl0IGVyYXQgdmVs +IGVyYXQuIEZ1c2NlIHNpdCBhbWV0IG5pc2wgdmVuZW5hdGlzIHF1YW0gdWx0cmljZXMgY29uZGlt +ZW50dW0uIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0 +dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBEb25lYyByaG9uY3VzIHNjZWxl +cmlzcXVlIGxpZ3VsYS4gVmVzdGlidWx1bSBtaSBvZGlvLCBhY2N1bXNhbiBldCwgYWRpcGlzY2lu +ZyBlZ2V0LCBvcm5hcmUgdXQsIHF1YW0uIE51bGxhbSBibGFuZGl0IG1vbGVzdGllIG1hdXJpcy4g +Q3VyYWJpdHVyIGRpZ25pc3NpbSBtYXVyaXMgZXQgbG9yZW0uIFN1c3BlbmRpc3NlIGEganVzdG8u +IE5hbSBtYXR0aXMgZmF1Y2lidXMgYXJjdS4gRHVpcyBibGFuZGl0IGVuaW0gbm9uIG1hc3NhLgoK +TnVsbGFtIGxvcmVtLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gTWF1cmlzIGNv +bnNlY3RldHVlciBwb3N1ZXJlIG1hdXJpcy4gTWFlY2VuYXMgdGluY2lkdW50IG1hdXJpcyBpbiBl +cm9zLiBOdWxsYSBldSBtZXR1cyBldSBvcmNpIHNvbGxpY2l0dWRpbiBmYXVjaWJ1cy4gU3VzcGVu +ZGlzc2UgYWxpcXVhbSBtYXVyaXMgaWQgZXN0LiBDcmFzIGJsYW5kaXQgZHVpIGV0IHVybmEuIE51 +bGxhIGFyY3UuIFNlZCBhIHVybmEuIE51bGxhIGRhcGlidXMgdmVoaWN1bGEgdG9ydG9yLiBEb25l +YyByaXN1cy4gU2VkIHF1YW0gbWV0dXMsIGVnZXN0YXMgZXUsIGN1cnN1cyB1dCwgdml2ZXJyYSBu +b24sIG9kaW8uIFV0IGp1c3RvIGp1c3RvLCBtYWxlc3VhZGEgc2l0IGFtZXQsIGJsYW5kaXQgc3Vz +Y2lwaXQsIG1vbGVzdGllIGluLCBqdXN0by4gVmVzdGlidWx1bSBjb25zZXF1YXQsIHF1YW0gYWMg +ZmV1Z2lhdCB0aW5jaWR1bnQsIGlwc3VtIGxpYmVybyBlbGVpZmVuZCBvZGlvLCBub24gZWxlaWZl +bmQgcGVkZSBpcHN1bSBub24gYW50ZS4gTnVsbGFtIGEgbWV0dXMuCgpOYW0gYWMgbmlzaSBhdCBm +ZWxpcyBjdXJzdXMgbWF0dGlzLiBQZWxsZW50ZXNxdWUgY29uc2VxdWF0IHNlbSBxdWlzIG9yY2ku +IFF1aXNxdWUgdGVtcHVzLiBBZW5lYW4gaW1wZXJkaWV0IG1vbGVzdGllIHBlZGUuIENsYXNzIGFw +dGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3Ry +YSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBldSB0ZWxsdXMuIE51bGxhIGRpYW0g +ZXJvcywgc29kYWxlcyB1dCwgc29kYWxlcyBuZWMsIHRpbmNpZHVudCBhYywgbnVuYy4gTnVuYyBs +YWNpbmlhIGZhdWNpYnVzIGlwc3VtLiBWaXZhbXVzIHZlbCBuZXF1ZSBpbiBlcmF0IGZlcm1lbnR1 +bSBsdWN0dXMuIE51bGxhIGVnZXQgbWV0dXMgbmVjIGF1Z3VlIGJpYmVuZHVtIHBsYWNlcmF0LiBW +aXZhbXVzIHRlbXB1cy4gUHJhZXNlbnQgY29uZ3VlIG9ybmFyZSBpcHN1bS4gRXRpYW0gbWF0dGlz +IGZldWdpYXQganVzdG8uCgpBbGlxdWFtIGR1aS4gQWVuZWFuIGNvbW1vZG8gdG9ydG9yIHZpdGFl +IG51bGxhLiBNb3JiaSBldCBpcHN1bS4gTWF1cmlzIGFjIGlwc3VtLiBOYW0gdmVsIHJpc3VzIHV0 +IGxlY3R1cyBtb2xsaXMgdml2ZXJyYS4gQ3VyYWJpdHVyIGVsZW1lbnR1bSBtb2xsaXMgZXN0LiBO +dWxsYW0gZWxpdC4gVmVzdGlidWx1bSBzdXNjaXBpdCBwcmV0aXVtIGVuaW0uIFZlc3RpYnVsdW0g +dXQgbWFzc2EuIFByb2luIG5lYyBmZWxpcy4gTWFlY2VuYXMgZ3JhdmlkYSwgYXJjdSBuZWMgY29u +c2VxdWF0IHNhZ2l0dGlzLCBlcm9zIHRlbGx1cyBzY2VsZXJpc3F1ZSBtYXVyaXMsIHZpdGFlIGFj +Y3Vtc2FuIHF1YW0gcXVhbSB1dCBudW5jLiBJbnRlZ2VyIGVnZXQgYW50ZSBldSB2ZWxpdCBsYW9y +ZWV0IG1hbGVzdWFkYS4gTnVuYyBzYWdpdHRpcywgbWF1cmlzIHZpdGFlIHBoYXJldHJhIHZvbHV0 +cGF0LCB0ZWxsdXMgdGVsbHVzIGVsZWlmZW5kIGVyb3MsIHNpdCBhbWV0IHJ1dHJ1bSBpcHN1bSBu +aXNpIGEgdmVsaXQuIFByYWVzZW50IHZhcml1cyBsZW8gZXUgZXJhdC4gVml2YW11cyBjb25zZXF1 +YXQgcGxhY2VyYXQgcHVydXMuIERvbmVjIHByZXRpdW0gZWxlbWVudHVtIG5pYmguIFByb2luIGF0 +IGVsaXQgbm9uIHNlbSBhbGlxdWV0IG1hdHRpcy4gU2VkIHVsbGFtY29ycGVyIGlwc3VtIHNpdCBh +bWV0IGVsaXQuCgpNYXVyaXMgaW4gbWV0dXMuIFN1c3BlbmRpc3NlIG1hZ25hIGxvcmVtLCBmYXVj +aWJ1cyB2ZWwsIHRpbmNpZHVudCBxdWlzLCBzY2VsZXJpc3F1ZSBub24sIHRlbGx1cy4gRnVzY2Ug +cXVpcyBsb3JlbS4gUHJvaW4gYSBsYWN1cyBzaXQgYW1ldCBtYXVyaXMgaWFjdWxpcyBwdWx2aW5h +ci4gU3VzcGVuZGlzc2UgcmhvbmN1cyBlcm9zIG5lYyBtaS4gUHJhZXNlbnQgZXVpc21vZCwgdHVy +cGlzIHZpdGFlIHJ1dHJ1bSBwcmV0aXVtLCBvZGlvIG1ldHVzIHZvbHV0cGF0IG5lcXVlLCBlZ2V0 +IHRlbXB1cyBzYXBpZW4gbmVxdWUgc2VkIGVyYXQuIERvbmVjIGZlcm1lbnR1bSBwdXJ1cyBhdCBs +ZWN0dXMuIE51bGxhbSBzZW0uIEZ1c2NlIHZlbCBtaSBxdWlzIGVyYXQgbG9ib3J0aXMgcG9zdWVy +ZS4gQWVuZWFuIGVnZXQgdXJuYS4gU3VzcGVuZGlzc2UgbGlndWxhLiBEdWlzIGluIG5pc2kuIExv +cmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LgoK +Q3VyYWJpdHVyIHZ1bHB1dGF0ZSBsZWN0dXMgaWQgcGVkZS4gUGhhc2VsbHVzIGV1IHZlbGl0LiBF +dGlhbSB2ZW5lbmF0aXMgYWRpcGlzY2luZyBuaWJoLiBBbGlxdWFtIGN1cnN1cyBwdWx2aW5hciB0 +ZWxsdXMuIFZlc3RpYnVsdW0gbmVxdWUuIE1hdXJpcyBuZWMganVzdG8gZXQgZXJhdCBzZW1wZXIg +cGVsbGVudGVzcXVlLiBGdXNjZSBtYXR0aXMgZGljdHVtIGRvbG9yLiBFdGlhbSBlZ2V0IHB1cnVz +IGV1IG1hc3NhIHZhcml1cyBlbGVtZW50dW0uIFBlbGxlbnRlc3F1ZSBtYXNzYS4gVXQgdWx0cmlj +aWVzIGRpYW0gc2VkIGlwc3VtLiBOdWxsYW0gZGlhbS4gUGVsbGVudGVzcXVlIGlkIG1hZ25hIGlk +IGxpYmVybyB0cmlzdGlxdWUgYWxpcXVhbS4KClV0IGVsZWlmZW5kLCBwdXJ1cyBpZCBwbGFjZXJh +dCB2ZW5lbmF0aXMsIHVybmEgYXVndWUgYWxpcXVldCBsaWd1bGEsIGluIHVsdHJpY2llcyBsZW8g +cmlzdXMgZXQgdGVsbHVzLiBNYXVyaXMgZXQgbnVsbGEgaWQgdXJuYSB0cmlzdGlxdWUgdGVtcHVz +LiBVdCBmYWNpbGlzaXMsIHVybmEgZXUgdmVzdGlidWx1bSByaG9uY3VzLCBsYWN1cyBlcm9zIGNv +bnNlY3RldHVlciBtZXR1cywgZXQgcnV0cnVtIGR1aSBsZWN0dXMgaW4gcHVydXMuIE51bmMgdmVs +IG5pc2wgbm9uIGlwc3VtIHRpbmNpZHVudCBtb2xsaXMuIE5hbSBxdWFtIGxhY3VzLCBvcm5hcmUg +dml0YWUsIHJob25jdXMgbm9uLCBjb25ndWUgc2VkLCBvZGlvLiBQcm9pbiBuaWJoIGR1aSwgcG9y +dGEgdmVsLCB2ZW5lbmF0aXMgbm9uLCBwZWxsZW50ZXNxdWUgdXQsIG5pc2kuIFNlZCB0cmlzdGlx +dWUgZmVsaXMgYSBtYWduYS4gU3VzcGVuZGlzc2UgZWdldCB0ZWxsdXMuIENyYXMgZ3JhdmlkYSBp +bXBlcmRpZXQgdmVsaXQuIEludGVnZXIgaGVuZHJlcml0IHJpc3VzLiBQcm9pbiBvcmNpLiBBbGlx +dWFtIHVsbGFtY29ycGVyIG1hdXJpcyBxdWlzIG1hdXJpcy4gTnVuYyBsYWNpbmlhIHZlc3RpYnVs +dW0gbWV0dXMuIER1aXMgdGVsbHVzLiBOdWxsYW0gZmF1Y2lidXMsIGxlbyBhYyB2dWxwdXRhdGUg +c29sbGljaXR1ZGluLCBsZW8gZG9sb3IgZmF1Y2lidXMgZXJhdCwgcXVpcyBiaWJlbmR1bSBvcmNp +IG9kaW8gbm9uIGFyY3UuCgpOdWxsYW0gYWNjdW1zYW4gbWF0dGlzIGRvbG9yLiBEb25lYyBldCBk +dWkuIFByYWVzZW50IGEgZmVsaXMgbW9sbGlzIGxhY3VzIHNlbXBlciBsYWNpbmlhLiBDdXJhYml0 +dXIgcGVsbGVudGVzcXVlIGx1Y3R1cyBlc3QuIFByb2luIG51bGxhIGR1aSwgY29uZGltZW50dW0g +dmVsLCBmYXVjaWJ1cyBub24sIGludGVyZHVtIGFjLCBlcmF0LiBNYWVjZW5hcyBzY2VsZXJpc3F1 +ZSwgbGVjdHVzIGlkIHZvbHV0cGF0IGFjY3Vtc2FuLCBzYXBpZW4gdG9ydG9yIHBlbGxlbnRlc3F1 +ZSBkdWksIHNlZCBzZW1wZXIgbWFnbmEgc2VtIHV0IGxlby4gUHJvaW4gbnVsbGEuIE51bGxhbSBk +YXBpYnVzIHVsbGFtY29ycGVyIHNlbS4gU3VzcGVuZGlzc2UgdmVoaWN1bGEgbWV0dXMgaW4gbnVu +Yy4gUGVsbGVudGVzcXVlIG5vbiBxdWFtIHZlbCBhcmN1IHVsdHJpY2VzIHVsbGFtY29ycGVyLiBQ +aGFzZWxsdXMgcXVpcyBmZWxpcyBzaXQgYW1ldCB0ZWxsdXMgdWxsYW1jb3JwZXIgZmVybWVudHVt +LiBTZWQgdmVoaWN1bGEgc29sbGljaXR1ZGluIHVybmEuIEN1cmFiaXR1ciBwaGFyZXRyYSBzY2Vs +ZXJpc3F1ZSByaXN1cy4gUGVsbGVudGVzcXVlIGlkIG1hc3NhIHF1aXMgbWV0dXMgYWxpcXVhbSBp +bXBlcmRpZXQuIEluIG51bmMgbGFjdXMsIGZldWdpYXQgaW4sIGdyYXZpZGEgZWdldCwgdmVuZW5h +dGlzIHV0LCB0ZWxsdXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE5hbSBjb25zZXF1YXQgYWRpcGlz +Y2luZyBkdWkuIEluIG51bGxhIG5pc2ksIGZldWdpYXQgdXQsIGZlcm1lbnR1bSB2ZWwsIGdyYXZp +ZGEgbmVjLCB0b3J0b3IuIEluIHNlZCBhdWd1ZS4KCkV0aWFtIHVsbGFtY29ycGVyIGF1Z3VlIGF0 +IGVuaW0uIEludGVnZXIgZGlnbmlzc2ltLiBBbGlxdWFtIHB1bHZpbmFyIGNvbmd1ZSBudWxsYS4g +TW9yYmkgZW5pbSBtYXNzYSwgZnJpbmdpbGxhIGEsIGFjY3Vtc2FuIGVnZXQsIGNvbmRpbWVudHVt +IG5lYywgZXJhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBh +cnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBBZW5lYW4gcGhhcmV0cmEu +IEV0aWFtIHBvcnR0aXRvciBwdXJ1cyBhIG1ldHVzLiBBbGlxdWFtIGludGVyZHVtIHNlbSBlZ2V0 +IGp1c3RvLiBRdWlzcXVlIHZvbHV0cGF0IGx1Y3R1cyBlc3QuIEFlbmVhbiBhdWd1ZS4gUGhhc2Vs +bHVzIGR1aSBsZWN0dXMsIHVsdHJpY2VzIG5lYywgY29tbW9kbyB2ZWwsIGF1Y3RvciB2ZWwsIG5p +c2kuIFV0IHVsdHJpY2VzIHBlbGxlbnRlc3F1ZSBuaXNpLiBJbnRlZ2VyIGFjIHZlbGl0IGV0IHNl +bSBpbXBlcmRpZXQgbHVjdHVzLiBGdXNjZSB2aXRhZSB0dXJwaXMgaWQgYXVndWUgbW9sbGlzIGNv +bnNlY3RldHVlci4KCk1hZWNlbmFzIG5lYyBsYWN1cy4gTWFlY2VuYXMgY29uZGltZW50dW0gb2Rp +byBldSBmZWxpcy4gTWF1cmlzIHV0IG5pc2wgdml2ZXJyYSBlcmF0IGZhdWNpYnVzIGFkaXBpc2Np +bmcuIEV0aWFtIGVnZXN0YXMuIE51bmMgZXQgZG9sb3Igdml0YWUgcmlzdXMgZGlnbmlzc2ltIGNv +bW1vZG8uIE1vcmJpIGxlY3R1cyB2ZWxpdCwgdGluY2lkdW50IG5lYywgYWxpcXVldCB2ZWwsIG1h +dHRpcyB2aXRhZSwgbGlndWxhLiBNYWVjZW5hcyB1bHRyaWNpZXMgc2VtcGVyIGRvbG9yLiBTdXNw +ZW5kaXNzZSBtYWxlc3VhZGEuIEludGVnZXIgbWF0dGlzIGVsaXQuIERvbmVjIGFjY3Vtc2FuLCBs +YWN1cyBmYWNpbGlzaXMgdmFyaXVzIHRlbXB1cywgbnVsbGEgZWxpdCBwb3J0YSBlcmF0LCBldCBy +dXRydW0gZWxpdCBzZW0gc2l0IGFtZXQgZHVpLgoKTWFlY2VuYXMgbW9sbGlzIG1pIG5vbiBudWxs +YS4gVml2YW11cyB0dXJwaXMuIFN1c3BlbmRpc3NlIGEgbWV0dXMuIEluIHF1aXMgbWkgaW4gdHVy +cGlzIGNvbmd1ZSBhdWN0b3IuIE1hZWNlbmFzIGxhY3VzLiBTdXNwZW5kaXNzZSBzb2xsaWNpdHVk +aW4uIFBoYXNlbGx1cyBwb3J0YSBudW5jIG5vbiBuaXNsIHB1bHZpbmFyIGVnZXN0YXMuIFNlZCBu +dWxsYS4gVmVzdGlidWx1bSBhYyBtaS4gTWF1cmlzIHVsdHJpY2llcyBjb25kaW1lbnR1bSBuZXF1 +ZS4gTnVsbGEgdGVtcHVzIGp1c3RvIHZlbCBtYXNzYS4gTnVsbGEgc3VzY2lwaXQgY29uZ3VlIGFy +Y3UuIFByYWVzZW50IGlkIHR1cnBpcy4gTWF1cmlzIG5pYmggcGVkZSwgZXVpc21vZCBzZW1wZXIs +IG1vbGVzdGllIGFjLCByaG9uY3VzIHZpdGFlLCBhbnRlLiBNYWVjZW5hcyBlcmF0IGZlbGlzLCB2 +aXZlcnJhIHNvbGxpY2l0dWRpbiwgc2FnaXR0aXMgZWdldCwgcGVsbGVudGVzcXVlIG5lYywgb3Jj +aS4gRnVzY2UgdWx0cmljZXMgY29uc2VxdWF0IGxhY3VzLiBBbGlxdWFtIGVyYXQgbWFnbmEsIGZl +dWdpYXQgYXQsIHZpdmVycmEgYSwgbW9sbGlzIG5vbiwgdHVycGlzLgoKRG9uZWMgbWkuIE5hbSBk +aWN0dW0gcGVsbGVudGVzcXVlIHNlbS4gRG9uZWMgbW9sbGlzIHJob25jdXMgZWxpdC4gUGhhc2Vs +bHVzIHJob25jdXMgcGVkZSBzaXQgYW1ldCByaXN1cy4gRG9uZWMgZWdldCBhdWd1ZS4gTWFlY2Vu +YXMgbm9uIGxlY3R1cy4gUGhhc2VsbHVzIHNvbGxpY2l0dWRpbiBuaXNpIG5lYyBmZWxpcy4gQWxp +cXVhbSBwcmV0aXVtLCBlc3QgZWdldCBzZW1wZXIgY29udmFsbGlzLCBuaWJoIG51bmMgc29sbGlj +aXR1ZGluIHB1cnVzLCBpZCB0ZW1wb3IgcGVkZSBkdWkgdmVsIG1hZ25hLiBWaXZhbXVzIGFjIGxv +cmVtLiBFdGlhbSBuaXNsIHRvcnRvciwgYWRpcGlzY2luZyBkaWN0dW0sIGVsZW1lbnR1bSBpbiwg +ZmFjaWxpc2lzIHNlZCwgbmliaC4gUHJvaW4gbWF1cmlzLiBQcm9pbiBydXRydW0gbWFzc2EgZWdl +dCBzZW0uIEN1cmFiaXR1ciB0ZW1wb3IgYWRpcGlzY2luZyBlbGl0LiBDdXJhYml0dXIgcHVydXMg +dGVsbHVzLCBmZXJtZW50dW0gZWdldCwgYWxpcXVldCB2aXRhZSwgY29udmFsbGlzIGFjLCBtYXVy +aXMuCgpJbnRlZ2VyIGNvbnNlcXVhdCB2ZWxpdCBldSBlcm9zIHRpbmNpZHVudCB2ZWhpY3VsYS4g +TnVsbGFtIGxvcmVtIHNhcGllbiwgcmhvbmN1cyBub24sIG1hdHRpcyBxdWlzLCB1bHRyaWNpZXMg +c2l0IGFtZXQsIGVuaW0uIEN1cmFiaXR1ciBjb21tb2RvLCBsaWJlcm8gaW4gZXVpc21vZCBzdXNj +aXBpdCwgc2VtIHB1cnVzIGZyaW5naWxsYSBlbmltLCBhYyBtb2xlc3RpZSB0b3J0b3Igb3JjaSBl +dCB2ZWxpdC4gRG9uZWMgcGVkZS4gRXRpYW0gcGxhY2VyYXQgY29uZGltZW50dW0gdHVycGlzLiBQ +aGFzZWxsdXMgZWdlc3RhcyBlbmltIG5lYyBtYWduYS4gVml2YW11cyBjb25kaW1lbnR1bSwgbnVs +bGEgdmVsIGx1Y3R1cyB0cmlzdGlxdWUsIGVyb3MgcmlzdXMgdmVzdGlidWx1bSBudWxsYSwgaW4g +dmVoaWN1bGEgYXJjdSBpcHN1bSBhdCBmZWxpcy4gRG9uZWMgYWxpcXVhbSBlbGl0IGF0IGF1Z3Vl +LiBRdWlzcXVlIGEgZXJvcyBldSBsaWd1bGEgYWNjdW1zYW4gZGljdHVtLiBFdGlhbSB2ZWhpY3Vs +YSB0dXJwaXMgcXVpcyBsaWJlcm8uIEFsaXF1YW0gbm9uIG1pLiBEb25lYyBldCBsZW8uIFByb2lu +IGxlbyBsaWJlcm8sIGFsaXF1YW0gdGluY2lkdW50LCBjb25ndWUgbmVjLCBhZGlwaXNjaW5nIHBv +cnRhLCBlbmltLiBOdWxsYSBsb2JvcnRpcywgdG9ydG9yIHNpdCBhbWV0IGltcGVyZGlldCB1bGxh +bWNvcnBlciwgZG9sb3Igb3JjaSBtYWxlc3VhZGEgcGVkZSwgc2VkIGdyYXZpZGEgbmliaCB1cm5h +IHZlbCBsb3JlbS4gU2VkIHBoYXJldHJhIG1hbGVzdWFkYSBlcm9zLiBRdWlzcXVlIGV1aXNtb2Qg +YWxpcXVldCBlcmF0LiBTdXNwZW5kaXNzZSBhbGlxdWV0IG1hdHRpcyBwdXJ1cy4KCk51bmMgaWQg +bnVsbGEgcXVpcyBqdXN0byBjb25ndWUgc29sbGljaXR1ZGluLiBQcmFlc2VudCBlcmF0IHR1cnBp +cywgcmhvbmN1cyBldSwgcHJldGl1bSBldSwgcGVsbGVudGVzcXVlIGEsIG5pYmguIFZpdmFtdXMg +dGVtcHVzLiBDcmFzIG5lYyByaXN1cyBhdCB0dXJwaXMgaW1wZXJkaWV0IGxvYm9ydGlzLiBVdCBt +YXR0aXMuIE1hZWNlbmFzIGVzdCBmZWxpcywgcGVsbGVudGVzcXVlIG5vbiwgaW1wZXJkaWV0IHNl +ZCwgZWxlaWZlbmQgdGluY2lkdW50LCBsb3JlbS4gSW4gdGluY2lkdW50LiBTZWQgdmVsIGxlby4g +RG9uZWMgZXQgdXJuYSBpbiB0dXJwaXMgaGVuZHJlcml0IGJsYW5kaXQuIERvbmVjIGNvbmRpbWVu +dHVtIGFjY3Vtc2FuIGVzdC4gVXQgcGhhcmV0cmEsIG1ldHVzIHZpdGFlIG1hdHRpcyBjb25zZWN0 +ZXR1ZXIsIGxlbyBxdWFtIHZ1bHB1dGF0ZSBvZGlvLCBuZWMgbGFvcmVldCBuaXNpIHZlbGl0IGV1 +IGVyYXQuIEludGVnZXIgbGVjdHVzIGF1Z3VlLCBlZ2VzdGFzIGluLCBpbnRlcmR1bSBldSwgdmVu +ZW5hdGlzIHZlbCwgc2FwaWVuLiBRdWlzcXVlIGV0IGVzdCB2aXRhZSBlcm9zIGxhb3JlZXQgbG9i +b3J0aXMuIE51bGxhbSB1dCByaXN1cyBub24gbnVsbGEgcGxhY2VyYXQgYWRpcGlzY2luZy4gUHJh +ZXNlbnQgZGFwaWJ1cy4gRXRpYW0gYSBmZWxpcy4gVXQgc29kYWxlcyBjb25zZXF1YXQgbWF1cmlz +LiBEdWlzIGxvcmVtIGZlbGlzLCBsdWN0dXMgYSwgdHJpc3RpcXVlIGluLCBtb2xlc3RpZSBhdCwg +cmlzdXMuIFNlZCB2ZWhpY3VsYSBiaWJlbmR1bSB0ZWxsdXMuIE5hbSBjb25zZXF1YXQgZXVpc21v +ZCBsYWN1cy4KCkFlbmVhbiB0b3J0b3IgZWxpdCwgZ3JhdmlkYSBuZWMsIGZlcm1lbnR1bSBldSwg +bG9ib3J0aXMgaWQsIGlwc3VtLiBNYWVjZW5hcyBldSBwdXJ1cy4gQ3JhcyBhYyB0dXJwaXMgdXQg +bmlzaSBpYWN1bGlzIHJob25jdXMuIE51bGxhIHB1cnVzIG1ldHVzLCBkaWduaXNzaW0gbmVjLCB0 +aW5jaWR1bnQgdml0YWUsIGRhcGlidXMgZXUsIG5pYmguIEZ1c2NlIGxvYm9ydGlzLCBudW5jIGF0 +IHZpdmVycmEgZWxlaWZlbmQsIGp1c3RvIHR1cnBpcyBzY2VsZXJpc3F1ZSBlcm9zLCBhYyBwZWxs +ZW50ZXNxdWUgbWV0dXMgbmlzbCBhdCBwdXJ1cy4gU2VkIGVsZW1lbnR1bSB0ZWxsdXMgc2VkIGVu +aW0gaW50ZXJkdW0gYmxhbmRpdC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3Rl +dHVlciBhZGlwaXNjaW5nIGVsaXQuIEludGVnZXIgdWx0cmljaWVzIGFsaXF1ZXQgb2Rpby4gTWF1 +cmlzIGVnZXQgbnVuYyBhIGlwc3VtIHVsdHJpY2VzIHNvbGxpY2l0dWRpbi4gVmVzdGlidWx1bSBh +bnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1 +ZXJlIGN1YmlsaWEgQ3VyYWU7IEFlbmVhbiBhY2N1bXNhbi4gRG9uZWMgc2FwaWVuIGxlY3R1cywg +Y29uZ3VlIGF0LCBwb3J0YSBpZCwgaGVuZHJlcml0IHZpdGFlLCBuaXNsLiBDdXJhYml0dXIgdmVs +IHF1YW0gdmVsIG5lcXVlIGFjY3Vtc2FuIGxhb3JlZXQuIE1vcmJpIHNhcGllbiBlc3QsIHByZXRp +dW0gaW4sIGNvbnNlY3RldHVlciBhYywgbW9sbGlzIHV0LCBsaWJlcm8uIERvbmVjIHRpbmNpZHVu +dCBhZGlwaXNjaW5nIG1ldHVzLiBOdW5jIHZlc3RpYnVsdW0gZWdlc3RhcyBhdWd1ZS4gRG9uZWMg +c2NlbGVyaXNxdWUgZHVpIHV0IHNlbS4gU3VzcGVuZGlzc2UgdmVsIG1ldHVzIGlkIGVzdCBtb2xl +c3RpZSBpYWN1bGlzLgoKVml2YW11cyBwaGFyZXRyYSwgZWxpdCBldSBtYWxlc3VhZGEgYmxhbmRp +dCwgZGlhbSB0b3J0b3IgbW9sbGlzIGR1aSwgc2VkIHB1bHZpbmFyIG1hc3NhIG51bmMgZXQgbWFn +bmEuIFNlZCBwbGFjZXJhdCBlbGl0IGF1Y3RvciB0b3J0b3IuIE51bGxhIGFjIGVyYXQuIFBlbGxl +bnRlc3F1ZSBjb25zZWN0ZXR1ZXIsIGR1aSBjb252YWxsaXMgdGluY2lkdW50IGNvbmRpbWVudHVt +LCBzZW0gb2RpbyB2b2x1dHBhdCBsaWJlcm8sIG5vbiBlbGVtZW50dW0gZmVsaXMgbmVxdWUgbmVj +IG9kaW8uIE1hZWNlbmFzIGhlbmRyZXJpdCBlcm9zIGlkIGRpYW0uIE1hdXJpcyB2ZWwgcHVydXMg +YWMgb3JjaSBjb252YWxsaXMgY29udmFsbGlzLiBTZWQgc2l0IGFtZXQgbGFjdXMuIENsYXNzIGFw +dGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3Ry +YSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUXVpc3F1ZSBkaWN0dW0gdmFyaXVzIGxhY3VzLiBN +YXVyaXMgZWdldCBuaXNsLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCwgbnVsbGEgbm9uIG9ybmFyZSBk +aWduaXNzaW0sIG5pc2wgZGlhbSBzYWdpdHRpcyB0ZWxsdXMsIGluIHNlbXBlciBuaXNpIGRvbG9y +IGF0IG5pYmguIER1aXMgdWxsYW1jb3JwZXIgdml2ZXJyYSBmZWxpcy4gSW50ZWdlciBhIHRlbGx1 +cy4gU3VzcGVuZGlzc2UgZWdldCBudW5jLiBBZW5lYW4gZGlhbSBlc3QsIGFjY3Vtc2FuIGlkLCBz +dXNjaXBpdCBpbnRlcmR1bSwgZnJpbmdpbGxhIHZpdGFlLCBqdXN0by4gUHJvaW4gcGVkZS4gTWFl +Y2VuYXMgYXQgbmVxdWUgaW4gbmVxdWUgdmVzdGlidWx1bSBlbGVpZmVuZC4KClZlc3RpYnVsdW0g +bnVsbGEgbG9yZW0sIHBvcnR0aXRvciBlZ2V0LCBldWlzbW9kIGFjLCBhbGlxdWFtIGF0LCBuaXNs +LiBNYWVjZW5hcyBldCBlc3QgZWdldCBtYXNzYSB2YXJpdXMgbG9ib3J0aXMuIEluIG1pLiBEdWlz +IHBvcnR0aXRvciBmZXJtZW50dW0gcHVydXMuIERvbmVjIGN1cnN1cyBpbXBlcmRpZXQgbGlndWxh +LiBNb3JiaSBldCBsaWd1bGEgZXQgYW50ZSBtb2xlc3RpZSB2ZWhpY3VsYS4gTWF1cmlzIHNlZCBk +b2xvci4gU2VkIGltcGVyZGlldCBmZWxpcyB1dCBzZW0uIFNlZCB2aXRhZSBuZXF1ZSBlbGVtZW50 +dW0gbGVvIGF1Y3RvciBmZXJtZW50dW0uIER1aXMgZmV1Z2lhdCB1bGxhbWNvcnBlciBlcmF0LiBB +ZW5lYW4gcHVydXMuIE1vcmJpIGZlcm1lbnR1bSB2ZXN0aWJ1bHVtIGVzdC4gUGVsbGVudGVzcXVl +IHZlbmVuYXRpcyBtYXVyaXMuIFBoYXNlbGx1cyBwdWx2aW5hci4gSW50ZWdlciBpcHN1bSBsZWN0 +dXMsIGlhY3VsaXMgYSwgbGFjaW5pYSBpZCwgYWNjdW1zYW4gaWQsIGFyY3UuIFBoYXNlbGx1cyBh +dCBlc3QuIEZ1c2NlIG5lcXVlIHF1YW0sIHVsdHJpY2llcyBpZCwgaWFjdWxpcyB2ZWwsIGRhcGli +dXMgdml0YWUsIGxhY3VzLiBJbiBsb2JvcnRpcyBjb252YWxsaXMgYW50ZS4gTnVsbGEgbnVuYyBw +dXJ1cywgdnVscHV0YXRlIGluLCBoZW5kcmVyaXQgZXQsIGJsYW5kaXQgZXQsIGxpZ3VsYS4KClBl +bGxlbnRlc3F1ZSBsZW8gbWV0dXMsIHNhZ2l0dGlzIGluLCBtb2xlc3RpZSB2aXRhZSwgZGljdHVt +IGluLCBwZWRlLiBNb3JiaSBwcmV0aXVtIGZlbGlzIG5lYyBxdWFtLiBQZWxsZW50ZXNxdWUgbWF0 +dGlzIGFudGUgc2VkIHF1YW0gc2FnaXR0aXMgZGFwaWJ1cy4gU3VzcGVuZGlzc2Ugc2FwaWVuLiBQ +cmFlc2VudCBiaWJlbmR1bSBpYWN1bGlzIHRvcnRvci4gRHVpcyBhIG5pc2wuIEFlbmVhbiBtaS4g +RG9uZWMgZGljdHVtIGFyY3UgaW4gZXN0LiBNb3JiaSBpbnRlcmR1bSB2dWxwdXRhdGUgaXBzdW0u +IEFlbmVhbiBzaXQgYW1ldCBtYWduYSBub24gbmlzbCB0cmlzdGlxdWUgcG9zdWVyZS4gUGhhc2Vs +bHVzIHZlbGl0IG1ldHVzLCB0ZW1wb3IgYWMsIGZlcm1lbnR1bSBlZ2V0LCBjb25kaW1lbnR1bSBu +b24sIHZlbGl0LiBWZXN0aWJ1bHVtIHNpdCBwb3N1ZXJlLgoKTG9yZW0gaXBzdW0gZG9sb3Igc2l0 +IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIENyYXMgYWxpcXVldCBtYXNzYSBu +ZWMgZHVpLiBDcmFzIGFyY3UgbnVuYywgaGVuZHJlcml0IGFjLCBlbGVpZmVuZCBldSwgdWxsYW1j +b3JwZXIgbmVjLCB0ZWxsdXMuIFNlZCBwaGFyZXRyYSBwdXJ1cyBzaXQgYW1ldCBxdWFtLiBDdXJh +Yml0dXIgbW9sbGlzLiBOYW0gdml0YWUgcGVkZS4gRXRpYW0gcmlzdXMgbWFzc2EsIHZlaGljdWxh +IHNpdCBhbWV0LCBwaGFyZXRyYSBuZWMsIHNvbGxpY2l0dWRpbiB1dCwgZHVpLiBEb25lYyBlZ2Vz +dGFzIGp1c3RvIGF0IHF1YW0uIFByb2luIG5pc2wgcmlzdXMsIHZlc3RpYnVsdW0gbmVjLCBwcmV0 +aXVtIHZpdGFlLCB0cmlzdGlxdWUgYWMsIGxvcmVtLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIENy +YXMgc2VkIG5pYmguIFBlbGxlbnRlc3F1ZSBzb2xsaWNpdHVkaW4gZXVpc21vZCBhdWd1ZS4KCkV0 +aWFtIGZyaW5naWxsYSBzb2xsaWNpdHVkaW4gb3JjaS4gTWF1cmlzIGN1cnN1cyBlbGl0IHF1aXMg +bGFjdXMuIENyYXMgdG9ydG9yLiBJbiBhZGlwaXNjaW5nLCBsZWN0dXMgaWQgYXVjdG9yIHZlc3Rp +YnVsdW0sIG5lcXVlIHBlZGUgYWNjdW1zYW4gZG9sb3IsIG5vbiBpbXBlcmRpZXQgbWFnbmEgZGlh +bSBhY2N1bXNhbiB2ZWxpdC4gU3VzcGVuZGlzc2UgYXQgbGliZXJvIHV0IG5pc2kgYmxhbmRpdCBz +YWdpdHRpcy4gUGhhc2VsbHVzIG5vbiBtYXVyaXMuIEZ1c2NlIGVsZW1lbnR1bSBzYWdpdHRpcyBz +ZW0uIFN1c3BlbmRpc3NlIGFsaXF1YW0gZWxlaWZlbmQgdGVsbHVzLiBQcm9pbiBsaWd1bGEgbG9y +ZW0sIGltcGVyZGlldCBxdWlzLCB2ZW5lbmF0aXMgaWQsIGlhY3VsaXMgbW9sbGlzLCBuaXNsLiBF +dGlhbSBjb252YWxsaXMgcGVkZSBhdCBtYXNzYS4gTW9yYmkgYWNjdW1zYW4gZHVpIGV0IG1hdXJp +cy4KClNlZCBzZWQgb3JjaS4gTnVuYyBwdXJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gVXQgbHVj +dHVzIGZyaW5naWxsYSBtYXVyaXMuIERvbmVjIG5pYmguIFBoYXNlbGx1cyBwb3J0YS4gUGhhc2Vs +bHVzIHNpdCBhbWV0IG9kaW8gc2VkIG1hZ25hIHNvZGFsZXMgcGhhcmV0cmEuIENyYXMgbGVjdHVz +LiBTdXNwZW5kaXNzZSBsaWJlcm8gaXBzdW0sIGNvbW1vZG8gbmVjLCBmYWNpbGlzaXMgaW4sIHN1 +c2NpcGl0IGxvYm9ydGlzLCBsaWd1bGEuIER1aXMgbWFzc2EgbnVsbGEsIHNlbXBlciBldCwgY29u +c2VxdWF0IG5lYywgcGhhcmV0cmEgZXUsIGVsaXQuIFZpdmFtdXMgdWx0cmljaWVzIGFsaXF1YW0g +b2Rpby4gVmVzdGlidWx1bSBzaXQgYW1ldCBtYXNzYS4gU2VkIGNvbnNlcXVhdCBsYWN1cyBzZWQg +dXJuYS4gRXRpYW0gZmF1Y2lidXMgZmVsaXMgdmVsIG9yY2kuIFBoYXNlbGx1cyB1bGxhbWNvcnBl +ci4gQWVuZWFuIGNvbnNlY3RldHVlciBsYWN1cyBhdCBsaWJlcm8uCgpDbGFzcyBhcHRlbnQgdGFj +aXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBp +bmNlcHRvcyBoaW1lbmFlb3MuIER1aXMgZmFjaWxpc2lzLCBsaWd1bGEgdml0YWUgY29uZGltZW50 +dW0gc2NlbGVyaXNxdWUsIHZlbGl0IG9yY2kgZ3JhdmlkYSBmZWxpcywgdmVsIHVsdHJpY2llcyBx +dWFtIG1pIG5vbiBkaWFtLiBWaXZhbXVzIGF1Y3RvciBtZXR1cyBub24gbGliZXJvLiBQcmFlc2Vu +dCBsaWd1bGEgbmlzaSwgY29tbW9kbyBjb25kaW1lbnR1bSwgbW9sZXN0aWUgZXQsIHZpdmVycmEg +ZXQsIGp1c3RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVz +IGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVml2YW11cyBz +b2xsaWNpdHVkaW4uIE51bmMgYmxhbmRpdCBjdXJzdXMgaXBzdW0uIEFlbmVhbiBuZWMgbGlndWxh +IHV0IHRlbGx1cyBzb2RhbGVzIG1hdHRpcy4gSW50ZWdlciBzZW0uIEFsaXF1YW0gaWQgbGlndWxh +LiBTZWQgdG9ydG9yIG1hdXJpcywgYmxhbmRpdCB2aXRhZSwgY3Vyc3VzIHZlbCwgZWxlbWVudHVt +IGV0LCBudWxsYS4gQWxpcXVhbSBzY2VsZXJpc3F1ZSBtZXR1cyBldCBuaXNsLiBEdWlzIGFkaXBp +c2NpbmcgbWFnbmEgYXQgbmVxdWUuIFF1aXNxdWUgdnVscHV0YXRlIGVsZWlmZW5kIG51bmMuIEFs +aXF1YW0gZWdldCBlbGl0LiBQaGFzZWxsdXMgZHVpIG9kaW8sIGJpYmVuZHVtIHNhZ2l0dGlzLCB2 +ZXN0aWJ1bHVtIGlkLCBkaWduaXNzaW0gaW1wZXJkaWV0LCBvcmNpLiBOdWxsYW0gZXUgZmVsaXMg +bm9uIG51bmMgbGFjaW5pYSBzb2RhbGVzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJp +c3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdl +c3Rhcy4KClN1c3BlbmRpc3NlIHBlbGxlbnRlc3F1ZSwgbGliZXJvIG1hdHRpcyB1bHRyaWNpZXMg +YWNjdW1zYW4sIHRvcnRvciB0b3J0b3IgbWFsZXN1YWRhIHNlbSwgZXQgc29kYWxlcyBsaWJlcm8g +b2RpbyBhYyBpcHN1bS4gVml2YW11cyBxdWlzIG1hZ25hIG5lYyBlc3Qgc3VzY2lwaXQgbG9ib3J0 +aXMuIENyYXMgdGVtcHVzIHBvc3VlcmUgbnVuYy4gUXVpc3F1ZSB1dCBlbmltIGEgZmVsaXMgZWdl +c3RhcyBzZW1wZXIuIFNlZCBwaGFyZXRyYSBtYXR0aXMgbmVxdWUuIEZ1c2NlIHR1cnBpcyBudW5j +LCBjb25ndWUgc2VkLCBjb25zZXF1YXQgbm9uLCBjb25ndWUgc2VkLCBudWxsYS4gU3VzcGVuZGlz +c2UgdmFyaXVzIGxvcmVtIGlkIHJpc3VzIHBvcnRhIHZlc3RpYnVsdW0uIFBlbGxlbnRlc3F1ZSBo +YWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZh +bWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBGdXNjZSBzZWQgcHVydXMuIEluIGEgZmVsaXMuIEludGVn +ZXIgZWdlc3RhcyBhdWN0b3Igb3JjaS4gTWF1cmlzIHVsdHJpY2VzIHN1c2NpcGl0IG5pc2wuIE51 +bGxhbSBwdXJ1cy4KCkNyYXMgdGVtcG9yIGFkaXBpc2NpbmcgaXBzdW0uIFV0IHF1aXMgbWkuIE1h +ZWNlbmFzIGluIGp1c3RvIHV0IG51bGxhIGNvbmd1ZSBwaGFyZXRyYS4gUGVsbGVudGVzcXVlIHV0 +IGxpYmVybyBldSBkb2xvciB2ZW5lbmF0aXMgc3VzY2lwaXQuIFByYWVzZW50IGZldWdpYXQgY29u +c2VjdGV0dWVyIG5pYmguIE1vcmJpIGZhdWNpYnVzIHNlbSBub24gZmVsaXMuIEluIGhlbmRyZXJp +dCBhcmN1IGFjIG1hc3NhLiBJbiBhY2N1bXNhbiB1bHRyaWNlcyBtaS4gUHJvaW4gbWFsZXN1YWRh +IGF1Y3RvciBmZWxpcy4gQ3VyYWJpdHVyIGludGVyZHVtLiBTZWQgZGlhbSBpcHN1bSwgdWx0cmlj +aWVzIGluLCB0ZW1wb3Igc2l0IGFtZXQsIHZpdmVycmEgaW1wZXJkaWV0LCBlbGl0LiBNb3JiaSBt +b2xlc3RpZSBuaXNpLiBNYXVyaXMgaXBzdW0uIEZ1c2NlIGRpY3R1bSBtb2xsaXMgbWFnbmEuIER1 +aXMgY29tbW9kbyBkaWduaXNzaW0gbnVsbGEuIFZlc3RpYnVsdW0gYXVndWUgZW5pbSwgdWx0cmlj +aWVzIHF1aXMsIGlhY3VsaXMgbmVjLCB0aW5jaWR1bnQgdml0YWUsIGRpYW0uIE1hdXJpcyBsYWNp +bmlhIHRlbXB1cyBpcHN1bS4gU2VkIGF0IG1hdXJpcy4gVXQgbG9yZW0uIERvbmVjIGxpYmVyby4K +CkR1aXMgaWFjdWxpcyBsYWNpbmlhIGxlY3R1cy4gQWVuZWFuIGNvbnZhbGxpcyBlcm9zIGFjIGFu +dGUuIFNlZCBxdWlzIG9yY2kgbmVjIHJpc3VzIGF1Y3RvciBmcmluZ2lsbGEuIFBoYXNlbGx1cyBm +YWNpbGlzaXMgZWxlbWVudHVtIG5pc2kuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0 +LiBOdW5jIHBvcnRhIGxhY3VzIG5lYyBhbnRlLiBNb3JiaSBtYXVyaXMgZXJhdCwgYWRpcGlzY2lu +ZyBpbiwgcHVsdmluYXIgbmVjLCBsb2JvcnRpcyBuZWMsIG9kaW8uIFV0IGVsZWlmZW5kIGxlY3R1 +cyBzZWQgcXVhbS4gTnVsbGFtIG1vbGxpcy4gSW4gbm9uIHR1cnBpcyBldCBuaXNsIGhlbmRyZXJp +dCBibGFuZGl0LiBEdWlzIGVsZW1lbnR1bS4gTnVuYyBuZWMgbGliZXJvLiBTdXNwZW5kaXNzZSB2 +ZXN0aWJ1bHVtIHJpc3VzIG5vbiBwZWRlLiBNb3JiaSBpbXBlcmRpZXQgb2RpbyBzaXQgYW1ldCBs +aWJlcm8uIFNlZCBzZWQgbWFzc2Egdml0YWUgaXBzdW0gbWF0dGlzIHRpbmNpZHVudC4gTnVsbGEg +bmVjIHRvcnRvciB2aXRhZSBsaWJlcm8gdm9sdXRwYXQgdGVtcHVzLiBEb25lYyBhbGlxdWFtLgoK +RHVpcyBzZWQgbnVuYy4gQ3VyYWJpdHVyIHR1cnBpcyBudWxsYSwgdmVoaWN1bGEgc2VkLCBsdWN0 +dXMgcXVpcywgZWxlbWVudHVtIGVnZXQsIGZlbGlzLiBNYWVjZW5hcyBldCBwdXJ1cy4gTWFlY2Vu +YXMgbGVvIHRlbGx1cywgdGluY2lkdW50IGEsIGZhY2lsaXNpcyB2aXRhZSwgbG9ib3J0aXMgc2l0 +IGFtZXQsIHZlbGl0LiBEb25lYyBjb252YWxsaXMgc2FwaWVuLiBNYWVjZW5hcyBtb2xsaXMgb2Rp +byBldSBuaWJoLiBFdGlhbSBncmF2aWRhLiBJbnRlZ2VyIG1vbGVzdGllLCBzYXBpZW4gZXUgbW9s +ZXN0aWUgbGFjaW5pYSwgbnVuYyBuaWJoIGFsaXF1YW0gbGlndWxhLCBldSBzYWdpdHRpcyB0ZWxs +dXMgZXJhdCBzb2xsaWNpdHVkaW4gb2Rpby4gRHVpcyBldCByaXN1cy4gUGhhc2VsbHVzIG5pc2kg +bmVxdWUsIHBsYWNlcmF0IG5lYywgY29uZGltZW50dW0gbm9uLCB1bHRyaWNlcyBldSwgc2VtLiBV +dCBwZWRlLiBFdGlhbSBudWxsYSBtZXR1cywgdm9sdXRwYXQgaWQsIGNvbnZhbGxpcyBzZWQsIHN1 +c2NpcGl0IHZlbCwgdXJuYS4gRG9uZWMgdmVsIGVsaXQuIFV0IGxlbyBuZXF1ZSwgdmVuZW5hdGlz +IGZhdWNpYnVzLCBsYWNpbmlhIG5lYywgdGluY2lkdW50IGV1LCBlbmltLiBDcmFzIGlkIGR1aSBh +IGxpYmVybyBwaGFyZXRyYSBkaWduaXNzaW0uIERvbmVjIGVyb3MgbGVvLCBwb3J0YSBxdWlzLCBs +YW9yZWV0IHV0LCBwZWxsZW50ZXNxdWUgdm9sdXRwYXQsIGxlY3R1cy4KCk51bGxhbSBibGFuZGl0 +LiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEZ1c2NlIGFkaXBpc2NpbmcgZW5pbS4gU3VzcGVuZGlz +c2Ugbm9uIGR1aSBxdWlzIGxpZ3VsYSBwb3J0YSB2ZXN0aWJ1bHVtLiBEb25lYyBldSB0ZWxsdXMg +dmVsIGxvcmVtIHByZXRpdW0gcG9ydHRpdG9yLiBQcmFlc2VudCBsdWN0dXMuIEFsaXF1YW0gYWMg +ZXJvcyBpbiBtYXNzYSBkYXBpYnVzIHRpbmNpZHVudC4gRG9uZWMgdXQgbWFnbmEuIEV0aWFtIGF1 +Y3RvciBsYWN1cyBzaXQgYW1ldCBsYWN1cy4gU2VkIHVsdHJpY2llcyBpcHN1bSBuZWMgZWxpdC4g +UXVpc3F1ZSBhIGVzdCBpbiBwdXJ1cyBzdXNjaXBpdCB0cmlzdGlxdWUuCgpBZW5lYW4gc2VkIGR1 +aSB2ZWwgZG9sb3IgcHVsdmluYXIgbGFvcmVldC4gVml2YW11cyB2ZWhpY3VsYSBsb3JlbSBpbiBw +ZWRlLiBWaXZhbXVzIGV0IGRpYW0uIEludGVnZXIgYWMgb2RpbyB2ZWwgZGlhbSBoZW5kcmVyaXQg +YmliZW5kdW0uIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50 +IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gQ3VtIHNvY2lpcyBu +YXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1 +ciByaWRpY3VsdXMgbXVzLiBOdWxsYSBhIG5pc2kuIFBoYXNlbGx1cyB0aW5jaWR1bnQgZHVpIHZp +dGFlIGF1Z3VlLiBEdWlzIGZhdWNpYnVzLCBkdWkgaW50ZXJkdW0gZnJpbmdpbGxhIHRpbmNpZHVu +dCwgb2RpbyBlbGl0IHZlc3RpYnVsdW0gbGliZXJvLCBhYyBtb2xlc3RpZSBtYWduYSBsZWN0dXMg +aWQgbGFjdXMuIEFlbmVhbiBsaWd1bGEuIE51bGxhIGZhY2lsaXNpLgoKRnVzY2UgdmVsIHNlbSBl +dSB2ZWxpdCBmcmluZ2lsbGEgb3JuYXJlLiBTZWQgZmV1Z2lhdCB0aW5jaWR1bnQgZmVsaXMuIE51 +bGxhbSBmZWxpcyBtaSwgZXVpc21vZCBzaXQgYW1ldCwgbW9sbGlzIGF0LCBzb2RhbGVzIGVnZXQs +IGF1Z3VlLiBOYW0gaW1wZXJkaWV0IG5pYmggYXQgdmVsaXQuIFNlZCB1dCBlcmF0LiBJbiBkdWku +IE51bGxhIGZhY2lsaXNpLiBOdWxsYW0gYXVndWUgbGliZXJvLCB0aW5jaWR1bnQgbmVjLCBwcmV0 +aXVtIGV1LCBwdWx2aW5hciBpbiwgZHVpLiBNb3JiaSB2aXRhZSBmZWxpcy4gUGVsbGVudGVzcXVl +IHZlbCBqdXN0byB2ZWwgdmVsaXQgc2FnaXR0aXMgbWFsZXN1YWRhLiBQcm9pbiB2ZWhpY3VsYSBi +bGFuZGl0IG1hc3NhLiBFdGlhbSB0aW5jaWR1bnQgcGhhcmV0cmEgdXJuYS4gSW4gbWV0dXMgZXN0 +LCBhdWN0b3IgbmVjLCBibGFuZGl0IGEsIGN1cnN1cyBuZWMsIHF1YW0uIE1hdXJpcyBhYyBtZXR1 +cyBhIGxpYmVybyBjb25ndWUgZmF1Y2lidXMuIE1hdXJpcyBtYXVyaXMgZG9sb3IsIHNvZGFsZXMg +aW4sIGN1cnN1cyB1dCwgc29kYWxlcyBydXRydW0sIGVyb3MuIFF1aXNxdWUgbWF1cmlzIGVyb3Ms +IHNhZ2l0dGlzIHZpdGFlLCBsb2JvcnRpcyB1dCwgZWxlaWZlbmQgaWQsIG5pc2kuCgpBZW5lYW4g +bmVxdWUuIFZlc3RpYnVsdW0gZWdlc3RhcyBwZWxsZW50ZXNxdWUgbGlndWxhLiBDdW0gc29jaWlz +IG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2Nl +dHVyIHJpZGljdWx1cyBtdXMuIFBoYXNlbGx1cyBzYWdpdHRpcyBqdXN0byB2ZWwgcmlzdXMuIFNl +ZCBwcmV0aXVtIG5lcXVlIHZpdGFlIHVybmEuIFBlbGxlbnRlc3F1ZSBjb25ndWUgbGliZXJvIGlk +IGxvcmVtLiBNYXVyaXMgbGVvIGxvcmVtLCBibGFuZGl0IHNpdCBhbWV0LCBjb252YWxsaXMgcXVp +cywgY29uc2VjdGV0dWVyIHNlZCwgZXJvcy4gTWF1cmlzIHRpbmNpZHVudCwgZW5pbSBhIGdyYXZp +ZGEgZXVpc21vZCwgbWFnbmEgbnVsbGEgZmVybWVudHVtIGxpYmVybywgdml2ZXJyYSBlZ2VzdGFz +IHZlbGl0IHF1YW0gZXQgdG9ydG9yLiBWaXZhbXVzIGFsaXF1ZXQgbWFzc2Egdml0YWUganVzdG8u +IE51bGxhIGNvbmd1ZSBsYWN1cyBhYyBlbGl0LgoKUGhhc2VsbHVzIGNvbW1vZG8gcXVhbSB2ZWwg +bGlndWxhLiBQcm9pbiBub24gbWV0dXMgYXQgZXJvcyBwdWx2aW5hciBsdWN0dXMuIE1hdXJpcyBk +aWFtIGxvcmVtLCBwb3N1ZXJlIHF1aXMsIGdyYXZpZGEgZXQsIHRpbmNpZHVudCBuZWMsIGxpZ3Vs +YS4gU2VkIGRpYW0uIEFsaXF1YW0gZWxpdCBsZWN0dXMsIGhlbmRyZXJpdCB1dCwgaW1wZXJkaWV0 +IHNpdCBhbWV0LCBwcmV0aXVtIHNpdCBhbWV0LCBpcHN1bS4gTWF1cmlzIHZlaGljdWxhIG5pc2wg +aW4gZHVpLiBDdXJhYml0dXIgZWdldCBxdWFtIHV0IG1hZ25hIGVsZW1lbnR1bSBmZXJtZW50dW0u +IE1hdXJpcyBzY2VsZXJpc3F1ZS4gUXVpc3F1ZSBsYW9yZWV0LiBFdGlhbSB0ZW1wdXMgdHVycGlz +LiBQZWxsZW50ZXNxdWUgYXVndWUgcXVhbSwgaGVuZHJlcml0IHNlZCwgdGluY2lkdW50IGF0LCBw +aGFyZXRyYSBhdCwgbmlzbC4gQWxpcXVhbSBsYWN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gQWVu +ZWFuIHZlbGl0IGxpYmVybywgdWx0cmljZXMgaW4sIGxhY2luaWEgZXUsIGx1Y3R1cyB2ZWwsIGFu +dGUuIEV0aWFtIGRpY3R1bSBtaSBpbiBmZWxpcy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3Nx +dSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGlt +ZW5hZW9zLiBGdXNjZSBncmF2aWRhIGRhcGlidXMgbmlzbC4gQ3JhcyB2aXRhZSBuaXNsLgoKTWFl +Y2VuYXMgZGlnbmlzc2ltLCBsaWd1bGEgbm9uIHBvcnRhIGN1cnN1cywgZW5pbSBudW5jIG1hbGVz +dWFkYSBzZW0sIGV1IHBvcnR0aXRvciBudWxsYSB1cm5hIGV1IHF1YW0uIEZ1c2NlIGVyb3MuIEFs +aXF1YW0gZXJvcy4gTmFtIGF1Y3Rvci4gTnVsbGEgbW9sZXN0aWUgcG9ydGEgZXN0LiBTdXNwZW5k +aXNzZSBwb3RlbnRpLiBWaXZhbXVzIG1vbGVzdGllIGxvcmVtIHNlZCBlcmF0LiBTZWQgZWdldCBp +cHN1bS4gSW50ZWdlciBhbGlxdWFtIHB1bHZpbmFyIG51bGxhLiBDcmFzIGFsaXF1ZXQgc2VtIHV0 +IG51bmMuIEZ1c2NlIGZhdWNpYnVzIHRlbXB1cyBsZWN0dXMuIENyYXMgc29kYWxlcywgbmlzaSBh +YyBmYWNpbGlzaXMgdWx0cmljZXMsIGVyb3MgYXJjdSBkYXBpYnVzIHNhcGllbiwgZXQgdWx0cmlj +ZXMgbWF1cmlzIHRlbGx1cyBub24gZG9sb3IuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMg +aW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFl +OyBDcmFzIGN1cnN1cyB2YXJpdXMgbWV0dXMuIFV0IHR1cnBpcy4gVml2YW11cyBlZ2V0IHRvcnRv +ci4KClNlZCBsYW9yZWV0LCB2ZWxpdCBub24gYWNjdW1zYW4gY3Vyc3VzLCBudW5jIHVybmEgcG9z +dWVyZSBqdXN0bywgaW4gZGljdHVtIGxlY3R1cyBwZWRlIGlkIGFudGUuIENyYXMgdnVscHV0YXRl +LiBDcmFzIGNvbmd1ZSBkdWkgc2VkIGVsaXQuIFByb2luIGxhY3VzIHNlbSwgdWx0cmljZXMgYXQs +IGNvbnNlcXVhdCBpbiwgdGVtcG9yIHF1aXMsIG1ldHVzLiBQcm9pbiB2ZWwgYXJjdS4gTmFtIGV1 +aXNtb2QgaGVuZHJlcml0IGVsaXQuIFV0IGVyYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhp +bWVuYWVvcy4gU2VkIHBvc3VlcmUuIE1vcmJpIGVyb3MgdXJuYSwgc2VtcGVyIGF0LCBzZW1wZXIg +bm9uLCBjb252YWxsaXMgcXVpcywgdmVsaXQuIE1hZWNlbmFzIG9yY2kuIFZlc3RpYnVsdW0gbG9i +b3J0aXMgdHJpc3RpcXVlIG1ldHVzLiBWZXN0aWJ1bHVtIGxvcmVtIG51bGxhLCBzb2xsaWNpdHVk +aW4gdml0YWUsIGNvbmRpbWVudHVtIHF1aXMsIGF1Y3RvciB1dCwgZHVpLiBWaXZhbXVzIHZlc3Rp +YnVsdW0gbWFnbmEgdXQgbmlzaS4gQ3VyYWJpdHVyIGVsZWlmZW5kIGR1aSB2ZWwgbnVuYy4gQ3Vy +YWJpdHVyIG1hdXJpcyBsYWN1cywgbWFsZXN1YWRhIHNpdCBhbWV0LCBzdXNjaXBpdCBzZWQsIHJ1 +dHJ1bSBsdWN0dXMsIHRlbGx1cy4gSW50ZWdlciBmYWNpbGlzaXMgdXJuYSB2aXRhZSBsZWN0dXMu +CgpBZW5lYW4gcXVhbSBsZW8sIGxvYm9ydGlzIHF1aXMsIG1hbGVzdWFkYSBldSwgdnVscHV0YXRl +IHZpdGFlLCBuaXNsLiBQcmFlc2VudCBlZ2V0IGVyb3MuIFV0IGZlcm1lbnR1bSB0dXJwaXMgaWQg +cXVhbS4gTmFtIHRvcnRvci4gUHJhZXNlbnQgbmVjIG9yY2kuIE51bGxhIGJpYmVuZHVtIGFkaXBp +c2NpbmcgYXVndWUuIFV0IGNvbW1vZG8sIG1hZ25hIGlkIG1hbGVzdWFkYSBncmF2aWRhLCBhdWd1 +ZSBvZGlvIG1hbGVzdWFkYSBtaSwgcG9ydGEgbWFsZXN1YWRhIGVsaXQgZXN0IHZpdGFlIGRpYW0u +IE1hdXJpcyBub24gbnVsbGEuIFN1c3BlbmRpc3NlIHRpbmNpZHVudCwgbnVuYyB1bHRyaWNpZXMg +cG9ydGEgdmVuZW5hdGlzLCBtaSBwZWRlIHRpbmNpZHVudCBsaWJlcm8sIGVnZXQgdmFyaXVzIGFu +dGUgbGliZXJvIHV0IGxpZ3VsYS4gQ3VyYWJpdHVyIHByZXRpdW0gcG9ydHRpdG9yIHRvcnRvci4K +Ck1hZWNlbmFzIHZpdGFlIGVsaXQgZWdldCBuaXNpIGRhcGlidXMgZGljdHVtLiBOdW5jIGluIGxp +YmVyby4gTnVsbGEgZGljdHVtIG9yY2kgZXUgZXJhdCBhdWN0b3IgbG9ib3J0aXMuIFBoYXNlbGx1 +cyByaXN1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gUHJhZXNl +bnQgYWRpcGlzY2luZyBjb25zZXF1YXQgZWxpdC4gSW50ZWdlciBpZCBhdWd1ZS4gUHJhZXNlbnQg +aW4ganVzdG8gbmVjIG1hZ25hIGRhcGlidXMgcHVsdmluYXIuIER1aXMgbmlzbC4gU3VzcGVuZGlz +c2UgYWMgb2Rpby4gVml2YW11cyBpbXBlcmRpZXQuIERvbmVjIG5vbiB2ZWxpdCBzaXQgYW1ldCBy +aXN1cyBkaWduaXNzaW0gY29uZ3VlLiBOYW0gYWxpcXVldCBwb3N1ZXJlIHZlbGl0LiBDcmFzIHR1 +cnBpcy4gTW9yYmkgbWFsZXN1YWRhIGRpZ25pc3NpbSBtaS4KClNlZCBsZW8gbmVxdWUsIHZhcml1 +cyBxdWlzLCB2ZW5lbmF0aXMgc2VkLCBwaGFyZXRyYSBzZWQsIGVzdC4gTW9yYmkgYmxhbmRpdC4g +Q2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnVi +aWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBFdGlhbSBzZW1wZXIgcGVsbGVudGVz +cXVlIG1pLiBVdCB2ZWwgbG9yZW0uIE51bmMgbWkgdG9ydG9yLCBsYW9yZWV0IGF0LCBmYXVjaWJ1 +cyBldSwgdGluY2lkdW50IHNpdCBhbWV0LCBlcmF0LiBEdWlzIHRlbXBvciBtYWxlc3VhZGEgaXBz +dW0uIFBoYXNlbGx1cyBhbGlxdWV0LiBEb25lYyBldCBlbGl0LiBQZWxsZW50ZXNxdWUgcHVydXMu +IFZlc3RpYnVsdW0gcnV0cnVtIHNlbXBlciBuaWJoLiBOdWxsYSBmYWNpbGlzaS4gUGhhc2VsbHVz +IGV0IGVuaW0gc2l0IGFtZXQgYW50ZSB2ZXN0aWJ1bHVtIHZlaGljdWxhLiBQaGFzZWxsdXMgaWQg +bmlzbC4gRG9uZWMgbW9sbGlzIGxlbyBhdCBlcm9zLiBNYXVyaXMgcGVsbGVudGVzcXVlIG5lcXVl +IGF0IHB1cnVzLiBNb3JiaSBxdWlzIGRvbG9yIGF0IGlwc3VtIHNjZWxlcmlzcXVlIHNvZGFsZXMu +IEV0aWFtIHZvbHV0cGF0IHR1cnBpcyBhIG1ldHVzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBk +aWN0dW1zdC4gTnVuYyBsb3JlbSBsb3JlbSwgdmVzdGlidWx1bSBhYywgZXVpc21vZCBlZ2V0LCB1 +bGxhbWNvcnBlciBkaWduaXNzaW0sIHZlbGl0LgoKQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1 +cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVz +LiBDcmFzIHVsdHJpY2VzLCBuaWJoIHZlbCBhbGlxdWFtIHZlc3RpYnVsdW0sIGVyb3MgZW5pbSB2 +ZW5lbmF0aXMgZHVpLCBpZCBpYWN1bGlzIGVuaW0gbnVuYyB2ZWwgbWFzc2EuIE1vcmJpIGVsZWlm +ZW5kIG9yY2kgZXQgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgbW9sbGlzIGVn +ZXN0YXMgdHVycGlzLiBJbiBzb2RhbGVzIG51bmMgZWdldCB0b3J0b3IuIFNlZCBpcHN1bSBlcm9z +LCB0ZW1wb3IgcXVpcywgYWxpcXVldCB2aXRhZSwgaW1wZXJkaWV0IG5vbiwgbG9yZW0uIFBlbGxl +bnRlc3F1ZSBxdWlzIGVsaXQgaWQgbWkgbHVjdHVzIGRhcGlidXMuIFNlZCBudW5jIGFyY3UsIHJo +b25jdXMgbmVjLCBjb252YWxsaXMgcXVpcywgY3Vyc3VzIGF0LCBuZXF1ZS4gTWF1cmlzIGNvbnZh +bGxpcyBwdXJ1cyBhdCBlcmF0LiBQZWxsZW50ZXNxdWUgdmVzdGlidWx1bS4gVml2YW11cyBmcmlu +Z2lsbGEgZWxpdCBhdCBhcmN1LiBOdWxsYW0gYWxpcXVldCBlbmltIG5lYyBhcmN1LiBOYW0gaWQg +dG9ydG9yLiBOdWxsYSBxdWlzIG51bmMuIFV0IGFyY3UuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBl +bGxlbnRlc3F1ZSB1bGxhbWNvcnBlciBsaWd1bGEgaWQgYXJjdS4KCk5hbSBub24gbGliZXJvIHZp +dGFlIG5pc2wgc2NlbGVyaXNxdWUgZnJpbmdpbGxhLiBRdWlzcXVlIHZhcml1cyBhbnRlIGlkIG1l +dHVzIHJob25jdXMgZnJpbmdpbGxhLiBOdWxsYSBmYWNpbGlzaS4gUHJhZXNlbnQgZWxlaWZlbmQg +cG9ydHRpdG9yIGxpZ3VsYS4gRXRpYW0gcXVpcyBkb2xvciBub24gYXVndWUgY29tbW9kbyBhdWN0 +b3IuIERvbmVjIGEgbWkuIFZlc3RpYnVsdW0gdGVtcG9yLiBEb25lYyBmZWxpcyB1cm5hLCBhdWN0 +b3IgYXQsIGN1cnN1cyBkaWN0dW0sIGdyYXZpZGEgaWQsIGFyY3UuIEFlbmVhbiBkaWN0dW0gbWFs +ZXN1YWRhIGRvbG9yLiBWaXZhbXVzIG1hdHRpcy4gUGhhc2VsbHVzIGV1IHBlZGUuIEZ1c2NlIGFk +aXBpc2NpbmcganVzdG8gZnJpbmdpbGxhIG1ldHVzLiBFdGlhbSBhbnRlLiBJbnRlZ2VyIG1vbGxp +cyBtYXNzYSBxdWlzIG51bmMuIEludGVnZXIgZGljdHVtIG5lcXVlIGx1Y3R1cyBlbmltLgoKU2Vk +IGV1IGxpYmVyby4gSW50ZWdlciB0ZW1wb3IgbGlndWxhIGluIHZlbGl0LiBVdCB0aW5jaWR1bnQg +bGFjaW5pYSBzZW0uIE51bGxhbSB2ZWwgcmlzdXMuIFNlZCBzb2RhbGVzIGFudGUgYSBkb2xvci4g +Q3VyYWJpdHVyIGVyb3MuIFNlZCBzb2RhbGVzLiBTZWQgbm9uIG1ldHVzLiBWZXN0aWJ1bHVtIGVs +ZW1lbnR1bSBmYXVjaWJ1cyBhbnRlLiBOdWxsYSB2ZWwgbmliaC4gTG9yZW0gaXBzdW0gZG9sb3Ig +c2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LiBOdW5jIG5lYyBsb3JlbSB1dCBpcHN1bSBsYWNpbmlhIGlhY3VsaXMu +IER1aXMgZXJhdC4gQWxpcXVhbSBlcmF0LiBDcmFzIGlhY3VsaXMuIEluIGhhYyBoYWJpdGFzc2Ug +cGxhdGVhIGRpY3R1bXN0LgoKTnVsbGFtIGFudGUuIENyYXMgdml0YWUgZXN0LiBQZWxsZW50ZXNx +dWUgdmVsIG1ldHVzIGEgbGlndWxhIGRhcGlidXMgbWF0dGlzLiBEdWlzIGZldWdpYXQgYWxpcXVl +dCBmZWxpcy4gRXRpYW0gaWQgbmlzbCBxdWlzIGVzdCBkaWduaXNzaW0gY29uZGltZW50dW0uIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIE1vcmJpIHZlbGl0IGxvcmVtLCBvcm5hcmUgcXVpcywgcGVsbGVu +dGVzcXVlIHZlbCwgcGxhY2VyYXQgZWdldCwgdG9ydG9yLiBWZXN0aWJ1bHVtIHRpbmNpZHVudCBt +b2xlc3RpZSBsaWJlcm8uIE51bGxhIG51bGxhIGVuaW0sIG1hbGVzdWFkYSBpZCwgdWxsYW1jb3Jw +ZXIgdml0YWUsIGRpY3R1bSBhdCwgcHVydXMuIERvbmVjIGRpZ25pc3NpbSBvZGlvIHV0IGVuaW0u +IFN1c3BlbmRpc3NlIGF0IGxlY3R1cy4KClByYWVzZW50IGxvYm9ydGlzIGF1Z3VlIHZlbCBsZWN0 +dXMuIFV0IGluIGxpZ3VsYSB1dCBmZWxpcyBjb25ndWUgc3VzY2lwaXQuIFF1aXNxdWUgZGlnbmlz +c2ltIHRvcnRvciB1dCBtaS4gRnVzY2UgbWFnbmEgbmlzaSwgZWxlaWZlbmQgYWMsIG9ybmFyZSB2 +ZWwsIHBvcnR0aXRvciB2aXRhZSwgcXVhbS4gVmVzdGlidWx1bSBzb2RhbGVzIGp1c3RvIHF1aXMg +dHVycGlzLiBGdXNjZSB1cm5hIG5pc2ksIHJob25jdXMgcXVpcywgY29uZGltZW50dW0gdmVsLCBk +aWN0dW0gZXUsIG51bmMuIEZ1c2NlIHNlZCBuaWJoIHZpdGFlIG9kaW8gcG9zdWVyZSBhZGlwaXNj +aW5nLiBTZWQgcG9ydGEgZWxpdCBxdWlzIGRvbG9yLiBOYW0gbGliZXJvIG51bGxhLCBhdWN0b3Ig +c2VkLCB0aW5jaWR1bnQgcXVpcywgZmF1Y2lidXMgc2l0IGFtZXQsIG1pLiBRdWlzcXVlIG9yY2ku +IExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0 +LiBOdWxsYW0gaWQgc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVz +IG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgRG9uZWMgdmVs +IGVyb3MuCgpWaXZhbXVzIGx1Y3R1cyBsb2JvcnRpcyBsZW8uIFN1c3BlbmRpc3NlIHZlbCBlbGl0 +IGEgZW5pbSB1bGxhbWNvcnBlciBwb3N1ZXJlLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwg +Y29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdC4gRG9uZWMgcXVpcyBwZWRlIG1hdHRpcyBsZWN0 +dXMgbW9sbGlzIGFkaXBpc2NpbmcuIFNlZCBhY2N1bXNhbiBwb3N1ZXJlIGVyYXQuIFByYWVzZW50 +IGV1aXNtb2QgdGluY2lkdW50IGZlbGlzLiBEb25lYyBtaS4gVXQgY29tbW9kbyBhcmN1IGxhY2lu +aWEgdGVsbHVzLiBBbGlxdWFtIGEgbGliZXJvIHF1aXMgbGVjdHVzIHNlbXBlciB2aXZlcnJhLiBD +dXJhYml0dXIgbGFjaW5pYSBtYXVyaXMgYXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0g +cHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgTnVuYyBzaXQgYW1ldCBtYWduYSBtb2xlc3RpZSBvcmNpIHN1c2NpcGl0IGZyaW5n +aWxsYS4gRnVzY2UgcHJldGl1bSBtZXR1cyBub24gc2VtLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0g +cHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxp +YSBDdXJhZTsgU2VkIGhlbmRyZXJpdC4gTnVsbGEgZmVsaXMuIFN1c3BlbmRpc3NlIHBvdGVudGku +IEFsaXF1YW0gYmxhbmRpdCB0cmlzdGlxdWUgbmVxdWUuIEN1cmFiaXR1ciBxdWlzIGVyYXQgdmVs +IG51bmMgYWNjdW1zYW4gbW9sbGlzLgoKRHVpcyBzYWdpdHRpcywgdGVsbHVzIHV0IGFsaXF1YW0g +ZnJpbmdpbGxhLCBkb2xvciBtaSB1bGxhbWNvcnBlciBuaXNsLCB1dCB0cmlzdGlxdWUgcGVkZSBl +bGl0IHNlZCBtYXVyaXMuIEN1cmFiaXR1ciBpZCBmZWxpcy4gRG9uZWMgcHVsdmluYXIgbGFjdXMg +ZXQgbGVjdHVzLiBBbGlxdWFtIHZ1bHB1dGF0ZSB2dWxwdXRhdGUgbWV0dXMuIEN1cmFiaXR1ciBt +YWduYSBmZWxpcywgYWRpcGlzY2luZyBhYywgYWNjdW1zYW4gdmVsLCBtb2xlc3RpZSBxdWlzLCBx +dWFtLiBNYXVyaXMgZWxpdCBhcmN1LCBwcmV0aXVtIHZpdGFlLCBtb2xsaXMgc2l0IGFtZXQsIHNv +bGxpY2l0dWRpbiB1dCwgbWkuIERvbmVjIGltcGVyZGlldCBkaWduaXNzaW0gbWkuIE51bGxhbSBz +aXQgYW1ldCB0b3J0b3IuIEFsaXF1YW0gbmVxdWUgbnVsbGEsIHZlbmVuYXRpcyBhLCBwb3J0YSBp +biwgcGxhY2VyYXQgdGVtcHVzLCBsYWN1cy4gUXVpc3F1ZSB2ZXN0aWJ1bHVtIGR1aSBldCBsYWN1 +cy4gUHJvaW4gZGlnbmlzc2ltIGNvbnNlY3RldHVlciBwdXJ1cy4gRXRpYW0gZ3JhdmlkYSB0b3J0 +b3IgaW4gbnVuYy4gVXQgdGVtcG9yIHRyaXN0aXF1ZSB0b3J0b3IuIFNlZCBsYW9yZWV0IHRpbmNp +ZHVudCBxdWFtLiBWZXN0aWJ1bHVtIHBvcnRhIHR1cnBpcyB1dCBlbGl0LiBQZWxsZW50ZXNxdWUg +aGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBm +YW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRG9uZWMgbmliaCBkdWksIGZldWdpYXQgbmVjLCBsYW9y +ZWV0IGlkLCBtYWxlc3VhZGEgZWdldCwgbmlzaS4gVXQgbmVxdWUgbWFzc2EsIHZlaGljdWxhIGV1 +LCBjb21tb2RvIG5vbiwgdWx0cmljaWVzIHZpdGFlLCBwdXJ1cy4KClZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOyBNYXVyaXMgZXVpc21vZCwgZmVsaXMgdmVsIHRlbXBvciBhbGlxdWV0LCB0 +b3J0b3IgbWF1cmlzIG1hbGVzdWFkYSBudW5jLCB2ZWwgZmVybWVudHVtIHNlbSBkaWFtIGlkIGR1 +aS4gTmFtIHJ1dHJ1bSBzYXBpZW4gZWdldCBvZGlvLiBBbGlxdWFtIHNlZCBsaWJlcm8gbm9uIG1p +IGZhdWNpYnVzIHRlbXB1cy4gRnVzY2UgaGVuZHJlcml0LCBkaWFtIG5vbiB2b2x1dHBhdCBydXRy +dW0sIGVyYXQgbWV0dXMgdmVuZW5hdGlzIGxpZ3VsYSwgbm9uIHNjZWxlcmlzcXVlIHBlZGUgbGln +dWxhIHZlbCBxdWFtLiBNb3JiaSByaG9uY3VzIGVyb3MgYWMgZHVpIGZldWdpYXQgZWxlbWVudHVt +LiBEdWlzIGV1IGxpYmVybyBldCB0ZWxsdXMgY29uZ3VlIHZpdmVycmEuIE1vcmJpIHF1YW0gcXVh +bSwgZWxlbWVudHVtIHNlZCwgdWxsYW1jb3JwZXIgaW1wZXJkaWV0LCBjb21tb2RvIG5vbiwgb2Rp +by4gTmFtIGFsaXF1ZXQgZWdlc3RhcyB1cm5hLiBNYXVyaXMgb2RpbyBmZWxpcywgdmFyaXVzIGV1 +LCBsYWNpbmlhIGV1LCBjb25kaW1lbnR1bSBhLCBsZWN0dXMuIFNlZCBqdXN0byBtYXNzYSwgcHVs +dmluYXIgaWQsIHZhcml1cyBhLCBwb3J0dGl0b3IgbmVjLCBsaWJlcm8uIEV0aWFtIHZhcml1cy4g +Q3VyYWJpdHVyIHNvZGFsZXMsIG9kaW8gYXQgcG9zdWVyZSBzZW1wZXIsIGVyb3MgbmliaCB0aW5j +aWR1bnQgbGVjdHVzLCB2ZWwgcnV0cnVtIHNhcGllbiBuaXNpIGluIGxpZ3VsYS4gU3VzcGVuZGlz +c2UgZWdldCBhcmN1LiBQaGFzZWxsdXMgaW1wZXJkaWV0IGVzdCBhYyBzYXBpZW4uIERvbmVjIG51 +bGxhIHRvcnRvciwgcGxhY2VyYXQgdmVsLCB0ZW1wdXMgYSwgbG9ib3J0aXMgdmVsLCBuaWJoLiBB +bGlxdWFtIHZhcml1cyBuaXNpLiBOdWxsYSBldCBlbmltLiBGdXNjZSBjb252YWxsaXMgbGFvcmVl +dCBsYWN1cy4KClBoYXNlbGx1cyBpcHN1bSBkb2xvciwgbW9sZXN0aWUgcXVpcywgY29uZGltZW50 +dW0gaW4sIGNvbW1vZG8gZXUsIGRpYW0uIFF1aXNxdWUgYmliZW5kdW0gbGFjaW5pYSBkdWkuIE51 +bGxhbSBibGFuZGl0IHZ1bHB1dGF0ZSBvcmNpLiBVdCBsYWNpbmlhIG1hc3NhIHZlbCBhdWd1ZS4g +QWxpcXVhbSBncmF2aWRhLCBxdWFtIHF1aXMgaW1wZXJkaWV0IGltcGVyZGlldCwgdGVsbHVzIGRp +YW0gcGhhcmV0cmEgZXJhdCwgYXQgcGhhcmV0cmEgbGFjdXMgbmliaCBlZ2VzdGFzIG1hZ25hLiBO +dWxsYSBzYWdpdHRpcyBsb3JlbSB1dCBsb3JlbS4gRHVpcyBjb25kaW1lbnR1bSwgZHVpIHZpdGFl +IGFsaXF1YW0gcG9zdWVyZSwgZGlhbSBxdWFtIGNvbnZhbGxpcyB2ZWxpdCwgdXQgZ3JhdmlkYSBs +ZW8gaXBzdW0gbm9uIHJpc3VzLiBVdCBmZXJtZW50dW0gc29sbGljaXR1ZGluIGVyYXQuIERvbmVj +IHNhZ2l0dGlzIHNjZWxlcmlzcXVlIGZlbGlzLiBOdW5jIGFyY3UuIEV0aWFtIHRlbXB1cywgbWFn +bmEgc2l0IGFtZXQgc3VzY2lwaXQgZXVpc21vZCwgZXJvcyBzZW0gcnV0cnVtIGR1aSwgdml0YWUg +c2FnaXR0aXMgbmliaCBwdXJ1cyBub24gbGFjdXMuIFNlZCBtb2xsaXMgYXJjdSBlZ2V0IGRvbG9y +LiBEb25lYyBvcm5hcmUsIGFyY3Ugc2l0IGFtZXQgZmVybWVudHVtIHZ1bHB1dGF0ZSwgcmlzdXMg +ZW5pbSBmZXJtZW50dW0gbGliZXJvLCBhIGxhY2luaWEgZG9sb3IgbWkgbm9uIHZlbGl0LiBFdGlh +bSBsb2JvcnRpcyBwdXJ1cyBhIGVsaXQuIE51bmMgbnVsbGEgZHVpLCBtYXR0aXMgcXVpcywgYmli +ZW5kdW0gYSwgdWx0cmljZXMgYWMsIGF1Z3VlLiBJbiBhbGlxdWFtIHZlaGljdWxhIHR1cnBpcy4g +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQu +CgpJbnRlZ2VyIGlkIG5pc2wuIFF1aXNxdWUgZGljdHVtIGVsZW1lbnR1bSBvZGlvLiBBZW5lYW4g +bHVjdHVzLiBTZWQgZXUgc2VtIGEgcGVkZSB2dWxwdXRhdGUgY29uZGltZW50dW0uIFF1aXNxdWUg +bWFnbmEuIERvbmVjIGFsaXF1YW0gbWF0dGlzIGlwc3VtLiBDdXJhYml0dXIgZGljdHVtIHNvbGxp +Y2l0dWRpbiBzZW0uIEFsaXF1YW0gcHVsdmluYXIuIE51bmMgc29sbGljaXR1ZGluIHJpc3VzIGEg +ZXJhdC4gVml2YW11cyBxdWlzIHRlbGx1cyBzaXQgYW1ldCBuaWJoIHZlc3RpYnVsdW0gY29uc2Vx +dWF0LiBOdWxsYSBwcmV0aXVtIHNvbGxpY2l0dWRpbiBkb2xvci4gQWxpcXVhbSBpYWN1bGlzIHRp +bmNpZHVudCB0dXJwaXMuIFBoYXNlbGx1cyBpcHN1bSBsZW8sIHZlbmVuYXRpcyBpbiwgc2FnaXR0 +aXMgaW4sIG9ybmFyZSBhdCwgbnVuYy4KClBlbGxlbnRlc3F1ZSB1bHRyaWNlcywgZHVpIGV1IGlh +Y3VsaXMgbHVjdHVzLCB0ZWxsdXMgYXVndWUgdm9sdXRwYXQgc2FwaWVuLCBpbiBkaWduaXNzaW0g +dXJuYSBmZWxpcyB1dCBtaS4gU2VkIGFyY3UgZHVpLCBkaWduaXNzaW0gaWQsIHBvcnR0aXRvciB1 +dCwgaW1wZXJkaWV0IHZpdGFlLCBhbnRlLiBOdWxsYSBkdWkgc2VtLCBjb21tb2RvIG5lYywgc2Fn +aXR0aXMgZXQsIGxhY2luaWEgZXQsIHBlZGUuIEV0aWFtIGVsZWlmZW5kIGR1aSB1dCBuaXNsLiBE +b25lYyBhbnRlIG1hdXJpcywgdGVtcHVzIHNpdCBhbWV0LCB2YXJpdXMgdml0YWUsIGdyYXZpZGEg +cXVpcywgbWkuIEluIHNjZWxlcmlzcXVlLCBmZWxpcyB2aXRhZSB2aXZlcnJhIHNhZ2l0dGlzLCB2 +ZWxpdCBtZXR1cyB1bHRyaWNpZXMgbmVxdWUsIHF1aXMgaW1wZXJkaWV0IHZlbGl0IGVsaXQgZXQg +bWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCB2ZWxpdCBlcm9zLCBldWlzbW9kIHNlZCwg +Y29uZGltZW50dW0gbmVjLCBmYXVjaWJ1cyBzZWQsIHNhcGllbi4gTmFtIGFjY3Vtc2FuIGxpZ3Vs +YSBzaXQgYW1ldCBuZXF1ZS4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKVmVzdGlidWx1bSBhbnRl +IGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJl +IGN1YmlsaWEgQ3VyYWU7IE5hbSBldSBwZWRlLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlz +IGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJh +ZTsgU2VkIGV1IGZlbGlzIHNlZCB0b3J0b3IgdGVtcG9yIGZlcm1lbnR1bS4gUGhhc2VsbHVzIGNv +bW1vZG8gc2VtIHZlbCBuaXNsLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVl +IHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4g +UHJvaW4gbGVjdHVzIGVsaXQsIHBoYXJldHJhIHNpdCBhbWV0LCBhY2N1bXNhbiBzZWQsIHRpbmNp +ZHVudCBldCwgbWF1cmlzLiBEdWlzIGRhcGlidXMgcGhhcmV0cmEgc2VtLiBJbnRlZ2VyIGluIGp1 +c3RvLiBQcmFlc2VudCBlcm9zLiBWZXN0aWJ1bHVtIGFjIGFudGUuIEFsaXF1YW0gc2NlbGVyaXNx +dWUgc2VtIHBlbGxlbnRlc3F1ZSBuaWJoIGNvbnNlY3RldHVlciBzb2RhbGVzLiBBbGlxdWFtIGNv +bnNlY3RldHVlciBvZGlvLiBEdWlzIGxlY3R1cyBvZGlvLCBsdWN0dXMgZXUsIGNvbW1vZG8gcXVp +cywgbW9sbGlzIHZpdGFlLCB2ZWxpdC4gQ3JhcyBuZWMgbnVuYyBub24gZWxpdCBpYWN1bGlzIG1h +dHRpcy4gQWVuZWFuIGp1c3RvIG5lcXVlLCBzb2xsaWNpdHVkaW4gZWdldCwgdWxsYW1jb3JwZXIg +ZWdldCwgZWdlc3RhcyBpZCwgc2VtLiBJbiBldSByaXN1cy4gU2VkIGVnZXN0YXMuCgpJbnRlZ2Vy +IGF0IG5lcXVlLiBTZWQgcHJldGl1bSBzY2VsZXJpc3F1ZSBudWxsYS4gVmVzdGlidWx1bSBhbnRl +IGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJl +IGN1YmlsaWEgQ3VyYWU7IEZ1c2NlIHV0IHBlZGUuIEV0aWFtIHZpdGFlIHF1YW0gYSB1cm5hIHZh +cml1cyBpbXBlcmRpZXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRp +cyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRHVpcyB2ZWhpY3Vs +YS4gRnVzY2UgdWxsYW1jb3JwZXIgbmliaCBub24gZXJhdC4gUXVpc3F1ZSBpbiBuZXF1ZS4gUHJh +ZXNlbnQgZXN0LiBQZWxsZW50ZXNxdWUgYXJjdS4KClByb2luIHBvc3VlcmUuIFN1c3BlbmRpc3Nl +IHBvdGVudGkuIEludGVnZXIgZmVsaXMgbGFjdXMsIGFsaXF1YW0gc2VkLCB2dWxwdXRhdGUgaW4s +IG1vbGxpcyB2ZWwsIHRlbGx1cy4gSW50ZWdlciB2ZWhpY3VsYSBiaWJlbmR1bSBlc3QuIE51bmMg +bm9uIGRvbG9yIGluIHRlbGx1cyBtYXR0aXMgZmFjaWxpc2lzLiBJbnRlZ2VyIHZlc3RpYnVsdW0s +IGF1Z3VlIGF0IGNvbW1vZG8gYWxpcXVhbSwgZHVpIGVzdCBtYXR0aXMgbGlndWxhLCBzaXQgYW1l +dCBhZGlwaXNjaW5nIG9yY2kgc2VtIHZpdGFlIG1hZ25hLiBQcmFlc2VudCBlbmltIHZlbGl0LCBt +YWxlc3VhZGEgYXQsIGNvbmd1ZSBuZWMsIGx1Y3R1cyBpbiwganVzdG8uIFNlZCB2YXJpdXMuIE1v +cmJpIHBoYXJldHJhLiBEb25lYyBldSBtYXNzYSBuZWMgdGVsbHVzIHZ1bHB1dGF0ZSBwdWx2aW5h +ci4gVXQgY29tbW9kbyB0dXJwaXMgbm9uIHNlbS4gVXQgY29udmFsbGlzIHVsbGFtY29ycGVyIHJp +c3VzLiBFdGlhbSBpbnRlcmR1bSBwZWRlIGlkIG5pc2kuIENyYXMgbWFnbmEgc2FwaWVuLCBzdXNj +aXBpdCBhLCBsYW9yZWV0IG5vbiwgcmhvbmN1cyBldCwgZmVsaXMuIEludGVnZXIgb3JjaSBsb3Jl +bSwgdmVzdGlidWx1bSBkaWN0dW0sIHVsbGFtY29ycGVyIGEsIHBvcnR0aXRvciBldCwgZHVpLiBQ +ZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0 +IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4KCk51bmMgZXQgbWFnbmEuIFNlZCBi +aWJlbmR1bSB0ZWxsdXMgaW4gZGlhbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNl +Y3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIE5hbSB2aXRhZSB0b3J0b3IuIEludGVnZXIgbWFnbmEu +IER1aXMgdmVuZW5hdGlzLCBsZW8gYWMgdGVtcG9yIGxhb3JlZXQsIGVsaXQgbnVsbGEgcGhhcmV0 +cmEgcGVkZSwgbm9uIGZlcm1lbnR1bSBudW5jIG9kaW8gYSBvZGlvLiBQcm9pbiBub24gdmVsaXQu +IFNlZCBpbXBlcmRpZXQgYXVndWUgcXVpcyBuaXNsLiBJbnRlZ2VyIGNvbmRpbWVudHVtIG5pc2wg +bmVjIGxpYmVyby4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBh +cnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBWaXZhbXVzIHBsYWNlcmF0 +IGxpYmVyby4gRHVpcyBjb25ndWUgZGljdHVtIG1hZ25hLiBBbGlxdWFtIGRhcGlidXMgYmliZW5k +dW0gZW5pbS4gTnVuYyBlbGVpZmVuZCBwZWRlIHZlbCBpcHN1bS4KCkV0aWFtIHZpdGFlIHZlbGl0 +LiBNYXVyaXMgZXJhdCBudW5jLCBtYWxlc3VhZGEgdXQsIGZldWdpYXQgYWMsIHBsYWNlcmF0IGNv +bmRpbWVudHVtLCBhdWd1ZS4gTmFtIHZvbHV0cGF0LiBBbGlxdWFtIHZlaGljdWxhIGlwc3VtIGlk +IG9kaW8uIFZpdmFtdXMgc29sbGljaXR1ZGluIHR1cnBpcyBpZCBzYXBpZW4uIEZ1c2NlIGEgZmVs +aXMgdml0YWUgb2RpbyBjb252YWxsaXMgYmxhbmRpdC4gQ3VyYWJpdHVyIHZpdGFlIGVyb3MgaWQg +ZXJvcyBwb3J0YSBwcmV0aXVtLiBOdWxsYSBpbiBtYWduYSBlZ2V0IHVybmEgbGFjaW5pYSBjb252 +YWxsaXMuIEFsaXF1YW0gbWF0dGlzIHZlbmVuYXRpcyBwdXJ1cy4gU2VkIHNlZCBtaSBlZ2V0IGVy +YXQgdHJpc3RpcXVlIHBvcnRhLiBEb25lYyBhdWN0b3IgZG9sb3IgYSBlcmF0LiBDdW0gc29jaWlz +IG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2Nl +dHVyIHJpZGljdWx1cyBtdXMuIEluIG5lYyBsaWd1bGEuIE51bmMgZWxlaWZlbmQuIFZlc3RpYnVs +dW0gcXVpcyBuaXNpIGVnZXQgZWxpdCBwb3J0dGl0b3IgY29uZ3VlLiBNYWVjZW5hcyBmYXVjaWJ1 +cywgbWFnbmEgZWdldCBhZGlwaXNjaW5nIHRpbmNpZHVudCwgZG9sb3IgYW50ZSBtYWxlc3VhZGEg +ZWxpdCwgbm9uIGVsZW1lbnR1bSBsYWN1cyB0dXJwaXMgaW4gcGVkZS4KClV0IG1hbGVzdWFkYSBt +aSBuZWMgbWV0dXMuIFByYWVzZW50IGF1Y3RvciBhdWd1ZSBhYyBuaXNsIHVsdHJpY2llcyBmYWNp +bGlzaXMuIE5hbSBwdXJ1cyBzYXBpZW4sIHBlbGxlbnRlc3F1ZSBkaWduaXNzaW0sIHBvc3VlcmUg +ZXUsIGN1cnN1cyBpZCwgZGlhbS4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGVsaXQgYSBwZWxsZW50 +ZXNxdWUgc2NlbGVyaXNxdWUsIGxvcmVtIHJpc3VzIGF1Y3RvciBxdWFtLCBxdWlzIGNvbnNlcXVh +dCB0ZWxsdXMgbmVxdWUgaWQgdXJuYS4gU3VzcGVuZGlzc2UgZGlhbSB0b3J0b3IsIGVsZWlmZW5k +IGRpZ25pc3NpbSwgZWdlc3RhcyB1dCwgbHVjdHVzIGluLCBhbnRlLiBEdWlzIGFudGUuIE1hZWNl +bmFzIGx1Y3R1cy4gQ3VyYWJpdHVyIGN1cnN1cyBwaGFyZXRyYSB1cm5hLiBNYWVjZW5hcyBpbXBl +cmRpZXQsIGVyYXQgbm9uIGVsZW1lbnR1bSBldWlzbW9kLCB0b3J0b3Igb2RpbyBldWlzbW9kIGxl +Y3R1cywgYWMgZmFjaWxpc2lzIHNlbSBuaWJoIHZpdGFlIG51bGxhLiBOdW5jIGdyYXZpZGEuIE1v +cmJpIHNvbGxpY2l0dWRpbiBvZGlvIHF1aXMgbGFjdXMuIEFsaXF1YW0gYSBuaWJoIG5vbiB1cm5h +IHBvcnRhIGltcGVyZGlldC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBJbiBpYWN1bGlzIGxhY2lu +aWEgdmVsaXQuIFNlZCBsaWJlcm8gbGFjdXMsIHRyaXN0aXF1ZSBldSwgbGFjaW5pYSBhYywgYWxp +cXVldCBlZ2V0LCB1cm5hLgoKRXRpYW0gYXQgbmlzbC4gUGhhc2VsbHVzIGZhdWNpYnVzIGx1Y3R1 +cyBsZWN0dXMuIFV0IHBsYWNlcmF0IHZ1bHB1dGF0ZSBkb2xvci4gUGhhc2VsbHVzIHZlbCB2ZWxp +dC4gTW9yYmkgdml2ZXJyYS4gUGhhc2VsbHVzIG9yY2kuIEludGVnZXIgZGlnbmlzc2ltIG1hdHRp +cyBtYXVyaXMuIFBlbGxlbnRlc3F1ZSBwb3N1ZXJlIGxlbyBwb3N1ZXJlIHF1YW0uIFF1aXNxdWUg +bmVjIG1hZ25hIGF0IGRpYW0gdml2ZXJyYSBwZWxsZW50ZXNxdWUuIFN1c3BlbmRpc3NlIHZlbGl0 +IGFyY3UsIHVsdHJpY2llcyBxdWlzLCBjb25ndWUgYSwgdmVuZW5hdGlzIGVnZXQsIGxhY3VzLiBJ +bnRlZ2VyIHNhZ2l0dGlzIGhlbmRyZXJpdCBkb2xvci4gRnVzY2UgdGluY2lkdW50IGFudGUgYSBz +ZW0uCgpNYWVjZW5hcyBjb25zZWN0ZXR1ZXIsIGp1c3RvIHNlZCByaG9uY3VzIHZlbmVuYXRpcywg +bmliaCBhcmN1IHJ1dHJ1bSBkb2xvciwgc2VkIGNvbmRpbWVudHVtIGxpYmVybyBsaWJlcm8gZXQg +aXBzdW0uIFZpdmFtdXMgbWF0dGlzIGp1c3RvIHV0IGxvcmVtIHRpbmNpZHVudCBsb2JvcnRpcy4g +VXQgbm9uIHZlbGl0IGlkIG5lcXVlIGFsaXF1ZXQgYWNjdW1zYW4uIFNlZCB0ZW1wdXMgdml2ZXJy +YSBudWxsYS4gQ3VyYWJpdHVyIHVsbGFtY29ycGVyLCBuZXF1ZSBxdWlzIGRhcGlidXMgc2NlbGVy +aXNxdWUsIGZlbGlzIGRpYW0gZ3JhdmlkYSBvcmNpLCBub24gY3Vyc3VzIHF1YW0gbmVxdWUgdml0 +YWUgZWxpdC4gRXRpYW0gcGhhcmV0cmEgdGluY2lkdW50IGxhY3VzLiBEdWlzIGV1aXNtb2QgZnJp +bmdpbGxhIGVzdC4gRXRpYW0gb3JuYXJlIHRpbmNpZHVudCBsZWN0dXMuIFByb2luIGluIHR1cnBp +cy4gTnVuYyBibGFuZGl0IGJsYW5kaXQgdHVycGlzLiBBZW5lYW4gdXQgYXVndWUuIER1aXMgb3Jj +aSBqdXN0bywgdGluY2lkdW50IGV1LCBydXRydW0gc2VkLCBydXRydW0gZXQsIHR1cnBpcy4gQ3Vy +YWJpdHVyIGZhY2lsaXNpcyBvZGlvIGluIGFudGUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRp +Y3R1bXN0LiBTZWQgZXJvcyBlc3QsIHBlbGxlbnRlc3F1ZSBhdCwgdGluY2lkdW50IGV1LCB1bHRy +aWNlcyBxdWlzLCBtZXR1cy4gTW9yYmkgc2l0IGFtZXQganVzdG8uIE1hZWNlbmFzIGFjIGFyY3Uu +IE1hdXJpcyBkaWduaXNzaW0uCgpQZWxsZW50ZXNxdWUgdWx0cmljaWVzIHJ1dHJ1bSBvcmNpLiBB +ZW5lYW4gb3JuYXJlLiBWaXZhbXVzIGV1IHJpc3VzIHZlbCBtYXVyaXMgbG9ib3J0aXMgZGljdHVt +LiBTZWQgZXQgdHVycGlzIGF1Y3RvciBtaSByaG9uY3VzIHB1bHZpbmFyLiBTZWQgbmVjIG51bmMg +YSBwdXJ1cyB0ZW1wb3Igdml2ZXJyYS4gUGVsbGVudGVzcXVlIHN1c2NpcGl0LiBEb25lYyB0cmlz +dGlxdWUgcmlzdXMgbm9uIG5pYmguIEV0aWFtIG5pc2wgbWFnbmEsIHNvbGxpY2l0dWRpbiB1dCwg +dWx0cmljZXMgc2l0IGFtZXQsIGVnZXN0YXMgZXUsIG51bGxhLiBBbGlxdWFtIGVyYXQgdm9sdXRw +YXQuIFZlc3RpYnVsdW0gcGhhcmV0cmEuIFNlZCBlZ2VzdGFzLCBtZXR1cyBzaXQgYW1ldCBsb2Jv +cnRpcyBjb25zZXF1YXQsIGVyYXQgZWxpdCBpbXBlcmRpZXQgbGliZXJvLCBldSBpbnRlcmR1bSBx +dWFtIG1hc3NhIGVnZXQgZG9sb3IuIFN1c3BlbmRpc3NlIHZpdGFlIG9kaW8uIFByb2luIGJsYW5k +aXQgbWF1cmlzIGlhY3VsaXMgbWV0dXMuCgpWaXZhbXVzIHZlc3RpYnVsdW0uIEV0aWFtIGV0IG5p +c2wuIEFsaXF1YW0gaW4gZGlhbSB2ZWwgZWxpdCBwbGFjZXJhdCBzdXNjaXBpdC4gRHVpcyBzb2Rh +bGVzIHB1cnVzIGFjIG5pYmguIE51bGxhIGluIG9kaW8gZWdldCBlbmltIGx1Y3R1cyBibGFuZGl0 +LiBDdXJhYml0dXIgdWx0cmljZXMgaXBzdW0gbm9uIG5lcXVlIGVnZXN0YXMgZWxlaWZlbmQuIFNl +ZCB0dXJwaXMuIFByb2luIGNvbnNlY3RldHVlci4gVml2YW11cyBtYXR0aXMuIEluIGFsaXF1ZXQu +CgpOdW5jIGlkIGVyb3MuIERvbmVjIHZlbmVuYXRpcywgbnVsbGEgZXQgbWF0dGlzIGx1Y3R1cywg +YW50ZSBsZW8gc2VtcGVyIGp1c3RvLCBub24gYWRpcGlzY2luZyBvZGlvIHJpc3VzIHNlZCBsYWN1 +cy4gUHJhZXNlbnQgdml0YWUgcmlzdXMgY29uZ3VlIGxpYmVybyBjb25ndWUgdGVtcHVzLiBQaGFz +ZWxsdXMgYWMgZXJvcy4gTnVsbGEgdmVoaWN1bGEsIGxvcmVtIGluIGFsaXF1ZXQgc3VzY2lwaXQs +IGFyY3UgZXJhdCBlZ2VzdGFzIHNlbSwgcXVpcyBsb2JvcnRpcyBxdWFtIGFudGUgZXUgbWFzc2Eu +IEN1cmFiaXR1ciBub24gbWFzc2EuIFNlZCBiaWJlbmR1bSBsYWNpbmlhIG9kaW8uIFZlc3RpYnVs +dW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWaXZhbXVzIHZvbHV0cGF0IGJsYW5kaXQgbGFjdXMuIFBy +b2luIHBvcnRhLCB0ZWxsdXMgdXQgYXVjdG9yIGxhb3JlZXQsIGxlY3R1cyBlcm9zIGZlcm1lbnR1 +bSBsZWN0dXMsIGlkIHNhZ2l0dGlzIGFyY3UganVzdG8gaW4gdHVycGlzLiBQaGFzZWxsdXMgY29u +c2VxdWF0LiBOYW0gcGVsbGVudGVzcXVlLCBtaSBpZCB2aXZlcnJhIGNvbnZhbGxpcywgbnVuYyBs +aWJlcm8gcGxhY2VyYXQgbGVvLCBlbGVpZmVuZCBwb3J0YSBzZW0gbmlzbCB2aXRhZSBzYXBpZW4u +IFBlbGxlbnRlc3F1ZSBsaWd1bGEgbGliZXJvLCB0cmlzdGlxdWUgbm9uLCBwb3J0dGl0b3IgcnV0 +cnVtLCBwb3J0dGl0b3Igbm9uLCBlcmF0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGlu +IGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsg +SW50ZWdlciBkaWN0dW0gdGVsbHVzIGEgdG9ydG9yLiBWaXZhbXVzIGZlbGlzIG51bmMsIG1vbGVz +dGllIG5vbiwgcmhvbmN1cyBxdWlzLCBwaGFyZXRyYSBpZCwgZHVpLiBEb25lYyByaXN1cyBtZXR1 +cywgZnJpbmdpbGxhIHZlbCwgYWxpcXVldCBldSwgcGxhY2VyYXQgaWQsIG5lcXVlLgoKU3VzcGVu +ZGlzc2UgaXBzdW0uIFZpdmFtdXMgbGVjdHVzLiBTZWQgdml2ZXJyYSwgbWFzc2EgZWdldCBjb252 +YWxsaXMgbWF0dGlzLCBxdWFtIHR1cnBpcyBjb25zZWN0ZXR1ZXIgbnVuYywgZWdldCBwb3N1ZXJl +IG1hZ25hIHNlbSBpZCB2ZWxpdC4gSW4gbmVjIG1hdXJpcy4gQWVuZWFuIGEgcHVydXMgc2VkIHF1 +YW0gbG9ib3J0aXMgZnJpbmdpbGxhLiBQcm9pbiB1bHRyaWNpZXMgbGFjaW5pYSBhbnRlLiBTZWQg +YWRpcGlzY2luZyBlcmF0IHF1aXMgdmVsaXQuIE51bGxhbSB2aXRhZSBuaXNsIGlkIGp1c3RvIHNv +bGxpY2l0dWRpbiBtb2xlc3RpZS4gTnVsbGEgZmFjaWxpc2kuIFNlZCBuZWMgdXJuYSBzZWQgbmlz +bCBmcmluZ2lsbGEgZGFwaWJ1cy4gTnVsbGEgYXQgZGlhbS4gQWxpcXVhbSBlZ2V0IG5pYmguIE51 +bmMgYWMgbmlzaSBzaXQgYW1ldCB0ZWxsdXMgZWdlc3RhcyB0ZW1wdXMuIE5hbSBzY2VsZXJpc3F1 +ZSB1cm5hIGV0IG5lcXVlLiBEb25lYyBlc3Qgb3JjaSwgc2FnaXR0aXMgbm9uLCB2dWxwdXRhdGUg +YSwgY29tbW9kbyBldCwgYXVndWUuIFV0IGRhcGlidXMgdG9ydG9yLiBVdCBudW5jLiBEb25lYyBk +aWN0dW0gZGFwaWJ1cyBvZGlvLiBOYW0gdWx0cmljaWVzIHVsbGFtY29ycGVyIGxpZ3VsYS4gUGVs +bGVudGVzcXVlIGFjY3Vtc2FuIHZhcml1cyBsZW8uCgpNb3JiaSBldWlzbW9kIGxhb3JlZXQgZXJh +dC4gVml2YW11cyBxdWlzIGlwc3VtLiBNb3JiaSBldWlzbW9kLiBDdW0gc29jaWlzIG5hdG9xdWUg +cGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGlj +dWx1cyBtdXMuIFN1c3BlbmRpc3NlIHZlbCBwdXJ1cy4gTnVsbGFtIGF0IG1hZ25hLiBDdXJhYml0 +dXIgbGFjdXMgbG9yZW0sIGlhY3VsaXMgcXVpcywgZGFwaWJ1cyBub24sIHZvbHV0cGF0IHZlbCwg +bnVsbGEuIERvbmVjIHV0IGFyY3UgcmhvbmN1cyBkb2xvciBwcmV0aXVtIGRpY3R1bS4gTnVsbGFt +IHZlbCBtZXR1cy4gVXQgYXJjdS4gUGVsbGVudGVzcXVlIG5pc2kgbnVuYywgcGxhY2VyYXQgZWdl +dCwgdGluY2lkdW50IHZlbCwgcGhhcmV0cmEgbm9uLCBudW5jLiBJbnRlZ2VyIHRpbmNpZHVudCB1 +bHRyaWNpZXMgbGVjdHVzLiBJbnRlZ2VyIHNlbXBlciwgcHVydXMgc2VkIHVsdHJpY2VzIGZldWdp +YXQsIG51bGxhIHBlZGUgc29sbGljaXR1ZGluIGVyYXQsIHZlbCBhdWN0b3IgbnVsbGEgaXBzdW0g +dmVsIGxlY3R1cy4gQWVuZWFuIG1pLgoKTnVsbGFtIHNlZCBuaXNpIGV0IGFyY3UgaW1wZXJkaWV0 +IGZlcm1lbnR1bS4gTWF1cmlzIG5lYyBtZXR1cy4gSW4gYWMgZG9sb3IuIEluIG1pIGFyY3UsIGNv +bmd1ZSBhYywgcGhhcmV0cmEgbmVjLCBzY2VsZXJpc3F1ZSBzaXQgYW1ldCwgbWFnbmEuIEN1cmFi +aXR1ciBsYWN1cy4gQ3VyYWJpdHVyIGV0IGVsaXQuIEFsaXF1YW0gdWxsYW1jb3JwZXIgbnVuYyBl +dSBlbGl0LiBTZWQgY29udmFsbGlzIGRvbG9yIGF0IHZlbGl0LiBWZXN0aWJ1bHVtIGRhcGlidXMs +IGF1Z3VlIGlkIGNvbnNlY3RldHVlciBwbGFjZXJhdCwgbnVuYyBtYXNzYSBibGFuZGl0IHNhcGll +biwgaWQgYWxpcXVhbSBlbGl0IG5pc2kgaWQgbWkuIFBoYXNlbGx1cyBzYXBpZW4gZXN0LCBncmF2 +aWRhIGV1LCBiaWJlbmR1bSB1dCwgYWRpcGlzY2luZyBxdWlzLCBlc3QuIFV0IG1vbGVzdGllIHF1 +YW0gdml0YWUgb2Rpby4gRG9uZWMgcXVpcyByaXN1cyBpZCBlcmF0IGZhdWNpYnVzIHNvbGxpY2l0 +dWRpbi4gTmFtIGlkIGZlbGlzLiBNYXVyaXMgc2VkIGVuaW0gdml0YWUgbGVvIGFjY3Vtc2FuIHBy +ZXRpdW0uCgpOYW0ganVzdG8uIERvbmVjIHR1cnBpcyBuaXNsLCBjb21tb2RvIGV0LCBpbnRlcmR1 +bSBhYywgY29uc2VjdGV0dWVyIG5vbiwgbWFzc2EuIEZ1c2NlIHNlbSBtZXR1cywgbGFvcmVldCBu +ZWMsIHBvc3VlcmUgaWQsIGltcGVyZGlldCBpbiwgdmVsaXQuIERvbmVjIHZ1bHB1dGF0ZSBqdXN0 +byBlZ2V0IHR1cnBpcy4gTnVsbGEgcGVkZS4gTW9yYmkgdGluY2lkdW50LiBGdXNjZSBhbGlxdWV0 +LCBxdWFtIGV0IGFsaXF1YW0gZnJpbmdpbGxhLCBhbnRlIGFudGUgaWFjdWxpcyBkdWksIG5lYyBh +bGlxdWFtIGFyY3UgcHVydXMgc2VkIGVyYXQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0 +cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBl +Z2VzdGFzLiBQaGFzZWxsdXMgc3VzY2lwaXQgcXVhbSBldCBlc3QuIFZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBj +dWJpbGlhIEN1cmFlOwoKSW50ZWdlciBzZWQgdGVsbHVzLiBTZWQgc2VkIHZlbGl0IHVsdHJpY2ll +cyBsZW8gcnV0cnVtIGxhb3JlZXQuIFNlZCBub24gZXJvcyBhYyBwdXJ1cyBzYWdpdHRpcyBmZXVn +aWF0LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dWVyIGFkaXBpc2Npbmcg +ZWxpdC4gU2VkIGhlbmRyZXJpdCBsaWd1bGEgc2l0IGFtZXQgbmliaC4gTWFlY2VuYXMgdHVycGlz +LiBNb3JiaSBjb25zZWN0ZXR1ZXIsIGRvbG9yIGV0IGFkaXBpc2NpbmcgaW1wZXJkaWV0LCBhbnRl +IG5lcXVlIGZldWdpYXQgZG9sb3IsIGF0IHBvcnRhIHF1YW0gbmVxdWUgcXVpcyBsaWd1bGEuIE1h +dXJpcyBzZW1wZXIgdmVsaXQgc2l0IGFtZXQgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0ZW1wdXMsIHB1 +cnVzIGluIHJ1dHJ1bSBjb25zZXF1YXQsIGVuaW0gZXJhdCB2ZWhpY3VsYSBtYXNzYSwgaWQgYWNj +dW1zYW4gbGVvIHNhcGllbiBuZWMgcHVydXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMg +aW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFl +OyBJbiBkb2xvci4gSW50ZWdlciBmYWNpbGlzaXMgbGliZXJvIHNpdCBhbWV0IHBlZGUuIENsYXNz +IGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gVXQgdmFyaXVzIGFsaXF1ZXQgZW5pbS4gTnVs +bGEgZmFjaWxpc2kuIEN1cmFiaXR1ciBjb25zZWN0ZXR1ZXIsIG9kaW8gZXUgcHJldGl1bSB0aW5j +aWR1bnQsIG51bmMgbmlzaSBhbGlxdWV0IG5lcXVlLCB2ZWwgaW1wZXJkaWV0IGVsaXQgbWFzc2Eg +c2l0IGFtZXQgdHVycGlzLiBQZWxsZW50ZXNxdWUgdGVtcHVzLCBvcmNpIHZvbHV0cGF0IGJsYW5k +aXQgZnJpbmdpbGxhLCBvZGlvIHNlbSBwb3N1ZXJlIGFudGUsIHZpdGFlIGJpYmVuZHVtIHVybmEg +bG9yZW0gdml0YWUgZXJvcy4gUHJhZXNlbnQgdml2ZXJyYSByaG9uY3VzIGFyY3UuIFNlZCBhdWN0 +b3IsIGVzdCBzaXQgYW1ldCBtb2xsaXMgbW9sbGlzLCBxdWFtIHF1YW0gZ3JhdmlkYSBzYXBpZW4s +IGluIGNvbW1vZG8gbWV0dXMgbnVsbGEgYXVjdG9yIGVuaW0uIERvbmVjIGZhY2lsaXNpcy4KClBy +b2luIHRpbmNpZHVudCwgc2FwaWVuIGVnZXQgdWx0cmljaWVzIGFkaXBpc2NpbmcsIGVzdCBvZGlv +IGRpY3R1bSBhcmN1LCB1dCBtb2xsaXMgZXJhdCBkdWkgc2l0IGFtZXQgdmVsaXQuIE1vcmJpIGVz +dCBzZW0sIGludGVyZHVtIGF0LCBjb25ndWUgYSwgZWxlbWVudHVtIHZpdGFlLCBtZXR1cy4gU3Vz +cGVuZGlzc2UgaWQgYXVndWUuIE1hdXJpcyBlbmltIHNlbSwgcHVsdmluYXIgZWdldCwgdGVtcHVz +IGEsIHRlbXB1cyBzaXQgYW1ldCwgc2FwaWVuLiBGdXNjZSB2ZXN0aWJ1bHVtIGNvbnNlY3RldHVl +ciBkdWkuIFBlbGxlbnRlc3F1ZSBlcmF0LiBTZWQgZGlnbmlzc2ltIHBsYWNlcmF0IG9kaW8uIE1h +ZWNlbmFzIHNlbXBlciByaG9uY3VzIGxlY3R1cy4gUGhhc2VsbHVzIHByZXRpdW0uIER1aXMgbGli +ZXJvIGVsaXQsIGVsZWlmZW5kIG5lYywgZWdlc3RhcyB1dCwgY3Vyc3VzIHNlZCwgZmVsaXMuIE5h +bSBuaXNsIGFyY3UsIGFsaXF1ZXQgZXQsIGZhY2lsaXNpcyBldSwgbHVjdHVzIHV0LCByaXN1cy4g +RXRpYW0gdWx0cmljZXMsIGRvbG9yIHNlZCB2b2x1dHBhdCBtYWxlc3VhZGEsIHR1cnBpcyBhcmN1 +IGltcGVyZGlldCB0b3J0b3IsIGV1aXNtb2QgY29tbW9kbyBsaWJlcm8gbWFzc2EgdXQgcXVhbS4g +SW50ZWdlciBtb2xlc3RpZSBwdXJ1cyBub24gZWxpdC4gVXQgdmVuZW5hdGlzIHNlbXBlciB0b3J0 +b3IuIEV0aWFtIGJpYmVuZHVtIGVnZXN0YXMgaXBzdW0uIE1hdXJpcyBzb2xsaWNpdHVkaW4gc2Vt +IG5lYyBuaWJoLiBOdWxsYSBwcmV0aXVtIG1ldHVzIGV1IG1ldHVzLiBQZWxsZW50ZXNxdWUgc2l0 +IGFtZXQgc2VtLgoKU3VzcGVuZGlzc2UgYWMgbmlzaS4gVXQgbGVvLiBWZXN0aWJ1bHVtIGhlbmRy +ZXJpdCBwcmV0aXVtIGRvbG9yLiBOdW5jIGZldWdpYXQgbWFsZXN1YWRhIHB1cnVzLiBDcmFzIGV0 +IG5pYmguIEN1cmFiaXR1ciBudW5jIGVyYXQsIG1hbGVzdWFkYSB2aXRhZSwgbGFvcmVldCBhYywg +dWx0cmljaWVzIGluLCBwdXJ1cy4gVml2YW11cyB0ZWxsdXMgYXJjdSwgc29kYWxlcyBldSwgZmFj +aWxpc2lzIGEsIGxhY2luaWEgbmVjLCBudW5jLiBQZWxsZW50ZXNxdWUgaWQgdmVsaXQuIEluIGV1 +IG5pYmguIE51bmMgbmVjIGVyYXQuIFNlZCBkaWN0dW0gbmVxdWUgdXQgbmlzbC4KCk1vcmJpIGxl +Y3R1cyB0ZWxsdXMsIHRpbmNpZHVudCBhYywgcG9ydHRpdG9yIGFjLCB0cmlzdGlxdWUgaW4sIGVy +b3MuIERvbmVjIGx1Y3R1cyBsdWN0dXMgbGVvLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1 +IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1l +bmFlb3MuIEZ1c2NlIHV0IGVzdCBldCBlbmltIHNjZWxlcmlzcXVlIGFjY3Vtc2FuLiBEb25lYyBs +aWd1bGEgZmVsaXMsIGxhY2luaWEgcXVpcywgcGVsbGVudGVzcXVlIGluLCBzZW1wZXIgdmVzdGli +dWx1bSwgZWxpdC4gTWF1cmlzIGVnZXQgb3JjaSBhIGZlbGlzIGNvbmd1ZSB2ZWhpY3VsYS4gVXQg +c29sbGljaXR1ZGluLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3Jx +dWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIE51bGxhbSBp +ZCBkb2xvciB1dCBsb3JlbSBkaWduaXNzaW0gdmVuZW5hdGlzLiBTdXNwZW5kaXNzZSB2aXRhZSBz +YXBpZW4uIFByb2luIG5vbiBtYWduYSB1dCBlcm9zIHZpdmVycmEgcHVsdmluYXIuIERvbmVjIHF1 +aXMgb2Rpby4gTnVsbGFtIG5vbiBhcmN1IHZlbCBsb3JlbSBzdXNjaXBpdCBhbGlxdWFtLiBBbGlx +dWFtIHJ1dHJ1bSB0dXJwaXMgaW4gbGVvLgoKVXQgbHVjdHVzIG5pYmggdHJpc3RpcXVlIGVyYXQu +IFN1c3BlbmRpc3NlIGJpYmVuZHVtIG9kaW8gdml0YWUgdG9ydG9yLiBEb25lYyBsYWNpbmlhLiBD +cmFzIHNvZGFsZXMgZmVsaXMgbHVjdHVzIG51bGxhLiBOYW0gZWxlaWZlbmQgc2FnaXR0aXMgbGln +dWxhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVz +IGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU3VzcGVuZGlzc2UgdmVsIG5lcXVl +LiBNb3JiaSBhbGlxdWV0IHZlaGljdWxhIG1hZ25hLiBBZW5lYW4gYXQgb2Rpby4gRHVpcyBwZWxs +ZW50ZXNxdWUgbWFnbmEuIE51bGxhIGF0IHRvcnRvciB1dCBkaWFtIGRpY3R1bSBmYXVjaWJ1cy4g +TWF1cmlzIHF1aXMgdmVsaXQuIERvbmVjIG5vbiB0ZWxsdXMgdml0YWUgbG9yZW0gZnJpbmdpbGxh +IHBvcnR0aXRvci4gRnVzY2UgdXQgc2FwaWVuIHF1aXMgdG9ydG9yIGZldWdpYXQgc2FnaXR0aXMu +IERvbmVjIHZpdmVycmEgc2VtIHZpdGFlIHNhcGllbi4gUHJhZXNlbnQgc29kYWxlcywgbGFjdXMg +aW4gZnJpbmdpbGxhIHZpdmVycmEsIG9kaW8gYXVndWUgYWRpcGlzY2luZyB1cm5hLCB2aXRhZSBp +bnRlcmR1bSBhbnRlIHNlbSBub24gbmlzaS4gTnVsbGFtIHRvcnRvciBsb3JlbSwgZWxlaWZlbmQg +YWMsIG1vbGxpcyBub24sIGxhb3JlZXQgYWMsIHJpc3VzLiBJbnRlZ2VyIG9ybmFyZSBsZW8gc2Vk +IGp1c3RvLiBRdWlzcXVlIGN1cnN1cywgc2VtIG5vbiBmYWNpbGlzaXMgYmliZW5kdW0sIG5pc2kg +bWkgdmFyaXVzIGZlbGlzLCBmZXJtZW50dW0gZmV1Z2lhdCBsb3JlbSBlcm9zIGxhb3JlZXQgcmlz +dXMuCgpRdWlzcXVlIHNpdCBhbWV0IGVzdCBldCBsb3JlbSB2ZWhpY3VsYSBsYWNpbmlhLiBEb25l +YyBuZWMgdG9ydG9yLiBDcmFzIG9kaW8uIE5hbSBzY2VsZXJpc3F1ZSB2dWxwdXRhdGUgdXJuYS4g +UHJhZXNlbnQgZHVpLiBFdGlhbSBuZWMgbmlzbCBsb2JvcnRpcyBpcHN1bSBhbGlxdWV0IHRlbXB1 +cy4gTWFlY2VuYXMgcHJldGl1bSBzb2xsaWNpdHVkaW4gbWF1cmlzLiBWZXN0aWJ1bHVtIGFudGUg +aXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUg +Y3ViaWxpYSBDdXJhZTsgUGhhc2VsbHVzIGF1Z3VlIG1hc3NhLCBjb25ndWUgZWdldCwgY29udmFs +bGlzIGVnZXQsIHRyaXN0aXF1ZSBzaXQgYW1ldCwgZXJvcy4gU2VkIGNvbnNlcXVhdCBuaXNpIGV1 +IGZlbGlzLiBQZWxsZW50ZXNxdWUganVzdG8uIFN1c3BlbmRpc3NlIG5vbiBhdWd1ZS4gSW4gZGln +bmlzc2ltIGxvYm9ydGlzIG1hdXJpcy4gTWF1cmlzIHNhZ2l0dGlzLiBDdW0gc29jaWlzIG5hdG9x +dWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJp +ZGljdWx1cyBtdXMuCgpTZWQgYWRpcGlzY2luZy4gRG9uZWMgYSB0ZWxsdXMgdml0YWUgZXN0IGN1 +cnN1cyB2ZWhpY3VsYS4gTmFtIGFudGUgc2VtLCBzb2RhbGVzIGlkLCBmcmluZ2lsbGEgdmVsLCBj +b25kaW1lbnR1bSB2ZWwsIG51bGxhLiBRdWlzcXVlIHNvZGFsZXMuIEV0aWFtIGltcGVyZGlldCBl +bGl0IGlkIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTWFlY2VuYXMgcG9ydGEgdGVtcG9y +IGFyY3UuIE51bGxhIHNlbSBhdWd1ZSwgcGVsbGVudGVzcXVlIGFjLCBjb25zZXF1YXQgdXQsIGNv +bmRpbWVudHVtIGV1aXNtb2QsIHJpc3VzLiBTZWQgYWxpcXVhbSB0aW5jaWR1bnQgbWkuIEluIGlu +dGVyZHVtIGxvYm9ydGlzIG9yY2kuCgpTZWQgdmVoaWN1bGEgaGVuZHJlcml0IHB1cnVzLiBFdGlh +bSBhIGRpYW0uIEN1cmFiaXR1ciBjb252YWxsaXMuIFN1c3BlbmRpc3NlIGEgbmlzaS4gRG9uZWMg +aWQgbWFnbmEgaW4gcXVhbSBzb2xsaWNpdHVkaW4gdWx0cmljaWVzLiBEb25lYyB2aXZlcnJhLiBR +dWlzcXVlIHZvbHV0cGF0IGVzdCBzZWQgc2VtLiBBbGlxdWFtIGp1c3RvLiBWZXN0aWJ1bHVtIHRv +cnRvciBtYXNzYSwgcG9ydHRpdG9yIHNlZCwgdmFyaXVzIHF1aXMsIGlhY3VsaXMgcXVpcywgb2Rp +by4gQWxpcXVhbSBlZ2V0IG5lcXVlLgoKTWF1cmlzIG51bGxhLiBQZWxsZW50ZXNxdWUgaGFiaXRh +bnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBldSBxdWFtIGluIG5lcXVlIHVsdHJpY2VzIHBl +bGxlbnRlc3F1ZS4gQ3JhcyBpbiBkb2xvciBxdWlzIHF1YW0gdmFyaXVzIGhlbmRyZXJpdC4gQWxp +cXVhbSBuaXNpIGxhY3VzLCBsb2JvcnRpcyBldSwgY29udmFsbGlzIHNpdCBhbWV0LCBmYWNpbGlz +aXMgdXQsIG1pLiBBbGlxdWFtIGF0IG5lcXVlLiBDcmFzIHNhZ2l0dGlzIGVsZW1lbnR1bSBqdXN0 +by4gVmVzdGlidWx1bSB1dCBsZWN0dXMgYWxpcXVldCBwdXJ1cyBtYWxlc3VhZGEgdm9sdXRwYXQu +IER1aXMgYXQgbGFjdXMgYWRpcGlzY2luZyBsaWJlcm8gdGluY2lkdW50IHZlc3RpYnVsdW0uIE1v +cmJpIGEgbGliZXJvLiBDcmFzIHB1cnVzLiBNb3JiaSB1dCBhdWd1ZSBldCBwdXJ1cyBpbnRlcmR1 +bSBzY2VsZXJpc3F1ZS4gSW50ZWdlciBhIGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGlj +dHVtc3QuIER1aXMgcGhhcmV0cmEgbWV0dXMgZWdldCBtYXVyaXMuIEFsaXF1YW0gaW50ZXJkdW0g +dWxsYW1jb3JwZXIgbWFzc2EuCgpFdGlhbSBvcm5hcmUuIE51bGxhbSBldWlzbW9kLiBBZW5lYW4g +Y29uc2VxdWF0IGdyYXZpZGEgbGlndWxhLiBBbGlxdWFtIGVzdC4gUHJvaW4gdml0YWUgbGFjdXMu +IFByYWVzZW50IGEgZXJvcyBzaXQgYW1ldCBkdWkgbHVjdHVzIGNvbW1vZG8uIFBoYXNlbGx1cyB2 +ZWhpY3VsYSBhcmN1IGVnZXQgZG9sb3IuIFByYWVzZW50IGZlcm1lbnR1bSBjb25ndWUgbGVvLiBB +bGlxdWFtIHZvbHV0cGF0IHB1cnVzIHV0IGxvcmVtLiBGdXNjZSBoZW5kcmVyaXQgZW5pbSBhdCBs +ZW8uIEFsaXF1YW0gcmhvbmN1cyBuaXNsLiBWaXZhbXVzIGRpY3R1bSBlZ2VzdGFzIG1pLiBTdXNw +ZW5kaXNzZSBwZWxsZW50ZXNxdWUgYmliZW5kdW0gZG9sb3IuIFBlbGxlbnRlc3F1ZSB0aW5jaWR1 +bnQsIHR1cnBpcyBzZW1wZXIgcGVsbGVudGVzcXVlIGNvbmRpbWVudHVtLCBpcHN1bSBtZXR1cyBz +b2RhbGVzIGxpZ3VsYSwgaWQgdm9sdXRwYXQgZGlhbSB0dXJwaXMgdXQgZWxpdC4KClByYWVzZW50 +IHNlZCBsYWN1cy4gTmFtIGVsZWlmZW5kIG1vbGVzdGllIG1hdXJpcy4gRG9uZWMgZGFwaWJ1cyBm +ZXJtZW50dW0gbWFzc2EuIERvbmVjIHZpdmVycmEgZmF1Y2lidXMgcHVydXMuIEN1cmFiaXR1ciBj +b25ndWUsIGxpYmVybyB2aXRhZSB2aXZlcnJhIHBlbGxlbnRlc3F1ZSwgZGlhbSB2ZWxpdCBzb2Rh +bGVzIGVuaW0sIHNlZCBzdXNjaXBpdCBsZWN0dXMgbmlzaSBuZWMgbmVxdWUuIFZlc3RpYnVsdW0g +bWFsZXN1YWRhLCBsYWN1cyBhdCBjdXJzdXMgY29uZ3VlLCB2ZWxpdCBsZWN0dXMgdHJpc3RpcXVl +IGRvbG9yLCBzaXQgYW1ldCBzb2RhbGVzIG5lcXVlIGlwc3VtIGEgbGliZXJvLiBWZXN0aWJ1bHVt +IGV0IHF1YW0uIEN1cmFiaXR1ciBwbGFjZXJhdC4gQ3VyYWJpdHVyIG51bmMgYXJjdSwgZXVpc21v +ZCBuZWMsIHZ1bHB1dGF0ZSBoZW5kcmVyaXQsIGFsaXF1ZXQgZWdldCwgcXVhbS4gQ3VyYWJpdHVy +IHZlbCBlbmltLiBTdXNwZW5kaXNzZSBwb3RlbnRpLgoKTnVuYyBjb25zZXF1YXQgb3JjaSB1dCBs +YWN1cy4gRnVzY2UgdmVsaXQgZG9sb3IsIGRhcGlidXMgc2VkLCBibGFuZGl0IHNpdCBhbWV0LCBy +aG9uY3VzIGlkLCByaXN1cy4gRHVpcyB1cm5hIG5pYmgsIHNjZWxlcmlzcXVlIHF1aXMsIGRhcGli +dXMgYSwgc2NlbGVyaXNxdWUgc2VkLCBuaWJoLiBEb25lYyBsdWN0dXMuIFV0IGV1IG1hdXJpcyBj +dXJzdXMgZGlhbSBsYWNpbmlhIHJob25jdXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMg +aW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFl +OyBBbGlxdWFtIHZlaGljdWxhIG1vbGVzdGllIGp1c3RvLiBNYWVjZW5hcyBpbXBlcmRpZXQgcGVk +ZSBzZWQgbWkuIFN1c3BlbmRpc3NlIG51bGxhIGRvbG9yLCBoZW5kcmVyaXQgZWdldCwgaGVuZHJl +cml0IGlkLCBkaWN0dW0gdmVsLCBsZW8uIER1aXMgYWNjdW1zYW4uIEN1cmFiaXR1ciBpbiBmZWxp +cy4gTnVuYyBsb3JlbS4gVXQgbGVvIGRvbG9yLCBsYW9yZWV0IG5lYywgdnVscHV0YXRlIGF0LCBl +bGVpZmVuZCBpbiwgbnVsbGEuIFF1aXNxdWUgbnVuYyBwdXJ1cywgdmFyaXVzIGVnZXQsIGFjY3Vt +c2FuIG5lYywgYWxpcXVldCBldCwgbmliaC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBl +dCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBD +cmFzIGFkaXBpc2Npbmcgdml2ZXJyYSBkb2xvci4gTWF1cmlzIHBvcnR0aXRvciB1bHRyaWNlcyBw +dXJ1cy4gTnVsbGEgZmFjaWxpc2kuIFByYWVzZW50IGZhdWNpYnVzIGFudGUgdml0YWUgbWF1cmlz +LgoKUHJhZXNlbnQgbGFjaW5pYSBsZWN0dXMgc2VkIG5pc2wuIEluIHRlbXB1cyBjb25ndWUgbWF1 +cmlzLiBJbnRlZ2VyIGZhY2lsaXNpcyBvcm5hcmUgZW5pbS4gTnVsbGEgaWQgbWFzc2EuIERvbmVj +IGNvbW1vZG8gZGlhbSBhdCB0ZWxsdXMuIE5hbSBkYXBpYnVzIHZpdmVycmEgZXN0LiBOYW0gdGVs +bHVzLiBQcmFlc2VudCBhIGxpYmVyby4gSW4gZmF1Y2lidXMgZXN0IGVnZXQgbmliaC4gTnVsbGEg +ZXJvcyBvcmNpLCBpbXBlcmRpZXQgbm9uLCBibGFuZGl0IG5vbiwgdGVtcG9yIGVnZXQsIG1pLiBQ +ZWxsZW50ZXNxdWUgY29udmFsbGlzLgoKUXVpc3F1ZSBlZ2V0IG1pIGFjIGxlbyBldWlzbW9kIGZh +dWNpYnVzLiBQaGFzZWxsdXMgcmhvbmN1cyBwdXJ1cyBpZCBkdWkuIFZlc3RpYnVsdW0gbWFsZXN1 +YWRhIGVsZWlmZW5kIGFudGUuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2li +dXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBQZWxsZW50 +ZXNxdWUgYmxhbmRpdCBtYXR0aXMgb2Rpby4gU3VzcGVuZGlzc2UgY29uc2VxdWF0LCBsZWN0dXMg +YWMgc2VtcGVyIHNvbGxpY2l0dWRpbiwgbWkgdmVsaXQgZGljdHVtIGF1Z3VlLCBhYyB0ZW1wdXMg +ZG9sb3IgZXJhdCBzaXQgYW1ldCBkdWkuIFByb2luIGhlbmRyZXJpdCwgZmVsaXMgcXVpcyB2b2x1 +dHBhdCBwb3N1ZXJlLCBkaWFtIG9kaW8gbWFsZXN1YWRhIG9kaW8sIGEgaW50ZXJkdW0gb3JjaSBk +aWFtIHF1aXMgc2FwaWVuLiBQZWxsZW50ZXNxdWUgb2RpbyBvZGlvLCB2aXZlcnJhIHZlbCwgZ3Jh +dmlkYSBldSwgbW9sZXN0aWUgc2VkLCBudWxsYS4gUGhhc2VsbHVzIG1hdXJpcyBwZWRlLCBjb21t +b2RvIHV0LCBldWlzbW9kIGV1LCBoZW5kcmVyaXQgZXUsIGVzdC4gSW4gaGFjIGhhYml0YXNzZSBw +bGF0ZWEgZGljdHVtc3QuIE51bGxhIGVsZW1lbnR1bSBsYWN1cyBldSBhdWd1ZS4gU2VkIGVyYXQu +IFByb2luIHBvcnRhLiBNYWVjZW5hcyBxdWlzIG1pLiBQaGFzZWxsdXMgYXQgZW5pbSBhYyBqdXN0 +byBncmF2aWRhIHVsdHJpY2VzLiBDcmFzIGxlby4KCkludGVnZXIgdXQgYXJjdS4gRG9uZWMgc2Vk +IG1hZ25hLiBQcm9pbiBmZWxpcy4gSW4gaWFjdWxpcywgbGlndWxhIGlkIGZyaW5naWxsYSBwcmV0 +aXVtLCBuaWJoIGRpYW0gYWNjdW1zYW4gdGVsbHVzLCBlZ2V0IGFjY3Vtc2FuIG1ldHVzIGR1aSB2 +YXJpdXMgdHVycGlzLiBQaGFzZWxsdXMgb3JjaSBtZXR1cywgZWxlaWZlbmQgc2VkLCB0ZW1wb3Ig +YWMsIHNjZWxlcmlzcXVlIGFjLCB1cm5hLiBJbnRlZ2VyIHZpdmVycmEgbmVxdWUgYSBtYXVyaXMu +IE1hdXJpcyBwb3J0dGl0b3IgZG9sb3IgZXUgdmVsaXQuIEludGVnZXIgb2RpbyBlbGl0LCB2ZXN0 +aWJ1bHVtIHV0LCB2b2x1dHBhdCBpZCwgcmhvbmN1cyBjb21tb2RvLCB1cm5hLiBFdGlhbSBwbGFj +ZXJhdCBwaGFyZXRyYSBlcmF0LiBVdCB0ZW1wb3IgZXN0LiBJbnRlZ2VyIGRpZ25pc3NpbSBibGFu +ZGl0IHRlbGx1cy4gTW9yYmkgbmliaCBkb2xvciwgc2NlbGVyaXNxdWUgaWQsIGNvbW1vZG8gbWFs +ZXN1YWRhLCBtYXR0aXMgYXQsIG1pLiBDcmFzIHRpbmNpZHVudCBjb21tb2RvIHB1cnVzLiBJbiB0 +aW5jaWR1bnQuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMg +ZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLiBFdGlhbSB1bGxh +bWNvcnBlci4gVXQgaGVuZHJlcml0LiBNb3JiaSB1bHRyaWNlcy4KClByYWVzZW50IGlhY3VsaXMs +IGVyb3MgYWMgZWdlc3RhcyBzb2RhbGVzLCB1cm5hIGxlbyBmZXJtZW50dW0gbGlndWxhLCBzaXQg +YW1ldCBhbGlxdWFtIHZlbGl0IHNlbSBub24gcHVydXMuIERvbmVjIHJ1dHJ1bSBhcmN1IHF1aXMg +cHVydXMuIE5hbSBwb3N1ZXJlLCBsYWN1cyBhdCBjb25zZXF1YXQgcGxhY2VyYXQsIG51bGxhIHBl +ZGUgcG9zdWVyZSBvcmNpLCBub24gZXVpc21vZCB0dXJwaXMgZHVpIHF1aXMgbmlzbC4gUHJvaW4g +cG9ydGEgYWRpcGlzY2luZyBuaWJoLiBEb25lYyB0cmlzdGlxdWUgZG9sb3IgYXQgdGVsbHVzLiBE +b25lYyBuZXF1ZSBtYXNzYSwgYXVjdG9yIGlkLCBmYXVjaWJ1cyB2aXRhZSwgdWxsYW1jb3JwZXIg +dmVsLCBuaXNpLiBQcm9pbiBtb2xlc3RpZSBuZXF1ZSBzZWQgbWFzc2EuIE5hbSB0ZW1wb3IuIE1v +cmJpIGFsaXF1YW0gc2FwaWVuIGF0IHRlbGx1cy4gRnVzY2UgcXVpcyByaXN1cyBldCBtaSBwcmV0 +aXVtIHB1bHZpbmFyLiBGdXNjZSBzaXQgYW1ldCBsaWd1bGEuCgpQZWxsZW50ZXNxdWUgaGFiaXRh +bnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2UgZXUgZW5pbSBldCBmZWxpcyBzY2VsZXJpc3F1 +ZSBsb2JvcnRpcy4gUHJhZXNlbnQgYmliZW5kdW0uIFZpdmFtdXMgdmVoaWN1bGEuIEludGVnZXIg +YXQgbmliaCBzZWQgdmVsaXQgcmhvbmN1cyBtb2xlc3RpZS4gQ3JhcyBsYWN1cy4gU2VkIHVsbGFt +Y29ycGVyIGVyb3MgdmVsIGVyYXQuIEZ1c2NlIGV1IHRvcnRvciBzaXQgYW1ldCBkaWFtIGV1aXNt +b2Qgc2FnaXR0aXMuIE51bmMgcXVpcyBsYWN1cyBpZCBuaWJoIGNvbnZhbGxpcyB2YXJpdXMuIFN1 +c3BlbmRpc3NlIHZpdGFlIG1pLiBWZXN0aWJ1bHVtIHRyaXN0aXF1ZS4gRG9uZWMgbWFsZXN1YWRh +IGlwc3VtIGlkIG5lcXVlLiBOdWxsYW0gc2VkIGxhY3VzLiBEdWlzIGVnZXN0YXMsIGp1c3RvIHV0 +IGNvbmd1ZSBvcm5hcmUsIGF1Z3VlIHNhcGllbiBsdWN0dXMgZGlhbSwgYXQgYWNjdW1zYW4gZXJh +dCBzYXBpZW4gdXQgbGliZXJvLiBQaGFzZWxsdXMgdmVsIG51bGxhLiBTdXNwZW5kaXNzZSBhcmN1 +IHRlbGx1cywgcG9ydHRpdG9yIGEsIHBoYXJldHJhIGZhdWNpYnVzLCBhbGlxdWFtIHNpdCBhbWV0 +LCBtYXNzYS4gTnVsbGEgcG9ydHRpdG9yIHRpbmNpZHVudCBsb3JlbS4gTnVuYyBkb2xvciBvZGlv +LCBzYWdpdHRpcyBpbiwgbG9ib3J0aXMgdmVsLCB2b2x1dHBhdCBzZWQsIG5pYmguCgpRdWlzcXVl +IGJsYW5kaXQgbGVvIHV0IHNhcGllbiB0ZW1wdXMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFi +aXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1l +cyBhYyB0dXJwaXMgZWdlc3Rhcy4gQWVuZWFuIHVsdHJpY2llcyBwb3J0dGl0b3IganVzdG8uIEZ1 +c2NlIHJ1dHJ1bSBlcm9zIHV0IHVybmEuIFByb2luIHF1aXMgcXVhbSBlZ2V0IGR1aSBhbGlxdWFt +IGFjY3Vtc2FuLiBEb25lYyBzdXNjaXBpdCBlbGVpZmVuZCBlbGl0LiBQZWxsZW50ZXNxdWUgbWF0 +dGlzLCBmZWxpcyBzb2RhbGVzIGlhY3VsaXMgaW1wZXJkaWV0LCBsYWN1cyBzZW0gY29udmFsbGlz +IGF1Z3VlLCBzaXQgYW1ldCBhbGlxdWV0IGFyY3UgcHVydXMgZnJpbmdpbGxhIHJpc3VzLiBJbiBl +dSBvZGlvIGlkIG1hZ25hIHBoYXJldHJhIG9ybmFyZS4gQWxpcXVhbSBpbnRlcmR1bSBwdWx2aW5h +ciBpcHN1bS4gU2VkIG5lcXVlLgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1 +ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMu +IEV0aWFtIHNpdCBhbWV0IG5pc2kuIFV0IGF0IGF1Z3VlLiBNYXVyaXMgdm9sdXRwYXQgYmxhbmRp +dCBsaWd1bGEuIE51bGxhIGV1IG1ldHVzLiBWZXN0aWJ1bHVtIGVnZXQgZWxpdC4gUHJhZXNlbnQg +cG9zdWVyZS4gVmVzdGlidWx1bSBpZCBzZW0gbm9uIGxlY3R1cyBtb2xsaXMgdGluY2lkdW50LiBB +bGlxdWFtIGlkIGZlbGlzIGF0IGFudGUgb3JuYXJlIHRlbXBvci4gTnVsbGEgbGFjdXMgdHVycGlz +LCBmZXVnaWF0IHZpdGFlLCBjdXJzdXMgcXVpcywgY29uc2VjdGV0dWVyIG5vbiwgbWF1cmlzLiBG +dXNjZSBsYWN1cyBtYXNzYSwgcG9ydHRpdG9yIHV0LCBtb2xlc3RpZSB1dCwgdmVuZW5hdGlzIGEs +IGxvcmVtLiBQcmFlc2VudCBzaXQgYW1ldCBvcmNpLiBNYXVyaXMgcmhvbmN1cyBmZWxpcyB2aXRh +ZSBmZWxpcyBhZGlwaXNjaW5nIGltcGVyZGlldC4gTWFlY2VuYXMgbW9sbGlzIGRpYW0gbmVjIGxl +by4KCkZ1c2NlIGVuaW0gaXBzdW0sIHVsdHJpY2VzIGV1LCBtb2xlc3RpZSBpZCwgZWxlbWVudHVt +IGlkLCBzYXBpZW4uIEludGVnZXIgYSB1cm5hLiBOYW0gdmVsaXQgbGliZXJvLCB2ZW5lbmF0aXMg +ZWdldCwgdGVtcG9yIHNpdCBhbWV0LCBmZXVnaWF0IHZpdGFlLCBhbnRlLiBGdXNjZSBudW5jLiBT +ZWQgc2VtcGVyIG5pc2wgbmVjIHJpc3VzLiBJbiBzZWQgbGliZXJvLiBQcm9pbiB0b3J0b3IgbmVx +dWUsIHRpbmNpZHVudCBhYywgdGVtcG9yIGFjLCBwaGFyZXRyYSBxdWlzLCB2ZWxpdC4gRHVpcyBs +ZWN0dXMgYXVndWUsIHVsdHJpY2llcyB2ZWwsIGNvbnNlcXVhdCBpZCwgaWFjdWxpcyBpZCwgYW50 +ZS4gVml2YW11cyBhdWN0b3IgbWV0dXMgYSBhbnRlLiBDdXJhYml0dXIgYXJjdSBuaXNpLCBmYWNp +bGlzaXMgYXQsIGxhb3JlZXQgaW4sIGNvbnNlY3RldHVlciBzZWQsIG1hdXJpcy4gUXVpc3F1ZSBw +bGFjZXJhdCBkaWFtIHNlZCBkdWkuIFZpdmFtdXMgcHJldGl1bSBjb25kaW1lbnR1bSBsb3JlbS4g +Q3VyYWJpdHVyIGxhb3JlZXQuIEFlbmVhbiBvcmNpIGxpZ3VsYSwgY3Vyc3VzIGVnZXQsIGxhY2lu +aWEgbm9uLCBmYXVjaWJ1cyB2ZWwsIGxvcmVtLgoKQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBDdXJh +Yml0dXIgZXJvcyBkb2xvciwgY29uZ3VlIGEsIGNvbmRpbWVudHVtIHNlZCwgbHVjdHVzIHV0LCBu +aWJoLiBNYWVjZW5hcyBub24gdG9ydG9yIG5lYyB0dXJwaXMgY29tbW9kbyBwZWxsZW50ZXNxdWUu +IFByYWVzZW50IGV1aXNtb2QgcGxhY2VyYXQgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBoYXNl +bGx1cyB1dCBuZXF1ZSB2aXRhZSBvcmNpIG1hdHRpcyBpYWN1bGlzLiBJbnRlZ2VyIGVnZXQgdGVs +bHVzLiBEb25lYyBhdCBhbnRlLiBOYW0gbGFjaW5pYSBsZW8gZWdldCBlcmF0LiBNYWVjZW5hcyBl +dWlzbW9kIG1hZ25hIGNvbmd1ZSB0b3J0b3IuIE1vcmJpIG5lYyBtYXNzYSBldSBlbmltIG1hbGVz +dWFkYSBzb2xsaWNpdHVkaW4uIFNlZCBhY2N1bXNhbi4gTnVsbGFtIGlwc3VtLiBVdCBvZGlvLiBB +bGlxdWFtIGVyYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0 +b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4g +UGVsbGVudGVzcXVlIGlkIHZlbGl0LiBOYW0gb2RpbyBzZW0sIGFsaXF1ZXQgdXQsIHRlbXB1cyBz +aXQgYW1ldCwgZXVpc21vZCBldCwgbnVuYy4KClBlbGxlbnRlc3F1ZSBsaWJlcm8uIEN1bSBzb2Np +aXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFz +Y2V0dXIgcmlkaWN1bHVzIG11cy4gUHJhZXNlbnQgbWF1cmlzIG51bmMsIHZhcml1cyB1dCwgY29u +dmFsbGlzIG1vbGVzdGllLCBsdWN0dXMgc2l0IGFtZXQsIGxlby4gU2VkIGRpY3R1bSBsb3JlbSBl +dCBhcmN1LiBOdW5jIHZlbmVuYXRpcyBwZWxsZW50ZXNxdWUgbWFzc2EuIE51bGxhIGZhY2lsaXNp +LiBQaGFzZWxsdXMgaW4gdG9ydG9yIGVnZXQgcmlzdXMgc2NlbGVyaXNxdWUgdnVscHV0YXRlLiBT +ZWQgbmliaCBlbGl0LCBzYWdpdHRpcyBhYywgY29uZGltZW50dW0gbmVjLCBjb252YWxsaXMgZXQs +IGp1c3RvLiBGdXNjZSB2b2x1dHBhdCBtZXR1cy4gTnVuYyBhdWN0b3IuIFZlc3RpYnVsdW0gbGVv +IGVyb3MsIHBlbGxlbnRlc3F1ZSBhYywgbW9sbGlzIHVsdHJpY2VzLCByaG9uY3VzIG5vbiwgZG9s +b3IuIE1hdXJpcyB2ZWhpY3VsYSBwbGFjZXJhdCBuaXNsLiBWZXN0aWJ1bHVtIGJpYmVuZHVtLCBh +cmN1IHF1aXMgY29uZ3VlIGVsZW1lbnR1bSwgdmVsaXQgbnVuYyBlbGVpZmVuZCB0dXJwaXMsIGlk +IGx1Y3R1cyByaXN1cyBuaXNsIHNpdCBhbWV0IHRlbGx1cy4gUGhhc2VsbHVzIHBlZGUgbmVxdWUs +IGJsYW5kaXQgbm9uLCBjb21tb2RvIHZpdGFlLCB1bHRyaWNpZXMgZWdldCwgbWFnbmEuIEFsaXF1 +YW0gZXJhdCB2b2x1dHBhdC4KCk51bGxhIGZhY2lsaXNpLiBBbGlxdWFtIGFjIGFudGUuIENyYXMg +cmlzdXMuIE1vcmJpIG1hdXJpcyBsYWN1cywgcG9zdWVyZSBldSwgYmxhbmRpdCBldCwgcGhhcmV0 +cmEgYXQsIG1pLiBQcm9pbiBhYyBwdXJ1cy4gRHVpcyBjdXJzdXMgbmlzbCBydXRydW0gcXVhbS4g +QWxpcXVhbSBhIG9kaW8gbm9uIG1hZ25hIHBlbGxlbnRlc3F1ZSB1bHRyaWNpZXMuIE1hZWNlbmFz +IGFjIG1hc3NhIHF1aXMgc2FwaWVuIHVsbGFtY29ycGVyIHRlbXB1cy4gQ3JhcyBjdXJzdXMgdmVs +aXQgc2VkIHNhcGllbi4gUHJvaW4gbnVsbGEuIFZpdmFtdXMgc29kYWxlcyBhbGlxdWFtIG5pYmgu +IEV0aWFtIGV0IGVyYXQgdXQgYW50ZSBsYWNpbmlhIGV1aXNtb2QuIEZ1c2NlIG5pc2kuIFByb2lu +IHF1aXMgbnVsbGEuCgpRdWlzcXVlIHZlbmVuYXRpcywgZXJvcyBzZWQgbGFvcmVldCBzb2xsaWNp +dHVkaW4sIG9yY2kgYW50ZSBwZWxsZW50ZXNxdWUgbmlzbCwgc2l0IGFtZXQgdml2ZXJyYSBxdWFt +IGVyYXQgbm9uIHJpc3VzLiBDcmFzIGVnZXQgbGliZXJvLiBTZWQgZWxpdCBtYWduYSwgc2VtcGVy +IGV1LCBmcmluZ2lsbGEgaW4sIGRpZ25pc3NpbSBzb2RhbGVzLCBlcmF0LiBWaXZhbXVzIGZldWdp +YXQgc2VtIHZlbCBkdWkuIERvbmVjIGNvbnZhbGxpcyBzb2xsaWNpdHVkaW4gZGlhbS4gQ3JhcyBz +ZWQgcHVydXMuIERvbmVjIGZlbGlzIGVyb3MsIHNlbXBlciBlZ2V0LCB0ZW1wb3IgY29uc2VjdGV0 +dWVyLCBzYWdpdHRpcyBxdWlzLCBuaXNsLiBEdWlzIGluIGFudGUuIENyYXMgbm9uIHR1cnBpcy4g +TnVsbGEgdGVtcG9yIHZlbGl0IGFsaXF1ZXQgdHVycGlzIG1vbGVzdGllIHBsYWNlcmF0LiBQcm9p +biBlbGVtZW50dW0gZmVybWVudHVtIG1hdXJpcy4gVml2YW11cyBzZWQgb3JjaSBsYWNpbmlhIGR1 +aSBwbGFjZXJhdCB2ZW5lbmF0aXMuIFZlc3RpYnVsdW0gZmV1Z2lhdCwgdGVsbHVzIGluIHZvbHV0 +cGF0IHJ1dHJ1bSwgbWFnbmEgbmlzaSB1bGxhbWNvcnBlciBlcm9zLCBpZCBwdWx2aW5hciBuZXF1 +ZSBlcmF0IHV0IGxhY3VzLiBWaXZhbXVzIHNlZCBhdWd1ZS4gTnVsbGEgZmFjaWxpc2kuIE1hZWNl +bmFzIGFudGUgYXVndWUsIGVsZW1lbnR1bSB1dCwgc29kYWxlcyB2aXRhZSwgY29uZGltZW50dW0g +bmVjLCBsb3JlbS4gRHVpcyBwZWRlIG9yY2ksIGZyaW5naWxsYSBhdCwgZWxlaWZlbmQgbmVjLCBw +cmV0aXVtIGluLCBlcmF0LiBOYW0gc2FnaXR0aXMsIHR1cnBpcyB2aXRhZSBjb252YWxsaXMgcGhh +cmV0cmEsIG9kaW8gc2VtIHNjZWxlcmlzcXVlIGxhY3VzLCBuZWMgbG9ib3J0aXMgZHVpIGRpYW0g +dmVsIGVyb3MuIEluIHNlbXBlciBncmF2aWRhIG5lcXVlLgoKSW50ZWdlciBudW5jLiBVdCBwcmV0 +aXVtIGlwc3VtIHNpdCBhbWV0IGVsaXQuIEluIG5lYyBhcmN1LiBTZWQgdmVzdGlidWx1bSB2dWxw +dXRhdGUgaXBzdW0uIFBlbGxlbnRlc3F1ZSB0aW5jaWR1bnQuIE51bGxhIGdyYXZpZGEgZG9sb3Ig +aW4gdGVsbHVzLiBDcmFzIHZlaGljdWxhLCBkb2xvciB1dCBwZWxsZW50ZXNxdWUgYWxpcXVhbSwg +ZXJhdCBlbmltIGF1Y3RvciBtYXNzYSwgdmVoaWN1bGEgbG9ib3J0aXMgb2RpbyBlcm9zIHF1aXMg +cXVhbS4gUHJvaW4gZGFwaWJ1cyBuZXF1ZSBpbiBlbmltLiBQcm9pbiBlbGl0LiBJbnRlZ2VyIHJo +b25jdXMgdGluY2lkdW50IGVsaXQuIEZ1c2NlIGxvcmVtIG1ldHVzLCBzZW1wZXIgYWMsIHZvbHV0 +cGF0IHZpdGFlLCBmYWNpbGlzaXMgdXQsIHRlbGx1cy4gRG9uZWMgdmVsIHR1cnBpcyB2aXRhZSBu +aXNpIHBoYXJldHJhIHBvcnR0aXRvci4gTWFlY2VuYXMgdG9ydG9yLiBGdXNjZSBtaS4gTnVsbGFt +IG5lYw==
diff --git a/core/src/test/resources/org/ldaptive/io/hex.txt b/core/src/test/resources/org/ldaptive/io/hex.txt new file mode 100644 index 0000000..843ac72 --- /dev/null +++ b/core/src/test/resources/org/ldaptive/io/hex.txt
@@ -0,0 +1 @@ +4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204372617320616C6971756574206D61737361206E6563206475692E20437261732061726375206E756E632C2068656E6472657269742061632C20656C656966656E642065752C20756C6C616D636F72706572206E65632C2074656C6C75732E205365642070686172657472612070757275732073697420616D6574207175616D2E20437572616269747572206D6F6C6C69732E204E616D20766974616520706564652E20457469616D207269737573206D617373612C207665686963756C612073697420616D65742C207068617265747261206E65632C20736F6C6C696369747564696E2075742C206475692E20446F6E65632065676573746173206A7573746F206174207175616D2E2050726F696E206E69736C2072697375732C20766573746962756C756D206E65632C207072657469756D2076697461652C207472697374697175652061632C206C6F72656D2E20416C697175616D206572617420766F6C75747061742E204372617320736564206E6962682E2050656C6C656E74657371756520736F6C6C696369747564696E20657569736D6F642061756775652E0A0A457469616D206672696E67696C6C6120736F6C6C696369747564696E206F7263692E204D61757269732063757273757320656C69742071756973206C616375732E204372617320746F72746F722E20496E2061646970697363696E672C206C656374757320696420617563746F7220766573746962756C756D2C206E65717565207065646520616363756D73616E20646F6C6F722C206E6F6E20696D70657264696574206D61676E61206469616D20616363756D73616E2076656C69742E2053757370656E6469737365206174206C696265726F207574206E69736920626C616E6469742073616769747469732E2050686173656C6C7573206E6F6E206D61757269732E20467573636520656C656D656E74756D2073616769747469732073656D2E2053757370656E646973736520616C697175616D20656C656966656E642074656C6C75732E2050726F696E206C6967756C61206C6F72656D2C20696D7065726469657420717569732C2076656E656E617469732069642C20696163756C6973206D6F6C6C69732C206E69736C2E20457469616D20636F6E76616C6C69732070656465206174206D617373612E204D6F72626920616363756D73616E20647569206574206D61757269732E0A0A53656420736564206F7263692E204E756E632070757275732E2053757370656E646973736520706F74656E74692E205574206C7563747573206672696E67696C6C61206D61757269732E20446F6E6563206E6962682E2050686173656C6C757320706F7274612E2050686173656C6C75732073697420616D6574206F64696F20736564206D61676E6120736F64616C65732070686172657472612E2043726173206C65637475732E2053757370656E6469737365206C696265726F20697073756D2C20636F6D6D6F646F206E65632C20666163696C6973697320696E2C207375736369706974206C6F626F727469732C206C6967756C612E2044756973206D61737361206E756C6C612C2073656D7065722065742C20636F6E736571756174206E65632C2070686172657472612065752C20656C69742E20566976616D757320756C7472696369657320616C697175616D206F64696F2E20566573746962756C756D2073697420616D6574206D617373612E2053656420636F6E736571756174206C61637573207365642075726E612E20457469616D2066617563696275732066656C69732076656C206F7263692E2050686173656C6C757320756C6C616D636F727065722E2041656E65616E20636F6E736563746574756572206C61637573206174206C696265726F2E0A0A436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204475697320666163696C697369732C206C6967756C6120766974616520636F6E64696D656E74756D207363656C657269737175652C2076656C6974206F72636920677261766964612066656C69732C2076656C20756C74726963696573207175616D206D69206E6F6E206469616D2E20566976616D757320617563746F72206D65747573206E6F6E206C696265726F2E205072616573656E74206C6967756C61206E6973692C20636F6D6D6F646F20636F6E64696D656E74756D2C206D6F6C65737469652065742C20766976657272612065742C206A7573746F2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320736F6C6C696369747564696E2E204E756E6320626C616E6469742063757273757320697073756D2E2041656E65616E206E6563206C6967756C612075742074656C6C757320736F64616C6573206D61747469732E20496E74656765722073656D2E20416C697175616D206964206C6967756C612E2053656420746F72746F72206D61757269732C20626C616E6469742076697461652C206375727375732076656C2C20656C656D656E74756D2065742C206E756C6C612E20416C697175616D207363656C65726973717565206D65747573206574206E69736C2E20447569732061646970697363696E67206D61676E61206174206E657175652E20517569737175652076756C70757461746520656C656966656E64206E756E632E20416C697175616D206567657420656C69742E2050686173656C6C757320647569206F64696F2C20626962656E64756D2073616769747469732C20766573746962756C756D2069642C206469676E697373696D20696D706572646965742C206F7263692E204E756C6C616D2065752066656C6973206E6F6E206E756E63206C6163696E696120736F64616C65732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A53757370656E64697373652070656C6C656E7465737175652C206C696265726F206D617474697320756C7472696369657320616363756D73616E2C20746F72746F7220746F72746F72206D616C6573756164612073656D2C20657420736F64616C6573206C696265726F206F64696F20616320697073756D2E20566976616D75732071756973206D61676E61206E656320657374207375736369706974206C6F626F727469732E20437261732074656D70757320706F7375657265206E756E632E205175697371756520757420656E696D20612066656C697320656765737461732073656D7065722E20536564207068617265747261206D6174746973206E657175652E20467573636520747572706973206E756E632C20636F6E677565207365642C20636F6E736571756174206E6F6E2C20636F6E677565207365642C206E756C6C612E2053757370656E646973736520766172697573206C6F72656D20696420726973757320706F72746120766573746962756C756D2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204675736365207365642070757275732E20496E20612066656C69732E20496E7465676572206567657374617320617563746F72206F7263692E204D617572697320756C747269636573207375736369706974206E69736C2E204E756C6C616D2070757275732E0A0A437261732074656D706F722061646970697363696E6720697073756D2E2055742071756973206D692E204D616563656E617320696E206A7573746F207574206E756C6C6120636F6E6775652070686172657472612E2050656C6C656E746573717565207574206C696265726F20657520646F6C6F722076656E656E617469732073757363697069742E205072616573656E74206665756769617420636F6E736563746574756572206E6962682E204D6F7262692066617563696275732073656D206E6F6E2066656C69732E20496E2068656E6472657269742061726375206163206D617373612E20496E20616363756D73616E20756C747269636573206D692E2050726F696E206D616C65737561646120617563746F722066656C69732E2043757261626974757220696E74657264756D2E20536564206469616D20697073756D2C20756C7472696369657320696E2C2074656D706F722073697420616D65742C207669766572726120696D706572646965742C20656C69742E204D6F726269206D6F6C6573746965206E6973692E204D617572697320697073756D2E2046757363652064696374756D206D6F6C6C6973206D61676E612E204475697320636F6D6D6F646F206469676E697373696D206E756C6C612E20566573746962756C756D20617567756520656E696D2C20756C7472696369657320717569732C20696163756C6973206E65632C2074696E636964756E742076697461652C206469616D2E204D6175726973206C6163696E69612074656D70757320697073756D2E20536564206174206D61757269732E205574206C6F72656D2E20446F6E6563206C696265726F2E0A0A4475697320696163756C6973206C6163696E6961206C65637475732E2041656E65616E20636F6E76616C6C69732065726F7320616320616E74652E205365642071756973206F726369206E656320726973757320617563746F72206672696E67696C6C612E2050686173656C6C757320666163696C6973697320656C656D656E74756D206E6973692E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E6320706F727461206C61637573206E656320616E74652E204D6F726269206D617572697320657261742C2061646970697363696E6720696E2C2070756C76696E6172206E65632C206C6F626F72746973206E65632C206F64696F2E20557420656C656966656E64206C656374757320736564207175616D2E204E756C6C616D206D6F6C6C69732E20496E206E6F6E20747572706973206574206E69736C2068656E64726572697420626C616E6469742E204475697320656C656D656E74756D2E204E756E63206E6563206C696265726F2E2053757370656E646973736520766573746962756C756D207269737573206E6F6E20706564652E204D6F72626920696D70657264696574206F64696F2073697420616D6574206C696265726F2E2053656420736564206D6173736120766974616520697073756D206D61747469732074696E636964756E742E204E756C6C61206E656320746F72746F72207669746165206C696265726F20766F6C75747061742074656D7075732E20446F6E656320616C697175616D2E0A0A4475697320736564206E756E632E2043757261626974757220747572706973206E756C6C612C207665686963756C61207365642C206C756374757320717569732C20656C656D656E74756D20656765742C2066656C69732E204D616563656E61732065742070757275732E204D616563656E6173206C656F2074656C6C75732C2074696E636964756E7420612C20666163696C697369732076697461652C206C6F626F727469732073697420616D65742C2076656C69742E20446F6E656320636F6E76616C6C69732073617069656E2E204D616563656E6173206D6F6C6C6973206F64696F206575206E6962682E20457469616D20677261766964612E20496E7465676572206D6F6C65737469652C2073617069656E206575206D6F6C6573746965206C6163696E69612C206E756E63206E69626820616C697175616D206C6967756C612C2065752073616769747469732074656C6C7573206572617420736F6C6C696369747564696E206F64696F2E20447569732065742072697375732E2050686173656C6C7573206E697369206E657175652C20706C616365726174206E65632C20636F6E64696D656E74756D206E6F6E2C20756C7472696365732065752C2073656D2E20557420706564652E20457469616D206E756C6C61206D657475732C20766F6C75747061742069642C20636F6E76616C6C6973207365642C2073757363697069742076656C2C2075726E612E20446F6E65632076656C20656C69742E205574206C656F206E657175652C2076656E656E617469732066617563696275732C206C6163696E6961206E65632C2074696E636964756E742065752C20656E696D2E2043726173206964206475692061206C696265726F207068617265747261206469676E697373696D2E20446F6E65632065726F73206C656F2C20706F72746120717569732C206C616F726565742075742C2070656C6C656E74657371756520766F6C75747061742C206C65637475732E0A0A4E756C6C616D20626C616E6469742E20416C697175616D206572617420766F6C75747061742E2046757363652061646970697363696E6720656E696D2E2053757370656E6469737365206E6F6E206475692071756973206C6967756C6120706F72746120766573746962756C756D2E20446F6E65632065752074656C6C75732076656C206C6F72656D207072657469756D20706F72747469746F722E205072616573656E74206C75637475732E20416C697175616D2061632065726F7320696E206D6173736120646170696275732074696E636964756E742E20446F6E6563207574206D61676E612E20457469616D20617563746F72206C616375732073697420616D6574206C616375732E2053656420756C7472696369657320697073756D206E656320656C69742E205175697371756520612065737420696E207075727573207375736369706974207472697374697175652E0A0A41656E65616E20736564206475692076656C20646F6C6F722070756C76696E6172206C616F726565742E20566976616D7573207665686963756C61206C6F72656D20696E20706564652E20566976616D7573206574206469616D2E20496E7465676572206163206F64696F2076656C206469616D2068656E64726572697420626962656E64756D2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E756C6C612061206E6973692E2050686173656C6C75732074696E636964756E74206475692076697461652061756775652E20447569732066617563696275732C2064756920696E74657264756D206672696E67696C6C612074696E636964756E742C206F64696F20656C697420766573746962756C756D206C696265726F2C206163206D6F6C6573746965206D61676E61206C6563747573206964206C616375732E2041656E65616E206C6967756C612E204E756C6C6120666163696C6973692E0A0A46757363652076656C2073656D2065752076656C6974206672696E67696C6C61206F726E6172652E2053656420666575676961742074696E636964756E742066656C69732E204E756C6C616D2066656C6973206D692C20657569736D6F642073697420616D65742C206D6F6C6C69732061742C20736F64616C657320656765742C2061756775652E204E616D20696D70657264696574206E6962682061742076656C69742E2053656420757420657261742E20496E206475692E204E756C6C6120666163696C6973692E204E756C6C616D206175677565206C696265726F2C2074696E636964756E74206E65632C207072657469756D2065752C2070756C76696E617220696E2C206475692E204D6F7262692076697461652066656C69732E2050656C6C656E7465737175652076656C206A7573746F2076656C2076656C6974207361676974746973206D616C6573756164612E2050726F696E207665686963756C6120626C616E646974206D617373612E20457469616D2074696E636964756E742070686172657472612075726E612E20496E206D65747573206573742C20617563746F72206E65632C20626C616E64697420612C20637572737573206E65632C207175616D2E204D6175726973206163206D657475732061206C696265726F20636F6E6775652066617563696275732E204D6175726973206D617572697320646F6C6F722C20736F64616C657320696E2C206375727375732075742C20736F64616C65732072757472756D2C2065726F732E2051756973717565206D61757269732065726F732C2073616769747469732076697461652C206C6F626F727469732075742C20656C656966656E642069642C206E6973692E0A0A41656E65616E206E657175652E20566573746962756C756D20656765737461732070656C6C656E746573717565206C6967756C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2050686173656C6C7573207361676974746973206A7573746F2076656C2072697375732E20536564207072657469756D206E657175652076697461652075726E612E2050656C6C656E74657371756520636F6E677565206C696265726F206964206C6F72656D2E204D6175726973206C656F206C6F72656D2C20626C616E6469742073697420616D65742C20636F6E76616C6C697320717569732C20636F6E736563746574756572207365642C2065726F732E204D61757269732074696E636964756E742C20656E696D2061206772617669646120657569736D6F642C206D61676E61206E756C6C61206665726D656E74756D206C696265726F2C207669766572726120656765737461732076656C6974207175616D20657420746F72746F722E20566976616D757320616C6971756574206D61737361207669746165206A7573746F2E204E756C6C6120636F6E677565206C6163757320616320656C69742E0A0A50686173656C6C757320636F6D6D6F646F207175616D2076656C206C6967756C612E2050726F696E206E6F6E206D657475732061742065726F732070756C76696E6172206C75637475732E204D6175726973206469616D206C6F72656D2C20706F737565726520717569732C20677261766964612065742C2074696E636964756E74206E65632C206C6967756C612E20536564206469616D2E20416C697175616D20656C6974206C65637475732C2068656E6472657269742075742C20696D706572646965742073697420616D65742C207072657469756D2073697420616D65742C20697073756D2E204D6175726973207665686963756C61206E69736C20696E206475692E204375726162697475722065676574207175616D207574206D61676E6120656C656D656E74756D206665726D656E74756D2E204D6175726973207363656C657269737175652E2051756973717565206C616F726565742E20457469616D2074656D707573207475727069732E2050656C6C656E746573717565206175677565207175616D2C2068656E647265726974207365642C2074696E636964756E742061742C2070686172657472612061742C206E69736C2E20416C697175616D206C616375732E2053757370656E646973736520706F74656E74692E2041656E65616E2076656C6974206C696265726F2C20756C74726963657320696E2C206C6163696E69612065752C206C75637475732076656C2C20616E74652E20457469616D2064696374756D206D6920696E2066656C69732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20467573636520677261766964612064617069627573206E69736C2E2043726173207669746165206E69736C2E0A0A4D616563656E6173206469676E697373696D2C206C6967756C61206E6F6E20706F727461206375727375732C20656E696D206E756E63206D616C6573756164612073656D2C20657520706F72747469746F72206E756C6C612075726E61206575207175616D2E2046757363652065726F732E20416C697175616D2065726F732E204E616D20617563746F722E204E756C6C61206D6F6C657374696520706F727461206573742E2053757370656E646973736520706F74656E74692E20566976616D7573206D6F6C6573746965206C6F72656D2073656420657261742E20536564206567657420697073756D2E20496E746567657220616C697175616D2070756C76696E6172206E756C6C612E204372617320616C69717565742073656D207574206E756E632E2046757363652066617563696275732074656D707573206C65637475732E204372617320736F64616C65732C206E69736920616320666163696C6973697320756C7472696365732C2065726F73206172637520646170696275732073617069656E2C20657420756C747269636573206D61757269732074656C6C7573206E6F6E20646F6C6F722E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20437261732063757273757320766172697573206D657475732E205574207475727069732E20566976616D7573206567657420746F72746F722E0A0A536564206C616F726565742C2076656C6974206E6F6E20616363756D73616E206375727375732C206E756E632075726E6120706F7375657265206A7573746F2C20696E2064696374756D206C6563747573207065646520696420616E74652E20437261732076756C7075746174652E204372617320636F6E677565206475692073656420656C69742E2050726F696E206C616375732073656D2C20756C7472696365732061742C20636F6E73657175617420696E2C2074656D706F7220717569732C206D657475732E2050726F696E2076656C20617263752E204E616D20657569736D6F642068656E64726572697420656C69742E20557420657261742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2053656420706F73756572652E204D6F7262692065726F732075726E612C2073656D7065722061742C2073656D706572206E6F6E2C20636F6E76616C6C697320717569732C2076656C69742E204D616563656E6173206F7263692E20566573746962756C756D206C6F626F7274697320747269737469717565206D657475732E20566573746962756C756D206C6F72656D206E756C6C612C20736F6C6C696369747564696E2076697461652C20636F6E64696D656E74756D20717569732C20617563746F722075742C206475692E20566976616D757320766573746962756C756D206D61676E61207574206E6973692E2043757261626974757220656C656966656E64206475692076656C206E756E632E20437572616269747572206D6175726973206C616375732C206D616C6573756164612073697420616D65742C207375736369706974207365642C2072757472756D206C75637475732C2074656C6C75732E20496E746567657220666163696C697369732075726E61207669746165206C65637475732E0A0A41656E65616E207175616D206C656F2C206C6F626F7274697320717569732C206D616C6573756164612065752C2076756C7075746174652076697461652C206E69736C2E205072616573656E7420656765742065726F732E205574206665726D656E74756D20747572706973206964207175616D2E204E616D20746F72746F722E205072616573656E74206E6563206F7263692E204E756C6C6120626962656E64756D2061646970697363696E672061756775652E20557420636F6D6D6F646F2C206D61676E61206964206D616C65737561646120677261766964612C206175677565206F64696F206D616C657375616461206D692C20706F727461206D616C65737561646120656C697420657374207669746165206469616D2E204D6175726973206E6F6E206E756C6C612E2053757370656E64697373652074696E636964756E742C206E756E6320756C7472696369657320706F7274612076656E656E617469732C206D6920706564652074696E636964756E74206C696265726F2C20656765742076617269757320616E7465206C696265726F207574206C6967756C612E20437572616269747572207072657469756D20706F72747469746F7220746F72746F722E0A0A4D616563656E617320766974616520656C69742065676574206E69736920646170696275732064696374756D2E204E756E6320696E206C696265726F2E204E756C6C612064696374756D206F726369206575206572617420617563746F72206C6F626F727469732E2050686173656C6C75732072697375732E2053757370656E646973736520706F74656E74692E2053757370656E646973736520706F74656E74692E205072616573656E742061646970697363696E6720636F6E73657175617420656C69742E20496E74656765722069642061756775652E205072616573656E7420696E206A7573746F206E6563206D61676E6120646170696275732070756C76696E61722E2044756973206E69736C2E2053757370656E6469737365206163206F64696F2E20566976616D757320696D706572646965742E20446F6E6563206E6F6E2076656C69742073697420616D6574207269737573206469676E697373696D20636F6E6775652E204E616D20616C697175657420706F73756572652076656C69742E2043726173207475727069732E204D6F726269206D616C657375616461206469676E697373696D206D692E0A0A536564206C656F206E657175652C2076617269757320717569732C2076656E656E61746973207365642C207068617265747261207365642C206573742E204D6F72626920626C616E6469742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D2073656D7065722070656C6C656E746573717565206D692E2055742076656C206C6F72656D2E204E756E63206D6920746F72746F722C206C616F726565742061742C2066617563696275732065752C2074696E636964756E742073697420616D65742C20657261742E20447569732074656D706F72206D616C65737561646120697073756D2E2050686173656C6C757320616C69717565742E20446F6E656320657420656C69742E2050656C6C656E7465737175652070757275732E20566573746962756C756D2072757472756D2073656D706572206E6962682E204E756C6C6120666163696C6973692E2050686173656C6C757320657420656E696D2073697420616D657420616E746520766573746962756C756D207665686963756C612E2050686173656C6C7573206964206E69736C2E20446F6E6563206D6F6C6C6973206C656F2061742065726F732E204D61757269732070656C6C656E746573717565206E657175652061742070757275732E204D6F726269207175697320646F6C6F7220617420697073756D207363656C6572697371756520736F64616C65732E20457469616D20766F6C7574706174207475727069732061206D657475732E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206C6F72656D206C6F72656D2C20766573746962756C756D2061632C20657569736D6F6420656765742C20756C6C616D636F72706572206469676E697373696D2C2076656C69742E0A0A43756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204372617320756C7472696365732C206E6962682076656C20616C697175616D20766573746962756C756D2C2065726F7320656E696D2076656E656E61746973206475692C20696420696163756C697320656E696D206E756E632076656C206D617373612E204D6F72626920656C656966656E64206F726369206574206D617373612E20416C697175616D206572617420766F6C75747061742E204E756C6C61206D6F6C6C69732065676573746173207475727069732E20496E20736F64616C6573206E756E63206567657420746F72746F722E2053656420697073756D2065726F732C2074656D706F7220717569732C20616C69717565742076697461652C20696D70657264696574206E6F6E2C206C6F72656D2E2050656C6C656E746573717565207175697320656C6974206964206D69206C756374757320646170696275732E20536564206E756E6320617263752C2072686F6E637573206E65632C20636F6E76616C6C697320717569732C206375727375732061742C206E657175652E204D617572697320636F6E76616C6C697320707572757320617420657261742E2050656C6C656E74657371756520766573746962756C756D2E20566976616D7573206672696E67696C6C6120656C697420617420617263752E204E756C6C616D20616C697175657420656E696D206E656320617263752E204E616D20696420746F72746F722E204E756C6C612071756973206E756E632E20557420617263752E2053757370656E646973736520706F74656E74692E2050656C6C656E74657371756520756C6C616D636F72706572206C6967756C6120696420617263752E0A0A4E616D206E6F6E206C696265726F207669746165206E69736C207363656C65726973717565206672696E67696C6C612E20517569737175652076617269757320616E7465206964206D657475732072686F6E637573206672696E67696C6C612E204E756C6C6120666163696C6973692E205072616573656E7420656C656966656E6420706F72747469746F72206C6967756C612E20457469616D207175697320646F6C6F72206E6F6E20617567756520636F6D6D6F646F20617563746F722E20446F6E65632061206D692E20566573746962756C756D2074656D706F722E20446F6E65632066656C69732075726E612C20617563746F722061742C206375727375732064696374756D2C20677261766964612069642C20617263752E2041656E65616E2064696374756D206D616C65737561646120646F6C6F722E20566976616D7573206D61747469732E2050686173656C6C757320657520706564652E2046757363652061646970697363696E67206A7573746F206672696E67696C6C61206D657475732E20457469616D20616E74652E20496E7465676572206D6F6C6C6973206D617373612071756973206E756E632E20496E74656765722064696374756D206E65717565206C756374757320656E696D2E0A0A536564206575206C696265726F2E20496E74656765722074656D706F72206C6967756C6120696E2076656C69742E2055742074696E636964756E74206C6163696E69612073656D2E204E756C6C616D2076656C2072697375732E2053656420736F64616C657320616E7465206120646F6C6F722E204375726162697475722065726F732E2053656420736F64616C65732E20536564206E6F6E206D657475732E20566573746962756C756D20656C656D656E74756D20666175636962757320616E74652E204E756C6C612076656C206E6962682E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206E6563206C6F72656D20757420697073756D206C6163696E696120696163756C69732E204475697320657261742E20416C697175616D20657261742E204372617320696163756C69732E20496E206861632068616269746173736520706C617465612064696374756D73742E0A0A4E756C6C616D20616E74652E2043726173207669746165206573742E2050656C6C656E7465737175652076656C206D657475732061206C6967756C612064617069627573206D61747469732E2044756973206665756769617420616C69717565742066656C69732E20457469616D206964206E69736C207175697320657374206469676E697373696D20636F6E64696D656E74756D2E2053757370656E646973736520706F74656E74692E204D6F7262692076656C6974206C6F72656D2C206F726E61726520717569732C2070656C6C656E7465737175652076656C2C20706C61636572617420656765742C20746F72746F722E20566573746962756C756D2074696E636964756E74206D6F6C6573746965206C696265726F2E204E756C6C61206E756C6C6120656E696D2C206D616C6573756164612069642C20756C6C616D636F727065722076697461652C2064696374756D2061742C2070757275732E20446F6E6563206469676E697373696D206F64696F20757420656E696D2E2053757370656E6469737365206174206C65637475732E0A0A5072616573656E74206C6F626F727469732061756775652076656C206C65637475732E20557420696E206C6967756C612075742066656C697320636F6E6775652073757363697069742E2051756973717565206469676E697373696D20746F72746F72207574206D692E204675736365206D61676E61206E6973692C20656C656966656E642061632C206F726E6172652076656C2C20706F72747469746F722076697461652C207175616D2E20566573746962756C756D20736F64616C6573206A7573746F2071756973207475727069732E2046757363652075726E61206E6973692C2072686F6E63757320717569732C20636F6E64696D656E74756D2076656C2C2064696374756D2065752C206E756E632E20467573636520736564206E696268207669746165206F64696F20706F73756572652061646970697363696E672E2053656420706F72746120656C6974207175697320646F6C6F722E204E616D206C696265726F206E756C6C612C20617563746F72207365642C2074696E636964756E7420717569732C2066617563696275732073697420616D65742C206D692E2051756973717565206F7263692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E756C6C616D2069642073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632076656C2065726F732E0A0A566976616D7573206C7563747573206C6F626F72746973206C656F2E2053757370656E64697373652076656C20656C6974206120656E696D20756C6C616D636F7270657220706F73756572652E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20446F6E656320717569732070656465206D6174746973206C6563747573206D6F6C6C69732061646970697363696E672E2053656420616363756D73616E20706F737565726520657261742E205072616573656E7420657569736D6F642074696E636964756E742066656C69732E20446F6E6563206D692E20557420636F6D6D6F646F2061726375206C6163696E69612074656C6C75732E20416C697175616D2061206C696265726F2071756973206C65637475732073656D70657220766976657272612E20437572616269747572206C6163696E6961206D61757269732061742074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E756E632073697420616D6574206D61676E61206D6F6C6573746965206F726369207375736369706974206672696E67696C6C612E204675736365207072657469756D206D65747573206E6F6E2073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642068656E6472657269742E204E756C6C612066656C69732E2053757370656E646973736520706F74656E74692E20416C697175616D20626C616E64697420747269737469717565206E657175652E20437572616269747572207175697320657261742076656C206E756E6320616363756D73616E206D6F6C6C69732E0A0A447569732073616769747469732C2074656C6C757320757420616C697175616D206672696E67696C6C612C20646F6C6F72206D6920756C6C616D636F72706572206E69736C2C20757420747269737469717565207065646520656C697420736564206D61757269732E204375726162697475722069642066656C69732E20446F6E65632070756C76696E6172206C61637573206574206C65637475732E20416C697175616D2076756C7075746174652076756C707574617465206D657475732E20437572616269747572206D61676E612066656C69732C2061646970697363696E672061632C20616363756D73616E2076656C2C206D6F6C657374696520717569732C207175616D2E204D617572697320656C697420617263752C207072657469756D2076697461652C206D6F6C6C69732073697420616D65742C20736F6C6C696369747564696E2075742C206D692E20446F6E656320696D70657264696574206469676E697373696D206D692E204E756C6C616D2073697420616D657420746F72746F722E20416C697175616D206E65717565206E756C6C612C2076656E656E6174697320612C20706F72746120696E2C20706C6163657261742074656D7075732C206C616375732E205175697371756520766573746962756C756D20647569206574206C616375732E2050726F696E206469676E697373696D20636F6E7365637465747565722070757275732E20457469616D206772617669646120746F72746F7220696E206E756E632E2055742074656D706F722074726973746971756520746F72746F722E20536564206C616F726565742074696E636964756E74207175616D2E20566573746962756C756D20706F7274612074757270697320757420656C69742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20446F6E6563206E696268206475692C2066657567696174206E65632C206C616F726565742069642C206D616C65737561646120656765742C206E6973692E205574206E65717565206D617373612C207665686963756C612065752C20636F6D6D6F646F206E6F6E2C20756C747269636965732076697461652C2070757275732E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204D617572697320657569736D6F642C2066656C69732076656C2074656D706F7220616C69717565742C20746F72746F72206D6175726973206D616C657375616461206E756E632C2076656C206665726D656E74756D2073656D206469616D206964206475692E204E616D2072757472756D2073617069656E2065676574206F64696F2E20416C697175616D20736564206C696265726F206E6F6E206D692066617563696275732074656D7075732E2046757363652068656E6472657269742C206469616D206E6F6E20766F6C75747061742072757472756D2C2065726174206D657475732076656E656E61746973206C6967756C612C206E6F6E207363656C657269737175652070656465206C6967756C612076656C207175616D2E204D6F7262692072686F6E6375732065726F7320616320647569206665756769617420656C656D656E74756D2E2044756973206575206C696265726F2065742074656C6C757320636F6E67756520766976657272612E204D6F726269207175616D207175616D2C20656C656D656E74756D207365642C20756C6C616D636F7270657220696D706572646965742C20636F6D6D6F646F206E6F6E2C206F64696F2E204E616D20616C697175657420656765737461732075726E612E204D6175726973206F64696F2066656C69732C207661726975732065752C206C6163696E69612065752C20636F6E64696D656E74756D20612C206C65637475732E20536564206A7573746F206D617373612C2070756C76696E61722069642C2076617269757320612C20706F72747469746F72206E65632C206C696265726F2E20457469616D207661726975732E2043757261626974757220736F64616C65732C206F64696F20617420706F73756572652073656D7065722C2065726F73206E6962682074696E636964756E74206C65637475732C2076656C2072757472756D2073617069656E206E69736920696E206C6967756C612E2053757370656E6469737365206567657420617263752E2050686173656C6C757320696D70657264696574206573742061632073617069656E2E20446F6E6563206E756C6C6120746F72746F722C20706C6163657261742076656C2C2074656D70757320612C206C6F626F727469732076656C2C206E6962682E20416C697175616D20766172697573206E6973692E204E756C6C6120657420656E696D2E20467573636520636F6E76616C6C6973206C616F72656574206C616375732E0A0A50686173656C6C757320697073756D20646F6C6F722C206D6F6C657374696520717569732C20636F6E64696D656E74756D20696E2C20636F6D6D6F646F2065752C206469616D2E205175697371756520626962656E64756D206C6163696E6961206475692E204E756C6C616D20626C616E6469742076756C707574617465206F7263692E205574206C6163696E6961206D617373612076656C2061756775652E20416C697175616D20677261766964612C207175616D207175697320696D7065726469657420696D706572646965742C2074656C6C7573206469616D20706861726574726120657261742C206174207068617265747261206C61637573206E6962682065676573746173206D61676E612E204E756C6C61207361676974746973206C6F72656D207574206C6F72656D2E204475697320636F6E64696D656E74756D2C2064756920766974616520616C697175616D20706F73756572652C206469616D207175616D20636F6E76616C6C69732076656C69742C2075742067726176696461206C656F20697073756D206E6F6E2072697375732E205574206665726D656E74756D20736F6C6C696369747564696E20657261742E20446F6E6563207361676974746973207363656C657269737175652066656C69732E204E756E6320617263752E20457469616D2074656D7075732C206D61676E612073697420616D657420737573636970697420657569736D6F642C2065726F732073656D2072757472756D206475692C207669746165207361676974746973206E696268207075727573206E6F6E206C616375732E20536564206D6F6C6C69732061726375206567657420646F6C6F722E20446F6E6563206F726E6172652C20617263752073697420616D6574206665726D656E74756D2076756C7075746174652C20726973757320656E696D206665726D656E74756D206C696265726F2C2061206C6163696E696120646F6C6F72206D69206E6F6E2076656C69742E20457469616D206C6F626F72746973207075727573206120656C69742E204E756E63206E756C6C61206475692C206D617474697320717569732C20626962656E64756D20612C20756C7472696365732061632C2061756775652E20496E20616C697175616D207665686963756C61207475727069732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A496E7465676572206964206E69736C2E20517569737175652064696374756D20656C656D656E74756D206F64696F2E2041656E65616E206C75637475732E205365642065752073656D206120706564652076756C70757461746520636F6E64696D656E74756D2E2051756973717565206D61676E612E20446F6E656320616C697175616D206D617474697320697073756D2E204375726162697475722064696374756D20736F6C6C696369747564696E2073656D2E20416C697175616D2070756C76696E61722E204E756E6320736F6C6C696369747564696E207269737573206120657261742E20566976616D757320717569732074656C6C75732073697420616D6574206E69626820766573746962756C756D20636F6E7365717561742E204E756C6C61207072657469756D20736F6C6C696369747564696E20646F6C6F722E20416C697175616D20696163756C69732074696E636964756E74207475727069732E2050686173656C6C757320697073756D206C656F2C2076656E656E6174697320696E2C20736167697474697320696E2C206F726E6172652061742C206E756E632E0A0A50656C6C656E74657371756520756C7472696365732C2064756920657520696163756C6973206C75637475732C2074656C6C757320617567756520766F6C75747061742073617069656E2C20696E206469676E697373696D2075726E612066656C6973207574206D692E205365642061726375206475692C206469676E697373696D2069642C20706F72747469746F722075742C20696D706572646965742076697461652C20616E74652E204E756C6C61206475692073656D2C20636F6D6D6F646F206E65632C2073616769747469732065742C206C6163696E69612065742C20706564652E20457469616D20656C656966656E6420647569207574206E69736C2E20446F6E656320616E7465206D61757269732C2074656D7075732073697420616D65742C207661726975732076697461652C206772617669646120717569732C206D692E20496E207363656C657269737175652C2066656C697320766974616520766976657272612073616769747469732C2076656C6974206D6574757320756C74726963696573206E657175652C207175697320696D706572646965742076656C697420656C6974206574206D61676E612E2053757370656E646973736520706F74656E74692E205365642076656C69742065726F732C20657569736D6F64207365642C20636F6E64696D656E74756D206E65632C206661756369627573207365642C2073617069656E2E204E616D20616363756D73616E206C6967756C612073697420616D6574206E657175652E20416C697175616D206572617420766F6C75747061742E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E616D20657520706564652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642065752066656C69732073656420746F72746F722074656D706F72206665726D656E74756D2E2050686173656C6C757320636F6D6D6F646F2073656D2076656C206E69736C2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050726F696E206C656374757320656C69742C2070686172657472612073697420616D65742C20616363756D73616E207365642C2074696E636964756E742065742C206D61757269732E204475697320646170696275732070686172657472612073656D2E20496E746567657220696E206A7573746F2E205072616573656E742065726F732E20566573746962756C756D20616320616E74652E20416C697175616D207363656C657269737175652073656D2070656C6C656E746573717565206E69626820636F6E73656374657475657220736F64616C65732E20416C697175616D20636F6E736563746574756572206F64696F2E2044756973206C6563747573206F64696F2C206C75637475732065752C20636F6D6D6F646F20717569732C206D6F6C6C69732076697461652C2076656C69742E2043726173206E6563206E756E63206E6F6E20656C697420696163756C6973206D61747469732E2041656E65616E206A7573746F206E657175652C20736F6C6C696369747564696E20656765742C20756C6C616D636F7270657220656765742C20656765737461732069642C2073656D2E20496E2065752072697375732E2053656420656765737461732E0A0A496E7465676572206174206E657175652E20536564207072657469756D207363656C65726973717565206E756C6C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20467573636520757420706564652E20457469616D207669746165207175616D20612075726E612076617269757320696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2044756973207665686963756C612E20467573636520756C6C616D636F72706572206E696268206E6F6E20657261742E205175697371756520696E206E657175652E205072616573656E74206573742E2050656C6C656E74657371756520617263752E0A0A50726F696E20706F73756572652E2053757370656E646973736520706F74656E74692E20496E74656765722066656C6973206C616375732C20616C697175616D207365642C2076756C70757461746520696E2C206D6F6C6C69732076656C2C2074656C6C75732E20496E7465676572207665686963756C6120626962656E64756D206573742E204E756E63206E6F6E20646F6C6F7220696E2074656C6C7573206D617474697320666163696C697369732E20496E746567657220766573746962756C756D2C20617567756520617420636F6D6D6F646F20616C697175616D2C2064756920657374206D6174746973206C6967756C612C2073697420616D65742061646970697363696E67206F7263692073656D207669746165206D61676E612E205072616573656E7420656E696D2076656C69742C206D616C6573756164612061742C20636F6E677565206E65632C206C756374757320696E2C206A7573746F2E20536564207661726975732E204D6F7262692070686172657472612E20446F6E6563206575206D61737361206E65632074656C6C75732076756C7075746174652070756C76696E61722E20557420636F6D6D6F646F20747572706973206E6F6E2073656D2E20557420636F6E76616C6C697320756C6C616D636F727065722072697375732E20457469616D20696E74657264756D2070656465206964206E6973692E2043726173206D61676E612073617069656E2C20737573636970697420612C206C616F72656574206E6F6E2C2072686F6E6375732065742C2066656C69732E20496E7465676572206F726369206C6F72656D2C20766573746962756C756D2064696374756D2C20756C6C616D636F7270657220612C20706F72747469746F722065742C206475692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A4E756E63206574206D61676E612E2053656420626962656E64756D2074656C6C757320696E206469616D2E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E616D20766974616520746F72746F722E20496E7465676572206D61676E612E20447569732076656E656E617469732C206C656F2061632074656D706F72206C616F726565742C20656C6974206E756C6C6120706861726574726120706564652C206E6F6E206665726D656E74756D206E756E63206F64696F2061206F64696F2E2050726F696E206E6F6E2076656C69742E2053656420696D706572646965742061756775652071756973206E69736C2E20496E746567657220636F6E64696D656E74756D206E69736C206E6563206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20566976616D757320706C616365726174206C696265726F2E204475697320636F6E6775652064696374756D206D61676E612E20416C697175616D206461706962757320626962656E64756D20656E696D2E204E756E6320656C656966656E6420706564652076656C20697073756D2E0A0A457469616D2076697461652076656C69742E204D61757269732065726174206E756E632C206D616C6573756164612075742C20666575676961742061632C20706C61636572617420636F6E64696D656E74756D2C2061756775652E204E616D20766F6C75747061742E20416C697175616D207665686963756C6120697073756D206964206F64696F2E20566976616D757320736F6C6C696369747564696E207475727069732069642073617069656E2E20467573636520612066656C6973207669746165206F64696F20636F6E76616C6C697320626C616E6469742E204375726162697475722076697461652065726F732069642065726F7320706F727461207072657469756D2E204E756C6C6120696E206D61676E6120656765742075726E61206C6163696E696120636F6E76616C6C69732E20416C697175616D206D61747469732076656E656E617469732070757275732E2053656420736564206D69206567657420657261742074726973746971756520706F7274612E20446F6E656320617563746F7220646F6C6F72206120657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20496E206E6563206C6967756C612E204E756E6320656C656966656E642E20566573746962756C756D2071756973206E697369206567657420656C697420706F72747469746F7220636F6E6775652E204D616563656E61732066617563696275732C206D61676E6120656765742061646970697363696E672074696E636964756E742C20646F6C6F7220616E7465206D616C65737561646120656C69742C206E6F6E20656C656D656E74756D206C616375732074757270697320696E20706564652E0A0A5574206D616C657375616461206D69206E6563206D657475732E205072616573656E7420617563746F72206175677565206163206E69736C20756C7472696369657320666163696C697369732E204E616D2070757275732073617069656E2C2070656C6C656E746573717565206469676E697373696D2C20706F73756572652065752C206375727375732069642C206469616D2E205175697371756520736F6C6C696369747564696E2C20656C697420612070656C6C656E746573717565207363656C657269737175652C206C6F72656D20726973757320617563746F72207175616D2C207175697320636F6E7365717561742074656C6C7573206E657175652069642075726E612E2053757370656E6469737365206469616D20746F72746F722C20656C656966656E64206469676E697373696D2C20656765737461732075742C206C756374757320696E2C20616E74652E204475697320616E74652E204D616563656E6173206C75637475732E20437572616269747572206375727375732070686172657472612075726E612E204D616563656E617320696D706572646965742C2065726174206E6F6E20656C656D656E74756D20657569736D6F642C20746F72746F72206F64696F20657569736D6F64206C65637475732C20616320666163696C697369732073656D206E696268207669746165206E756C6C612E204E756E6320677261766964612E204D6F72626920736F6C6C696369747564696E206F64696F2071756973206C616375732E20416C697175616D2061206E696268206E6F6E2075726E6120706F72746120696D706572646965742E20416C697175616D206572617420766F6C75747061742E20496E20696163756C6973206C6163696E69612076656C69742E20536564206C696265726F206C616375732C207472697374697175652065752C206C6163696E69612061632C20616C697175657420656765742C2075726E612E0A0A457469616D206174206E69736C2E2050686173656C6C7573206661756369627573206C7563747573206C65637475732E20557420706C6163657261742076756C70757461746520646F6C6F722E2050686173656C6C75732076656C2076656C69742E204D6F72626920766976657272612E2050686173656C6C7573206F7263692E20496E7465676572206469676E697373696D206D6174746973206D61757269732E2050656C6C656E74657371756520706F7375657265206C656F20706F7375657265207175616D2E2051756973717565206E6563206D61676E61206174206469616D20766976657272612070656C6C656E7465737175652E2053757370656E64697373652076656C697420617263752C20756C7472696369657320717569732C20636F6E67756520612C2076656E656E6174697320656765742C206C616375732E20496E74656765722073616769747469732068656E64726572697420646F6C6F722E2046757363652074696E636964756E7420616E746520612073656D2E0A0A4D616563656E617320636F6E7365637465747565722C206A7573746F207365642072686F6E6375732076656E656E617469732C206E69626820617263752072757472756D20646F6C6F722C2073656420636F6E64696D656E74756D206C696265726F206C696265726F20657420697073756D2E20566976616D7573206D6174746973206A7573746F207574206C6F72656D2074696E636964756E74206C6F626F727469732E205574206E6F6E2076656C6974206964206E6571756520616C697175657420616363756D73616E2E205365642074656D7075732076697665727261206E756C6C612E2043757261626974757220756C6C616D636F727065722C206E6571756520717569732064617069627573207363656C657269737175652C2066656C6973206469616D2067726176696461206F7263692C206E6F6E20637572737573207175616D206E6571756520766974616520656C69742E20457469616D2070686172657472612074696E636964756E74206C616375732E204475697320657569736D6F64206672696E67696C6C61206573742E20457469616D206F726E6172652074696E636964756E74206C65637475732E2050726F696E20696E207475727069732E204E756E6320626C616E64697420626C616E646974207475727069732E2041656E65616E2075742061756775652E2044756973206F726369206A7573746F2C2074696E636964756E742065752C2072757472756D207365642C2072757472756D2065742C207475727069732E2043757261626974757220666163696C69736973206F64696F20696E20616E74652E20496E206861632068616269746173736520706C617465612064696374756D73742E205365642065726F73206573742C2070656C6C656E7465737175652061742C2074696E636964756E742065752C20756C74726963657320717569732C206D657475732E204D6F7262692073697420616D6574206A7573746F2E204D616563656E617320616320617263752E204D6175726973206469676E697373696D2E0A0A50656C6C656E74657371756520756C747269636965732072757472756D206F7263692E2041656E65616E206F726E6172652E20566976616D75732065752072697375732076656C206D6175726973206C6F626F727469732064696374756D2E205365642065742074757270697320617563746F72206D692072686F6E6375732070756C76696E61722E20536564206E6563206E756E6320612070757275732074656D706F7220766976657272612E2050656C6C656E7465737175652073757363697069742E20446F6E656320747269737469717565207269737573206E6F6E206E6962682E20457469616D206E69736C206D61676E612C20736F6C6C696369747564696E2075742C20756C7472696365732073697420616D65742C20656765737461732065752C206E756C6C612E20416C697175616D206572617420766F6C75747061742E20566573746962756C756D2070686172657472612E2053656420656765737461732C206D657475732073697420616D6574206C6F626F7274697320636F6E7365717561742C206572617420656C697420696D70657264696574206C696265726F2C20657520696E74657264756D207175616D206D61737361206567657420646F6C6F722E2053757370656E6469737365207669746165206F64696F2E2050726F696E20626C616E646974206D617572697320696163756C6973206D657475732E0A0A566976616D757320766573746962756C756D2E20457469616D206574206E69736C2E20416C697175616D20696E206469616D2076656C20656C697420706C6163657261742073757363697069742E204475697320736F64616C6573207075727573206163206E6962682E204E756C6C6120696E206F64696F206567657420656E696D206C756374757320626C616E6469742E2043757261626974757220756C74726963657320697073756D206E6F6E206E65717565206567657374617320656C656966656E642E20536564207475727069732E2050726F696E20636F6E7365637465747565722E20566976616D7573206D61747469732E20496E20616C69717565742E0A0A4E756E632069642065726F732E20446F6E65632076656E656E617469732C206E756C6C61206574206D6174746973206C75637475732C20616E7465206C656F2073656D706572206A7573746F2C206E6F6E2061646970697363696E67206F64696F20726973757320736564206C616375732E205072616573656E7420766974616520726973757320636F6E677565206C696265726F20636F6E6775652074656D7075732E2050686173656C6C75732061632065726F732E204E756C6C61207665686963756C612C206C6F72656D20696E20616C69717565742073757363697069742C2061726375206572617420656765737461732073656D2C2071756973206C6F626F72746973207175616D20616E7465206575206D617373612E20437572616269747572206E6F6E206D617373612E2053656420626962656E64756D206C6163696E6961206F64696F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20566976616D757320766F6C757470617420626C616E646974206C616375732E2050726F696E20706F7274612C2074656C6C757320757420617563746F72206C616F726565742C206C65637475732065726F73206665726D656E74756D206C65637475732C2069642073616769747469732061726375206A7573746F20696E207475727069732E2050686173656C6C757320636F6E7365717561742E204E616D2070656C6C656E7465737175652C206D69206964207669766572726120636F6E76616C6C69732C206E756E63206C696265726F20706C616365726174206C656F2C20656C656966656E6420706F7274612073656D206E69736C2076697461652073617069656E2E2050656C6C656E746573717565206C6967756C61206C696265726F2C20747269737469717565206E6F6E2C20706F72747469746F722072757472756D2C20706F72747469746F72206E6F6E2C20657261742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E74656765722064696374756D2074656C6C7573206120746F72746F722E20566976616D75732066656C6973206E756E632C206D6F6C6573746965206E6F6E2C2072686F6E63757320717569732C2070686172657472612069642C206475692E20446F6E6563207269737573206D657475732C206672696E67696C6C612076656C2C20616C69717565742065752C20706C6163657261742069642C206E657175652E0A0A53757370656E646973736520697073756D2E20566976616D7573206C65637475732E2053656420766976657272612C206D61737361206567657420636F6E76616C6C6973206D61747469732C207175616D2074757270697320636F6E736563746574756572206E756E632C206567657420706F7375657265206D61676E612073656D2069642076656C69742E20496E206E6563206D61757269732E2041656E65616E206120707572757320736564207175616D206C6F626F72746973206672696E67696C6C612E2050726F696E20756C74726963696573206C6163696E696120616E74652E205365642061646970697363696E67206572617420717569732076656C69742E204E756C6C616D207669746165206E69736C206964206A7573746F20736F6C6C696369747564696E206D6F6C65737469652E204E756C6C6120666163696C6973692E20536564206E65632075726E6120736564206E69736C206672696E67696C6C6120646170696275732E204E756C6C61206174206469616D2E20416C697175616D2065676574206E6962682E204E756E63206163206E6973692073697420616D65742074656C6C757320656765737461732074656D7075732E204E616D207363656C657269737175652075726E61206574206E657175652E20446F6E656320657374206F7263692C207361676974746973206E6F6E2C2076756C70757461746520612C20636F6D6D6F646F2065742C2061756775652E205574206461706962757320746F72746F722E205574206E756E632E20446F6E65632064696374756D2064617069627573206F64696F2E204E616D20756C7472696369657320756C6C616D636F72706572206C6967756C612E2050656C6C656E74657371756520616363756D73616E20766172697573206C656F2E0A0A4D6F72626920657569736D6F64206C616F7265657420657261742E20566976616D7573207175697320697073756D2E204D6F72626920657569736D6F642E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2053757370656E64697373652076656C2070757275732E204E756C6C616D206174206D61676E612E20437572616269747572206C61637573206C6F72656D2C20696163756C697320717569732C2064617069627573206E6F6E2C20766F6C75747061742076656C2C206E756C6C612E20446F6E656320757420617263752072686F6E63757320646F6C6F72207072657469756D2064696374756D2E204E756C6C616D2076656C206D657475732E20557420617263752E2050656C6C656E746573717565206E697369206E756E632C20706C61636572617420656765742C2074696E636964756E742076656C2C207068617265747261206E6F6E2C206E756E632E20496E74656765722074696E636964756E7420756C74726963696573206C65637475732E20496E74656765722073656D7065722C2070757275732073656420756C74726963657320666575676961742C206E756C6C61207065646520736F6C6C696369747564696E20657261742C2076656C20617563746F72206E756C6C6120697073756D2076656C206C65637475732E2041656E65616E206D692E0A0A4E756C6C616D20736564206E697369206574206172637520696D70657264696574206665726D656E74756D2E204D6175726973206E6563206D657475732E20496E20616320646F6C6F722E20496E206D6920617263752C20636F6E6775652061632C207068617265747261206E65632C207363656C657269737175652073697420616D65742C206D61676E612E20437572616269747572206C616375732E2043757261626974757220657420656C69742E20416C697175616D20756C6C616D636F72706572206E756E6320657520656C69742E2053656420636F6E76616C6C697320646F6C6F722061742076656C69742E20566573746962756C756D20646170696275732C20617567756520696420636F6E73656374657475657220706C6163657261742C206E756E63206D6173736120626C616E6469742073617069656E2C20696420616C697175616D20656C6974206E697369206964206D692E2050686173656C6C75732073617069656E206573742C20677261766964612065752C20626962656E64756D2075742C2061646970697363696E6720717569732C206573742E205574206D6F6C6573746965207175616D207669746165206F64696F2E20446F6E65632071756973207269737573206964206572617420666175636962757320736F6C6C696369747564696E2E204E616D2069642066656C69732E204D61757269732073656420656E696D207669746165206C656F20616363756D73616E207072657469756D2E0A0A4E616D206A7573746F2E20446F6E656320747572706973206E69736C2C20636F6D6D6F646F2065742C20696E74657264756D2061632C20636F6E736563746574756572206E6F6E2C206D617373612E2046757363652073656D206D657475732C206C616F72656574206E65632C20706F73756572652069642C20696D7065726469657420696E2C2076656C69742E20446F6E65632076756C707574617465206A7573746F2065676574207475727069732E204E756C6C6120706564652E204D6F7262692074696E636964756E742E20467573636520616C69717565742C207175616D20657420616C697175616D206672696E67696C6C612C20616E746520616E746520696163756C6973206475692C206E656320616C697175616D20617263752070757275732073656420657261742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050686173656C6C7573207375736369706974207175616D206574206573742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B0A0A496E7465676572207365642074656C6C75732E20536564207365642076656C697420756C74726963696573206C656F2072757472756D206C616F726565742E20536564206E6F6E2065726F7320616320707572757320736167697474697320666575676961742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E205365642068656E647265726974206C6967756C612073697420616D6574206E6962682E204D616563656E6173207475727069732E204D6F72626920636F6E7365637465747565722C20646F6C6F722065742061646970697363696E6720696D706572646965742C20616E7465206E65717565206665756769617420646F6C6F722C20617420706F727461207175616D206E657175652071756973206C6967756C612E204D61757269732073656D7065722076656C69742073697420616D657420697073756D2E2050656C6C656E7465737175652074656D7075732C20707572757320696E2072757472756D20636F6E7365717561742C20656E696D2065726174207665686963756C61206D617373612C20696420616363756D73616E206C656F2073617069656E206E65632070757275732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E20646F6C6F722E20496E746567657220666163696C69736973206C696265726F2073697420616D657420706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2055742076617269757320616C697175657420656E696D2E204E756C6C6120666163696C6973692E2043757261626974757220636F6E7365637465747565722C206F64696F206575207072657469756D2074696E636964756E742C206E756E63206E69736920616C6971756574206E657175652C2076656C20696D7065726469657420656C6974206D617373612073697420616D6574207475727069732E2050656C6C656E7465737175652074656D7075732C206F72636920766F6C757470617420626C616E646974206672696E67696C6C612C206F64696F2073656D20706F737565726520616E74652C20766974616520626962656E64756D2075726E61206C6F72656D2076697461652065726F732E205072616573656E7420766976657272612072686F6E63757320617263752E2053656420617563746F722C206573742073697420616D6574206D6F6C6C6973206D6F6C6C69732C207175616D207175616D20677261766964612073617069656E2C20696E20636F6D6D6F646F206D65747573206E756C6C6120617563746F7220656E696D2E20446F6E656320666163696C697369732E0A0A50726F696E2074696E636964756E742C2073617069656E206567657420756C747269636965732061646970697363696E672C20657374206F64696F2064696374756D20617263752C207574206D6F6C6C69732065726174206475692073697420616D65742076656C69742E204D6F726269206573742073656D2C20696E74657264756D2061742C20636F6E67756520612C20656C656D656E74756D2076697461652C206D657475732E2053757370656E64697373652069642061756775652E204D617572697320656E696D2073656D2C2070756C76696E617220656765742C2074656D70757320612C2074656D7075732073697420616D65742C2073617069656E2E20467573636520766573746962756C756D20636F6E736563746574756572206475692E2050656C6C656E74657371756520657261742E20536564206469676E697373696D20706C616365726174206F64696F2E204D616563656E61732073656D7065722072686F6E637573206C65637475732E2050686173656C6C7573207072657469756D2E2044756973206C696265726F20656C69742C20656C656966656E64206E65632C20656765737461732075742C20637572737573207365642C2066656C69732E204E616D206E69736C20617263752C20616C69717565742065742C20666163696C697369732065752C206C75637475732075742C2072697375732E20457469616D20756C7472696365732C20646F6C6F722073656420766F6C7574706174206D616C6573756164612C20747572706973206172637520696D7065726469657420746F72746F722C20657569736D6F6420636F6D6D6F646F206C696265726F206D61737361207574207175616D2E20496E7465676572206D6F6C6573746965207075727573206E6F6E20656C69742E2055742076656E656E617469732073656D70657220746F72746F722E20457469616D20626962656E64756D206567657374617320697073756D2E204D617572697320736F6C6C696369747564696E2073656D206E6563206E6962682E204E756C6C61207072657469756D206D65747573206575206D657475732E2050656C6C656E7465737175652073697420616D65742073656D2E0A0A53757370656E6469737365206163206E6973692E205574206C656F2E20566573746962756C756D2068656E647265726974207072657469756D20646F6C6F722E204E756E632066657567696174206D616C6573756164612070757275732E2043726173206574206E6962682E20437572616269747572206E756E6320657261742C206D616C6573756164612076697461652C206C616F726565742061632C20756C7472696369657320696E2C2070757275732E20566976616D75732074656C6C757320617263752C20736F64616C65732065752C20666163696C6973697320612C206C6163696E6961206E65632C206E756E632E2050656C6C656E7465737175652069642076656C69742E20496E206575206E6962682E204E756E63206E656320657261742E205365642064696374756D206E65717565207574206E69736C2E0A0A4D6F726269206C65637475732074656C6C75732C2074696E636964756E742061632C20706F72747469746F722061632C2074726973746971756520696E2C2065726F732E20446F6E6563206C7563747573206C7563747573206C656F2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2046757363652075742065737420657420656E696D207363656C6572697371756520616363756D73616E2E20446F6E6563206C6967756C612066656C69732C206C6163696E696120717569732C2070656C6C656E74657371756520696E2C2073656D70657220766573746962756C756D2C20656C69742E204D61757269732065676574206F72636920612066656C697320636F6E677565207665686963756C612E20557420736F6C6C696369747564696E2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204E756C6C616D20696420646F6C6F72207574206C6F72656D206469676E697373696D2076656E656E617469732E2053757370656E64697373652076697461652073617069656E2E2050726F696E206E6F6E206D61676E612075742065726F7320766976657272612070756C76696E61722E20446F6E65632071756973206F64696F2E204E756C6C616D206E6F6E20617263752076656C206C6F72656D20737573636970697420616C697175616D2E20416C697175616D2072757472756D2074757270697320696E206C656F2E0A0A5574206C7563747573206E6962682074726973746971756520657261742E2053757370656E646973736520626962656E64756D206F64696F20766974616520746F72746F722E20446F6E6563206C6163696E69612E204372617320736F64616C65732066656C6973206C7563747573206E756C6C612E204E616D20656C656966656E64207361676974746973206C6967756C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E64697373652076656C206E657175652E204D6F72626920616C6971756574207665686963756C61206D61676E612E2041656E65616E206174206F64696F2E20447569732070656C6C656E746573717565206D61676E612E204E756C6C6120617420746F72746F72207574206469616D2064696374756D2066617563696275732E204D617572697320717569732076656C69742E20446F6E6563206E6F6E2074656C6C7573207669746165206C6F72656D206672696E67696C6C6120706F72747469746F722E2046757363652075742073617069656E207175697320746F72746F7220666575676961742073616769747469732E20446F6E656320766976657272612073656D2076697461652073617069656E2E205072616573656E7420736F64616C65732C206C6163757320696E206672696E67696C6C6120766976657272612C206F64696F2061756775652061646970697363696E672075726E612C20766974616520696E74657264756D20616E74652073656D206E6F6E206E6973692E204E756C6C616D20746F72746F72206C6F72656D2C20656C656966656E642061632C206D6F6C6C6973206E6F6E2C206C616F726565742061632C2072697375732E20496E7465676572206F726E617265206C656F20736564206A7573746F2E2051756973717565206375727375732C2073656D206E6F6E20666163696C6973697320626962656E64756D2C206E697369206D69207661726975732066656C69732C206665726D656E74756D2066657567696174206C6F72656D2065726F73206C616F726565742072697375732E0A0A517569737175652073697420616D657420657374206574206C6F72656D207665686963756C61206C6163696E69612E20446F6E6563206E656320746F72746F722E2043726173206F64696F2E204E616D207363656C657269737175652076756C7075746174652075726E612E205072616573656E74206475692E20457469616D206E6563206E69736C206C6F626F7274697320697073756D20616C69717565742074656D7075732E204D616563656E6173207072657469756D20736F6C6C696369747564696E206D61757269732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206175677565206D617373612C20636F6E67756520656765742C20636F6E76616C6C697320656765742C207472697374697175652073697420616D65742C2065726F732E2053656420636F6E736571756174206E6973692065752066656C69732E2050656C6C656E746573717565206A7573746F2E2053757370656E6469737365206E6F6E2061756775652E20496E206469676E697373696D206C6F626F72746973206D61757269732E204D61757269732073616769747469732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E0A0A5365642061646970697363696E672E20446F6E656320612074656C6C75732076697461652065737420637572737573207665686963756C612E204E616D20616E74652073656D2C20736F64616C65732069642C206672696E67696C6C612076656C2C20636F6E64696D656E74756D2076656C2C206E756C6C612E205175697371756520736F64616C65732E20457469616D20696D7065726469657420656C6974206964206F64696F2E20416C697175616D206572617420766F6C75747061742E204D616563656E617320706F7274612074656D706F7220617263752E204E756C6C612073656D2061756775652C2070656C6C656E7465737175652061632C20636F6E7365717561742075742C20636F6E64696D656E74756D20657569736D6F642C2072697375732E2053656420616C697175616D2074696E636964756E74206D692E20496E20696E74657264756D206C6F626F72746973206F7263692E0A0A536564207665686963756C612068656E6472657269742070757275732E20457469616D2061206469616D2E2043757261626974757220636F6E76616C6C69732E2053757370656E64697373652061206E6973692E20446F6E6563206964206D61676E6120696E207175616D20736F6C6C696369747564696E20756C747269636965732E20446F6E656320766976657272612E205175697371756520766F6C757470617420657374207365642073656D2E20416C697175616D206A7573746F2E20566573746962756C756D20746F72746F72206D617373612C20706F72747469746F72207365642C2076617269757320717569732C20696163756C697320717569732C206F64696F2E20416C697175616D2065676574206E657175652E0A0A4D6175726973206E756C6C612E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566573746962756C756D206575207175616D20696E206E6571756520756C7472696365732070656C6C656E7465737175652E204372617320696E20646F6C6F722071756973207175616D207661726975732068656E6472657269742E20416C697175616D206E697369206C616375732C206C6F626F727469732065752C20636F6E76616C6C69732073697420616D65742C20666163696C697369732075742C206D692E20416C697175616D206174206E657175652E204372617320736167697474697320656C656D656E74756D206A7573746F2E20566573746962756C756D207574206C656374757320616C6971756574207075727573206D616C65737561646120766F6C75747061742E2044756973206174206C616375732061646970697363696E67206C696265726F2074696E636964756E7420766573746962756C756D2E204D6F7262692061206C696265726F2E20437261732070757275732E204D6F72626920757420617567756520657420707572757320696E74657264756D207363656C657269737175652E20496E74656765722061206475692E20496E206861632068616269746173736520706C617465612064696374756D73742E2044756973207068617265747261206D657475732065676574206D61757269732E20416C697175616D20696E74657264756D20756C6C616D636F72706572206D617373612E0A0A457469616D206F726E6172652E204E756C6C616D20657569736D6F642E2041656E65616E20636F6E7365717561742067726176696461206C6967756C612E20416C697175616D206573742E2050726F696E207669746165206C616375732E205072616573656E7420612065726F732073697420616D657420647569206C756374757320636F6D6D6F646F2E2050686173656C6C7573207665686963756C612061726375206567657420646F6C6F722E205072616573656E74206665726D656E74756D20636F6E677565206C656F2E20416C697175616D20766F6C7574706174207075727573207574206C6F72656D2E2046757363652068656E64726572697420656E696D206174206C656F2E20416C697175616D2072686F6E637573206E69736C2E20566976616D75732064696374756D2065676573746173206D692E2053757370656E64697373652070656C6C656E74657371756520626962656E64756D20646F6C6F722E2050656C6C656E7465737175652074696E636964756E742C207475727069732073656D7065722070656C6C656E74657371756520636F6E64696D656E74756D2C20697073756D206D6574757320736F64616C6573206C6967756C612C20696420766F6C7574706174206469616D2074757270697320757420656C69742E0A0A5072616573656E7420736564206C616375732E204E616D20656C656966656E64206D6F6C6573746965206D61757269732E20446F6E65632064617069627573206665726D656E74756D206D617373612E20446F6E656320766976657272612066617563696275732070757275732E2043757261626974757220636F6E6775652C206C696265726F20766974616520766976657272612070656C6C656E7465737175652C206469616D2076656C697420736F64616C657320656E696D2C20736564207375736369706974206C6563747573206E697369206E6563206E657175652E20566573746962756C756D206D616C6573756164612C206C616375732061742063757273757320636F6E6775652C2076656C6974206C65637475732074726973746971756520646F6C6F722C2073697420616D657420736F64616C6573206E6571756520697073756D2061206C696265726F2E20566573746962756C756D206574207175616D2E2043757261626974757220706C6163657261742E20437572616269747572206E756E6320617263752C20657569736D6F64206E65632C2076756C7075746174652068656E6472657269742C20616C697175657420656765742C207175616D2E204375726162697475722076656C20656E696D2E2053757370656E646973736520706F74656E74692E0A0A4E756E6320636F6E736571756174206F726369207574206C616375732E2046757363652076656C697420646F6C6F722C2064617069627573207365642C20626C616E6469742073697420616D65742C2072686F6E6375732069642C2072697375732E20447569732075726E61206E6962682C207363656C6572697371756520717569732C206461706962757320612C207363656C65726973717565207365642C206E6962682E20446F6E6563206C75637475732E205574206575206D617572697320637572737573206469616D206C6163696E69612072686F6E6375732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20416C697175616D207665686963756C61206D6F6C6573746965206A7573746F2E204D616563656E617320696D70657264696574207065646520736564206D692E2053757370656E6469737365206E756C6C6120646F6C6F722C2068656E64726572697420656765742C2068656E6472657269742069642C2064696374756D2076656C2C206C656F2E204475697320616363756D73616E2E2043757261626974757220696E2066656C69732E204E756E63206C6F72656D2E205574206C656F20646F6C6F722C206C616F72656574206E65632C2076756C7075746174652061742C20656C656966656E6420696E2C206E756C6C612E2051756973717565206E756E632070757275732C2076617269757320656765742C20616363756D73616E206E65632C20616C69717565742065742C206E6962682E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20437261732061646970697363696E67207669766572726120646F6C6F722E204D617572697320706F72747469746F7220756C7472696365732070757275732E204E756C6C6120666163696C6973692E205072616573656E7420666175636962757320616E7465207669746165206D61757269732E0A0A5072616573656E74206C6163696E6961206C656374757320736564206E69736C2E20496E2074656D70757320636F6E677565206D61757269732E20496E746567657220666163696C69736973206F726E61726520656E696D2E204E756C6C61206964206D617373612E20446F6E656320636F6D6D6F646F206469616D2061742074656C6C75732E204E616D20646170696275732076697665727261206573742E204E616D2074656C6C75732E205072616573656E742061206C696265726F2E20496E206661756369627573206573742065676574206E6962682E204E756C6C612065726F73206F7263692C20696D70657264696574206E6F6E2C20626C616E646974206E6F6E2C2074656D706F7220656765742C206D692E2050656C6C656E74657371756520636F6E76616C6C69732E0A0A517569737175652065676574206D69206163206C656F20657569736D6F642066617563696275732E2050686173656C6C75732072686F6E637573207075727573206964206475692E20566573746962756C756D206D616C65737561646120656C656966656E6420616E74652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050656C6C656E74657371756520626C616E646974206D6174746973206F64696F2E2053757370656E646973736520636F6E7365717561742C206C65637475732061632073656D70657220736F6C6C696369747564696E2C206D692076656C69742064696374756D2061756775652C2061632074656D70757320646F6C6F7220657261742073697420616D6574206475692E2050726F696E2068656E6472657269742C2066656C6973207175697320766F6C757470617420706F73756572652C206469616D206F64696F206D616C657375616461206F64696F2C206120696E74657264756D206F726369206469616D20717569732073617069656E2E2050656C6C656E746573717565206F64696F206F64696F2C20766976657272612076656C2C20677261766964612065752C206D6F6C6573746965207365642C206E756C6C612E2050686173656C6C7573206D617572697320706564652C20636F6D6D6F646F2075742C20657569736D6F642065752C2068656E6472657269742065752C206573742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C6120656C656D656E74756D206C616375732065752061756775652E2053656420657261742E2050726F696E20706F7274612E204D616563656E61732071756973206D692E2050686173656C6C757320617420656E696D206163206A7573746F206772617669646120756C7472696365732E2043726173206C656F2E0A0A496E746567657220757420617263752E20446F6E656320736564206D61676E612E2050726F696E2066656C69732E20496E20696163756C69732C206C6967756C61206964206672696E67696C6C61207072657469756D2C206E696268206469616D20616363756D73616E2074656C6C75732C206567657420616363756D73616E206D657475732064756920766172697573207475727069732E2050686173656C6C7573206F726369206D657475732C20656C656966656E64207365642C2074656D706F722061632C207363656C657269737175652061632C2075726E612E20496E74656765722076697665727261206E657175652061206D61757269732E204D617572697320706F72747469746F7220646F6C6F722065752076656C69742E20496E7465676572206F64696F20656C69742C20766573746962756C756D2075742C20766F6C75747061742069642C2072686F6E63757320636F6D6D6F646F2C2075726E612E20457469616D20706C61636572617420706861726574726120657261742E2055742074656D706F72206573742E20496E7465676572206469676E697373696D20626C616E6469742074656C6C75732E204D6F726269206E69626820646F6C6F722C207363656C657269737175652069642C20636F6D6D6F646F206D616C6573756164612C206D61747469732061742C206D692E20437261732074696E636964756E7420636F6D6D6F646F2070757275732E20496E2074696E636964756E742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D20756C6C616D636F727065722E2055742068656E6472657269742E204D6F72626920756C7472696365732E0A0A5072616573656E7420696163756C69732C2065726F73206163206567657374617320736F64616C65732C2075726E61206C656F206665726D656E74756D206C6967756C612C2073697420616D657420616C697175616D2076656C69742073656D206E6F6E2070757275732E20446F6E65632072757472756D206172637520717569732070757275732E204E616D20706F73756572652C206C6163757320617420636F6E73657175617420706C6163657261742C206E756C6C61207065646520706F7375657265206F7263692C206E6F6E20657569736D6F6420747572706973206475692071756973206E69736C2E2050726F696E20706F7274612061646970697363696E67206E6962682E20446F6E65632074726973746971756520646F6C6F722061742074656C6C75732E20446F6E6563206E65717565206D617373612C20617563746F722069642C2066617563696275732076697461652C20756C6C616D636F727065722076656C2C206E6973692E2050726F696E206D6F6C6573746965206E6571756520736564206D617373612E204E616D2074656D706F722E204D6F72626920616C697175616D2073617069656E2061742074656C6C75732E2046757363652071756973207269737573206574206D69207072657469756D2070756C76696E61722E2046757363652073697420616D6574206C6967756C612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E646973736520657520656E696D2065742066656C6973207363656C65726973717565206C6F626F727469732E205072616573656E7420626962656E64756D2E20566976616D7573207665686963756C612E20496E7465676572206174206E696268207365642076656C69742072686F6E637573206D6F6C65737469652E2043726173206C616375732E2053656420756C6C616D636F727065722065726F732076656C20657261742E20467573636520657520746F72746F722073697420616D6574206469616D20657569736D6F642073616769747469732E204E756E632071756973206C61637573206964206E69626820636F6E76616C6C6973207661726975732E2053757370656E6469737365207669746165206D692E20566573746962756C756D207472697374697175652E20446F6E6563206D616C65737561646120697073756D206964206E657175652E204E756C6C616D20736564206C616375732E204475697320656765737461732C206A7573746F20757420636F6E677565206F726E6172652C2061756775652073617069656E206C7563747573206469616D2C20617420616363756D73616E20657261742073617069656E207574206C696265726F2E2050686173656C6C75732076656C206E756C6C612E2053757370656E646973736520617263752074656C6C75732C20706F72747469746F7220612C2070686172657472612066617563696275732C20616C697175616D2073697420616D65742C206D617373612E204E756C6C6120706F72747469746F722074696E636964756E74206C6F72656D2E204E756E6320646F6C6F72206F64696F2C20736167697474697320696E2C206C6F626F727469732076656C2C20766F6C7574706174207365642C206E6962682E0A0A5175697371756520626C616E646974206C656F2075742073617069656E2074656D70757320666163696C697369732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2041656E65616E20756C7472696369657320706F72747469746F72206A7573746F2E2046757363652072757472756D2065726F732075742075726E612E2050726F696E2071756973207175616D20656765742064756920616C697175616D20616363756D73616E2E20446F6E656320737573636970697420656C656966656E6420656C69742E2050656C6C656E746573717565206D61747469732C2066656C697320736F64616C657320696163756C697320696D706572646965742C206C616375732073656D20636F6E76616C6C69732061756775652C2073697420616D657420616C69717565742061726375207075727573206672696E67696C6C612072697375732E20496E206575206F64696F206964206D61676E61207068617265747261206F726E6172652E20416C697175616D20696E74657264756D2070756C76696E617220697073756D2E20536564206E657175652E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D2073697420616D6574206E6973692E2055742061742061756775652E204D617572697320766F6C757470617420626C616E646974206C6967756C612E204E756C6C61206575206D657475732E20566573746962756C756D206567657420656C69742E205072616573656E7420706F73756572652E20566573746962756C756D2069642073656D206E6F6E206C6563747573206D6F6C6C69732074696E636964756E742E20416C697175616D2069642066656C697320617420616E7465206F726E6172652074656D706F722E204E756C6C61206C61637573207475727069732C20666575676961742076697461652C2063757273757320717569732C20636F6E736563746574756572206E6F6E2C206D61757269732E204675736365206C61637573206D617373612C20706F72747469746F722075742C206D6F6C65737469652075742C2076656E656E6174697320612C206C6F72656D2E205072616573656E742073697420616D6574206F7263692E204D61757269732072686F6E6375732066656C69732076697461652066656C69732061646970697363696E6720696D706572646965742E204D616563656E6173206D6F6C6C6973206469616D206E6563206C656F2E0A0A467573636520656E696D20697073756D2C20756C7472696365732065752C206D6F6C65737469652069642C20656C656D656E74756D2069642C2073617069656E2E20496E746567657220612075726E612E204E616D2076656C6974206C696265726F2C2076656E656E6174697320656765742C2074656D706F722073697420616D65742C20666575676961742076697461652C20616E74652E204675736365206E756E632E205365642073656D706572206E69736C206E65632072697375732E20496E20736564206C696265726F2E2050726F696E20746F72746F72206E657175652C2074696E636964756E742061632C2074656D706F722061632C20706861726574726120717569732C2076656C69742E2044756973206C65637475732061756775652C20756C747269636965732076656C2C20636F6E7365717561742069642C20696163756C69732069642C20616E74652E20566976616D757320617563746F72206D65747573206120616E74652E204375726162697475722061726375206E6973692C20666163696C697369732061742C206C616F7265657420696E2C20636F6E736563746574756572207365642C206D61757269732E205175697371756520706C616365726174206469616D20736564206475692E20566976616D7573207072657469756D20636F6E64696D656E74756D206C6F72656D2E20437572616269747572206C616F726565742E2041656E65616E206F726369206C6967756C612C2063757273757320656765742C206C6163696E6961206E6F6E2C2066617563696275732076656C2C206C6F72656D2E0A0A416C697175616D206572617420766F6C75747061742E204375726162697475722065726F7320646F6C6F722C20636F6E67756520612C20636F6E64696D656E74756D207365642C206C75637475732075742C206E6962682E204D616563656E6173206E6F6E20746F72746F72206E65632074757270697320636F6D6D6F646F2070656C6C656E7465737175652E205072616573656E7420657569736D6F6420706C616365726174206D692E2053757370656E646973736520706F74656E74692E2050686173656C6C7573207574206E65717565207669746165206F726369206D617474697320696163756C69732E20496E746567657220656765742074656C6C75732E20446F6E656320617420616E74652E204E616D206C6163696E6961206C656F206567657420657261742E204D616563656E617320657569736D6F64206D61676E6120636F6E67756520746F72746F722E204D6F726269206E6563206D6173736120657520656E696D206D616C65737561646120736F6C6C696369747564696E2E2053656420616363756D73616E2E204E756C6C616D20697073756D2E205574206F64696F2E20416C697175616D206572617420766F6C75747061742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2050656C6C656E7465737175652069642076656C69742E204E616D206F64696F2073656D2C20616C69717565742075742C2074656D7075732073697420616D65742C20657569736D6F642065742C206E756E632E0A0A50656C6C656E746573717565206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205072616573656E74206D6175726973206E756E632C207661726975732075742C20636F6E76616C6C6973206D6F6C65737469652C206C75637475732073697420616D65742C206C656F2E205365642064696374756D206C6F72656D20657420617263752E204E756E632076656E656E617469732070656C6C656E746573717565206D617373612E204E756C6C6120666163696C6973692E2050686173656C6C757320696E20746F72746F722065676574207269737573207363656C657269737175652076756C7075746174652E20536564206E69626820656C69742C2073616769747469732061632C20636F6E64696D656E74756D206E65632C20636F6E76616C6C69732065742C206A7573746F2E20467573636520766F6C7574706174206D657475732E204E756E6320617563746F722E20566573746962756C756D206C656F2065726F732C2070656C6C656E7465737175652061632C206D6F6C6C697320756C7472696365732C2072686F6E637573206E6F6E2C20646F6C6F722E204D6175726973207665686963756C6120706C616365726174206E69736C2E20566573746962756C756D20626962656E64756D2C2061726375207175697320636F6E67756520656C656D656E74756D2C2076656C6974206E756E6320656C656966656E64207475727069732C206964206C7563747573207269737573206E69736C2073697420616D65742074656C6C75732E2050686173656C6C75732070656465206E657175652C20626C616E646974206E6F6E2C20636F6D6D6F646F2076697461652C20756C7472696369657320656765742C206D61676E612E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120666163696C6973692E20416C697175616D20616320616E74652E20437261732072697375732E204D6F726269206D6175726973206C616375732C20706F73756572652065752C20626C616E6469742065742C2070686172657472612061742C206D692E2050726F696E2061632070757275732E204475697320637572737573206E69736C2072757472756D207175616D2E20416C697175616D2061206F64696F206E6F6E206D61676E612070656C6C656E74657371756520756C747269636965732E204D616563656E6173206163206D6173736120717569732073617069656E20756C6C616D636F727065722074656D7075732E2043726173206375727375732076656C6974207365642073617069656E2E2050726F696E206E756C6C612E20566976616D757320736F64616C657320616C697175616D206E6962682E20457469616D206574206572617420757420616E7465206C6163696E696120657569736D6F642E204675736365206E6973692E2050726F696E2071756973206E756C6C612E0A0A517569737175652076656E656E617469732C2065726F7320736564206C616F7265657420736F6C6C696369747564696E2C206F72636920616E74652070656C6C656E746573717565206E69736C2C2073697420616D65742076697665727261207175616D2065726174206E6F6E2072697375732E20437261732065676574206C696265726F2E2053656420656C6974206D61676E612C2073656D7065722065752C206672696E67696C6C6120696E2C206469676E697373696D20736F64616C65732C20657261742E20566976616D757320666575676961742073656D2076656C206475692E20446F6E656320636F6E76616C6C697320736F6C6C696369747564696E206469616D2E2043726173207365642070757275732E20446F6E65632066656C69732065726F732C2073656D70657220656765742C2074656D706F7220636F6E7365637465747565722C20736167697474697320717569732C206E69736C2E204475697320696E20616E74652E2043726173206E6F6E207475727069732E204E756C6C612074656D706F722076656C697420616C697175657420747572706973206D6F6C657374696520706C6163657261742E2050726F696E20656C656D656E74756D206665726D656E74756D206D61757269732E20566976616D757320736564206F726369206C6163696E69612064756920706C6163657261742076656E656E617469732E20566573746962756C756D20666575676961742C2074656C6C757320696E20766F6C75747061742072757472756D2C206D61676E61206E69736920756C6C616D636F727065722065726F732C2069642070756C76696E6172206E657175652065726174207574206C616375732E20566976616D7573207365642061756775652E204E756C6C6120666163696C6973692E204D616563656E617320616E74652061756775652C20656C656D656E74756D2075742C20736F64616C65732076697461652C20636F6E64696D656E74756D206E65632C206C6F72656D2E20447569732070656465206F7263692C206672696E67696C6C612061742C20656C656966656E64206E65632C207072657469756D20696E2C20657261742E204E616D2073616769747469732C2074757270697320766974616520636F6E76616C6C69732070686172657472612C206F64696F2073656D207363656C65726973717565206C616375732C206E6563206C6F626F7274697320647569206469616D2076656C2065726F732E20496E2073656D7065722067726176696461206E657175652E0A0A496E7465676572206E756E632E205574207072657469756D20697073756D2073697420616D657420656C69742E20496E206E656320617263752E2053656420766573746962756C756D2076756C70757461746520697073756D2E2050656C6C656E7465737175652074696E636964756E742E204E756C6C61206772617669646120646F6C6F7220696E2074656C6C75732E2043726173207665686963756C612C20646F6C6F722075742070656C6C656E74657371756520616C697175616D2C206572617420656E696D20617563746F72206D617373612C207665686963756C61206C6F626F72746973206F64696F2065726F732071756973207175616D2E2050726F696E2064617069627573206E6571756520696E20656E696D2E2050726F696E20656C69742E20496E74656765722072686F6E6375732074696E636964756E7420656C69742E204675736365206C6F72656D206D657475732C2073656D7065722061632C20766F6C75747061742076697461652C20666163696C697369732075742C2074656C6C75732E20446F6E65632076656C20747572706973207669746165206E69736920706861726574726120706F72747469746F722E204D616563656E617320746F72746F722E204675736365206D692E204E756C6C616D206E6563207475727069732E2053656420736F64616C657320766573746962756C756D206E756E632E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A50656C6C656E74657371756520646F6C6F7220646F6C6F722C206C616F726565742065752C20616C697175657420717569732C207363656C657269737175652073697420616D65742C20617263752E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C616D206375727375732075726E61206567657420656C69742E205175697371756520626C616E6469742073617069656E20616320616E74652E2050726F696E206E756C6C612065726F732C206772617669646120766F6C75747061742C20736F64616C65732076656C2C206D6F6C6C69732065752C206D617373612E204E756C6C612074726973746971756520736F6C6C696369747564696E206E69736C2E20437572616269747572207669746165206C6F72656D2076697461652076656C69742065676573746173206F726E6172652E2041656E65616E20656765742065726F732E20416C697175616D206572617420766F6C75747061742E20467573636520612075726E61206964206F64696F20616C697175657420636F6E76616C6C69732E204375726162697475722073697420616D6574206E69736C20706F7375657265206C656F20706F737565726520646170696275732E2044756973206D6574757320657261742C206C75637475732076656C2C2072686F6E6375732061742C20636F6E76616C6C69732073697420616D65742C20656E696D2E20566976616D75732068656E6472657269742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D206567657420656C69742E0A0A4E756C6C616D2061206E756E632E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206D657475732075726E612C2074696E636964756E742065742C206C6163696E69612073697420616D65742C206C6F626F727469732076697461652C206C6967756C612E2050726F696E206574206D6175726973207669746165206D6920616363756D73616E2070656C6C656E7465737175652E20457469616D207175616D2070757275732C2068656E647265726974207365642C20666575676961742076697461652C20657569736D6F6420656765742C20746F72746F722E20557420616C697175616D206D61676E61207669746165206A7573746F2E2053757370656E6469737365206E6F6E206A7573746F2076656C2076656C697420636F6E64696D656E74756D2074656D7075732E20447569732074656D70757320697073756D2076697461652074656C6C75732E2050726F696E20696E206D617373612E20457469616D20756C6C616D636F727065722064696374756D2074656C6C75732E2050726F696E20616C69717565742066656C6973206174206C656F206C616F726565742070756C76696E61722E20566573746962756C756D20617263752070757275732C206D616C6573756164612073697420616D65742C206375727375732065752C20706C6163657261742073697420616D65742C206E756E632E204E616D206D61737361206F64696F2C20736F6C6C696369747564696E20696E2C2061646970697363696E6720612C20616C697175616D206E65632C2072697375732E20416C697175616D20626C616E6469742068656E647265726974206C696265726F2E204D617572697320677261766964612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204375726162697475722061206E6962682E20557420696E74657264756D206665726D656E74756D206E657175652E2050656C6C656E74657371756520736564206E756E632E204D6175726973207665686963756C61206E697369206574206E756E632E205072616573656E74206C6F72656D2E20446F6E65632073656D7065722E20496E7465676572206575206C6163757320696E2065737420616C697175616D2068656E6472657269742E20566573746962756C756D2065676574206E657175652E205365642073656D706572206C75637475732076656C69742E20437572616269747572206E6962682061756775652C20636F6E6775652065752C2068656E6472657269742069642C20636F6E6775652065742C20656E696D2E20496E746567657220706C61636572617420616C697175616D206C65637475732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20566976616D75732076697461652065726F732E20446F6E65632076656C206E69736C2E0A0A496E20766573746962756C756D20666163696C697369732075726E612E2055742072697375732E204D61757269732070686172657472612E2050656C6C656E746573717565206D61747469732E20496E746567657220737573636970697420616C697175616D20697073756D2E204475697320626C616E6469742C2073617069656E20657420756C7472696369657320636F6E64696D656E74756D2C2066656C6973206D6920656C656D656E74756D20706564652C206E6563207361676974746973206D65747573206D61757269732071756973207175616D2E205175697371756520616363756D73616E20617263752076656C206E756C6C612E20437261732073656D2073617069656E2C20706F72747469746F722069642C20756C747269636965732073616769747469732C206C75637475732065752C206E756C6C612E20496E746567657220717569732065726F732E204D6F726269207365642075726E6120612074656C6C7573207665686963756C612076756C7075746174652E20457469616D206E656320617567756520656765742066656C69732073656D706572207472697374697175652E205175697371756520757420646F6C6F722076656C2072697375732064696374756D20636F6E7365717561742E20536564206567657420646F6C6F7220736564206E756E63206C6163696E696120616C69717565742E2053757370656E646973736520616320746F72746F7220696E20697073756D20706F73756572652076656E656E617469732E20536564206567657420657261742E204E756C6C612066617563696275732E2044756973206C616F726565742C206D6173736120706F72747469746F7220616C697175657420656765737461732C20697073756D206C65637475732072686F6E637573207175616D2C20696E2061646970697363696E672065726F732073656D2075742074656C6C75732E2050656C6C656E74657371756520666575676961742074656D707573207175616D2E20566976616D757320696420646F6C6F7220656765742073617069656E20636F6E7365637465747565722074656D706F722E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120696163756C6973206665726D656E74756D206C696265726F2E204375726162697475722066617563696275732C206D61737361206D616C657375616461206375727375732074696E636964756E742C20657261742073656D20656C656966656E64206D61757269732C20736564206672696E67696C6C61206D6920616E74652061632070757275732E204475697320656C656D656E74756D206C65637475732E204E756E63206F726E617265206172637520657520746F72746F722E20566573746962756C756D2076656C20646F6C6F72206174207075727573206C6163696E6961206672696E67696C6C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E616D20696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204D616563656E61732074696E636964756E742C2065726F73206120656765737461732070656C6C656E7465737175652C2072697375732072697375732064696374756D206C696265726F2C20696420616C6971756574206D65747573206A7573746F20696E206D617373612E2050726F696E20612074656C6C75732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205365642070757275732E20536564206E6F6E20706564652E2041656E65616E206D617373612073617069656E2C20736F64616C65732073697420616D65742C20636F6E7365717561742064696374756D2C20656C656966656E642076697461652C20746F72746F722E20446F6E656320756C747269636573206C6163696E696120656C69742E0A0A4D6F7262692061646970697363696E6720736F64616C657320646F6C6F722E20557420756C6C616D636F7270657220756C74726963696573206573742E20496E2076656E656E617469732074656D7075732061756775652E2053757370656E646973736520746F72746F7220646F6C6F722C20616363756D73616E2065742C20737573636970697420612C2074696E636964756E742075742C206C696265726F2E20416C697175616D207363656C65726973717565206D61676E61207365642066656C69732E2051756973717565207574206E756E632061206D61676E612076756C70757461746520706C6163657261742E20416C697175616D2072686F6E637573207665686963756C61206475692E2053656420746F72746F722E204E756C6C616D2073697420616D6574206469616D2E204E756E63207365642065726F732E20536564206574206F64696F2074696E636964756E7420656C6974206772617669646120636F6E76616C6C69732E20437572616269747572207175697320746F72746F722061206C616375732073656D706572207661726975732E204D6175726973206174206175677565206E6F6E206D6920736F6C6C696369747564696E20616C697175616D2E20496E746567657220756C6C616D636F727065722E2050656C6C656E746573717565207375736369706974207175616D206E6F6E2070757275732E20416C697175616D2061632065726F73206174206172637520756C6C616D636F7270657220636F6E7365637465747565722E2053757370656E6469737365207072657469756D206D6174746973206C656F2E0A0A44756973206174206E756E632E2053656420646F6C6F72206573742C207661726975732061632C20706F7274612065742C2074696E636964756E742068656E6472657269742C2072697375732E20566976616D7573207574206D61676E612E205072616573656E74207574206D61757269732E20496E207075727573206C616375732C206D6174746973207365642C20766573746962756C756D206E65632C2074656D706F722061742C206E69736C2E204372617320756C6C616D636F727065722076656E656E617469732074656C6C75732E20557420646F6C6F722E204D616563656E6173206D616C6573756164612C207065646520612070756C76696E6172206D61747469732C2061726375206469616D207665686963756C612072697375732C207175697320706F72747469746F72206175677565206D6173736120696E2076656C69742E204E756E6320636F6E6775652E204D6F7262692076656C6974206D657475732C2072686F6E6375732065742C20616C697175616D20636F6E7365637465747565722C20756C74726963696573206D616C6573756164612C206C6967756C612E205365642076656C6974206E69736C2C2073616769747469732076697461652C20706861726574726120612C20706F7375657265207365642C206D617373612E204E756C6C6120666163696C6973692E20496E207661726975732C206C6967756C61206964206C6F626F7274697320736F64616C65732C206175677565206F726369206665726D656E74756D2074656C6C75732C2065752070756C76696E6172207269737573206C6967756C6120612073617069656E2E204D6F726269206C616F7265657420697073756D206E6F6E206D692E204E616D20637572737573206C6F72656D207574206D692E20566976616D7573206D61676E6120656E696D2C20706F7375657265206E6F6E2C2073656D70657220717569732C20736F64616C65732065752C20617263752E20457469616D206D692070757275732C207072657469756D20666575676961742C20766172697573207365642C2070656C6C656E74657371756520656765742C206C6967756C612E20496E206C656F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E6563207669746165206F726369206575206F72636920736F6C6C696369747564696E20666575676961742E0A0A5072616573656E74207075727573206D617373612C20657569736D6F642076697461652C2074656D707573206E65632C20636F6E7365717561742068656E6472657269742C206D657475732E2041656E65616E2066656C6973206573742C20656765737461732076697461652C20616363756D73616E20656765742C2070656C6C656E74657371756520696E2C2073617069656E2E204475697320646170696275732070656465206E6F6E2073617069656E2E204E756E632075726E612E20496E74656765722076656C206C696265726F2E204475697320617567756520617263752C2064617069627573206E6F6E2C20666163696C697369732076697461652C20706F73756572652075742C2065726F732E20446F6E6563207669746165206E756E632073697420616D6574206172637520696D706572646965742064696374756D2E204D6F72626920656C656966656E642C206C6F72656D20657520636F6E73656374657475657220766573746962756C756D2C206469616D206E756E63206F726E61726520617263752C2061632074656D706F722066656C697320646F6C6F7220656765742065726F732E2050686173656C6C7573206D617373612073656D2C20736F6C6C696369747564696E2061632C20736F64616C657320677261766964612C206C756374757320612C207175616D2E204E616D206E65717565207175616D2C20766976657272612061742C2076656E656E6174697320717569732C207361676974746973206E6F6E2C20656E696D2E0A0A4E756C6C6120666163696C6973692E2050656C6C656E7465737175652065676573746173206C6163696E6961206573742E205365642074696E636964756E742C2070656465207365642074696E636964756E7420766573746962756C756D2C2075726E6120646F6C6F722061646970697363696E672070757275732C207669746165206672696E67696C6C612066656C697320656C697420696E206E6962682E204E756C6C6120736564206E6973692E204D6175726973207375736369706974207363656C6572697371756520617263752E20457469616D206E6F6E20656E696D2076656C2065726F7320616363756D73616E206D616C6573756164612E204E756E632074696E636964756E7420636F6D6D6F646F206D61757269732E20496E2074696E636964756E7420726973757320717569732075726E612E204E756C6C61206469616D20746F72746F722C20616C69717565742065742C2074696E636964756E7420717569732C20736F6C6C696369747564696E2061632C20746F72746F722E2043726173206E69736C206E657175652C2076756C7075746174652073757363697069742C206D6F6C657374696520717569732C2070756C76696E61722061742C206E756C6C612E204E756C6C616D206163206D65747573206E6563206F64696F20706F7375657265207661726975732E2043726173207365642070656465206E65632064756920706F737565726520626962656E64756D2E204475697320657569736D6F6420756C6C616D636F72706572206C696265726F2E20416C697175616D2066617563696275732070756C76696E6172207475727069732E0A0A496E207574206E65717565206964206E756E63206665756769617420636F6D6D6F646F2E20437572616269747572206469676E697373696D2C2066656C697320617420736F6C6C696369747564696E206C6163696E69612C20656E696D20656C6974207375736369706974206E657175652C20736564206C7563747573206C6F72656D20697073756D20696E206C656F2E204475697320646170696275732C206F64696F207175697320617563746F7220636F6D6D6F646F2C206E69736C206F64696F206D61747469732074656C6C75732C206E65632074696E636964756E7420747572706973206469616D20696E20617263752E2043757261626974757220612073656D2E204E756C6C616D20766F6C7574706174206D61676E612E2050656C6C656E7465737175652073616769747469732C206E6571756520636F6E736571756174207072657469756D206375727375732C20646F6C6F72206C6163757320636F6E73656374657475657220617263752C20736564206C616F72656574206573742075726E61206574206D657475732E2053757370656E646973736520706C6163657261742C20647569206120706F7274612074656D706F722C206C6F72656D20647569206C6F626F72746973206E657175652C207365642076656E656E61746973206469616D20656E696D2069642065726F732E20457469616D206574206E69736C206E6F6E206C656374757320666175636962757320636F6E7365637465747565722E204D6F726269207363656C657269737175652C2073656D206E65632074656D70757320756C6C616D636F727065722C20697073756D206469616D2066657567696174206C6F72656D2C2061206672696E67696C6C612073617069656E20656C69742071756973206E6962682E204E756C6C616D206469616D2075726E612C2076697665727261207365642C2070686172657472612072686F6E6375732C2074696E636964756E742076656C2C206F7263692E20496E746567657220616363756D73616E206D617474697320657261742E204E616D2064696374756D2E204D6175726973206E6563206C656F2E204E756C6C6120696163756C69732E204E756C6C61206E69736C206D692C206461706962757320717569732C207665686963756C6120612C2063757273757320656765742C206F64696F2E0A0A50686173656C6C7573206461706962757320657569736D6F64206E6962682E20566976616D757320696D7065726469657420616E746520696E206C6967756C612E2050656C6C656E74657371756520616363756D73616E2E20496E20696D706572646965742C20647569206120617563746F72206672696E67696C6C612C206D65747573206E6973692063757273757320646F6C6F722C2076656C206C7563747573206C6967756C61206C6F72656D207669746165206D61757269732E205072616573656E74206D617474697320766573746962756C756D20656C69742E20416C697175616D20656E696D206C616375732C2070756C76696E6172206E6F6E2C206C6163696E69612073697420616D65742C20656C656966656E64206E6F6E2C2076656C69742E20566573746962756C756D206163206C656F2E204D617572697320696D70657264696574206A7573746F206163206C65637475732E20536564206D6F6C6573746965206C656374757320736564206475692E20536564206665726D656E74756D2074656D707573206D61757269732E204E616D206F726E617265206F7263692061632074656C6C75732E205574206D616C6573756164612C206C61637573206964206C6163696E696120616363756D73616E2C206469616D20656C69742061646970697363696E67206D657475732C20657420626962656E64756D2073617069656E206E69626820626C616E646974206F7263692E2053757370656E646973736520697073756D2074656C6C75732C20736167697474697320717569732C20766573746962756C756D206E6F6E2C2076756C7075746174652065752C2065726F732E205072616573656E74206174206E756C6C612069642070656465207363656C6572697371756520756C747269636965732E204372617320626C616E646974207072657469756D2074656C6C75732E204D616563656E6173206461706962757320636F6E64696D656E74756D2061756775652E2050686173656C6C75732074696E636964756E74207068617265747261206C6F72656D2E204D6F726269206E6F6E2065726F732E205365642074656D706F722C206E69736C20612074696E636964756E742074696E636964756E742C2065726F73206469616D2064696374756D2073656D2C2076656C206469676E697373696D20616E7465206469616D20736564206D61676E612E205072616573656E74206E6F6E206C6967756C61206964206D65747573206D6F6C657374696520636F6E7365637465747565722E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E64697373652076656C206D692E2043757261626974757220616E7465206E756C6C612C2072757472756D20612C20636F6E76616C6C69732076656C2C207665686963756C612061632C206E756E632E204E756E632073616769747469732C20656E696D2073697420616D657420617563746F722072757472756D2C206D617572697320617263752076756C707574617465206E657175652C20657420657569736D6F64206573742066656C6973207175697320616E74652E20566573746962756C756D207475727069732074656C6C75732C2068656E64726572697420696E2C206C6163696E696120636F6D6D6F646F2C20756C6C616D636F7270657220677261766964612C2072697375732E204D61757269732072686F6E637573206C6163696E69612072697375732E204D616563656E617320736F6C6C696369747564696E2065726174207669746165206E756E632E205072616573656E74207072657469756D2070656C6C656E7465737175652061756775652E20446F6E656320696E74657264756D2E205072616573656E742061632065726F732076697461652065726174206C6F626F72746973206672696E67696C6C612E2041656E65616E20636F6E7365717561742074656C6C75732E204E756C6C6120616363756D73616E20626962656E64756D2066656C69732E204D616563656E6173207072657469756D20616E7465206964206E6973692E2041656E65616E206D6920617263752C2073656D706572207365642C206D61747469732065752C2076656E656E617469732073697420616D65742C20617263752E20446F6E656320616C697175657420657569736D6F64206C656F2E2050726F696E206D61676E61206A7573746F2C2074726973746971756520612C2073656D7065722061632C20736F6C6C696369747564696E20612C206C6967756C612E204D6F7262692076656C69742E20416C697175616D2076656C206E6973692E0A0A496E2061206C6F72656D207574206E756E63206665756769617420636F6E6775652E20446F6E6563206665726D656E74756D20626962656E64756D206475692E2050726F696E207661726975732065737420717569732076656C69742E20446F6E656320616C69717565742073656D20616363756D73616E206D692E2053656420706C6163657261742E204E756C6C616D206163206E6973692061206D61737361206C6F626F727469732073757363697069742E204E756E63206964206C656F2E20416C697175616D206574206D617373612E204E756C6C616D20766573746962756C756D20656C656D656E74756D206D657475732E20496E20636F6E736563746574756572206E6973692076656C206A7573746F2E204D616563656E6173206567657420707572757320736564206D61737361207661726975732070656C6C656E7465737175652E2050686173656C6C75732066617563696275732066656C697320717569732066656C69732E2041656E65616E206F64696F20617263752C20626C616E64697420717569732C20666163696C6973697320696E2C20696D706572646965742065752C206C6F72656D2E204E616D20706F73756572652070756C76696E6172206D692E204675736365207472697374697175652C206D617572697320657420636F6E73656374657475657220756C747269636965732C206D6175726973206C65637475732074656D706F72206A7573746F2C206174206672696E67696C6C61206573742065737420736564206E6973692E20517569737175652066617563696275732E2053656420696E20746F72746F722074696E636964756E7420657374206C6163696E696120696163756C69732E204D616563656E61732061206D617373612E2050656C6C656E7465737175652061206E69626820617420707572757320706F7274612068656E6472657269742E0A0A4E756C6C616D207475727069732E2046757363652061632073656D20736564206F64696F2070656C6C656E74657371756520696D706572646965742E2043757261626974757220696E20617263752E205072616573656E74206C61637573206C616375732C20666575676961742069642C2070756C76696E617220696E2C2074696E636964756E74207365642C206E657175652E204D616563656E61732076697665727261206F64696F206567657420746F72746F722E20496E746567657220616C697175616D2C206C6F72656D2072757472756D2076656E656E61746973206469676E697373696D2C206C6967756C61206D61676E61206D616C65737561646120617263752C2076656C2066657567696174206C6F72656D20697073756D2071756973206D617373612E204D6F72626920616E74652E20566573746962756C756D206D6175726973206C696265726F2C20756C6C616D636F7270657220717569732C20756C74726963657320717569732C20666163696C69736973206E6F6E2C206D617373612E204D616563656E617320696D706572646965742E20416C697175616D206572617420766F6C75747061742E2050656C6C656E746573717565206469676E697373696D2067726176696461206C65637475732E20496E206E696268206F64696F2C20617563746F7220656765742C206461706962757320717569732C206469676E697373696D2076656E656E617469732C20617263752E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20447569732070656C6C656E746573717565206C6967756C612071756973206D617373612E2043757261626974757220636F6E64696D656E74756D2C206A7573746F2065676574206F726E617265206C75637475732C206C6F72656D206C6967756C6120736167697474697320706564652C206120706F727461206E756E63206E756E6320696E206E657175652E20517569737175652066656C6973206D61757269732C20636F6E64696D656E74756D2076697461652C20617563746F722076697461652C2074696E636964756E7420717569732C20706564652E204E756E63206C6163696E696120616E746520696E206C656F2E2050656C6C656E746573717565206C696265726F2E2041656E65616E2061206C6967756C61206574206E756E6320766573746962756C756D20636F6E7365637465747565722E0A0A4675736365206F726E6172652E205072616573656E742069642075726E612E20496E74656765722076656E656E617469732C207175616D206E6F6E20736167697474697320616363756D73616E2C20616E7465206E6962682073616769747469732061756775652C20736F6C6C696369747564696E2061646970697363696E6720646F6C6F722076656C697420657520657261742E2050726F696E207175697320656E696D206575207075727573207665686963756C6120616C697175616D2E204E756C6C612076656C20656E696D2076656C20656C697420736F6C6C696369747564696E206672696E67696C6C612E20416C697175616D206572617420766F6C75747061742E205365642073757363697069742066656C6973207574207475727069732E20457469616D2072757472756D20726973757320696D70657264696574206573742E20416C697175616D20612074656C6C75732061742074656C6C757320636F6D6D6F646F20646170696275732E204D61757269732072757472756D206D61676E61206574206F64696F2E20496E20617420646F6C6F722E20437572616269747572207665686963756C61206C656374757320696E20746F72746F722E204675736365206A7573746F2070757275732C206C75637475732076697461652C206D6F6C6C697320696E2C2070686172657472612061632C2070757275732E204E756C6C616D20706F737565726520696E74657264756D206A7573746F2E20437572616269747572207669746165206C616375732076656C206C656F20636F6E6775652070756C76696E61722E0A0A41656E65616E20656C656966656E64206E6962682076617269757320746F72746F722E2053757370656E64697373652076656C2065726F732E2050726F696E206E6563206469616D206120746F72746F7220756C747269636573206F726E6172652E20416C697175616D207363656C657269737175652066657567696174206A7573746F2E20566976616D757320616E74652075726E612C2061646970697363696E672076697461652C20706F72747469746F722065752C20736F64616C65732065742C2066656C69732E2053757370656E646973736520706F74656E74692E20437572616269747572206163206D6173736120696E206E69736C207361676974746973206D6F6C6C69732E204E616D207175616D206C6967756C612C20636F6E73656374657475657220656765742C20696163756C69732061742C207661726975732065752C206C656F2E204475697320646F6C6F72206C6967756C612C2074696E636964756E742061742C20756C6C616D636F72706572207365642C20616363756D73616E20616C697175616D2C206C6967756C612E2050686173656C6C75732076756C7075746174652C206C6F72656D2061742074696E636964756E742070686172657472612C207269737573206C6563747573206C6163696E6961206D61676E612C20717569732072757472756D20656E696D206D61676E612061742073656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E20447569732069642073656D2061206D617572697320736F6C6C696369747564696E2074696E636964756E742E20457469616D2065752070757275732065752061726375206672696E67696C6C612061646970697363696E672E20566976616D7573206F726E6172652074656D707573206469616D2E2050726F696E20747572706973207175616D2C206C6163696E6961206E6F6E2C20656765737461732061742C20636F6D6D6F646F20656765742C20706564652E205072616573656E742076756C70757461746520726973757320696E206573742E204E756C6C6120666163696C6973692E0A0A557420656C656D656E74756D206C6163696E69612070757275732E2050726F696E2076697461652061726375206163206E756C6C6120636F6E76616C6C697320616C697175616D2E204E756C6C6120636F6E6775652C206C696265726F2069642070656C6C656E746573717565206D61747469732C207175616D206C656374757320706F72747469746F72206469616D2C2061207363656C6572697371756520647569206C696265726F20696E2073617069656E2E204E756C6C616D2066656C6973206469616D2C207665686963756C612076656C2C206D6F6C65737469652075742C20766573746962756C756D20616C697175616D2C2073617069656E2E20446F6E656320636F6E76616C6C69732C2065737420757420656C656D656E74756D20766F6C75747061742C206D617572697320697073756D20677261766964612073656D2C20636F6D6D6F646F20666163696C697369732073617069656E206C65637475732073656D706572206C65637475732E205175697371756520706F72747469746F722065726F73207574206E6962682E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20457469616D206D617474697320726973757320736564206F64696F2E20566573746962756C756D206574206F64696F2E20496E206861632068616269746173736520706C617465612064696374756D73742E204E616D20747269737469717565206D61737361207574206C6967756C612E2051756973717565206E6962682074656C6C75732C207665686963756C612073697420616D65742C2061646970697363696E672061742C20636F6E76616C6C6973206E65632C206C6967756C612E20566573746962756C756D207072657469756D2C206D69206E6563206672696E67696C6C6120626962656E64756D2C20647569206E756E6320736F64616C657320706564652C20612073656D706572206D61676E61206E696268206E6F6E206469616D2E20446F6E6563206D61737361206E756E632C20766976657272612076656C2C20636F6E73656374657475657220706F7274612C2064617069627573206E6F6E2C20697073756D2E2044756973206E69736C206D61757269732C206375727375732076656C2C2073656D706572206E6F6E2C20736F6C6C696369747564696E20626962656E64756D2C2066656C69732E20566573746962756C756D206575206E657175652E0A0A43726173206E656320646F6C6F722E20446F6E6563206C616F726565742074656D707573206C65637475732E20437261732073656420746F72746F7220696E74657264756D206C6163757320656C656966656E64206469676E697373696D2E204D616563656E61732073697420616D657420656C69742E204E756C6C616D207175697320646F6C6F722076656C20647569207068617265747261206C75637475732E20496E2073697420616D6574207175616D2073697420616D6574207065646520756C74726963657320756C7472696365732E204D616563656E6173206469616D2E20496E74656765722075726E612E204375726162697475722064696374756D2C2076656C69742073656420706C6163657261742073757363697069742C206572617420747572706973206665726D656E74756D206A7573746F2C2073656420696E74657264756D206E657175652073656D206574206E6962682E20566976616D757320636F6E73657175617420636F6E76616C6C6973206D61676E612E204E616D20616C697175616D2C2065737420616320626962656E64756D20636F6D6D6F646F2C206D61676E61206573742064696374756D206D692C207669746165206D616C65737561646120656C6974206D61676E61207669746165206F64696F2E204D616563656E61732074656D706F722076756C7075746174652074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206475692E20457469616D20616363756D73616E207065646520636F6E67756520746F72746F722E0A0A4D6F7262692074656D706F72206C696265726F206163206C6F72656D2E20496E20616C697175657420766172697573206D61676E612E20496E20617263752E2050686173656C6C7573206F64696F2E2046757363652074696E636964756E7420616C69717565742066656C69732E20517569737175652076656C69742E20536564206C75637475732E20416C697175616D2066657567696174206672696E67696C6C61206D692E20416C697175616D206D6F6C657374696520766976657272612072697375732E2050726F696E20617263752E20566573746962756C756D206C6F626F727469732074656D707573206E6973692E205072616573656E742061206172637520696E2076656C697420766976657272612072757472756D2E0A0A496E20736564206C65637475732E20446F6E656320726973757320646F6C6F722C20626C616E6469742073697420616D65742C20656C656D656E74756D20636F6E76616C6C69732C20706861726574726120717569732C20706564652E20496E7465676572206F726E6172652E2041656E65616E20656765737461732064617069627573206A7573746F2E20536564207175616D206C656F2C20706F73756572652061742C20656C656D656E74756D2076697461652C20636F6D6D6F646F20656765742C206573742E20416C697175616D206D6F6C65737469652072686F6E63757320656E696D2E2043757261626974757220696163756C697320756C74726963657320706564652E204D6F72626920616C69717565742072757472756D206C616375732E20416C697175616D207175616D2E2053656420636F6D6D6F646F2C2074757270697320696E20706861726574726120706F73756572652C206D6920726973757320696D7065726469657420657261742C206120766573746962756C756D206D617373612074656C6C7573207665686963756C612073656D2E204D6175726973206672696E67696C6C6120756C747269636573206E756E632E204E616D206E69736920656E696D2C20656C656966656E642073697420616D65742C20756C747269636573207365642C206665726D656E74756D206E6F6E2C2061756775652E2050726F696E20636F6E677565206C6F626F72746973206E6973692E204D616563656E61732068656E6472657269742E204E616D20736564206E69736C2E204E756E6320656C656D656E74756D206F64696F2065752072697375732E20496E206D657475732E2050686173656C6C75732067726176696461207072657469756D206C6967756C612E204E756C6C61207669746165206E657175652E204E616D206E69736920746F72746F722C206F726E617265206E6F6E2C20626C616E6469742061742C206375727375732065752C20746F72746F722E0A0A4475697320626962656E64756D20697073756D20696E206E756E6320637572737573206D6F6C65737469652E204E756E63206F7263692E204E756C6C616D206E656320616E7465206E6F6E20657374206469676E697373696D20766976657272612E204D617572697320626C616E6469742C2076656C69742069642066657567696174207072657469756D2C20656C6974206D61676E612070656C6C656E74657371756520646F6C6F722C206174207361676974746973206C616375732076656C69742065676573746173206D61676E612E2050656C6C656E746573717565206375727375732C206469616D20636F6E736563746574756572207361676974746973206672696E67696C6C612C20746F72746F72206E6973692061646970697363696E67206E756E632C20657520766172697573206C6163757320726973757320616320656C69742E204D6175726973206964206E6973692071756973206C656F20657569736D6F642076656E656E617469732E2050656C6C656E74657371756520616320616E74652E204D617572697320617263752073617069656E2C2074656D706F722061742C20706F72747469746F722069642C20636F6E64696D656E74756D2075742C206475692E20457469616D206665726D656E74756D20756C747269636965732061756775652E20437261732075742065726F73206174206A7573746F20756C7472696369657320696163756C69732E2044756973206469676E697373696D2C206E69736C20657420666163696C69736973206665726D656E74756D2C2065726174207075727573206D6F6C65737469652074656C6C75732C20717569732074656D70757320697073756D206C656374757320617420656C69742E204E756C6C61207669746165206C6F72656D2E0A0A41656E65616E2076656C2073656D206574206469616D2073656D70657220636F6E6775652E20496E20626962656E64756D206469616D20717569732074656C6C75732E204E756E6320666163696C6973697320756C74726963696573206E6962682E2043726173206E756E6320656E696D2C2066657567696174207365642C20756C7472696365732076697461652C2073616769747469732076697461652C20697073756D2E204675736365207669746165206E756C6C612E20446F6E65632070656C6C656E7465737175652C2076656C697420696E20706F72747469746F7220656C656966656E642C20657374206E65717565206C6F626F727469732076656C69742C2073697420616D65742072757472756D20616E746520746F72746F72206E656320646F6C6F722E20446F6E6563207665686963756C612E204E756C6C6120666163696C6973692E20536564206567657374617320756C747269636573206E6962682E20446F6E656320656C6974206C65637475732C20636F6E76616C6C697320706F72747469746F722C20616C697175657420646170696275732C206665756769617420656765742C206C6967756C612E2053656420636F6E736563746574756572206A7573746F2E204D616563656E617320612073617069656E2073697420616D6574206E6973692064617069627573206C6F626F727469732E20566976616D7573206C7563747573206C6F72656D206E6F6E206E756C6C612E2053656420656765742065726174207669746165206C696265726F20696E74657264756D20706F73756572652E20437261732070756C76696E61722E204E756C6C616D20696D706572646965742C20646F6C6F722074656D706F72206469676E697373696D20626C616E6469742C206475692073617069656E2072686F6E637573206E657175652C206964206D616C657375616461206175677565206D61676E612073697420616D65742075726E612E204475697320736564206D61757269732E0A0A4D6F72626920616363756D73616E2E20536564206D61757269732061756775652C206672696E67696C6C61206E6F6E2C20617563746F722075742C20617563746F722065742C206F7263692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320757420706564652E20446F6E6563207669766572726120656E696D2076656C206C6F72656D2E2050656C6C656E746573717565206E65717565206D61757269732C20696E74657264756D2065752C2076656E656E617469732069642C20636F6E64696D656E74756D2065752C2073617069656E2E20446F6E656320697073756D20617263752C206C6163696E69612061646970697363696E672C206C616F726565742065742C206375727375732076656C2C2076656C69742E205574207361676974746973206D617572697320717569732072697375732E20496E7465676572206575206F64696F207669746165206C61637573207669766572726120616363756D73616E2E204D6F726269206C656F20616E74652C206469676E697373696D207365642C2076617269757320717569732C20766F6C75747061742076697461652C206E6973692E204E756C6C6120706C61636572617420696E74657264756D20656C69742E20446F6E6563206E65717565206475692C2073616769747469732076697461652C20736F6C6C696369747564696E20717569732C20636F6D6D6F646F2076697461652C206E657175652E204E756C6C612071756973206C6967756C61206F726E617265206C6967756C612064696374756D206F726E6172652E204D61757269732072757472756D2072757472756D206E657175652E2041656E65616E207665686963756C612074656D707573206573742E20446F6E656320766172697573207363656C6572697371756520706564652E20446F6E656320706C6163657261742076756C707574617465206C656F2E204E756C6C616D206E756E63206E69736C2C20706F7375657265206E6F6E2C20666575676961742076697461652C2070656C6C656E74657371756520717569732C206D61757269732E20496E20647569206E657175652C2063757273757320656765742C20736167697474697320656765742C20646170696275732076697461652C206D692E2050726F696E2065676574206573742E0A0A467573636520706F727461206573742E204D6175726973206D61676E612E20416C697175616D20697073756D206C616375732C20756C747269636965732069642C20766573746962756C756D206C75637475732C20616363756D73616E2075742C20616E74652E20536564206D61757269732E205365642061646970697363696E67206C656F2073697420616D6574206D61676E612E2053757370656E646973736520706F74656E74692E204E756E63206D6173736120656C69742C206672696E67696C6C6120656765742C20656765737461732076697461652C206C75637475732076697461652C20646F6C6F722E2050686173656C6C75732071756973206E756C6C61206575206E69736920696E74657264756D20736F6C6C696369747564696E2E204E756C6C616D2069642074656C6C75732E20496E746567657220696163756C697320646F6C6F722061632070757275732E205365642076656C206D692E20437572616269747572206E6F6E206D61676E612073697420616D6574206A7573746F20636F6E64696D656E74756D2076756C7075746174652E20517569737175652074696E636964756E742070656465206575206E69736C2E20566976616D7573206C6F626F727469732E204E756E63206D65747573206D657475732C20636F6E677565207365642C2074696E636964756E74207365642C207072657469756D2061742C206F64696F2E20446F6E6563206120617263752E20496E2073656D206A7573746F2C207665686963756C61207365642C207661726975732069642C20766F6C75747061742061742C2072697375732E205072616573656E7420696163756C6973206D617373612E20496E206172637520656C69742C2068656E64726572697420656765742C20756C6C616D636F7270657220696E2C20706F7274612069642C2074656C6C75732E20446F6E65632073616769747469732068656E647265726974206469616D2E0A0A53757370656E646973736520706F74656E74692E20536564206574206469616D206574206175677565207361676974746973206C6F626F727469732E2050686173656C6C757320646F6C6F722E2055742065742061726375206567657420616E74652074656D706F7220706F73756572652E20416C697175616D206665726D656E74756D207363656C65726973717565206475692E204D61757269732061742070757275732E20446F6E656320657261742073656D2C20766573746962756C756D206E65632C2066617563696275732061632C206D617474697320612C206C656F2E2053757370656E64697373652061646970697363696E67206C6163696E69612073656D2E204E756C6C616D206F72636920617263752C2064696374756D2065742C20666175636962757320766976657272612C20646170696275732065742C206E657175652E2043726173206E756E63206469616D2C2061646970697363696E67206E6F6E2C20736F6C6C696369747564696E20696E2C20696E74657264756D2076656C2C206D617373612E204D61757269732073616769747469732C206A7573746F206174207472697374697175652074656D7075732C206D6175726973206D617572697320616C697175616D20616E74652C2073697420616D657420706F7375657265206469616D206475692065676574206C6967756C612E20496E206469676E697373696D2C206E69736C207574206C6163696E696120636F6E64696D656E74756D2C2065726174206A7573746F20706F72747469746F72206E756C6C612C206E6F6E2067726176696461206C6967756C61206D61676E612065676574206D617373612E20566573746962756C756D207669746165206C6967756C61206174206D6920766573746962756C756D2073757363697069742E2044756973206C616F726565742E204E756C6C6120636F6D6D6F646F206C696265726F2073697420616D6574206C6F72656D2E20557420656C656D656E74756D2073656D2E20496E74656765722076656C20646F6C6F722E204E616D20666163696C69736973206D6920717569732073656D20756C7472696365732073616769747469732E205365642071756973207175616D206174206D65747573206D6F6C657374696520626962656E64756D2E0A0A50726F696E2064756920656E696D2C206C6163696E696120612C20666575676961742061632C20706C6163657261742076697461652C20706564652E205175697371756520656765737461732C206C656F206567657420616C697175616D207072657469756D2C206C696265726F206A7573746F2074696E636964756E742065726F732C2075742065676573746173206175677565207065646520656C656D656E74756D206E6962682E20437572616269747572206D6F6C6C697320736F64616C657320656E696D2E20446F6E65632061756775652E2050686173656C6C757320696420697073756D20706F737565726520647569207072657469756D2066617563696275732E204D6175726973206C756374757320616E74652073656D706572206E69736920696E74657264756D2061646970697363696E672E204475697320646170696275732C206F64696F207175697320766976657272612072686F6E6375732C206A7573746F207175616D20626962656E64756D20646F6C6F722C20696420646170696275732076656C697420657261742076656C20657261742E2046757363652073697420616D6574206E69736C2076656E656E61746973207175616D20756C74726963657320636F6E64696D656E74756D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632072686F6E637573207363656C65726973717565206C6967756C612E20566573746962756C756D206D69206F64696F2C20616363756D73616E2065742C2061646970697363696E6720656765742C206F726E6172652075742C207175616D2E204E756C6C616D20626C616E646974206D6F6C6573746965206D61757269732E20437572616269747572206469676E697373696D206D6175726973206574206C6F72656D2E2053757370656E64697373652061206A7573746F2E204E616D206D617474697320666175636962757320617263752E204475697320626C616E64697420656E696D206E6F6E206D617373612E0A0A4E756C6C616D206C6F72656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E204D617572697320636F6E73656374657475657220706F7375657265206D61757269732E204D616563656E61732074696E636964756E74206D617572697320696E2065726F732E204E756C6C61206575206D65747573206575206F72636920736F6C6C696369747564696E2066617563696275732E2053757370656E646973736520616C697175616D206D6175726973206964206573742E204372617320626C616E646974206475692065742075726E612E204E756C6C6120617263752E2053656420612075726E612E204E756C6C612064617069627573207665686963756C6120746F72746F722E20446F6E65632072697375732E20536564207175616D206D657475732C20656765737461732065752C206375727375732075742C2076697665727261206E6F6E2C206F64696F2E205574206A7573746F206A7573746F2C206D616C6573756164612073697420616D65742C20626C616E6469742073757363697069742C206D6F6C657374696520696E2C206A7573746F2E20566573746962756C756D20636F6E7365717561742C207175616D20616320666575676961742074696E636964756E742C20697073756D206C696265726F20656C656966656E64206F64696F2C206E6F6E20656C656966656E64207065646520697073756D206E6F6E20616E74652E204E756C6C616D2061206D657475732E0A0A4E616D206163206E6973692061742066656C697320637572737573206D61747469732E2050656C6C656E74657371756520636F6E7365717561742073656D2071756973206F7263692E20517569737175652074656D7075732E2041656E65616E20696D70657264696574206D6F6C657374696520706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652065752074656C6C75732E204E756C6C61206469616D2065726F732C20736F64616C65732075742C20736F64616C6573206E65632C2074696E636964756E742061632C206E756E632E204E756E63206C6163696E696120666175636962757320697073756D2E20566976616D75732076656C206E6571756520696E2065726174206665726D656E74756D206C75637475732E204E756C6C612065676574206D65747573206E656320617567756520626962656E64756D20706C6163657261742E20566976616D75732074656D7075732E205072616573656E7420636F6E677565206F726E61726520697073756D2E20457469616D206D61747469732066657567696174206A7573746F2E0A0A416C697175616D206475692E2041656E65616E20636F6D6D6F646F20746F72746F72207669746165206E756C6C612E204D6F72626920657420697073756D2E204D617572697320616320697073756D2E204E616D2076656C207269737573207574206C6563747573206D6F6C6C697320766976657272612E2043757261626974757220656C656D656E74756D206D6F6C6C6973206573742E204E756C6C616D20656C69742E20566573746962756C756D207375736369706974207072657469756D20656E696D2E20566573746962756C756D207574206D617373612E2050726F696E206E65632066656C69732E204D616563656E617320677261766964612C2061726375206E656320636F6E7365717561742073616769747469732C2065726F732074656C6C7573207363656C65726973717565206D61757269732C20766974616520616363756D73616E207175616D207175616D207574206E756E632E20496E7465676572206567657420616E74652065752076656C6974206C616F72656574206D616C6573756164612E204E756E632073616769747469732C206D617572697320766974616520706861726574726120766F6C75747061742C2074656C6C75732074656C6C757320656C656966656E642065726F732C2073697420616D65742072757472756D20697073756D206E69736920612076656C69742E205072616573656E7420766172697573206C656F20657520657261742E20566976616D757320636F6E73657175617420706C6163657261742070757275732E20446F6E6563207072657469756D20656C656D656E74756D206E6962682E2050726F696E20617420656C6974206E6F6E2073656D20616C6971756574206D61747469732E2053656420756C6C616D636F7270657220697073756D2073697420616D657420656C69742E0A0A4D617572697320696E206D657475732E2053757370656E6469737365206D61676E61206C6F72656D2C2066617563696275732076656C2C2074696E636964756E7420717569732C207363656C65726973717565206E6F6E2C2074656C6C75732E2046757363652071756973206C6F72656D2E2050726F696E2061206C616375732073697420616D6574206D617572697320696163756C69732070756C76696E61722E2053757370656E64697373652072686F6E6375732065726F73206E6563206D692E205072616573656E7420657569736D6F642C207475727069732076697461652072757472756D207072657469756D2C206F64696F206D6574757320766F6C7574706174206E657175652C20656765742074656D7075732073617069656E206E657175652073656420657261742E20446F6E6563206665726D656E74756D207075727573206174206C65637475732E204E756C6C616D2073656D2E2046757363652076656C206D6920717569732065726174206C6F626F7274697320706F73756572652E2041656E65616E20656765742075726E612E2053757370656E6469737365206C6967756C612E204475697320696E206E6973692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A4375726162697475722076756C707574617465206C656374757320696420706564652E2050686173656C6C75732065752076656C69742E20457469616D2076656E656E617469732061646970697363696E67206E6962682E20416C697175616D206375727375732070756C76696E61722074656C6C75732E20566573746962756C756D206E657175652E204D6175726973206E6563206A7573746F20657420657261742073656D7065722070656C6C656E7465737175652E204675736365206D61747469732064696374756D20646F6C6F722E20457469616D2065676574207075727573206575206D617373612076617269757320656C656D656E74756D2E2050656C6C656E746573717565206D617373612E20557420756C74726963696573206469616D2073656420697073756D2E204E756C6C616D206469616D2E2050656C6C656E746573717565206964206D61676E61206964206C696265726F2074726973746971756520616C697175616D2E0A0A557420656C656966656E642C20707572757320696420706C6163657261742076656E656E617469732C2075726E6120617567756520616C6971756574206C6967756C612C20696E20756C74726963696573206C656F2072697375732065742074656C6C75732E204D6175726973206574206E756C6C612069642075726E61207472697374697175652074656D7075732E20557420666163696C697369732C2075726E6120657520766573746962756C756D2072686F6E6375732C206C616375732065726F7320636F6E736563746574756572206D657475732C2065742072757472756D20647569206C656374757320696E2070757275732E204E756E632076656C206E69736C206E6F6E20697073756D2074696E636964756E74206D6F6C6C69732E204E616D207175616D206C616375732C206F726E6172652076697461652C2072686F6E637573206E6F6E2C20636F6E677565207365642C206F64696F2E2050726F696E206E696268206475692C20706F7274612076656C2C2076656E656E61746973206E6F6E2C2070656C6C656E7465737175652075742C206E6973692E20536564207472697374697175652066656C69732061206D61676E612E2053757370656E646973736520656765742074656C6C75732E2043726173206772617669646120696D706572646965742076656C69742E20496E74656765722068656E6472657269742072697375732E2050726F696E206F7263692E20416C697175616D20756C6C616D636F72706572206D61757269732071756973206D61757269732E204E756E63206C6163696E696120766573746962756C756D206D657475732E20447569732074656C6C75732E204E756C6C616D2066617563696275732C206C656F2061632076756C70757461746520736F6C6C696369747564696E2C206C656F20646F6C6F7220666175636962757320657261742C207175697320626962656E64756D206F726369206F64696F206E6F6E20617263752E0A0A4E756C6C616D20616363756D73616E206D617474697320646F6C6F722E20446F6E6563206574206475692E205072616573656E7420612066656C6973206D6F6C6C6973206C616375732073656D706572206C6163696E69612E204375726162697475722070656C6C656E746573717565206C7563747573206573742E2050726F696E206E756C6C61206475692C20636F6E64696D656E74756D2076656C2C206661756369627573206E6F6E2C20696E74657264756D2061632C20657261742E204D616563656E6173207363656C657269737175652C206C656374757320696420766F6C757470617420616363756D73616E2C2073617069656E20746F72746F722070656C6C656E746573717565206475692C207365642073656D706572206D61676E612073656D207574206C656F2E2050726F696E206E756C6C612E204E756C6C616D206461706962757320756C6C616D636F727065722073656D2E2053757370656E6469737365207665686963756C61206D6574757320696E206E756E632E2050656C6C656E746573717565206E6F6E207175616D2076656C206172637520756C74726963657320756C6C616D636F727065722E2050686173656C6C757320717569732066656C69732073697420616D65742074656C6C757320756C6C616D636F72706572206665726D656E74756D2E20536564207665686963756C6120736F6C6C696369747564696E2075726E612E20437572616269747572207068617265747261207363656C657269737175652072697375732E2050656C6C656E746573717565206964206D617373612071756973206D6574757320616C697175616D20696D706572646965742E20496E206E756E63206C616375732C206665756769617420696E2C206772617669646120656765742C2076656E656E617469732075742C2074656C6C75732E2053757370656E646973736520706F74656E74692E204E616D20636F6E7365717561742061646970697363696E67206475692E20496E206E756C6C61206E6973692C20666575676961742075742C206665726D656E74756D2076656C2C2067726176696461206E65632C20746F72746F722E20496E207365642061756775652E0A0A457469616D20756C6C616D636F7270657220617567756520617420656E696D2E20496E7465676572206469676E697373696D2E20416C697175616D2070756C76696E617220636F6E677565206E756C6C612E204D6F72626920656E696D206D617373612C206672696E67696C6C6120612C20616363756D73616E20656765742C20636F6E64696D656E74756D206E65632C20657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2041656E65616E2070686172657472612E20457469616D20706F72747469746F722070757275732061206D657475732E20416C697175616D20696E74657264756D2073656D2065676574206A7573746F2E205175697371756520766F6C7574706174206C7563747573206573742E2041656E65616E2061756775652E2050686173656C6C757320647569206C65637475732C20756C747269636573206E65632C20636F6D6D6F646F2076656C2C20617563746F722076656C2C206E6973692E20557420756C7472696365732070656C6C656E746573717565206E6973692E20496E74656765722061632076656C69742065742073656D20696D70657264696574206C75637475732E20467573636520766974616520747572706973206964206175677565206D6F6C6C697320636F6E7365637465747565722E0A0A4D616563656E6173206E6563206C616375732E204D616563656E617320636F6E64696D656E74756D206F64696F2065752066656C69732E204D6175726973207574206E69736C207669766572726120657261742066617563696275732061646970697363696E672E20457469616D20656765737461732E204E756E6320657420646F6C6F72207669746165207269737573206469676E697373696D20636F6D6D6F646F2E204D6F726269206C65637475732076656C69742C2074696E636964756E74206E65632C20616C69717565742076656C2C206D61747469732076697461652C206C6967756C612E204D616563656E617320756C747269636965732073656D70657220646F6C6F722E2053757370656E6469737365206D616C6573756164612E20496E7465676572206D617474697320656C69742E20446F6E656320616363756D73616E2C206C6163757320666163696C69736973207661726975732074656D7075732C206E756C6C6120656C697420706F72746120657261742C2065742072757472756D20656C69742073656D2073697420616D6574206475692E0A0A4D616563656E6173206D6F6C6C6973206D69206E6F6E206E756C6C612E20566976616D7573207475727069732E2053757370656E64697373652061206D657475732E20496E2071756973206D6920696E2074757270697320636F6E67756520617563746F722E204D616563656E6173206C616375732E2053757370656E646973736520736F6C6C696369747564696E2E2050686173656C6C757320706F727461206E756E63206E6F6E206E69736C2070756C76696E617220656765737461732E20536564206E756C6C612E20566573746962756C756D206163206D692E204D617572697320756C7472696369657320636F6E64696D656E74756D206E657175652E204E756C6C612074656D707573206A7573746F2076656C206D617373612E204E756C6C6120737573636970697420636F6E67756520617263752E205072616573656E74206964207475727069732E204D6175726973206E69626820706564652C20657569736D6F642073656D7065722C206D6F6C65737469652061632C2072686F6E6375732076697461652C20616E74652E204D616563656E617320657261742066656C69732C207669766572726120736F6C6C696369747564696E2C20736167697474697320656765742C2070656C6C656E746573717565206E65632C206F7263692E20467573636520756C74726963657320636F6E736571756174206C616375732E20416C697175616D2065726174206D61676E612C20666575676961742061742C207669766572726120612C206D6F6C6C6973206E6F6E2C207475727069732E0A0A446F6E6563206D692E204E616D2064696374756D2070656C6C656E7465737175652073656D2E20446F6E6563206D6F6C6C69732072686F6E63757320656C69742E2050686173656C6C75732072686F6E63757320706564652073697420616D65742072697375732E20446F6E656320656765742061756775652E204D616563656E6173206E6F6E206C65637475732E2050686173656C6C757320736F6C6C696369747564696E206E697369206E65632066656C69732E20416C697175616D207072657469756D2C2065737420656765742073656D70657220636F6E76616C6C69732C206E696268206E756E6320736F6C6C696369747564696E2070757275732C2069642074656D706F722070656465206475692076656C206D61676E612E20566976616D7573206163206C6F72656D2E20457469616D206E69736C20746F72746F722C2061646970697363696E672064696374756D2C20656C656D656E74756D20696E2C20666163696C69736973207365642C206E6962682E2050726F696E206D61757269732E2050726F696E2072757472756D206D6173736120656765742073656D2E204375726162697475722074656D706F722061646970697363696E6720656C69742E204375726162697475722070757275732074656C6C75732C206665726D656E74756D20656765742C20616C69717565742076697461652C20636F6E76616C6C69732061632C206D61757269732E0A0A496E746567657220636F6E7365717561742076656C69742065752065726F732074696E636964756E74207665686963756C612E204E756C6C616D206C6F72656D2073617069656E2C2072686F6E637573206E6F6E2C206D617474697320717569732C20756C747269636965732073697420616D65742C20656E696D2E2043757261626974757220636F6D6D6F646F2C206C696265726F20696E20657569736D6F642073757363697069742C2073656D207075727573206672696E67696C6C6120656E696D2C206163206D6F6C657374696520746F72746F72206F7263692065742076656C69742E20446F6E656320706564652E20457469616D20706C61636572617420636F6E64696D656E74756D207475727069732E2050686173656C6C7573206567657374617320656E696D206E6563206D61676E612E20566976616D757320636F6E64696D656E74756D2C206E756C6C612076656C206C7563747573207472697374697175652C2065726F7320726973757320766573746962756C756D206E756C6C612C20696E207665686963756C61206172637520697073756D2061742066656C69732E20446F6E656320616C697175616D20656C69742061742061756775652E205175697371756520612065726F73206575206C6967756C6120616363756D73616E2064696374756D2E20457469616D207665686963756C61207475727069732071756973206C696265726F2E20416C697175616D206E6F6E206D692E20446F6E6563206574206C656F2E2050726F696E206C656F206C696265726F2C20616C697175616D2074696E636964756E742C20636F6E677565206E65632C2061646970697363696E6720706F7274612C20656E696D2E204E756C6C61206C6F626F727469732C20746F72746F722073697420616D657420696D7065726469657420756C6C616D636F727065722C20646F6C6F72206F726369206D616C65737561646120706564652C207365642067726176696461206E6962682075726E612076656C206C6F72656D2E20536564207068617265747261206D616C6573756164612065726F732E205175697371756520657569736D6F6420616C697175657420657261742E2053757370656E646973736520616C6971756574206D61747469732070757275732E0A0A4E756E63206964206E756C6C612071756973206A7573746F20636F6E67756520736F6C6C696369747564696E2E205072616573656E742065726174207475727069732C2072686F6E6375732065752C207072657469756D2065752C2070656C6C656E74657371756520612C206E6962682E20566976616D75732074656D7075732E2043726173206E65632072697375732061742074757270697320696D70657264696574206C6F626F727469732E205574206D61747469732E204D616563656E6173206573742066656C69732C2070656C6C656E746573717565206E6F6E2C20696D70657264696574207365642C20656C656966656E642074696E636964756E742C206C6F72656D2E20496E2074696E636964756E742E205365642076656C206C656F2E20446F6E65632065742075726E6120696E207475727069732068656E64726572697420626C616E6469742E20446F6E656320636F6E64696D656E74756D20616363756D73616E206573742E2055742070686172657472612C206D65747573207669746165206D617474697320636F6E7365637465747565722C206C656F207175616D2076756C707574617465206F64696F2C206E6563206C616F72656574206E6973692076656C697420657520657261742E20496E7465676572206C65637475732061756775652C206567657374617320696E2C20696E74657264756D2065752C2076656E656E617469732076656C2C2073617069656E2E2051756973717565206574206573742076697461652065726F73206C616F72656574206C6F626F727469732E204E756C6C616D207574207269737573206E6F6E206E756C6C6120706C6163657261742061646970697363696E672E205072616573656E7420646170696275732E20457469616D20612066656C69732E20557420736F64616C657320636F6E736571756174206D61757269732E2044756973206C6F72656D2066656C69732C206C756374757320612C2074726973746971756520696E2C206D6F6C65737469652061742C2072697375732E20536564207665686963756C6120626962656E64756D2074656C6C75732E204E616D20636F6E73657175617420657569736D6F64206C616375732E0A0A41656E65616E20746F72746F7220656C69742C2067726176696461206E65632C206665726D656E74756D2065752C206C6F626F727469732069642C20697073756D2E204D616563656E61732065752070757275732E204372617320616320747572706973207574206E69736920696163756C69732072686F6E6375732E204E756C6C61207075727573206D657475732C206469676E697373696D206E65632C2074696E636964756E742076697461652C20646170696275732065752C206E6962682E204675736365206C6F626F727469732C206E756E63206174207669766572726120656C656966656E642C206A7573746F20747572706973207363656C657269737175652065726F732C2061632070656C6C656E746573717565206D65747573206E69736C2061742070757275732E2053656420656C656D656E74756D2074656C6C75732073656420656E696D20696E74657264756D20626C616E6469742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E746567657220756C7472696369657320616C6971756574206F64696F2E204D61757269732065676574206E756E63206120697073756D20756C74726963657320736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2041656E65616E20616363756D73616E2E20446F6E65632073617069656E206C65637475732C20636F6E6775652061742C20706F7274612069642C2068656E6472657269742076697461652C206E69736C2E204375726162697475722076656C207175616D2076656C206E6571756520616363756D73616E206C616F726565742E204D6F7262692073617069656E206573742C207072657469756D20696E2C20636F6E7365637465747565722061632C206D6F6C6C69732075742C206C696265726F2E20446F6E65632074696E636964756E742061646970697363696E67206D657475732E204E756E6320766573746962756C756D20656765737461732061756775652E20446F6E6563207363656C65726973717565206475692075742073656D2E2053757370656E64697373652076656C206D6574757320696420657374206D6F6C657374696520696163756C69732E0A0A566976616D75732070686172657472612C20656C6974206575206D616C65737561646120626C616E6469742C206469616D20746F72746F72206D6F6C6C6973206475692C207365642070756C76696E6172206D61737361206E756E63206574206D61676E612E2053656420706C61636572617420656C697420617563746F7220746F72746F722E204E756C6C6120616320657261742E2050656C6C656E74657371756520636F6E7365637465747565722C2064756920636F6E76616C6C69732074696E636964756E7420636F6E64696D656E74756D2C2073656D206F64696F20766F6C7574706174206C696265726F2C206E6F6E20656C656D656E74756D2066656C6973206E65717565206E6563206F64696F2E204D616563656E61732068656E6472657269742065726F73206964206469616D2E204D61757269732076656C207075727573206163206F72636920636F6E76616C6C697320636F6E76616C6C69732E205365642073697420616D6574206C616375732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652064696374756D20766172697573206C616375732E204D61757269732065676574206E69736C2E2053757370656E646973736520706C6163657261742C206E756C6C61206E6F6E206F726E617265206469676E697373696D2C206E69736C206469616D2073616769747469732074656C6C75732C20696E2073656D706572206E69736920646F6C6F72206174206E6962682E204475697320756C6C616D636F7270657220766976657272612066656C69732E20496E746567657220612074656C6C75732E2053757370656E64697373652065676574206E756E632E2041656E65616E206469616D206573742C20616363756D73616E2069642C20737573636970697420696E74657264756D2C206672696E67696C6C612076697461652C206A7573746F2E2050726F696E20706564652E204D616563656E6173206174206E6571756520696E206E6571756520766573746962756C756D20656C656966656E642E0A0A566573746962756C756D206E756C6C61206C6F72656D2C20706F72747469746F7220656765742C20657569736D6F642061632C20616C697175616D2061742C206E69736C2E204D616563656E6173206574206573742065676574206D6173736120766172697573206C6F626F727469732E20496E206D692E204475697320706F72747469746F72206665726D656E74756D2070757275732E20446F6E65632063757273757320696D70657264696574206C6967756C612E204D6F726269206574206C6967756C6120657420616E7465206D6F6C6573746965207665686963756C612E204D61757269732073656420646F6C6F722E2053656420696D706572646965742066656C69732075742073656D2E20536564207669746165206E6571756520656C656D656E74756D206C656F20617563746F72206665726D656E74756D2E2044756973206665756769617420756C6C616D636F7270657220657261742E2041656E65616E2070757275732E204D6F726269206665726D656E74756D20766573746962756C756D206573742E2050656C6C656E7465737175652076656E656E61746973206D61757269732E2050686173656C6C75732070756C76696E61722E20496E746567657220697073756D206C65637475732C20696163756C697320612C206C6163696E69612069642C20616363756D73616E2069642C20617263752E2050686173656C6C7573206174206573742E204675736365206E65717565207175616D2C20756C747269636965732069642C20696163756C69732076656C2C20646170696275732076697461652C206C616375732E20496E206C6F626F7274697320636F6E76616C6C697320616E74652E204E756C6C61206E756E632070757275732C2076756C70757461746520696E2C2068656E6472657269742065742C20626C616E6469742065742C206C6967756C612E0A0A50656C6C656E746573717565206C656F206D657475732C20736167697474697320696E2C206D6F6C65737469652076697461652C2064696374756D20696E2C20706564652E204D6F726269207072657469756D2066656C6973206E6563207175616D2E2050656C6C656E746573717565206D617474697320616E746520736564207175616D20736167697474697320646170696275732E2053757370656E64697373652073617069656E2E205072616573656E7420626962656E64756D20696163756C697320746F72746F722E20447569732061206E69736C2E2041656E65616E206D692E20446F6E65632064696374756D206172637520696E206573742E204D6F72626920696E74657264756D2076756C70757461746520697073756D2E2041656E65616E2073697420616D6574206D61676E61206E6F6E206E69736C2074726973746971756520706F73756572652E2050686173656C6C75732076656C6974206D657475732C2074656D706F722061632C206665726D656E74756D20656765742C20636F6E64696D656E74756D206E6F6E2C2076656C69742E20566573746962756C756D2073697420706F73756572652E0A0A4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204372617320616C6971756574206D61737361206E6563206475692E20437261732061726375206E756E632C2068656E6472657269742061632C20656C656966656E642065752C20756C6C616D636F72706572206E65632C2074656C6C75732E205365642070686172657472612070757275732073697420616D6574207175616D2E20437572616269747572206D6F6C6C69732E204E616D20766974616520706564652E20457469616D207269737573206D617373612C207665686963756C612073697420616D65742C207068617265747261206E65632C20736F6C6C696369747564696E2075742C206475692E20446F6E65632065676573746173206A7573746F206174207175616D2E2050726F696E206E69736C2072697375732C20766573746962756C756D206E65632C207072657469756D2076697461652C207472697374697175652061632C206C6F72656D2E20416C697175616D206572617420766F6C75747061742E204372617320736564206E6962682E2050656C6C656E74657371756520736F6C6C696369747564696E20657569736D6F642061756775652E0A0A457469616D206672696E67696C6C6120736F6C6C696369747564696E206F7263692E204D61757269732063757273757320656C69742071756973206C616375732E204372617320746F72746F722E20496E2061646970697363696E672C206C656374757320696420617563746F7220766573746962756C756D2C206E65717565207065646520616363756D73616E20646F6C6F722C206E6F6E20696D70657264696574206D61676E61206469616D20616363756D73616E2076656C69742E2053757370656E6469737365206174206C696265726F207574206E69736920626C616E6469742073616769747469732E2050686173656C6C7573206E6F6E206D61757269732E20467573636520656C656D656E74756D2073616769747469732073656D2E2053757370656E646973736520616C697175616D20656C656966656E642074656C6C75732E2050726F696E206C6967756C61206C6F72656D2C20696D7065726469657420717569732C2076656E656E617469732069642C20696163756C6973206D6F6C6C69732C206E69736C2E20457469616D20636F6E76616C6C69732070656465206174206D617373612E204D6F72626920616363756D73616E20647569206574206D61757269732E0A0A53656420736564206F7263692E204E756E632070757275732E2053757370656E646973736520706F74656E74692E205574206C7563747573206672696E67696C6C61206D61757269732E20446F6E6563206E6962682E2050686173656C6C757320706F7274612E2050686173656C6C75732073697420616D6574206F64696F20736564206D61676E6120736F64616C65732070686172657472612E2043726173206C65637475732E2053757370656E6469737365206C696265726F20697073756D2C20636F6D6D6F646F206E65632C20666163696C6973697320696E2C207375736369706974206C6F626F727469732C206C6967756C612E2044756973206D61737361206E756C6C612C2073656D7065722065742C20636F6E736571756174206E65632C2070686172657472612065752C20656C69742E20566976616D757320756C7472696369657320616C697175616D206F64696F2E20566573746962756C756D2073697420616D6574206D617373612E2053656420636F6E736571756174206C61637573207365642075726E612E20457469616D2066617563696275732066656C69732076656C206F7263692E2050686173656C6C757320756C6C616D636F727065722E2041656E65616E20636F6E736563746574756572206C61637573206174206C696265726F2E0A0A436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204475697320666163696C697369732C206C6967756C6120766974616520636F6E64696D656E74756D207363656C657269737175652C2076656C6974206F72636920677261766964612066656C69732C2076656C20756C74726963696573207175616D206D69206E6F6E206469616D2E20566976616D757320617563746F72206D65747573206E6F6E206C696265726F2E205072616573656E74206C6967756C61206E6973692C20636F6D6D6F646F20636F6E64696D656E74756D2C206D6F6C65737469652065742C20766976657272612065742C206A7573746F2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320736F6C6C696369747564696E2E204E756E6320626C616E6469742063757273757320697073756D2E2041656E65616E206E6563206C6967756C612075742074656C6C757320736F64616C6573206D61747469732E20496E74656765722073656D2E20416C697175616D206964206C6967756C612E2053656420746F72746F72206D61757269732C20626C616E6469742076697461652C206375727375732076656C2C20656C656D656E74756D2065742C206E756C6C612E20416C697175616D207363656C65726973717565206D65747573206574206E69736C2E20447569732061646970697363696E67206D61676E61206174206E657175652E20517569737175652076756C70757461746520656C656966656E64206E756E632E20416C697175616D206567657420656C69742E2050686173656C6C757320647569206F64696F2C20626962656E64756D2073616769747469732C20766573746962756C756D2069642C206469676E697373696D20696D706572646965742C206F7263692E204E756C6C616D2065752066656C6973206E6F6E206E756E63206C6163696E696120736F64616C65732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A53757370656E64697373652070656C6C656E7465737175652C206C696265726F206D617474697320756C7472696369657320616363756D73616E2C20746F72746F7220746F72746F72206D616C6573756164612073656D2C20657420736F64616C6573206C696265726F206F64696F20616320697073756D2E20566976616D75732071756973206D61676E61206E656320657374207375736369706974206C6F626F727469732E20437261732074656D70757320706F7375657265206E756E632E205175697371756520757420656E696D20612066656C697320656765737461732073656D7065722E20536564207068617265747261206D6174746973206E657175652E20467573636520747572706973206E756E632C20636F6E677565207365642C20636F6E736571756174206E6F6E2C20636F6E677565207365642C206E756C6C612E2053757370656E646973736520766172697573206C6F72656D20696420726973757320706F72746120766573746962756C756D2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204675736365207365642070757275732E20496E20612066656C69732E20496E7465676572206567657374617320617563746F72206F7263692E204D617572697320756C747269636573207375736369706974206E69736C2E204E756C6C616D2070757275732E0A0A437261732074656D706F722061646970697363696E6720697073756D2E2055742071756973206D692E204D616563656E617320696E206A7573746F207574206E756C6C6120636F6E6775652070686172657472612E2050656C6C656E746573717565207574206C696265726F20657520646F6C6F722076656E656E617469732073757363697069742E205072616573656E74206665756769617420636F6E736563746574756572206E6962682E204D6F7262692066617563696275732073656D206E6F6E2066656C69732E20496E2068656E6472657269742061726375206163206D617373612E20496E20616363756D73616E20756C747269636573206D692E2050726F696E206D616C65737561646120617563746F722066656C69732E2043757261626974757220696E74657264756D2E20536564206469616D20697073756D2C20756C7472696369657320696E2C2074656D706F722073697420616D65742C207669766572726120696D706572646965742C20656C69742E204D6F726269206D6F6C6573746965206E6973692E204D617572697320697073756D2E2046757363652064696374756D206D6F6C6C6973206D61676E612E204475697320636F6D6D6F646F206469676E697373696D206E756C6C612E20566573746962756C756D20617567756520656E696D2C20756C7472696369657320717569732C20696163756C6973206E65632C2074696E636964756E742076697461652C206469616D2E204D6175726973206C6163696E69612074656D70757320697073756D2E20536564206174206D61757269732E205574206C6F72656D2E20446F6E6563206C696265726F2E0A0A4475697320696163756C6973206C6163696E6961206C65637475732E2041656E65616E20636F6E76616C6C69732065726F7320616320616E74652E205365642071756973206F726369206E656320726973757320617563746F72206672696E67696C6C612E2050686173656C6C757320666163696C6973697320656C656D656E74756D206E6973692E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E6320706F727461206C61637573206E656320616E74652E204D6F726269206D617572697320657261742C2061646970697363696E6720696E2C2070756C76696E6172206E65632C206C6F626F72746973206E65632C206F64696F2E20557420656C656966656E64206C656374757320736564207175616D2E204E756C6C616D206D6F6C6C69732E20496E206E6F6E20747572706973206574206E69736C2068656E64726572697420626C616E6469742E204475697320656C656D656E74756D2E204E756E63206E6563206C696265726F2E2053757370656E646973736520766573746962756C756D207269737573206E6F6E20706564652E204D6F72626920696D70657264696574206F64696F2073697420616D6574206C696265726F2E2053656420736564206D6173736120766974616520697073756D206D61747469732074696E636964756E742E204E756C6C61206E656320746F72746F72207669746165206C696265726F20766F6C75747061742074656D7075732E20446F6E656320616C697175616D2E0A0A4475697320736564206E756E632E2043757261626974757220747572706973206E756C6C612C207665686963756C61207365642C206C756374757320717569732C20656C656D656E74756D20656765742C2066656C69732E204D616563656E61732065742070757275732E204D616563656E6173206C656F2074656C6C75732C2074696E636964756E7420612C20666163696C697369732076697461652C206C6F626F727469732073697420616D65742C2076656C69742E20446F6E656320636F6E76616C6C69732073617069656E2E204D616563656E6173206D6F6C6C6973206F64696F206575206E6962682E20457469616D20677261766964612E20496E7465676572206D6F6C65737469652C2073617069656E206575206D6F6C6573746965206C6163696E69612C206E756E63206E69626820616C697175616D206C6967756C612C2065752073616769747469732074656C6C7573206572617420736F6C6C696369747564696E206F64696F2E20447569732065742072697375732E2050686173656C6C7573206E697369206E657175652C20706C616365726174206E65632C20636F6E64696D656E74756D206E6F6E2C20756C7472696365732065752C2073656D2E20557420706564652E20457469616D206E756C6C61206D657475732C20766F6C75747061742069642C20636F6E76616C6C6973207365642C2073757363697069742076656C2C2075726E612E20446F6E65632076656C20656C69742E205574206C656F206E657175652C2076656E656E617469732066617563696275732C206C6163696E6961206E65632C2074696E636964756E742065752C20656E696D2E2043726173206964206475692061206C696265726F207068617265747261206469676E697373696D2E20446F6E65632065726F73206C656F2C20706F72746120717569732C206C616F726565742075742C2070656C6C656E74657371756520766F6C75747061742C206C65637475732E0A0A4E756C6C616D20626C616E6469742E20416C697175616D206572617420766F6C75747061742E2046757363652061646970697363696E6720656E696D2E2053757370656E6469737365206E6F6E206475692071756973206C6967756C6120706F72746120766573746962756C756D2E20446F6E65632065752074656C6C75732076656C206C6F72656D207072657469756D20706F72747469746F722E205072616573656E74206C75637475732E20416C697175616D2061632065726F7320696E206D6173736120646170696275732074696E636964756E742E20446F6E6563207574206D61676E612E20457469616D20617563746F72206C616375732073697420616D6574206C616375732E2053656420756C7472696369657320697073756D206E656320656C69742E205175697371756520612065737420696E207075727573207375736369706974207472697374697175652E0A0A41656E65616E20736564206475692076656C20646F6C6F722070756C76696E6172206C616F726565742E20566976616D7573207665686963756C61206C6F72656D20696E20706564652E20566976616D7573206574206469616D2E20496E7465676572206163206F64696F2076656C206469616D2068656E64726572697420626962656E64756D2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E756C6C612061206E6973692E2050686173656C6C75732074696E636964756E74206475692076697461652061756775652E20447569732066617563696275732C2064756920696E74657264756D206672696E67696C6C612074696E636964756E742C206F64696F20656C697420766573746962756C756D206C696265726F2C206163206D6F6C6573746965206D61676E61206C6563747573206964206C616375732E2041656E65616E206C6967756C612E204E756C6C6120666163696C6973692E0A0A46757363652076656C2073656D2065752076656C6974206672696E67696C6C61206F726E6172652E2053656420666575676961742074696E636964756E742066656C69732E204E756C6C616D2066656C6973206D692C20657569736D6F642073697420616D65742C206D6F6C6C69732061742C20736F64616C657320656765742C2061756775652E204E616D20696D70657264696574206E6962682061742076656C69742E2053656420757420657261742E20496E206475692E204E756C6C6120666163696C6973692E204E756C6C616D206175677565206C696265726F2C2074696E636964756E74206E65632C207072657469756D2065752C2070756C76696E617220696E2C206475692E204D6F7262692076697461652066656C69732E2050656C6C656E7465737175652076656C206A7573746F2076656C2076656C6974207361676974746973206D616C6573756164612E2050726F696E207665686963756C6120626C616E646974206D617373612E20457469616D2074696E636964756E742070686172657472612075726E612E20496E206D65747573206573742C20617563746F72206E65632C20626C616E64697420612C20637572737573206E65632C207175616D2E204D6175726973206163206D657475732061206C696265726F20636F6E6775652066617563696275732E204D6175726973206D617572697320646F6C6F722C20736F64616C657320696E2C206375727375732075742C20736F64616C65732072757472756D2C2065726F732E2051756973717565206D61757269732065726F732C2073616769747469732076697461652C206C6F626F727469732075742C20656C656966656E642069642C206E6973692E0A0A41656E65616E206E657175652E20566573746962756C756D20656765737461732070656C6C656E746573717565206C6967756C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2050686173656C6C7573207361676974746973206A7573746F2076656C2072697375732E20536564207072657469756D206E657175652076697461652075726E612E2050656C6C656E74657371756520636F6E677565206C696265726F206964206C6F72656D2E204D6175726973206C656F206C6F72656D2C20626C616E6469742073697420616D65742C20636F6E76616C6C697320717569732C20636F6E736563746574756572207365642C2065726F732E204D61757269732074696E636964756E742C20656E696D2061206772617669646120657569736D6F642C206D61676E61206E756C6C61206665726D656E74756D206C696265726F2C207669766572726120656765737461732076656C6974207175616D20657420746F72746F722E20566976616D757320616C6971756574206D61737361207669746165206A7573746F2E204E756C6C6120636F6E677565206C6163757320616320656C69742E0A0A50686173656C6C757320636F6D6D6F646F207175616D2076656C206C6967756C612E2050726F696E206E6F6E206D657475732061742065726F732070756C76696E6172206C75637475732E204D6175726973206469616D206C6F72656D2C20706F737565726520717569732C20677261766964612065742C2074696E636964756E74206E65632C206C6967756C612E20536564206469616D2E20416C697175616D20656C6974206C65637475732C2068656E6472657269742075742C20696D706572646965742073697420616D65742C207072657469756D2073697420616D65742C20697073756D2E204D6175726973207665686963756C61206E69736C20696E206475692E204375726162697475722065676574207175616D207574206D61676E6120656C656D656E74756D206665726D656E74756D2E204D6175726973207363656C657269737175652E2051756973717565206C616F726565742E20457469616D2074656D707573207475727069732E2050656C6C656E746573717565206175677565207175616D2C2068656E647265726974207365642C2074696E636964756E742061742C2070686172657472612061742C206E69736C2E20416C697175616D206C616375732E2053757370656E646973736520706F74656E74692E2041656E65616E2076656C6974206C696265726F2C20756C74726963657320696E2C206C6163696E69612065752C206C75637475732076656C2C20616E74652E20457469616D2064696374756D206D6920696E2066656C69732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20467573636520677261766964612064617069627573206E69736C2E2043726173207669746165206E69736C2E0A0A4D616563656E6173206469676E697373696D2C206C6967756C61206E6F6E20706F727461206375727375732C20656E696D206E756E63206D616C6573756164612073656D2C20657520706F72747469746F72206E756C6C612075726E61206575207175616D2E2046757363652065726F732E20416C697175616D2065726F732E204E616D20617563746F722E204E756C6C61206D6F6C657374696520706F727461206573742E2053757370656E646973736520706F74656E74692E20566976616D7573206D6F6C6573746965206C6F72656D2073656420657261742E20536564206567657420697073756D2E20496E746567657220616C697175616D2070756C76696E6172206E756C6C612E204372617320616C69717565742073656D207574206E756E632E2046757363652066617563696275732074656D707573206C65637475732E204372617320736F64616C65732C206E69736920616320666163696C6973697320756C7472696365732C2065726F73206172637520646170696275732073617069656E2C20657420756C747269636573206D61757269732074656C6C7573206E6F6E20646F6C6F722E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20437261732063757273757320766172697573206D657475732E205574207475727069732E20566976616D7573206567657420746F72746F722E0A0A536564206C616F726565742C2076656C6974206E6F6E20616363756D73616E206375727375732C206E756E632075726E6120706F7375657265206A7573746F2C20696E2064696374756D206C6563747573207065646520696420616E74652E20437261732076756C7075746174652E204372617320636F6E677565206475692073656420656C69742E2050726F696E206C616375732073656D2C20756C7472696365732061742C20636F6E73657175617420696E2C2074656D706F7220717569732C206D657475732E2050726F696E2076656C20617263752E204E616D20657569736D6F642068656E64726572697420656C69742E20557420657261742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2053656420706F73756572652E204D6F7262692065726F732075726E612C2073656D7065722061742C2073656D706572206E6F6E2C20636F6E76616C6C697320717569732C2076656C69742E204D616563656E6173206F7263692E20566573746962756C756D206C6F626F7274697320747269737469717565206D657475732E20566573746962756C756D206C6F72656D206E756C6C612C20736F6C6C696369747564696E2076697461652C20636F6E64696D656E74756D20717569732C20617563746F722075742C206475692E20566976616D757320766573746962756C756D206D61676E61207574206E6973692E2043757261626974757220656C656966656E64206475692076656C206E756E632E20437572616269747572206D6175726973206C616375732C206D616C6573756164612073697420616D65742C207375736369706974207365642C2072757472756D206C75637475732C2074656C6C75732E20496E746567657220666163696C697369732075726E61207669746165206C65637475732E0A0A41656E65616E207175616D206C656F2C206C6F626F7274697320717569732C206D616C6573756164612065752C2076756C7075746174652076697461652C206E69736C2E205072616573656E7420656765742065726F732E205574206665726D656E74756D20747572706973206964207175616D2E204E616D20746F72746F722E205072616573656E74206E6563206F7263692E204E756C6C6120626962656E64756D2061646970697363696E672061756775652E20557420636F6D6D6F646F2C206D61676E61206964206D616C65737561646120677261766964612C206175677565206F64696F206D616C657375616461206D692C20706F727461206D616C65737561646120656C697420657374207669746165206469616D2E204D6175726973206E6F6E206E756C6C612E2053757370656E64697373652074696E636964756E742C206E756E6320756C7472696369657320706F7274612076656E656E617469732C206D6920706564652074696E636964756E74206C696265726F2C20656765742076617269757320616E7465206C696265726F207574206C6967756C612E20437572616269747572207072657469756D20706F72747469746F7220746F72746F722E0A0A4D616563656E617320766974616520656C69742065676574206E69736920646170696275732064696374756D2E204E756E6320696E206C696265726F2E204E756C6C612064696374756D206F726369206575206572617420617563746F72206C6F626F727469732E2050686173656C6C75732072697375732E2053757370656E646973736520706F74656E74692E2053757370656E646973736520706F74656E74692E205072616573656E742061646970697363696E6720636F6E73657175617420656C69742E20496E74656765722069642061756775652E205072616573656E7420696E206A7573746F206E6563206D61676E6120646170696275732070756C76696E61722E2044756973206E69736C2E2053757370656E6469737365206163206F64696F2E20566976616D757320696D706572646965742E20446F6E6563206E6F6E2076656C69742073697420616D6574207269737573206469676E697373696D20636F6E6775652E204E616D20616C697175657420706F73756572652076656C69742E2043726173207475727069732E204D6F726269206D616C657375616461206469676E697373696D206D692E0A0A536564206C656F206E657175652C2076617269757320717569732C2076656E656E61746973207365642C207068617265747261207365642C206573742E204D6F72626920626C616E6469742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D2073656D7065722070656C6C656E746573717565206D692E2055742076656C206C6F72656D2E204E756E63206D6920746F72746F722C206C616F726565742061742C2066617563696275732065752C2074696E636964756E742073697420616D65742C20657261742E20447569732074656D706F72206D616C65737561646120697073756D2E2050686173656C6C757320616C69717565742E20446F6E656320657420656C69742E2050656C6C656E7465737175652070757275732E20566573746962756C756D2072757472756D2073656D706572206E6962682E204E756C6C6120666163696C6973692E2050686173656C6C757320657420656E696D2073697420616D657420616E746520766573746962756C756D207665686963756C612E2050686173656C6C7573206964206E69736C2E20446F6E6563206D6F6C6C6973206C656F2061742065726F732E204D61757269732070656C6C656E746573717565206E657175652061742070757275732E204D6F726269207175697320646F6C6F7220617420697073756D207363656C6572697371756520736F64616C65732E20457469616D20766F6C7574706174207475727069732061206D657475732E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206C6F72656D206C6F72656D2C20766573746962756C756D2061632C20657569736D6F6420656765742C20756C6C616D636F72706572206469676E697373696D2C2076656C69742E0A0A43756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204372617320756C7472696365732C206E6962682076656C20616C697175616D20766573746962756C756D2C2065726F7320656E696D2076656E656E61746973206475692C20696420696163756C697320656E696D206E756E632076656C206D617373612E204D6F72626920656C656966656E64206F726369206574206D617373612E20416C697175616D206572617420766F6C75747061742E204E756C6C61206D6F6C6C69732065676573746173207475727069732E20496E20736F64616C6573206E756E63206567657420746F72746F722E2053656420697073756D2065726F732C2074656D706F7220717569732C20616C69717565742076697461652C20696D70657264696574206E6F6E2C206C6F72656D2E2050656C6C656E746573717565207175697320656C6974206964206D69206C756374757320646170696275732E20536564206E756E6320617263752C2072686F6E637573206E65632C20636F6E76616C6C697320717569732C206375727375732061742C206E657175652E204D617572697320636F6E76616C6C697320707572757320617420657261742E2050656C6C656E74657371756520766573746962756C756D2E20566976616D7573206672696E67696C6C6120656C697420617420617263752E204E756C6C616D20616C697175657420656E696D206E656320617263752E204E616D20696420746F72746F722E204E756C6C612071756973206E756E632E20557420617263752E2053757370656E646973736520706F74656E74692E2050656C6C656E74657371756520756C6C616D636F72706572206C6967756C6120696420617263752E0A0A4E616D206E6F6E206C696265726F207669746165206E69736C207363656C65726973717565206672696E67696C6C612E20517569737175652076617269757320616E7465206964206D657475732072686F6E637573206672696E67696C6C612E204E756C6C6120666163696C6973692E205072616573656E7420656C656966656E6420706F72747469746F72206C6967756C612E20457469616D207175697320646F6C6F72206E6F6E20617567756520636F6D6D6F646F20617563746F722E20446F6E65632061206D692E20566573746962756C756D2074656D706F722E20446F6E65632066656C69732075726E612C20617563746F722061742C206375727375732064696374756D2C20677261766964612069642C20617263752E2041656E65616E2064696374756D206D616C65737561646120646F6C6F722E20566976616D7573206D61747469732E2050686173656C6C757320657520706564652E2046757363652061646970697363696E67206A7573746F206672696E67696C6C61206D657475732E20457469616D20616E74652E20496E7465676572206D6F6C6C6973206D617373612071756973206E756E632E20496E74656765722064696374756D206E65717565206C756374757320656E696D2E0A0A536564206575206C696265726F2E20496E74656765722074656D706F72206C6967756C6120696E2076656C69742E2055742074696E636964756E74206C6163696E69612073656D2E204E756C6C616D2076656C2072697375732E2053656420736F64616C657320616E7465206120646F6C6F722E204375726162697475722065726F732E2053656420736F64616C65732E20536564206E6F6E206D657475732E20566573746962756C756D20656C656D656E74756D20666175636962757320616E74652E204E756C6C612076656C206E6962682E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206E6563206C6F72656D20757420697073756D206C6163696E696120696163756C69732E204475697320657261742E20416C697175616D20657261742E204372617320696163756C69732E20496E206861632068616269746173736520706C617465612064696374756D73742E0A0A4E756C6C616D20616E74652E2043726173207669746165206573742E2050656C6C656E7465737175652076656C206D657475732061206C6967756C612064617069627573206D61747469732E2044756973206665756769617420616C69717565742066656C69732E20457469616D206964206E69736C207175697320657374206469676E697373696D20636F6E64696D656E74756D2E2053757370656E646973736520706F74656E74692E204D6F7262692076656C6974206C6F72656D2C206F726E61726520717569732C2070656C6C656E7465737175652076656C2C20706C61636572617420656765742C20746F72746F722E20566573746962756C756D2074696E636964756E74206D6F6C6573746965206C696265726F2E204E756C6C61206E756C6C6120656E696D2C206D616C6573756164612069642C20756C6C616D636F727065722076697461652C2064696374756D2061742C2070757275732E20446F6E6563206469676E697373696D206F64696F20757420656E696D2E2053757370656E6469737365206174206C65637475732E0A0A5072616573656E74206C6F626F727469732061756775652076656C206C65637475732E20557420696E206C6967756C612075742066656C697320636F6E6775652073757363697069742E2051756973717565206469676E697373696D20746F72746F72207574206D692E204675736365206D61676E61206E6973692C20656C656966656E642061632C206F726E6172652076656C2C20706F72747469746F722076697461652C207175616D2E20566573746962756C756D20736F64616C6573206A7573746F2071756973207475727069732E2046757363652075726E61206E6973692C2072686F6E63757320717569732C20636F6E64696D656E74756D2076656C2C2064696374756D2065752C206E756E632E20467573636520736564206E696268207669746165206F64696F20706F73756572652061646970697363696E672E2053656420706F72746120656C6974207175697320646F6C6F722E204E616D206C696265726F206E756C6C612C20617563746F72207365642C2074696E636964756E7420717569732C2066617563696275732073697420616D65742C206D692E2051756973717565206F7263692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E756C6C616D2069642073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632076656C2065726F732E0A0A566976616D7573206C7563747573206C6F626F72746973206C656F2E2053757370656E64697373652076656C20656C6974206120656E696D20756C6C616D636F7270657220706F73756572652E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20446F6E656320717569732070656465206D6174746973206C6563747573206D6F6C6C69732061646970697363696E672E2053656420616363756D73616E20706F737565726520657261742E205072616573656E7420657569736D6F642074696E636964756E742066656C69732E20446F6E6563206D692E20557420636F6D6D6F646F2061726375206C6163696E69612074656C6C75732E20416C697175616D2061206C696265726F2071756973206C65637475732073656D70657220766976657272612E20437572616269747572206C6163696E6961206D61757269732061742074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E756E632073697420616D6574206D61676E61206D6F6C6573746965206F726369207375736369706974206672696E67696C6C612E204675736365207072657469756D206D65747573206E6F6E2073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642068656E6472657269742E204E756C6C612066656C69732E2053757370656E646973736520706F74656E74692E20416C697175616D20626C616E64697420747269737469717565206E657175652E20437572616269747572207175697320657261742076656C206E756E6320616363756D73616E206D6F6C6C69732E0A0A447569732073616769747469732C2074656C6C757320757420616C697175616D206672696E67696C6C612C20646F6C6F72206D6920756C6C616D636F72706572206E69736C2C20757420747269737469717565207065646520656C697420736564206D61757269732E204375726162697475722069642066656C69732E20446F6E65632070756C76696E6172206C61637573206574206C65637475732E20416C697175616D2076756C7075746174652076756C707574617465206D657475732E20437572616269747572206D61676E612066656C69732C2061646970697363696E672061632C20616363756D73616E2076656C2C206D6F6C657374696520717569732C207175616D2E204D617572697320656C697420617263752C207072657469756D2076697461652C206D6F6C6C69732073697420616D65742C20736F6C6C696369747564696E2075742C206D692E20446F6E656320696D70657264696574206469676E697373696D206D692E204E756C6C616D2073697420616D657420746F72746F722E20416C697175616D206E65717565206E756C6C612C2076656E656E6174697320612C20706F72746120696E2C20706C6163657261742074656D7075732C206C616375732E205175697371756520766573746962756C756D20647569206574206C616375732E2050726F696E206469676E697373696D20636F6E7365637465747565722070757275732E20457469616D206772617669646120746F72746F7220696E206E756E632E2055742074656D706F722074726973746971756520746F72746F722E20536564206C616F726565742074696E636964756E74207175616D2E20566573746962756C756D20706F7274612074757270697320757420656C69742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20446F6E6563206E696268206475692C2066657567696174206E65632C206C616F726565742069642C206D616C65737561646120656765742C206E6973692E205574206E65717565206D617373612C207665686963756C612065752C20636F6D6D6F646F206E6F6E2C20756C747269636965732076697461652C2070757275732E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204D617572697320657569736D6F642C2066656C69732076656C2074656D706F7220616C69717565742C20746F72746F72206D6175726973206D616C657375616461206E756E632C2076656C206665726D656E74756D2073656D206469616D206964206475692E204E616D2072757472756D2073617069656E2065676574206F64696F2E20416C697175616D20736564206C696265726F206E6F6E206D692066617563696275732074656D7075732E2046757363652068656E6472657269742C206469616D206E6F6E20766F6C75747061742072757472756D2C2065726174206D657475732076656E656E61746973206C6967756C612C206E6F6E207363656C657269737175652070656465206C6967756C612076656C207175616D2E204D6F7262692072686F6E6375732065726F7320616320647569206665756769617420656C656D656E74756D2E2044756973206575206C696265726F2065742074656C6C757320636F6E67756520766976657272612E204D6F726269207175616D207175616D2C20656C656D656E74756D207365642C20756C6C616D636F7270657220696D706572646965742C20636F6D6D6F646F206E6F6E2C206F64696F2E204E616D20616C697175657420656765737461732075726E612E204D6175726973206F64696F2066656C69732C207661726975732065752C206C6163696E69612065752C20636F6E64696D656E74756D20612C206C65637475732E20536564206A7573746F206D617373612C2070756C76696E61722069642C2076617269757320612C20706F72747469746F72206E65632C206C696265726F2E20457469616D207661726975732E2043757261626974757220736F64616C65732C206F64696F20617420706F73756572652073656D7065722C2065726F73206E6962682074696E636964756E74206C65637475732C2076656C2072757472756D2073617069656E206E69736920696E206C6967756C612E2053757370656E6469737365206567657420617263752E2050686173656C6C757320696D70657264696574206573742061632073617069656E2E20446F6E6563206E756C6C6120746F72746F722C20706C6163657261742076656C2C2074656D70757320612C206C6F626F727469732076656C2C206E6962682E20416C697175616D20766172697573206E6973692E204E756C6C6120657420656E696D2E20467573636520636F6E76616C6C6973206C616F72656574206C616375732E0A0A50686173656C6C757320697073756D20646F6C6F722C206D6F6C657374696520717569732C20636F6E64696D656E74756D20696E2C20636F6D6D6F646F2065752C206469616D2E205175697371756520626962656E64756D206C6163696E6961206475692E204E756C6C616D20626C616E6469742076756C707574617465206F7263692E205574206C6163696E6961206D617373612076656C2061756775652E20416C697175616D20677261766964612C207175616D207175697320696D7065726469657420696D706572646965742C2074656C6C7573206469616D20706861726574726120657261742C206174207068617265747261206C61637573206E6962682065676573746173206D61676E612E204E756C6C61207361676974746973206C6F72656D207574206C6F72656D2E204475697320636F6E64696D656E74756D2C2064756920766974616520616C697175616D20706F73756572652C206469616D207175616D20636F6E76616C6C69732076656C69742C2075742067726176696461206C656F20697073756D206E6F6E2072697375732E205574206665726D656E74756D20736F6C6C696369747564696E20657261742E20446F6E6563207361676974746973207363656C657269737175652066656C69732E204E756E6320617263752E20457469616D2074656D7075732C206D61676E612073697420616D657420737573636970697420657569736D6F642C2065726F732073656D2072757472756D206475692C207669746165207361676974746973206E696268207075727573206E6F6E206C616375732E20536564206D6F6C6C69732061726375206567657420646F6C6F722E20446F6E6563206F726E6172652C20617263752073697420616D6574206665726D656E74756D2076756C7075746174652C20726973757320656E696D206665726D656E74756D206C696265726F2C2061206C6163696E696120646F6C6F72206D69206E6F6E2076656C69742E20457469616D206C6F626F72746973207075727573206120656C69742E204E756E63206E756C6C61206475692C206D617474697320717569732C20626962656E64756D20612C20756C7472696365732061632C2061756775652E20496E20616C697175616D207665686963756C61207475727069732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A496E7465676572206964206E69736C2E20517569737175652064696374756D20656C656D656E74756D206F64696F2E2041656E65616E206C75637475732E205365642065752073656D206120706564652076756C70757461746520636F6E64696D656E74756D2E2051756973717565206D61676E612E20446F6E656320616C697175616D206D617474697320697073756D2E204375726162697475722064696374756D20736F6C6C696369747564696E2073656D2E20416C697175616D2070756C76696E61722E204E756E6320736F6C6C696369747564696E207269737573206120657261742E20566976616D757320717569732074656C6C75732073697420616D6574206E69626820766573746962756C756D20636F6E7365717561742E204E756C6C61207072657469756D20736F6C6C696369747564696E20646F6C6F722E20416C697175616D20696163756C69732074696E636964756E74207475727069732E2050686173656C6C757320697073756D206C656F2C2076656E656E6174697320696E2C20736167697474697320696E2C206F726E6172652061742C206E756E632E0A0A50656C6C656E74657371756520756C7472696365732C2064756920657520696163756C6973206C75637475732C2074656C6C757320617567756520766F6C75747061742073617069656E2C20696E206469676E697373696D2075726E612066656C6973207574206D692E205365642061726375206475692C206469676E697373696D2069642C20706F72747469746F722075742C20696D706572646965742076697461652C20616E74652E204E756C6C61206475692073656D2C20636F6D6D6F646F206E65632C2073616769747469732065742C206C6163696E69612065742C20706564652E20457469616D20656C656966656E6420647569207574206E69736C2E20446F6E656320616E7465206D61757269732C2074656D7075732073697420616D65742C207661726975732076697461652C206772617669646120717569732C206D692E20496E207363656C657269737175652C2066656C697320766974616520766976657272612073616769747469732C2076656C6974206D6574757320756C74726963696573206E657175652C207175697320696D706572646965742076656C697420656C6974206574206D61676E612E2053757370656E646973736520706F74656E74692E205365642076656C69742065726F732C20657569736D6F64207365642C20636F6E64696D656E74756D206E65632C206661756369627573207365642C2073617069656E2E204E616D20616363756D73616E206C6967756C612073697420616D6574206E657175652E20416C697175616D206572617420766F6C75747061742E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E616D20657520706564652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642065752066656C69732073656420746F72746F722074656D706F72206665726D656E74756D2E2050686173656C6C757320636F6D6D6F646F2073656D2076656C206E69736C2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050726F696E206C656374757320656C69742C2070686172657472612073697420616D65742C20616363756D73616E207365642C2074696E636964756E742065742C206D61757269732E204475697320646170696275732070686172657472612073656D2E20496E746567657220696E206A7573746F2E205072616573656E742065726F732E20566573746962756C756D20616320616E74652E20416C697175616D207363656C657269737175652073656D2070656C6C656E746573717565206E69626820636F6E73656374657475657220736F64616C65732E20416C697175616D20636F6E736563746574756572206F64696F2E2044756973206C6563747573206F64696F2C206C75637475732065752C20636F6D6D6F646F20717569732C206D6F6C6C69732076697461652C2076656C69742E2043726173206E6563206E756E63206E6F6E20656C697420696163756C6973206D61747469732E2041656E65616E206A7573746F206E657175652C20736F6C6C696369747564696E20656765742C20756C6C616D636F7270657220656765742C20656765737461732069642C2073656D2E20496E2065752072697375732E2053656420656765737461732E0A0A496E7465676572206174206E657175652E20536564207072657469756D207363656C65726973717565206E756C6C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20467573636520757420706564652E20457469616D207669746165207175616D20612075726E612076617269757320696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2044756973207665686963756C612E20467573636520756C6C616D636F72706572206E696268206E6F6E20657261742E205175697371756520696E206E657175652E205072616573656E74206573742E2050656C6C656E74657371756520617263752E0A0A50726F696E20706F73756572652E2053757370656E646973736520706F74656E74692E20496E74656765722066656C6973206C616375732C20616C697175616D207365642C2076756C70757461746520696E2C206D6F6C6C69732076656C2C2074656C6C75732E20496E7465676572207665686963756C6120626962656E64756D206573742E204E756E63206E6F6E20646F6C6F7220696E2074656C6C7573206D617474697320666163696C697369732E20496E746567657220766573746962756C756D2C20617567756520617420636F6D6D6F646F20616C697175616D2C2064756920657374206D6174746973206C6967756C612C2073697420616D65742061646970697363696E67206F7263692073656D207669746165206D61676E612E205072616573656E7420656E696D2076656C69742C206D616C6573756164612061742C20636F6E677565206E65632C206C756374757320696E2C206A7573746F2E20536564207661726975732E204D6F7262692070686172657472612E20446F6E6563206575206D61737361206E65632074656C6C75732076756C7075746174652070756C76696E61722E20557420636F6D6D6F646F20747572706973206E6F6E2073656D2E20557420636F6E76616C6C697320756C6C616D636F727065722072697375732E20457469616D20696E74657264756D2070656465206964206E6973692E2043726173206D61676E612073617069656E2C20737573636970697420612C206C616F72656574206E6F6E2C2072686F6E6375732065742C2066656C69732E20496E7465676572206F726369206C6F72656D2C20766573746962756C756D2064696374756D2C20756C6C616D636F7270657220612C20706F72747469746F722065742C206475692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A4E756E63206574206D61676E612E2053656420626962656E64756D2074656C6C757320696E206469616D2E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E616D20766974616520746F72746F722E20496E7465676572206D61676E612E20447569732076656E656E617469732C206C656F2061632074656D706F72206C616F726565742C20656C6974206E756C6C6120706861726574726120706564652C206E6F6E206665726D656E74756D206E756E63206F64696F2061206F64696F2E2050726F696E206E6F6E2076656C69742E2053656420696D706572646965742061756775652071756973206E69736C2E20496E746567657220636F6E64696D656E74756D206E69736C206E6563206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20566976616D757320706C616365726174206C696265726F2E204475697320636F6E6775652064696374756D206D61676E612E20416C697175616D206461706962757320626962656E64756D20656E696D2E204E756E6320656C656966656E6420706564652076656C20697073756D2E0A0A457469616D2076697461652076656C69742E204D61757269732065726174206E756E632C206D616C6573756164612075742C20666575676961742061632C20706C61636572617420636F6E64696D656E74756D2C2061756775652E204E616D20766F6C75747061742E20416C697175616D207665686963756C6120697073756D206964206F64696F2E20566976616D757320736F6C6C696369747564696E207475727069732069642073617069656E2E20467573636520612066656C6973207669746165206F64696F20636F6E76616C6C697320626C616E6469742E204375726162697475722076697461652065726F732069642065726F7320706F727461207072657469756D2E204E756C6C6120696E206D61676E6120656765742075726E61206C6163696E696120636F6E76616C6C69732E20416C697175616D206D61747469732076656E656E617469732070757275732E2053656420736564206D69206567657420657261742074726973746971756520706F7274612E20446F6E656320617563746F7220646F6C6F72206120657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20496E206E6563206C6967756C612E204E756E6320656C656966656E642E20566573746962756C756D2071756973206E697369206567657420656C697420706F72747469746F7220636F6E6775652E204D616563656E61732066617563696275732C206D61676E6120656765742061646970697363696E672074696E636964756E742C20646F6C6F7220616E7465206D616C65737561646120656C69742C206E6F6E20656C656D656E74756D206C616375732074757270697320696E20706564652E0A0A5574206D616C657375616461206D69206E6563206D657475732E205072616573656E7420617563746F72206175677565206163206E69736C20756C7472696369657320666163696C697369732E204E616D2070757275732073617069656E2C2070656C6C656E746573717565206469676E697373696D2C20706F73756572652065752C206375727375732069642C206469616D2E205175697371756520736F6C6C696369747564696E2C20656C697420612070656C6C656E746573717565207363656C657269737175652C206C6F72656D20726973757320617563746F72207175616D2C207175697320636F6E7365717561742074656C6C7573206E657175652069642075726E612E2053757370656E6469737365206469616D20746F72746F722C20656C656966656E64206469676E697373696D2C20656765737461732075742C206C756374757320696E2C20616E74652E204475697320616E74652E204D616563656E6173206C75637475732E20437572616269747572206375727375732070686172657472612075726E612E204D616563656E617320696D706572646965742C2065726174206E6F6E20656C656D656E74756D20657569736D6F642C20746F72746F72206F64696F20657569736D6F64206C65637475732C20616320666163696C697369732073656D206E696268207669746165206E756C6C612E204E756E6320677261766964612E204D6F72626920736F6C6C696369747564696E206F64696F2071756973206C616375732E20416C697175616D2061206E696268206E6F6E2075726E6120706F72746120696D706572646965742E20416C697175616D206572617420766F6C75747061742E20496E20696163756C6973206C6163696E69612076656C69742E20536564206C696265726F206C616375732C207472697374697175652065752C206C6163696E69612061632C20616C697175657420656765742C2075726E612E0A0A457469616D206174206E69736C2E2050686173656C6C7573206661756369627573206C7563747573206C65637475732E20557420706C6163657261742076756C70757461746520646F6C6F722E2050686173656C6C75732076656C2076656C69742E204D6F72626920766976657272612E2050686173656C6C7573206F7263692E20496E7465676572206469676E697373696D206D6174746973206D61757269732E2050656C6C656E74657371756520706F7375657265206C656F20706F7375657265207175616D2E2051756973717565206E6563206D61676E61206174206469616D20766976657272612070656C6C656E7465737175652E2053757370656E64697373652076656C697420617263752C20756C7472696369657320717569732C20636F6E67756520612C2076656E656E6174697320656765742C206C616375732E20496E74656765722073616769747469732068656E64726572697420646F6C6F722E2046757363652074696E636964756E7420616E746520612073656D2E0A0A4D616563656E617320636F6E7365637465747565722C206A7573746F207365642072686F6E6375732076656E656E617469732C206E69626820617263752072757472756D20646F6C6F722C2073656420636F6E64696D656E74756D206C696265726F206C696265726F20657420697073756D2E20566976616D7573206D6174746973206A7573746F207574206C6F72656D2074696E636964756E74206C6F626F727469732E205574206E6F6E2076656C6974206964206E6571756520616C697175657420616363756D73616E2E205365642074656D7075732076697665727261206E756C6C612E2043757261626974757220756C6C616D636F727065722C206E6571756520717569732064617069627573207363656C657269737175652C2066656C6973206469616D2067726176696461206F7263692C206E6F6E20637572737573207175616D206E6571756520766974616520656C69742E20457469616D2070686172657472612074696E636964756E74206C616375732E204475697320657569736D6F64206672696E67696C6C61206573742E20457469616D206F726E6172652074696E636964756E74206C65637475732E2050726F696E20696E207475727069732E204E756E6320626C616E64697420626C616E646974207475727069732E2041656E65616E2075742061756775652E2044756973206F726369206A7573746F2C2074696E636964756E742065752C2072757472756D207365642C2072757472756D2065742C207475727069732E2043757261626974757220666163696C69736973206F64696F20696E20616E74652E20496E206861632068616269746173736520706C617465612064696374756D73742E205365642065726F73206573742C2070656C6C656E7465737175652061742C2074696E636964756E742065752C20756C74726963657320717569732C206D657475732E204D6F7262692073697420616D6574206A7573746F2E204D616563656E617320616320617263752E204D6175726973206469676E697373696D2E0A0A50656C6C656E74657371756520756C747269636965732072757472756D206F7263692E2041656E65616E206F726E6172652E20566976616D75732065752072697375732076656C206D6175726973206C6F626F727469732064696374756D2E205365642065742074757270697320617563746F72206D692072686F6E6375732070756C76696E61722E20536564206E6563206E756E6320612070757275732074656D706F7220766976657272612E2050656C6C656E7465737175652073757363697069742E20446F6E656320747269737469717565207269737573206E6F6E206E6962682E20457469616D206E69736C206D61676E612C20736F6C6C696369747564696E2075742C20756C7472696365732073697420616D65742C20656765737461732065752C206E756C6C612E20416C697175616D206572617420766F6C75747061742E20566573746962756C756D2070686172657472612E2053656420656765737461732C206D657475732073697420616D6574206C6F626F7274697320636F6E7365717561742C206572617420656C697420696D70657264696574206C696265726F2C20657520696E74657264756D207175616D206D61737361206567657420646F6C6F722E2053757370656E6469737365207669746165206F64696F2E2050726F696E20626C616E646974206D617572697320696163756C6973206D657475732E0A0A566976616D757320766573746962756C756D2E20457469616D206574206E69736C2E20416C697175616D20696E206469616D2076656C20656C697420706C6163657261742073757363697069742E204475697320736F64616C6573207075727573206163206E6962682E204E756C6C6120696E206F64696F206567657420656E696D206C756374757320626C616E6469742E2043757261626974757220756C74726963657320697073756D206E6F6E206E65717565206567657374617320656C656966656E642E20536564207475727069732E2050726F696E20636F6E7365637465747565722E20566976616D7573206D61747469732E20496E20616C69717565742E0A0A4E756E632069642065726F732E20446F6E65632076656E656E617469732C206E756C6C61206574206D6174746973206C75637475732C20616E7465206C656F2073656D706572206A7573746F2C206E6F6E2061646970697363696E67206F64696F20726973757320736564206C616375732E205072616573656E7420766974616520726973757320636F6E677565206C696265726F20636F6E6775652074656D7075732E2050686173656C6C75732061632065726F732E204E756C6C61207665686963756C612C206C6F72656D20696E20616C69717565742073757363697069742C2061726375206572617420656765737461732073656D2C2071756973206C6F626F72746973207175616D20616E7465206575206D617373612E20437572616269747572206E6F6E206D617373612E2053656420626962656E64756D206C6163696E6961206F64696F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20566976616D757320766F6C757470617420626C616E646974206C616375732E2050726F696E20706F7274612C2074656C6C757320757420617563746F72206C616F726565742C206C65637475732065726F73206665726D656E74756D206C65637475732C2069642073616769747469732061726375206A7573746F20696E207475727069732E2050686173656C6C757320636F6E7365717561742E204E616D2070656C6C656E7465737175652C206D69206964207669766572726120636F6E76616C6C69732C206E756E63206C696265726F20706C616365726174206C656F2C20656C656966656E6420706F7274612073656D206E69736C2076697461652073617069656E2E2050656C6C656E746573717565206C6967756C61206C696265726F2C20747269737469717565206E6F6E2C20706F72747469746F722072757472756D2C20706F72747469746F72206E6F6E2C20657261742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E74656765722064696374756D2074656C6C7573206120746F72746F722E20566976616D75732066656C6973206E756E632C206D6F6C6573746965206E6F6E2C2072686F6E63757320717569732C2070686172657472612069642C206475692E20446F6E6563207269737573206D657475732C206672696E67696C6C612076656C2C20616C69717565742065752C20706C6163657261742069642C206E657175652E0A0A53757370656E646973736520697073756D2E20566976616D7573206C65637475732E2053656420766976657272612C206D61737361206567657420636F6E76616C6C6973206D61747469732C207175616D2074757270697320636F6E736563746574756572206E756E632C206567657420706F7375657265206D61676E612073656D2069642076656C69742E20496E206E6563206D61757269732E2041656E65616E206120707572757320736564207175616D206C6F626F72746973206672696E67696C6C612E2050726F696E20756C74726963696573206C6163696E696120616E74652E205365642061646970697363696E67206572617420717569732076656C69742E204E756C6C616D207669746165206E69736C206964206A7573746F20736F6C6C696369747564696E206D6F6C65737469652E204E756C6C6120666163696C6973692E20536564206E65632075726E6120736564206E69736C206672696E67696C6C6120646170696275732E204E756C6C61206174206469616D2E20416C697175616D2065676574206E6962682E204E756E63206163206E6973692073697420616D65742074656C6C757320656765737461732074656D7075732E204E616D207363656C657269737175652075726E61206574206E657175652E20446F6E656320657374206F7263692C207361676974746973206E6F6E2C2076756C70757461746520612C20636F6D6D6F646F2065742C2061756775652E205574206461706962757320746F72746F722E205574206E756E632E20446F6E65632064696374756D2064617069627573206F64696F2E204E616D20756C7472696369657320756C6C616D636F72706572206C6967756C612E2050656C6C656E74657371756520616363756D73616E20766172697573206C656F2E0A0A4D6F72626920657569736D6F64206C616F7265657420657261742E20566976616D7573207175697320697073756D2E204D6F72626920657569736D6F642E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2053757370656E64697373652076656C2070757275732E204E756C6C616D206174206D61676E612E20437572616269747572206C61637573206C6F72656D2C20696163756C697320717569732C2064617069627573206E6F6E2C20766F6C75747061742076656C2C206E756C6C612E20446F6E656320757420617263752072686F6E63757320646F6C6F72207072657469756D2064696374756D2E204E756C6C616D2076656C206D657475732E20557420617263752E2050656C6C656E746573717565206E697369206E756E632C20706C61636572617420656765742C2074696E636964756E742076656C2C207068617265747261206E6F6E2C206E756E632E20496E74656765722074696E636964756E7420756C74726963696573206C65637475732E20496E74656765722073656D7065722C2070757275732073656420756C74726963657320666575676961742C206E756C6C61207065646520736F6C6C696369747564696E20657261742C2076656C20617563746F72206E756C6C6120697073756D2076656C206C65637475732E2041656E65616E206D692E0A0A4E756C6C616D20736564206E697369206574206172637520696D70657264696574206665726D656E74756D2E204D6175726973206E6563206D657475732E20496E20616320646F6C6F722E20496E206D6920617263752C20636F6E6775652061632C207068617265747261206E65632C207363656C657269737175652073697420616D65742C206D61676E612E20437572616269747572206C616375732E2043757261626974757220657420656C69742E20416C697175616D20756C6C616D636F72706572206E756E6320657520656C69742E2053656420636F6E76616C6C697320646F6C6F722061742076656C69742E20566573746962756C756D20646170696275732C20617567756520696420636F6E73656374657475657220706C6163657261742C206E756E63206D6173736120626C616E6469742073617069656E2C20696420616C697175616D20656C6974206E697369206964206D692E2050686173656C6C75732073617069656E206573742C20677261766964612065752C20626962656E64756D2075742C2061646970697363696E6720717569732C206573742E205574206D6F6C6573746965207175616D207669746165206F64696F2E20446F6E65632071756973207269737573206964206572617420666175636962757320736F6C6C696369747564696E2E204E616D2069642066656C69732E204D61757269732073656420656E696D207669746165206C656F20616363756D73616E207072657469756D2E0A0A4E616D206A7573746F2E20446F6E656320747572706973206E69736C2C20636F6D6D6F646F2065742C20696E74657264756D2061632C20636F6E736563746574756572206E6F6E2C206D617373612E2046757363652073656D206D657475732C206C616F72656574206E65632C20706F73756572652069642C20696D7065726469657420696E2C2076656C69742E20446F6E65632076756C707574617465206A7573746F2065676574207475727069732E204E756C6C6120706564652E204D6F7262692074696E636964756E742E20467573636520616C69717565742C207175616D20657420616C697175616D206672696E67696C6C612C20616E746520616E746520696163756C6973206475692C206E656320616C697175616D20617263752070757275732073656420657261742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050686173656C6C7573207375736369706974207175616D206574206573742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B0A0A496E7465676572207365642074656C6C75732E20536564207365642076656C697420756C74726963696573206C656F2072757472756D206C616F726565742E20536564206E6F6E2065726F7320616320707572757320736167697474697320666575676961742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E205365642068656E647265726974206C6967756C612073697420616D6574206E6962682E204D616563656E6173207475727069732E204D6F72626920636F6E7365637465747565722C20646F6C6F722065742061646970697363696E6720696D706572646965742C20616E7465206E65717565206665756769617420646F6C6F722C20617420706F727461207175616D206E657175652071756973206C6967756C612E204D61757269732073656D7065722076656C69742073697420616D657420697073756D2E2050656C6C656E7465737175652074656D7075732C20707572757320696E2072757472756D20636F6E7365717561742C20656E696D2065726174207665686963756C61206D617373612C20696420616363756D73616E206C656F2073617069656E206E65632070757275732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E20646F6C6F722E20496E746567657220666163696C69736973206C696265726F2073697420616D657420706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2055742076617269757320616C697175657420656E696D2E204E756C6C6120666163696C6973692E2043757261626974757220636F6E7365637465747565722C206F64696F206575207072657469756D2074696E636964756E742C206E756E63206E69736920616C6971756574206E657175652C2076656C20696D7065726469657420656C6974206D617373612073697420616D6574207475727069732E2050656C6C656E7465737175652074656D7075732C206F72636920766F6C757470617420626C616E646974206672696E67696C6C612C206F64696F2073656D20706F737565726520616E74652C20766974616520626962656E64756D2075726E61206C6F72656D2076697461652065726F732E205072616573656E7420766976657272612072686F6E63757320617263752E2053656420617563746F722C206573742073697420616D6574206D6F6C6C6973206D6F6C6C69732C207175616D207175616D20677261766964612073617069656E2C20696E20636F6D6D6F646F206D65747573206E756C6C6120617563746F7220656E696D2E20446F6E656320666163696C697369732E0A0A50726F696E2074696E636964756E742C2073617069656E206567657420756C747269636965732061646970697363696E672C20657374206F64696F2064696374756D20617263752C207574206D6F6C6C69732065726174206475692073697420616D65742076656C69742E204D6F726269206573742073656D2C20696E74657264756D2061742C20636F6E67756520612C20656C656D656E74756D2076697461652C206D657475732E2053757370656E64697373652069642061756775652E204D617572697320656E696D2073656D2C2070756C76696E617220656765742C2074656D70757320612C2074656D7075732073697420616D65742C2073617069656E2E20467573636520766573746962756C756D20636F6E736563746574756572206475692E2050656C6C656E74657371756520657261742E20536564206469676E697373696D20706C616365726174206F64696F2E204D616563656E61732073656D7065722072686F6E637573206C65637475732E2050686173656C6C7573207072657469756D2E2044756973206C696265726F20656C69742C20656C656966656E64206E65632C20656765737461732075742C20637572737573207365642C2066656C69732E204E616D206E69736C20617263752C20616C69717565742065742C20666163696C697369732065752C206C75637475732075742C2072697375732E20457469616D20756C7472696365732C20646F6C6F722073656420766F6C7574706174206D616C6573756164612C20747572706973206172637520696D7065726469657420746F72746F722C20657569736D6F6420636F6D6D6F646F206C696265726F206D61737361207574207175616D2E20496E7465676572206D6F6C6573746965207075727573206E6F6E20656C69742E2055742076656E656E617469732073656D70657220746F72746F722E20457469616D20626962656E64756D206567657374617320697073756D2E204D617572697320736F6C6C696369747564696E2073656D206E6563206E6962682E204E756C6C61207072657469756D206D65747573206575206D657475732E2050656C6C656E7465737175652073697420616D65742073656D2E0A0A53757370656E6469737365206163206E6973692E205574206C656F2E20566573746962756C756D2068656E647265726974207072657469756D20646F6C6F722E204E756E632066657567696174206D616C6573756164612070757275732E2043726173206574206E6962682E20437572616269747572206E756E6320657261742C206D616C6573756164612076697461652C206C616F726565742061632C20756C7472696369657320696E2C2070757275732E20566976616D75732074656C6C757320617263752C20736F64616C65732065752C20666163696C6973697320612C206C6163696E6961206E65632C206E756E632E2050656C6C656E7465737175652069642076656C69742E20496E206575206E6962682E204E756E63206E656320657261742E205365642064696374756D206E65717565207574206E69736C2E0A0A4D6F726269206C65637475732074656C6C75732C2074696E636964756E742061632C20706F72747469746F722061632C2074726973746971756520696E2C2065726F732E20446F6E6563206C7563747573206C7563747573206C656F2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2046757363652075742065737420657420656E696D207363656C6572697371756520616363756D73616E2E20446F6E6563206C6967756C612066656C69732C206C6163696E696120717569732C2070656C6C656E74657371756520696E2C2073656D70657220766573746962756C756D2C20656C69742E204D61757269732065676574206F72636920612066656C697320636F6E677565207665686963756C612E20557420736F6C6C696369747564696E2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204E756C6C616D20696420646F6C6F72207574206C6F72656D206469676E697373696D2076656E656E617469732E2053757370656E64697373652076697461652073617069656E2E2050726F696E206E6F6E206D61676E612075742065726F7320766976657272612070756C76696E61722E20446F6E65632071756973206F64696F2E204E756C6C616D206E6F6E20617263752076656C206C6F72656D20737573636970697420616C697175616D2E20416C697175616D2072757472756D2074757270697320696E206C656F2E0A0A5574206C7563747573206E6962682074726973746971756520657261742E2053757370656E646973736520626962656E64756D206F64696F20766974616520746F72746F722E20446F6E6563206C6163696E69612E204372617320736F64616C65732066656C6973206C7563747573206E756C6C612E204E616D20656C656966656E64207361676974746973206C6967756C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E64697373652076656C206E657175652E204D6F72626920616C6971756574207665686963756C61206D61676E612E2041656E65616E206174206F64696F2E20447569732070656C6C656E746573717565206D61676E612E204E756C6C6120617420746F72746F72207574206469616D2064696374756D2066617563696275732E204D617572697320717569732076656C69742E20446F6E6563206E6F6E2074656C6C7573207669746165206C6F72656D206672696E67696C6C6120706F72747469746F722E2046757363652075742073617069656E207175697320746F72746F7220666575676961742073616769747469732E20446F6E656320766976657272612073656D2076697461652073617069656E2E205072616573656E7420736F64616C65732C206C6163757320696E206672696E67696C6C6120766976657272612C206F64696F2061756775652061646970697363696E672075726E612C20766974616520696E74657264756D20616E74652073656D206E6F6E206E6973692E204E756C6C616D20746F72746F72206C6F72656D2C20656C656966656E642061632C206D6F6C6C6973206E6F6E2C206C616F726565742061632C2072697375732E20496E7465676572206F726E617265206C656F20736564206A7573746F2E2051756973717565206375727375732C2073656D206E6F6E20666163696C6973697320626962656E64756D2C206E697369206D69207661726975732066656C69732C206665726D656E74756D2066657567696174206C6F72656D2065726F73206C616F726565742072697375732E0A0A517569737175652073697420616D657420657374206574206C6F72656D207665686963756C61206C6163696E69612E20446F6E6563206E656320746F72746F722E2043726173206F64696F2E204E616D207363656C657269737175652076756C7075746174652075726E612E205072616573656E74206475692E20457469616D206E6563206E69736C206C6F626F7274697320697073756D20616C69717565742074656D7075732E204D616563656E6173207072657469756D20736F6C6C696369747564696E206D61757269732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206175677565206D617373612C20636F6E67756520656765742C20636F6E76616C6C697320656765742C207472697374697175652073697420616D65742C2065726F732E2053656420636F6E736571756174206E6973692065752066656C69732E2050656C6C656E746573717565206A7573746F2E2053757370656E6469737365206E6F6E2061756775652E20496E206469676E697373696D206C6F626F72746973206D61757269732E204D61757269732073616769747469732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E0A0A5365642061646970697363696E672E20446F6E656320612074656C6C75732076697461652065737420637572737573207665686963756C612E204E616D20616E74652073656D2C20736F64616C65732069642C206672696E67696C6C612076656C2C20636F6E64696D656E74756D2076656C2C206E756C6C612E205175697371756520736F64616C65732E20457469616D20696D7065726469657420656C6974206964206F64696F2E20416C697175616D206572617420766F6C75747061742E204D616563656E617320706F7274612074656D706F7220617263752E204E756C6C612073656D2061756775652C2070656C6C656E7465737175652061632C20636F6E7365717561742075742C20636F6E64696D656E74756D20657569736D6F642C2072697375732E2053656420616C697175616D2074696E636964756E74206D692E20496E20696E74657264756D206C6F626F72746973206F7263692E0A0A536564207665686963756C612068656E6472657269742070757275732E20457469616D2061206469616D2E2043757261626974757220636F6E76616C6C69732E2053757370656E64697373652061206E6973692E20446F6E6563206964206D61676E6120696E207175616D20736F6C6C696369747564696E20756C747269636965732E20446F6E656320766976657272612E205175697371756520766F6C757470617420657374207365642073656D2E20416C697175616D206A7573746F2E20566573746962756C756D20746F72746F72206D617373612C20706F72747469746F72207365642C2076617269757320717569732C20696163756C697320717569732C206F64696F2E20416C697175616D2065676574206E657175652E0A0A4D6175726973206E756C6C612E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566573746962756C756D206575207175616D20696E206E6571756520756C7472696365732070656C6C656E7465737175652E204372617320696E20646F6C6F722071756973207175616D207661726975732068656E6472657269742E20416C697175616D206E697369206C616375732C206C6F626F727469732065752C20636F6E76616C6C69732073697420616D65742C20666163696C697369732075742C206D692E20416C697175616D206174206E657175652E204372617320736167697474697320656C656D656E74756D206A7573746F2E20566573746962756C756D207574206C656374757320616C6971756574207075727573206D616C65737561646120766F6C75747061742E2044756973206174206C616375732061646970697363696E67206C696265726F2074696E636964756E7420766573746962756C756D2E204D6F7262692061206C696265726F2E20437261732070757275732E204D6F72626920757420617567756520657420707572757320696E74657264756D207363656C657269737175652E20496E74656765722061206475692E20496E206861632068616269746173736520706C617465612064696374756D73742E2044756973207068617265747261206D657475732065676574206D61757269732E20416C697175616D20696E74657264756D20756C6C616D636F72706572206D617373612E0A0A457469616D206F726E6172652E204E756C6C616D20657569736D6F642E2041656E65616E20636F6E7365717561742067726176696461206C6967756C612E20416C697175616D206573742E2050726F696E207669746165206C616375732E205072616573656E7420612065726F732073697420616D657420647569206C756374757320636F6D6D6F646F2E2050686173656C6C7573207665686963756C612061726375206567657420646F6C6F722E205072616573656E74206665726D656E74756D20636F6E677565206C656F2E20416C697175616D20766F6C7574706174207075727573207574206C6F72656D2E2046757363652068656E64726572697420656E696D206174206C656F2E20416C697175616D2072686F6E637573206E69736C2E20566976616D75732064696374756D2065676573746173206D692E2053757370656E64697373652070656C6C656E74657371756520626962656E64756D20646F6C6F722E2050656C6C656E7465737175652074696E636964756E742C207475727069732073656D7065722070656C6C656E74657371756520636F6E64696D656E74756D2C20697073756D206D6574757320736F64616C6573206C6967756C612C20696420766F6C7574706174206469616D2074757270697320757420656C69742E0A0A5072616573656E7420736564206C616375732E204E616D20656C656966656E64206D6F6C6573746965206D61757269732E20446F6E65632064617069627573206665726D656E74756D206D617373612E20446F6E656320766976657272612066617563696275732070757275732E2043757261626974757220636F6E6775652C206C696265726F20766974616520766976657272612070656C6C656E7465737175652C206469616D2076656C697420736F64616C657320656E696D2C20736564207375736369706974206C6563747573206E697369206E6563206E657175652E20566573746962756C756D206D616C6573756164612C206C616375732061742063757273757320636F6E6775652C2076656C6974206C65637475732074726973746971756520646F6C6F722C2073697420616D657420736F64616C6573206E6571756520697073756D2061206C696265726F2E20566573746962756C756D206574207175616D2E2043757261626974757220706C6163657261742E20437572616269747572206E756E6320617263752C20657569736D6F64206E65632C2076756C7075746174652068656E6472657269742C20616C697175657420656765742C207175616D2E204375726162697475722076656C20656E696D2E2053757370656E646973736520706F74656E74692E0A0A4E756E6320636F6E736571756174206F726369207574206C616375732E2046757363652076656C697420646F6C6F722C2064617069627573207365642C20626C616E6469742073697420616D65742C2072686F6E6375732069642C2072697375732E20447569732075726E61206E6962682C207363656C6572697371756520717569732C206461706962757320612C207363656C65726973717565207365642C206E6962682E20446F6E6563206C75637475732E205574206575206D617572697320637572737573206469616D206C6163696E69612072686F6E6375732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20416C697175616D207665686963756C61206D6F6C6573746965206A7573746F2E204D616563656E617320696D70657264696574207065646520736564206D692E2053757370656E6469737365206E756C6C6120646F6C6F722C2068656E64726572697420656765742C2068656E6472657269742069642C2064696374756D2076656C2C206C656F2E204475697320616363756D73616E2E2043757261626974757220696E2066656C69732E204E756E63206C6F72656D2E205574206C656F20646F6C6F722C206C616F72656574206E65632C2076756C7075746174652061742C20656C656966656E6420696E2C206E756C6C612E2051756973717565206E756E632070757275732C2076617269757320656765742C20616363756D73616E206E65632C20616C69717565742065742C206E6962682E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20437261732061646970697363696E67207669766572726120646F6C6F722E204D617572697320706F72747469746F7220756C7472696365732070757275732E204E756C6C6120666163696C6973692E205072616573656E7420666175636962757320616E7465207669746165206D61757269732E0A0A5072616573656E74206C6163696E6961206C656374757320736564206E69736C2E20496E2074656D70757320636F6E677565206D61757269732E20496E746567657220666163696C69736973206F726E61726520656E696D2E204E756C6C61206964206D617373612E20446F6E656320636F6D6D6F646F206469616D2061742074656C6C75732E204E616D20646170696275732076697665727261206573742E204E616D2074656C6C75732E205072616573656E742061206C696265726F2E20496E206661756369627573206573742065676574206E6962682E204E756C6C612065726F73206F7263692C20696D70657264696574206E6F6E2C20626C616E646974206E6F6E2C2074656D706F7220656765742C206D692E2050656C6C656E74657371756520636F6E76616C6C69732E0A0A517569737175652065676574206D69206163206C656F20657569736D6F642066617563696275732E2050686173656C6C75732072686F6E637573207075727573206964206475692E20566573746962756C756D206D616C65737561646120656C656966656E6420616E74652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050656C6C656E74657371756520626C616E646974206D6174746973206F64696F2E2053757370656E646973736520636F6E7365717561742C206C65637475732061632073656D70657220736F6C6C696369747564696E2C206D692076656C69742064696374756D2061756775652C2061632074656D70757320646F6C6F7220657261742073697420616D6574206475692E2050726F696E2068656E6472657269742C2066656C6973207175697320766F6C757470617420706F73756572652C206469616D206F64696F206D616C657375616461206F64696F2C206120696E74657264756D206F726369206469616D20717569732073617069656E2E2050656C6C656E746573717565206F64696F206F64696F2C20766976657272612076656C2C20677261766964612065752C206D6F6C6573746965207365642C206E756C6C612E2050686173656C6C7573206D617572697320706564652C20636F6D6D6F646F2075742C20657569736D6F642065752C2068656E6472657269742065752C206573742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C6120656C656D656E74756D206C616375732065752061756775652E2053656420657261742E2050726F696E20706F7274612E204D616563656E61732071756973206D692E2050686173656C6C757320617420656E696D206163206A7573746F206772617669646120756C7472696365732E2043726173206C656F2E0A0A496E746567657220757420617263752E20446F6E656320736564206D61676E612E2050726F696E2066656C69732E20496E20696163756C69732C206C6967756C61206964206672696E67696C6C61207072657469756D2C206E696268206469616D20616363756D73616E2074656C6C75732C206567657420616363756D73616E206D657475732064756920766172697573207475727069732E2050686173656C6C7573206F726369206D657475732C20656C656966656E64207365642C2074656D706F722061632C207363656C657269737175652061632C2075726E612E20496E74656765722076697665727261206E657175652061206D61757269732E204D617572697320706F72747469746F7220646F6C6F722065752076656C69742E20496E7465676572206F64696F20656C69742C20766573746962756C756D2075742C20766F6C75747061742069642C2072686F6E63757320636F6D6D6F646F2C2075726E612E20457469616D20706C61636572617420706861726574726120657261742E2055742074656D706F72206573742E20496E7465676572206469676E697373696D20626C616E6469742074656C6C75732E204D6F726269206E69626820646F6C6F722C207363656C657269737175652069642C20636F6D6D6F646F206D616C6573756164612C206D61747469732061742C206D692E20437261732074696E636964756E7420636F6D6D6F646F2070757275732E20496E2074696E636964756E742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D20756C6C616D636F727065722E2055742068656E6472657269742E204D6F72626920756C7472696365732E0A0A5072616573656E7420696163756C69732C2065726F73206163206567657374617320736F64616C65732C2075726E61206C656F206665726D656E74756D206C6967756C612C2073697420616D657420616C697175616D2076656C69742073656D206E6F6E2070757275732E20446F6E65632072757472756D206172637520717569732070757275732E204E616D20706F73756572652C206C6163757320617420636F6E73657175617420706C6163657261742C206E756C6C61207065646520706F7375657265206F7263692C206E6F6E20657569736D6F6420747572706973206475692071756973206E69736C2E2050726F696E20706F7274612061646970697363696E67206E6962682E20446F6E65632074726973746971756520646F6C6F722061742074656C6C75732E20446F6E6563206E65717565206D617373612C20617563746F722069642C2066617563696275732076697461652C20756C6C616D636F727065722076656C2C206E6973692E2050726F696E206D6F6C6573746965206E6571756520736564206D617373612E204E616D2074656D706F722E204D6F72626920616C697175616D2073617069656E2061742074656C6C75732E2046757363652071756973207269737573206574206D69207072657469756D2070756C76696E61722E2046757363652073697420616D6574206C6967756C612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E646973736520657520656E696D2065742066656C6973207363656C65726973717565206C6F626F727469732E205072616573656E7420626962656E64756D2E20566976616D7573207665686963756C612E20496E7465676572206174206E696268207365642076656C69742072686F6E637573206D6F6C65737469652E2043726173206C616375732E2053656420756C6C616D636F727065722065726F732076656C20657261742E20467573636520657520746F72746F722073697420616D6574206469616D20657569736D6F642073616769747469732E204E756E632071756973206C61637573206964206E69626820636F6E76616C6C6973207661726975732E2053757370656E6469737365207669746165206D692E20566573746962756C756D207472697374697175652E20446F6E6563206D616C65737561646120697073756D206964206E657175652E204E756C6C616D20736564206C616375732E204475697320656765737461732C206A7573746F20757420636F6E677565206F726E6172652C2061756775652073617069656E206C7563747573206469616D2C20617420616363756D73616E20657261742073617069656E207574206C696265726F2E2050686173656C6C75732076656C206E756C6C612E2053757370656E646973736520617263752074656C6C75732C20706F72747469746F7220612C2070686172657472612066617563696275732C20616C697175616D2073697420616D65742C206D617373612E204E756C6C6120706F72747469746F722074696E636964756E74206C6F72656D2E204E756E6320646F6C6F72206F64696F2C20736167697474697320696E2C206C6F626F727469732076656C2C20766F6C7574706174207365642C206E6962682E0A0A5175697371756520626C616E646974206C656F2075742073617069656E2074656D70757320666163696C697369732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2041656E65616E20756C7472696369657320706F72747469746F72206A7573746F2E2046757363652072757472756D2065726F732075742075726E612E2050726F696E2071756973207175616D20656765742064756920616C697175616D20616363756D73616E2E20446F6E656320737573636970697420656C656966656E6420656C69742E2050656C6C656E746573717565206D61747469732C2066656C697320736F64616C657320696163756C697320696D706572646965742C206C616375732073656D20636F6E76616C6C69732061756775652C2073697420616D657420616C69717565742061726375207075727573206672696E67696C6C612072697375732E20496E206575206F64696F206964206D61676E61207068617265747261206F726E6172652E20416C697175616D20696E74657264756D2070756C76696E617220697073756D2E20536564206E657175652E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D2073697420616D6574206E6973692E2055742061742061756775652E204D617572697320766F6C757470617420626C616E646974206C6967756C612E204E756C6C61206575206D657475732E20566573746962756C756D206567657420656C69742E205072616573656E7420706F73756572652E20566573746962756C756D2069642073656D206E6F6E206C6563747573206D6F6C6C69732074696E636964756E742E20416C697175616D2069642066656C697320617420616E7465206F726E6172652074656D706F722E204E756C6C61206C61637573207475727069732C20666575676961742076697461652C2063757273757320717569732C20636F6E736563746574756572206E6F6E2C206D61757269732E204675736365206C61637573206D617373612C20706F72747469746F722075742C206D6F6C65737469652075742C2076656E656E6174697320612C206C6F72656D2E205072616573656E742073697420616D6574206F7263692E204D61757269732072686F6E6375732066656C69732076697461652066656C69732061646970697363696E6720696D706572646965742E204D616563656E6173206D6F6C6C6973206469616D206E6563206C656F2E0A0A467573636520656E696D20697073756D2C20756C7472696365732065752C206D6F6C65737469652069642C20656C656D656E74756D2069642C2073617069656E2E20496E746567657220612075726E612E204E616D2076656C6974206C696265726F2C2076656E656E6174697320656765742C2074656D706F722073697420616D65742C20666575676961742076697461652C20616E74652E204675736365206E756E632E205365642073656D706572206E69736C206E65632072697375732E20496E20736564206C696265726F2E2050726F696E20746F72746F72206E657175652C2074696E636964756E742061632C2074656D706F722061632C20706861726574726120717569732C2076656C69742E2044756973206C65637475732061756775652C20756C747269636965732076656C2C20636F6E7365717561742069642C20696163756C69732069642C20616E74652E20566976616D757320617563746F72206D65747573206120616E74652E204375726162697475722061726375206E6973692C20666163696C697369732061742C206C616F7265657420696E2C20636F6E736563746574756572207365642C206D61757269732E205175697371756520706C616365726174206469616D20736564206475692E20566976616D7573207072657469756D20636F6E64696D656E74756D206C6F72656D2E20437572616269747572206C616F726565742E2041656E65616E206F726369206C6967756C612C2063757273757320656765742C206C6163696E6961206E6F6E2C2066617563696275732076656C2C206C6F72656D2E0A0A416C697175616D206572617420766F6C75747061742E204375726162697475722065726F7320646F6C6F722C20636F6E67756520612C20636F6E64696D656E74756D207365642C206C75637475732075742C206E6962682E204D616563656E6173206E6F6E20746F72746F72206E65632074757270697320636F6D6D6F646F2070656C6C656E7465737175652E205072616573656E7420657569736D6F6420706C616365726174206D692E2053757370656E646973736520706F74656E74692E2050686173656C6C7573207574206E65717565207669746165206F726369206D617474697320696163756C69732E20496E746567657220656765742074656C6C75732E20446F6E656320617420616E74652E204E616D206C6163696E6961206C656F206567657420657261742E204D616563656E617320657569736D6F64206D61676E6120636F6E67756520746F72746F722E204D6F726269206E6563206D6173736120657520656E696D206D616C65737561646120736F6C6C696369747564696E2E2053656420616363756D73616E2E204E756C6C616D20697073756D2E205574206F64696F2E20416C697175616D206572617420766F6C75747061742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2050656C6C656E7465737175652069642076656C69742E204E616D206F64696F2073656D2C20616C69717565742075742C2074656D7075732073697420616D65742C20657569736D6F642065742C206E756E632E0A0A50656C6C656E746573717565206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205072616573656E74206D6175726973206E756E632C207661726975732075742C20636F6E76616C6C6973206D6F6C65737469652C206C75637475732073697420616D65742C206C656F2E205365642064696374756D206C6F72656D20657420617263752E204E756E632076656E656E617469732070656C6C656E746573717565206D617373612E204E756C6C6120666163696C6973692E2050686173656C6C757320696E20746F72746F722065676574207269737573207363656C657269737175652076756C7075746174652E20536564206E69626820656C69742C2073616769747469732061632C20636F6E64696D656E74756D206E65632C20636F6E76616C6C69732065742C206A7573746F2E20467573636520766F6C7574706174206D657475732E204E756E6320617563746F722E20566573746962756C756D206C656F2065726F732C2070656C6C656E7465737175652061632C206D6F6C6C697320756C7472696365732C2072686F6E637573206E6F6E2C20646F6C6F722E204D6175726973207665686963756C6120706C616365726174206E69736C2E20566573746962756C756D20626962656E64756D2C2061726375207175697320636F6E67756520656C656D656E74756D2C2076656C6974206E756E6320656C656966656E64207475727069732C206964206C7563747573207269737573206E69736C2073697420616D65742074656C6C75732E2050686173656C6C75732070656465206E657175652C20626C616E646974206E6F6E2C20636F6D6D6F646F2076697461652C20756C7472696369657320656765742C206D61676E612E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120666163696C6973692E20416C697175616D20616320616E74652E20437261732072697375732E204D6F726269206D6175726973206C616375732C20706F73756572652065752C20626C616E6469742065742C2070686172657472612061742C206D692E2050726F696E2061632070757275732E204475697320637572737573206E69736C2072757472756D207175616D2E20416C697175616D2061206F64696F206E6F6E206D61676E612070656C6C656E74657371756520756C747269636965732E204D616563656E6173206163206D6173736120717569732073617069656E20756C6C616D636F727065722074656D7075732E2043726173206375727375732076656C6974207365642073617069656E2E2050726F696E206E756C6C612E20566976616D757320736F64616C657320616C697175616D206E6962682E20457469616D206574206572617420757420616E7465206C6163696E696120657569736D6F642E204675736365206E6973692E2050726F696E2071756973206E756C6C612E0A0A517569737175652076656E656E617469732C2065726F7320736564206C616F7265657420736F6C6C696369747564696E2C206F72636920616E74652070656C6C656E746573717565206E69736C2C2073697420616D65742076697665727261207175616D2065726174206E6F6E2072697375732E20437261732065676574206C696265726F2E2053656420656C6974206D61676E612C2073656D7065722065752C206672696E67696C6C6120696E2C206469676E697373696D20736F64616C65732C20657261742E20566976616D757320666575676961742073656D2076656C206475692E20446F6E656320636F6E76616C6C697320736F6C6C696369747564696E206469616D2E2043726173207365642070757275732E20446F6E65632066656C69732065726F732C2073656D70657220656765742C2074656D706F7220636F6E7365637465747565722C20736167697474697320717569732C206E69736C2E204475697320696E20616E74652E2043726173206E6F6E207475727069732E204E756C6C612074656D706F722076656C697420616C697175657420747572706973206D6F6C657374696520706C6163657261742E2050726F696E20656C656D656E74756D206665726D656E74756D206D61757269732E20566976616D757320736564206F726369206C6163696E69612064756920706C6163657261742076656E656E617469732E20566573746962756C756D20666575676961742C2074656C6C757320696E20766F6C75747061742072757472756D2C206D61676E61206E69736920756C6C616D636F727065722065726F732C2069642070756C76696E6172206E657175652065726174207574206C616375732E20566976616D7573207365642061756775652E204E756C6C6120666163696C6973692E204D616563656E617320616E74652061756775652C20656C656D656E74756D2075742C20736F64616C65732076697461652C20636F6E64696D656E74756D206E65632C206C6F72656D2E20447569732070656465206F7263692C206672696E67696C6C612061742C20656C656966656E64206E65632C207072657469756D20696E2C20657261742E204E616D2073616769747469732C2074757270697320766974616520636F6E76616C6C69732070686172657472612C206F64696F2073656D207363656C65726973717565206C616375732C206E6563206C6F626F7274697320647569206469616D2076656C2065726F732E20496E2073656D7065722067726176696461206E657175652E0A0A496E7465676572206E756E632E205574207072657469756D20697073756D2073697420616D657420656C69742E20496E206E656320617263752E2053656420766573746962756C756D2076756C70757461746520697073756D2E2050656C6C656E7465737175652074696E636964756E742E204E756C6C61206772617669646120646F6C6F7220696E2074656C6C75732E2043726173207665686963756C612C20646F6C6F722075742070656C6C656E74657371756520616C697175616D2C206572617420656E696D20617563746F72206D617373612C207665686963756C61206C6F626F72746973206F64696F2065726F732071756973207175616D2E2050726F696E2064617069627573206E6571756520696E20656E696D2E2050726F696E20656C69742E20496E74656765722072686F6E6375732074696E636964756E7420656C69742E204675736365206C6F72656D206D657475732C2073656D7065722061632C20766F6C75747061742076697461652C20666163696C697369732075742C2074656C6C75732E20446F6E65632076656C20747572706973207669746165206E69736920706861726574726120706F72747469746F722E204D616563656E617320746F72746F722E204675736365206D692E204E756C6C616D206E6563207475727069732E2053656420736F64616C657320766573746962756C756D206E756E632E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A50656C6C656E74657371756520646F6C6F7220646F6C6F722C206C616F726565742065752C20616C697175657420717569732C207363656C657269737175652073697420616D65742C20617263752E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C616D206375727375732075726E61206567657420656C69742E205175697371756520626C616E6469742073617069656E20616320616E74652E2050726F696E206E756C6C612065726F732C206772617669646120766F6C75747061742C20736F64616C65732076656C2C206D6F6C6C69732065752C206D617373612E204E756C6C612074726973746971756520736F6C6C696369747564696E206E69736C2E20437572616269747572207669746165206C6F72656D2076697461652076656C69742065676573746173206F726E6172652E2041656E65616E20656765742065726F732E20416C697175616D206572617420766F6C75747061742E20467573636520612075726E61206964206F64696F20616C697175657420636F6E76616C6C69732E204375726162697475722073697420616D6574206E69736C20706F7375657265206C656F20706F737565726520646170696275732E2044756973206D6574757320657261742C206C75637475732076656C2C2072686F6E6375732061742C20636F6E76616C6C69732073697420616D65742C20656E696D2E20566976616D75732068656E6472657269742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D206567657420656C69742E0A0A4E756C6C616D2061206E756E632E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206D657475732075726E612C2074696E636964756E742065742C206C6163696E69612073697420616D65742C206C6F626F727469732076697461652C206C6967756C612E2050726F696E206574206D6175726973207669746165206D6920616363756D73616E2070656C6C656E7465737175652E20457469616D207175616D2070757275732C2068656E647265726974207365642C20666575676961742076697461652C20657569736D6F6420656765742C20746F72746F722E20557420616C697175616D206D61676E61207669746165206A7573746F2E2053757370656E6469737365206E6F6E206A7573746F2076656C2076656C697420636F6E64696D656E74756D2074656D7075732E20447569732074656D70757320697073756D2076697461652074656C6C75732E2050726F696E20696E206D617373612E20457469616D20756C6C616D636F727065722064696374756D2074656C6C75732E2050726F696E20616C69717565742066656C6973206174206C656F206C616F726565742070756C76696E61722E20566573746962756C756D20617263752070757275732C206D616C6573756164612073697420616D65742C206375727375732065752C20706C6163657261742073697420616D65742C206E756E632E204E616D206D61737361206F64696F2C20736F6C6C696369747564696E20696E2C2061646970697363696E6720612C20616C697175616D206E65632C2072697375732E20416C697175616D20626C616E6469742068656E647265726974206C696265726F2E204D617572697320677261766964612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204375726162697475722061206E6962682E20557420696E74657264756D206665726D656E74756D206E657175652E2050656C6C656E74657371756520736564206E756E632E204D6175726973207665686963756C61206E697369206574206E756E632E205072616573656E74206C6F72656D2E20446F6E65632073656D7065722E20496E7465676572206575206C6163757320696E2065737420616C697175616D2068656E6472657269742E20566573746962756C756D2065676574206E657175652E205365642073656D706572206C75637475732076656C69742E20437572616269747572206E6962682061756775652C20636F6E6775652065752C2068656E6472657269742069642C20636F6E6775652065742C20656E696D2E20496E746567657220706C61636572617420616C697175616D206C65637475732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20566976616D75732076697461652065726F732E20446F6E65632076656C206E69736C2E0A0A496E20766573746962756C756D20666163696C697369732075726E612E2055742072697375732E204D61757269732070686172657472612E2050656C6C656E746573717565206D61747469732E20496E746567657220737573636970697420616C697175616D20697073756D2E204475697320626C616E6469742C2073617069656E20657420756C7472696369657320636F6E64696D656E74756D2C2066656C6973206D6920656C656D656E74756D20706564652C206E6563207361676974746973206D65747573206D61757269732071756973207175616D2E205175697371756520616363756D73616E20617263752076656C206E756C6C612E20437261732073656D2073617069656E2C20706F72747469746F722069642C20756C747269636965732073616769747469732C206C75637475732065752C206E756C6C612E20496E746567657220717569732065726F732E204D6F726269207365642075726E6120612074656C6C7573207665686963756C612076756C7075746174652E20457469616D206E656320617567756520656765742066656C69732073656D706572207472697374697175652E205175697371756520757420646F6C6F722076656C2072697375732064696374756D20636F6E7365717561742E20536564206567657420646F6C6F7220736564206E756E63206C6163696E696120616C69717565742E2053757370656E646973736520616320746F72746F7220696E20697073756D20706F73756572652076656E656E617469732E20536564206567657420657261742E204E756C6C612066617563696275732E2044756973206C616F726565742C206D6173736120706F72747469746F7220616C697175657420656765737461732C20697073756D206C65637475732072686F6E637573207175616D2C20696E2061646970697363696E672065726F732073656D2075742074656C6C75732E2050656C6C656E74657371756520666575676961742074656D707573207175616D2E20566976616D757320696420646F6C6F7220656765742073617069656E20636F6E7365637465747565722074656D706F722E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120696163756C6973206665726D656E74756D206C696265726F2E204375726162697475722066617563696275732C206D61737361206D616C657375616461206375727375732074696E636964756E742C20657261742073656D20656C656966656E64206D61757269732C20736564206672696E67696C6C61206D6920616E74652061632070757275732E204475697320656C656D656E74756D206C65637475732E204E756E63206F726E617265206172637520657520746F72746F722E20566573746962756C756D2076656C20646F6C6F72206174207075727573206C6163696E6961206672696E67696C6C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E616D20696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204D616563656E61732074696E636964756E742C2065726F73206120656765737461732070656C6C656E7465737175652C2072697375732072697375732064696374756D206C696265726F2C20696420616C6971756574206D65747573206A7573746F20696E206D617373612E2050726F696E20612074656C6C75732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205365642070757275732E20536564206E6F6E20706564652E2041656E65616E206D617373612073617069656E2C20736F64616C65732073697420616D65742C20636F6E7365717561742064696374756D2C20656C656966656E642076697461652C20746F72746F722E20446F6E656320756C747269636573206C6163696E696120656C69742E0A0A4D6F7262692061646970697363696E6720736F64616C657320646F6C6F722E20557420756C6C616D636F7270657220756C74726963696573206573742E20496E2076656E656E617469732074656D7075732061756775652E2053757370656E646973736520746F72746F7220646F6C6F722C20616363756D73616E2065742C20737573636970697420612C2074696E636964756E742075742C206C696265726F2E20416C697175616D207363656C65726973717565206D61676E61207365642066656C69732E2051756973717565207574206E756E632061206D61676E612076756C70757461746520706C6163657261742E20416C697175616D2072686F6E637573207665686963756C61206475692E2053656420746F72746F722E204E756C6C616D2073697420616D6574206469616D2E204E756E63207365642065726F732E20536564206574206F64696F2074696E636964756E7420656C6974206772617669646120636F6E76616C6C69732E20437572616269747572207175697320746F72746F722061206C616375732073656D706572207661726975732E204D6175726973206174206175677565206E6F6E206D6920736F6C6C696369747564696E20616C697175616D2E20496E746567657220756C6C616D636F727065722E2050656C6C656E746573717565207375736369706974207175616D206E6F6E2070757275732E20416C697175616D2061632065726F73206174206172637520756C6C616D636F7270657220636F6E7365637465747565722E2053757370656E6469737365207072657469756D206D6174746973206C656F2E0A0A44756973206174206E756E632E2053656420646F6C6F72206573742C207661726975732061632C20706F7274612065742C2074696E636964756E742068656E6472657269742C2072697375732E20566976616D7573207574206D61676E612E205072616573656E74207574206D61757269732E20496E207075727573206C616375732C206D6174746973207365642C20766573746962756C756D206E65632C2074656D706F722061742C206E69736C2E204372617320756C6C616D636F727065722076656E656E617469732074656C6C75732E20557420646F6C6F722E204D616563656E6173206D616C6573756164612C207065646520612070756C76696E6172206D61747469732C2061726375206469616D207665686963756C612072697375732C207175697320706F72747469746F72206175677565206D6173736120696E2076656C69742E204E756E6320636F6E6775652E204D6F7262692076656C6974206D657475732C2072686F6E6375732065742C20616C697175616D20636F6E7365637465747565722C20756C74726963696573206D616C6573756164612C206C6967756C612E205365642076656C6974206E69736C2C2073616769747469732076697461652C20706861726574726120612C20706F7375657265207365642C206D617373612E204E756C6C6120666163696C6973692E20496E207661726975732C206C6967756C61206964206C6F626F7274697320736F64616C65732C206175677565206F726369206665726D656E74756D2074656C6C75732C2065752070756C76696E6172207269737573206C6967756C6120612073617069656E2E204D6F726269206C616F7265657420697073756D206E6F6E206D692E204E616D20637572737573206C6F72656D207574206D692E20566976616D7573206D61676E6120656E696D2C20706F7375657265206E6F6E2C2073656D70657220717569732C20736F64616C65732065752C20617263752E20457469616D206D692070757275732C207072657469756D20666575676961742C20766172697573207365642C2070656C6C656E74657371756520656765742C206C6967756C612E20496E206C656F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E6563207669746165206F726369206575206F72636920736F6C6C696369747564696E20666575676961742E0A0A5072616573656E74207075727573206D617373612C20657569736D6F642076697461652C2074656D707573206E65632C20636F6E7365717561742068656E6472657269742C206D657475732E2041656E65616E2066656C6973206573742C20656765737461732076697461652C20616363756D73616E20656765742C2070656C6C656E74657371756520696E2C2073617069656E2E204475697320646170696275732070656465206E6F6E2073617069656E2E204E756E632075726E612E20496E74656765722076656C206C696265726F2E204475697320617567756520617263752C2064617069627573206E6F6E2C20666163696C697369732076697461652C20706F73756572652075742C2065726F732E20446F6E6563207669746165206E756E632073697420616D6574206172637520696D706572646965742064696374756D2E204D6F72626920656C656966656E642C206C6F72656D20657520636F6E73656374657475657220766573746962756C756D2C206469616D206E756E63206F726E61726520617263752C2061632074656D706F722066656C697320646F6C6F7220656765742065726F732E2050686173656C6C7573206D617373612073656D2C20736F6C6C696369747564696E2061632C20736F64616C657320677261766964612C206C756374757320612C207175616D2E204E616D206E65717565207175616D2C20766976657272612061742C2076656E656E6174697320717569732C207361676974746973206E6F6E2C20656E696D2E0A0A4E756C6C6120666163696C6973692E2050656C6C656E7465737175652065676573746173206C6163696E6961206573742E205365642074696E636964756E742C2070656465207365642074696E636964756E7420766573746962756C756D2C2075726E6120646F6C6F722061646970697363696E672070757275732C207669746165206672696E67696C6C612066656C697320656C697420696E206E6962682E204E756C6C6120736564206E6973692E204D6175726973207375736369706974207363656C6572697371756520617263752E20457469616D206E6F6E20656E696D2076656C2065726F7320616363756D73616E206D616C6573756164612E204E756E632074696E636964756E7420636F6D6D6F646F206D61757269732E20496E2074696E636964756E7420726973757320717569732075726E612E204E756C6C61206469616D20746F72746F722C20616C69717565742065742C2074696E636964756E7420717569732C20736F6C6C696369747564696E2061632C20746F72746F722E2043726173206E69736C206E657175652C2076756C7075746174652073757363697069742C206D6F6C657374696520717569732C2070756C76696E61722061742C206E756C6C612E204E756C6C616D206163206D65747573206E6563206F64696F20706F7375657265207661726975732E2043726173207365642070656465206E65632064756920706F737565726520626962656E64756D2E204475697320657569736D6F6420756C6C616D636F72706572206C696265726F2E20416C697175616D2066617563696275732070756C76696E6172207475727069732E0A0A496E207574206E65717565206964206E756E63206665756769617420636F6D6D6F646F2E20437572616269747572206469676E697373696D2C2066656C697320617420736F6C6C696369747564696E206C6163696E69612C20656E696D20656C6974207375736369706974206E657175652C20736564206C7563747573206C6F72656D20697073756D20696E206C656F2E204475697320646170696275732C206F64696F207175697320617563746F7220636F6D6D6F646F2C206E69736C206F64696F206D61747469732074656C6C75732C206E65632074696E636964756E7420747572706973206469616D20696E20617263752E2043757261626974757220612073656D2E204E756C6C616D20766F6C7574706174206D61676E612E2050656C6C656E7465737175652073616769747469732C206E6571756520636F6E736571756174207072657469756D206375727375732C20646F6C6F72206C6163757320636F6E73656374657475657220617263752C20736564206C616F72656574206573742075726E61206574206D657475732E2053757370656E646973736520706C6163657261742C20647569206120706F7274612074656D706F722C206C6F72656D20647569206C6F626F72746973206E657175652C207365642076656E656E61746973206469616D20656E696D2069642065726F732E20457469616D206574206E69736C206E6F6E206C656374757320666175636962757320636F6E7365637465747565722E204D6F726269207363656C657269737175652C2073656D206E65632074656D70757320756C6C616D636F727065722C20697073756D206469616D2066657567696174206C6F72656D2C2061206672696E67696C6C612073617069656E20656C69742071756973206E6962682E204E756C6C616D206469616D2075726E612C2076697665727261207365642C2070686172657472612072686F6E6375732C2074696E636964756E742076656C2C206F7263692E20496E746567657220616363756D73616E206D617474697320657261742E204E616D2064696374756D2E204D6175726973206E6563206C656F2E204E756C6C6120696163756C69732E204E756C6C61206E69736C206D692C206461706962757320717569732C207665686963756C6120612C2063757273757320656765742C206F64696F2E0A0A50686173656C6C7573206461706962757320657569736D6F64206E6962682E20566976616D757320696D7065726469657420616E746520696E206C6967756C612E2050656C6C656E74657371756520616363756D73616E2E20496E20696D706572646965742C20647569206120617563746F72206672696E67696C6C612C206D65747573206E6973692063757273757320646F6C6F722C2076656C206C7563747573206C6967756C61206C6F72656D207669746165206D61757269732E205072616573656E74206D617474697320766573746962756C756D20656C69742E20416C697175616D20656E696D206C616375732C2070756C76696E6172206E6F6E2C206C6163696E69612073697420616D65742C20656C656966656E64206E6F6E2C2076656C69742E20566573746962756C756D206163206C656F2E204D617572697320696D70657264696574206A7573746F206163206C65637475732E20536564206D6F6C6573746965206C656374757320736564206475692E20536564206665726D656E74756D2074656D707573206D61757269732E204E616D206F726E617265206F7263692061632074656C6C75732E205574206D616C6573756164612C206C61637573206964206C6163696E696120616363756D73616E2C206469616D20656C69742061646970697363696E67206D657475732C20657420626962656E64756D2073617069656E206E69626820626C616E646974206F7263692E2053757370656E646973736520697073756D2074656C6C75732C20736167697474697320717569732C20766573746962756C756D206E6F6E2C2076756C7075746174652065752C2065726F732E205072616573656E74206174206E756C6C612069642070656465207363656C6572697371756520756C747269636965732E204372617320626C616E646974207072657469756D2074656C6C75732E204D616563656E6173206461706962757320636F6E64696D656E74756D2061756775652E2050686173656C6C75732074696E636964756E74207068617265747261206C6F72656D2E204D6F726269206E6F6E2065726F732E205365642074656D706F722C206E69736C20612074696E636964756E742074696E636964756E742C2065726F73206469616D2064696374756D2073656D2C2076656C206469676E697373696D20616E7465206469616D20736564206D61676E612E205072616573656E74206E6F6E206C6967756C61206964206D65747573206D6F6C657374696520636F6E7365637465747565722E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E64697373652076656C206D692E2043757261626974757220616E7465206E756C6C612C2072757472756D20612C20636F6E76616C6C69732076656C2C207665686963756C612061632C206E756E632E204E756E632073616769747469732C20656E696D2073697420616D657420617563746F722072757472756D2C206D617572697320617263752076756C707574617465206E657175652C20657420657569736D6F64206573742066656C6973207175697320616E74652E20566573746962756C756D207475727069732074656C6C75732C2068656E64726572697420696E2C206C6163696E696120636F6D6D6F646F2C20756C6C616D636F7270657220677261766964612C2072697375732E204D61757269732072686F6E637573206C6163696E69612072697375732E204D616563656E617320736F6C6C696369747564696E2065726174207669746165206E756E632E205072616573656E74207072657469756D2070656C6C656E7465737175652061756775652E20446F6E656320696E74657264756D2E205072616573656E742061632065726F732076697461652065726174206C6F626F72746973206672696E67696C6C612E2041656E65616E20636F6E7365717561742074656C6C75732E204E756C6C6120616363756D73616E20626962656E64756D2066656C69732E204D616563656E6173207072657469756D20616E7465206964206E6973692E2041656E65616E206D6920617263752C2073656D706572207365642C206D61747469732065752C2076656E656E617469732073697420616D65742C20617263752E20446F6E656320616C697175657420657569736D6F64206C656F2E2050726F696E206D61676E61206A7573746F2C2074726973746971756520612C2073656D7065722061632C20736F6C6C696369747564696E20612C206C6967756C612E204D6F7262692076656C69742E20416C697175616D2076656C206E6973692E0A0A496E2061206C6F72656D207574206E756E63206665756769617420636F6E6775652E20446F6E6563206665726D656E74756D20626962656E64756D206475692E2050726F696E207661726975732065737420717569732076656C69742E20446F6E656320616C69717565742073656D20616363756D73616E206D692E2053656420706C6163657261742E204E756C6C616D206163206E6973692061206D61737361206C6F626F727469732073757363697069742E204E756E63206964206C656F2E20416C697175616D206574206D617373612E204E756C6C616D20766573746962756C756D20656C656D656E74756D206D657475732E20496E20636F6E736563746574756572206E6973692076656C206A7573746F2E204D616563656E6173206567657420707572757320736564206D61737361207661726975732070656C6C656E7465737175652E2050686173656C6C75732066617563696275732066656C697320717569732066656C69732E2041656E65616E206F64696F20617263752C20626C616E64697420717569732C20666163696C6973697320696E2C20696D706572646965742065752C206C6F72656D2E204E616D20706F73756572652070756C76696E6172206D692E204675736365207472697374697175652C206D617572697320657420636F6E73656374657475657220756C747269636965732C206D6175726973206C65637475732074656D706F72206A7573746F2C206174206672696E67696C6C61206573742065737420736564206E6973692E20517569737175652066617563696275732E2053656420696E20746F72746F722074696E636964756E7420657374206C6163696E696120696163756C69732E204D616563656E61732061206D617373612E2050656C6C656E7465737175652061206E69626820617420707572757320706F7274612068656E6472657269742E0A0A4E756C6C616D207475727069732E2046757363652061632073656D20736564206F64696F2070656C6C656E74657371756520696D706572646965742E2043757261626974757220696E20617263752E205072616573656E74206C61637573206C616375732C20666575676961742069642C2070756C76696E617220696E2C2074696E636964756E74207365642C206E657175652E204D616563656E61732076697665727261206F64696F206567657420746F72746F722E20496E746567657220616C697175616D2C206C6F72656D2072757472756D2076656E656E61746973206469676E697373696D2C206C6967756C61206D61676E61206D616C65737561646120617263752C2076656C2066657567696174206C6F72656D20697073756D2071756973206D617373612E204D6F72626920616E74652E20566573746962756C756D206D6175726973206C696265726F2C20756C6C616D636F7270657220717569732C20756C74726963657320717569732C20666163696C69736973206E6F6E2C206D617373612E204D616563656E617320696D706572646965742E20416C697175616D206572617420766F6C75747061742E2050656C6C656E746573717565206469676E697373696D2067726176696461206C65637475732E20496E206E696268206F64696F2C20617563746F7220656765742C206461706962757320717569732C206469676E697373696D2076656E656E617469732C20617263752E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20447569732070656C6C656E746573717565206C6967756C612071756973206D617373612E2043757261626974757220636F6E64696D656E74756D2C206A7573746F2065676574206F726E617265206C75637475732C206C6F72656D206C6967756C6120736167697474697320706564652C206120706F727461206E756E63206E756E6320696E206E657175652E20517569737175652066656C6973206D61757269732C20636F6E64696D656E74756D2076697461652C20617563746F722076697461652C2074696E636964756E7420717569732C20706564652E204E756E63206C6163696E696120616E746520696E206C656F2E2050656C6C656E746573717565206C696265726F2E2041656E65616E2061206C6967756C61206574206E756E6320766573746962756C756D20636F6E7365637465747565722E0A0A4675736365206F726E6172652E205072616573656E742069642075726E612E20496E74656765722076656E656E617469732C207175616D206E6F6E20736167697474697320616363756D73616E2C20616E7465206E6962682073616769747469732061756775652C20736F6C6C696369747564696E2061646970697363696E6720646F6C6F722076656C697420657520657261742E2050726F696E207175697320656E696D206575207075727573207665686963756C6120616C697175616D2E204E756C6C612076656C20656E696D2076656C20656C697420736F6C6C696369747564696E206672696E67696C6C612E20416C697175616D206572617420766F6C75747061742E205365642073757363697069742066656C6973207574207475727069732E20457469616D2072757472756D20726973757320696D70657264696574206573742E20416C697175616D20612074656C6C75732061742074656C6C757320636F6D6D6F646F20646170696275732E204D61757269732072757472756D206D61676E61206574206F64696F2E20496E20617420646F6C6F722E20437572616269747572207665686963756C61206C656374757320696E20746F72746F722E204675736365206A7573746F2070757275732C206C75637475732076697461652C206D6F6C6C697320696E2C2070686172657472612061632C2070757275732E204E756C6C616D20706F737565726520696E74657264756D206A7573746F2E20437572616269747572207669746165206C616375732076656C206C656F20636F6E6775652070756C76696E61722E0A0A41656E65616E20656C656966656E64206E6962682076617269757320746F72746F722E2053757370656E64697373652076656C2065726F732E2050726F696E206E6563206469616D206120746F72746F7220756C747269636573206F726E6172652E20416C697175616D207363656C657269737175652066657567696174206A7573746F2E20566976616D757320616E74652075726E612C2061646970697363696E672076697461652C20706F72747469746F722065752C20736F64616C65732065742C2066656C69732E2053757370656E646973736520706F74656E74692E20437572616269747572206163206D6173736120696E206E69736C207361676974746973206D6F6C6C69732E204E616D207175616D206C6967756C612C20636F6E73656374657475657220656765742C20696163756C69732061742C207661726975732065752C206C656F2E204475697320646F6C6F72206C6967756C612C2074696E636964756E742061742C20756C6C616D636F72706572207365642C20616363756D73616E20616C697175616D2C206C6967756C612E2050686173656C6C75732076756C7075746174652C206C6F72656D2061742074696E636964756E742070686172657472612C207269737573206C6563747573206C6163696E6961206D61676E612C20717569732072757472756D20656E696D206D61676E612061742073656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E20447569732069642073656D2061206D617572697320736F6C6C696369747564696E2074696E636964756E742E20457469616D2065752070757275732065752061726375206672696E67696C6C612061646970697363696E672E20566976616D7573206F726E6172652074656D707573206469616D2E2050726F696E20747572706973207175616D2C206C6163696E6961206E6F6E2C20656765737461732061742C20636F6D6D6F646F20656765742C20706564652E205072616573656E742076756C70757461746520726973757320696E206573742E204E756C6C6120666163696C6973692E0A0A557420656C656D656E74756D206C6163696E69612070757275732E2050726F696E2076697461652061726375206163206E756C6C6120636F6E76616C6C697320616C697175616D2E204E756C6C6120636F6E6775652C206C696265726F2069642070656C6C656E746573717565206D61747469732C207175616D206C656374757320706F72747469746F72206469616D2C2061207363656C6572697371756520647569206C696265726F20696E2073617069656E2E204E756C6C616D2066656C6973206469616D2C207665686963756C612076656C2C206D6F6C65737469652075742C20766573746962756C756D20616C697175616D2C2073617069656E2E20446F6E656320636F6E76616C6C69732C2065737420757420656C656D656E74756D20766F6C75747061742C206D617572697320697073756D20677261766964612073656D2C20636F6D6D6F646F20666163696C697369732073617069656E206C65637475732073656D706572206C65637475732E205175697371756520706F72747469746F722065726F73207574206E6962682E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20457469616D206D617474697320726973757320736564206F64696F2E20566573746962756C756D206574206F64696F2E20496E206861632068616269746173736520706C617465612064696374756D73742E204E616D20747269737469717565206D61737361207574206C6967756C612E2051756973717565206E6962682074656C6C75732C207665686963756C612073697420616D65742C2061646970697363696E672061742C20636F6E76616C6C6973206E65632C206C6967756C612E20566573746962756C756D207072657469756D2C206D69206E6563206672696E67696C6C6120626962656E64756D2C20647569206E756E6320736F64616C657320706564652C20612073656D706572206D61676E61206E696268206E6F6E206469616D2E20446F6E6563206D61737361206E756E632C20766976657272612076656C2C20636F6E73656374657475657220706F7274612C2064617069627573206E6F6E2C20697073756D2E2044756973206E69736C206D61757269732C206375727375732076656C2C2073656D706572206E6F6E2C20736F6C6C696369747564696E20626962656E64756D2C2066656C69732E20566573746962756C756D206575206E657175652E0A0A43726173206E656320646F6C6F722E20446F6E6563206C616F726565742074656D707573206C65637475732E20437261732073656420746F72746F7220696E74657264756D206C6163757320656C656966656E64206469676E697373696D2E204D616563656E61732073697420616D657420656C69742E204E756C6C616D207175697320646F6C6F722076656C20647569207068617265747261206C75637475732E20496E2073697420616D6574207175616D2073697420616D6574207065646520756C74726963657320756C7472696365732E204D616563656E6173206469616D2E20496E74656765722075726E612E204375726162697475722064696374756D2C2076656C69742073656420706C6163657261742073757363697069742C206572617420747572706973206665726D656E74756D206A7573746F2C2073656420696E74657264756D206E657175652073656D206574206E6962682E20566976616D757320636F6E73657175617420636F6E76616C6C6973206D61676E612E204E616D20616C697175616D2C2065737420616320626962656E64756D20636F6D6D6F646F2C206D61676E61206573742064696374756D206D692C207669746165206D616C65737561646120656C6974206D61676E61207669746165206F64696F2E204D616563656E61732074656D706F722076756C7075746174652074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206475692E20457469616D20616363756D73616E207065646520636F6E67756520746F72746F722E0A0A4D6F7262692074656D706F72206C696265726F206163206C6F72656D2E20496E20616C697175657420766172697573206D61676E612E20496E20617263752E2050686173656C6C7573206F64696F2E2046757363652074696E636964756E7420616C69717565742066656C69732E20517569737175652076656C69742E20536564206C75637475732E20416C697175616D2066657567696174206672696E67696C6C61206D692E20416C697175616D206D6F6C657374696520766976657272612072697375732E2050726F696E20617263752E20566573746962756C756D206C6F626F727469732074656D707573206E6973692E205072616573656E742061206172637520696E2076656C697420766976657272612072757472756D2E0A0A496E20736564206C65637475732E20446F6E656320726973757320646F6C6F722C20626C616E6469742073697420616D65742C20656C656D656E74756D20636F6E76616C6C69732C20706861726574726120717569732C20706564652E20496E7465676572206F726E6172652E2041656E65616E20656765737461732064617069627573206A7573746F2E20536564207175616D206C656F2C20706F73756572652061742C20656C656D656E74756D2076697461652C20636F6D6D6F646F20656765742C206573742E20416C697175616D206D6F6C65737469652072686F6E63757320656E696D2E2043757261626974757220696163756C697320756C74726963657320706564652E204D6F72626920616C69717565742072757472756D206C616375732E20416C697175616D207175616D2E2053656420636F6D6D6F646F2C2074757270697320696E20706861726574726120706F73756572652C206D6920726973757320696D7065726469657420657261742C206120766573746962756C756D206D617373612074656C6C7573207665686963756C612073656D2E204D6175726973206672696E67696C6C6120756C747269636573206E756E632E204E616D206E69736920656E696D2C20656C656966656E642073697420616D65742C20756C747269636573207365642C206665726D656E74756D206E6F6E2C2061756775652E2050726F696E20636F6E677565206C6F626F72746973206E6973692E204D616563656E61732068656E6472657269742E204E616D20736564206E69736C2E204E756E6320656C656D656E74756D206F64696F2065752072697375732E20496E206D657475732E2050686173656C6C75732067726176696461207072657469756D206C6967756C612E204E756C6C61207669746165206E657175652E204E616D206E69736920746F72746F722C206F726E617265206E6F6E2C20626C616E6469742061742C206375727375732065752C20746F72746F722E0A0A4475697320626962656E64756D20697073756D20696E206E756E6320637572737573206D6F6C65737469652E204E756E63206F7263692E204E756C6C616D206E656320616E7465206E6F6E20657374206469676E697373696D20766976657272612E204D617572697320626C616E6469742C2076656C69742069642066657567696174207072657469756D2C20656C6974206D61676E612070656C6C656E74657371756520646F6C6F722C206174207361676974746973206C616375732076656C69742065676573746173206D61676E612E2050656C6C656E746573717565206375727375732C206469616D20636F6E736563746574756572207361676974746973206672696E67696C6C612C20746F72746F72206E6973692061646970697363696E67206E756E632C20657520766172697573206C6163757320726973757320616320656C69742E204D6175726973206964206E6973692071756973206C656F20657569736D6F642076656E656E617469732E2050656C6C656E74657371756520616320616E74652E204D617572697320617263752073617069656E2C2074656D706F722061742C20706F72747469746F722069642C20636F6E64696D656E74756D2075742C206475692E20457469616D206665726D656E74756D20756C747269636965732061756775652E20437261732075742065726F73206174206A7573746F20756C7472696369657320696163756C69732E2044756973206469676E697373696D2C206E69736C20657420666163696C69736973206665726D656E74756D2C2065726174207075727573206D6F6C65737469652074656C6C75732C20717569732074656D70757320697073756D206C656374757320617420656C69742E204E756C6C61207669746165206C6F72656D2E0A0A41656E65616E2076656C2073656D206574206469616D2073656D70657220636F6E6775652E20496E20626962656E64756D206469616D20717569732074656C6C75732E204E756E6320666163696C6973697320756C74726963696573206E6962682E2043726173206E756E6320656E696D2C2066657567696174207365642C20756C7472696365732076697461652C2073616769747469732076697461652C20697073756D2E204675736365207669746165206E756C6C612E20446F6E65632070656C6C656E7465737175652C2076656C697420696E20706F72747469746F7220656C656966656E642C20657374206E65717565206C6F626F727469732076656C69742C2073697420616D65742072757472756D20616E746520746F72746F72206E656320646F6C6F722E20446F6E6563207665686963756C612E204E756C6C6120666163696C6973692E20536564206567657374617320756C747269636573206E6962682E20446F6E656320656C6974206C65637475732C20636F6E76616C6C697320706F72747469746F722C20616C697175657420646170696275732C206665756769617420656765742C206C6967756C612E2053656420636F6E736563746574756572206A7573746F2E204D616563656E617320612073617069656E2073697420616D6574206E6973692064617069627573206C6F626F727469732E20566976616D7573206C7563747573206C6F72656D206E6F6E206E756C6C612E2053656420656765742065726174207669746165206C696265726F20696E74657264756D20706F73756572652E20437261732070756C76696E61722E204E756C6C616D20696D706572646965742C20646F6C6F722074656D706F72206469676E697373696D20626C616E6469742C206475692073617069656E2072686F6E637573206E657175652C206964206D616C657375616461206175677565206D61676E612073697420616D65742075726E612E204475697320736564206D61757269732E0A0A4D6F72626920616363756D73616E2E20536564206D61757269732061756775652C206672696E67696C6C61206E6F6E2C20617563746F722075742C20617563746F722065742C206F7263692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320757420706564652E20446F6E6563207669766572726120656E696D2076656C206C6F72656D2E2050656C6C656E746573717565206E65717565206D61757269732C20696E74657264756D2065752C2076656E656E617469732069642C20636F6E64696D656E74756D2065752C2073617069656E2E20446F6E656320697073756D20617263752C206C6163696E69612061646970697363696E672C206C616F726565742065742C206375727375732076656C2C2076656C69742E205574207361676974746973206D617572697320717569732072697375732E20496E7465676572206575206F64696F207669746165206C61637573207669766572726120616363756D73616E2E204D6F726269206C656F20616E74652C206469676E697373696D207365642C2076617269757320717569732C20766F6C75747061742076697461652C206E6973692E204E756C6C6120706C61636572617420696E74657264756D20656C69742E20446F6E6563206E65717565206475692C2073616769747469732076697461652C20736F6C6C696369747564696E20717569732C20636F6D6D6F646F2076697461652C206E657175652E204E756C6C612071756973206C6967756C61206F726E617265206C6967756C612064696374756D206F726E6172652E204D61757269732072757472756D2072757472756D206E657175652E2041656E65616E207665686963756C612074656D707573206573742E20446F6E656320766172697573207363656C6572697371756520706564652E20446F6E656320706C6163657261742076756C707574617465206C656F2E204E756C6C616D206E756E63206E69736C2C20706F7375657265206E6F6E2C20666575676961742076697461652C2070656C6C656E74657371756520717569732C206D61757269732E20496E20647569206E657175652C2063757273757320656765742C20736167697474697320656765742C20646170696275732076697461652C206D692E2050726F696E2065676574206573742E0A0A467573636520706F727461206573742E204D6175726973206D61676E612E20416C697175616D20697073756D206C616375732C20756C747269636965732069642C20766573746962756C756D206C75637475732C20616363756D73616E2075742C20616E74652E20536564206D61757269732E205365642061646970697363696E67206C656F2073697420616D6574206D61676E612E2053757370656E646973736520706F74656E74692E204E756E63206D6173736120656C69742C206672696E67696C6C6120656765742C20656765737461732076697461652C206C75637475732076697461652C20646F6C6F722E2050686173656C6C75732071756973206E756C6C61206575206E69736920696E74657264756D20736F6C6C696369747564696E2E204E756C6C616D2069642074656C6C75732E20496E746567657220696163756C697320646F6C6F722061632070757275732E205365642076656C206D692E20437572616269747572206E6F6E206D61676E612073697420616D6574206A7573746F20636F6E64696D656E74756D2076756C7075746174652E20517569737175652074696E636964756E742070656465206575206E69736C2E20566976616D7573206C6F626F727469732E204E756E63206D65747573206D657475732C20636F6E677565207365642C2074696E636964756E74207365642C207072657469756D2061742C206F64696F2E20446F6E6563206120617263752E20496E2073656D206A7573746F2C207665686963756C61207365642C207661726975732069642C20766F6C75747061742061742C2072697375732E205072616573656E7420696163756C6973206D617373612E20496E206172637520656C69742C2068656E64726572697420656765742C20756C6C616D636F7270657220696E2C20706F7274612069642C2074656C6C75732E20446F6E65632073616769747469732068656E647265726974206469616D2E0A0A53757370656E646973736520706F74656E74692E20536564206574206469616D206574206175677565207361676974746973206C6F626F727469732E2050686173656C6C757320646F6C6F722E2055742065742061726375206567657420616E74652074656D706F7220706F73756572652E20416C697175616D206665726D656E74756D207363656C65726973717565206475692E204D61757269732061742070757275732E20446F6E656320657261742073656D2C20766573746962756C756D206E65632C2066617563696275732061632C206D617474697320612C206C656F2E2053757370656E64697373652061646970697363696E67206C6163696E69612073656D2E204E756C6C616D206F72636920617263752C2064696374756D2065742C20666175636962757320766976657272612C20646170696275732065742C206E657175652E2043726173206E756E63206469616D2C2061646970697363696E67206E6F6E2C20736F6C6C696369747564696E20696E2C20696E74657264756D2076656C2C206D617373612E204D61757269732073616769747469732C206A7573746F206174207472697374697175652074656D7075732C206D6175726973206D617572697320616C697175616D20616E74652C2073697420616D657420706F7375657265206469616D206475692065676574206C6967756C612E20496E206469676E697373696D2C206E69736C207574206C6163696E696120636F6E64696D656E74756D2C2065726174206A7573746F20706F72747469746F72206E756C6C612C206E6F6E2067726176696461206C6967756C61206D61676E612065676574206D617373612E20566573746962756C756D207669746165206C6967756C61206174206D6920766573746962756C756D2073757363697069742E2044756973206C616F726565742E204E756C6C6120636F6D6D6F646F206C696265726F2073697420616D6574206C6F72656D2E20557420656C656D656E74756D2073656D2E20496E74656765722076656C20646F6C6F722E204E616D20666163696C69736973206D6920717569732073656D20756C7472696365732073616769747469732E205365642071756973207175616D206174206D65747573206D6F6C657374696520626962656E64756D2E0A0A50726F696E2064756920656E696D2C206C6163696E696120612C20666575676961742061632C20706C6163657261742076697461652C20706564652E205175697371756520656765737461732C206C656F206567657420616C697175616D207072657469756D2C206C696265726F206A7573746F2074696E636964756E742065726F732C2075742065676573746173206175677565207065646520656C656D656E74756D206E6962682E20437572616269747572206D6F6C6C697320736F64616C657320656E696D2E20446F6E65632061756775652E2050686173656C6C757320696420697073756D20706F737565726520647569207072657469756D2066617563696275732E204D6175726973206C756374757320616E74652073656D706572206E69736920696E74657264756D2061646970697363696E672E204475697320646170696275732C206F64696F207175697320766976657272612072686F6E6375732C206A7573746F207175616D20626962656E64756D20646F6C6F722C20696420646170696275732076656C697420657261742076656C20657261742E2046757363652073697420616D6574206E69736C2076656E656E61746973207175616D20756C74726963657320636F6E64696D656E74756D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632072686F6E637573207363656C65726973717565206C6967756C612E20566573746962756C756D206D69206F64696F2C20616363756D73616E2065742C2061646970697363696E6720656765742C206F726E6172652075742C207175616D2E204E756C6C616D20626C616E646974206D6F6C6573746965206D61757269732E20437572616269747572206469676E697373696D206D6175726973206574206C6F72656D2E2053757370656E64697373652061206A7573746F2E204E616D206D617474697320666175636962757320617263752E204475697320626C616E64697420656E696D206E6F6E206D617373612E0A0A4E756C6C616D206C6F72656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E204D617572697320636F6E73656374657475657220706F7375657265206D61757269732E204D616563656E61732074696E636964756E74206D617572697320696E2065726F732E204E756C6C61206575206D65747573206575206F72636920736F6C6C696369747564696E2066617563696275732E2053757370656E646973736520616C697175616D206D6175726973206964206573742E204372617320626C616E646974206475692065742075726E612E204E756C6C6120617263752E2053656420612075726E612E204E756C6C612064617069627573207665686963756C6120746F72746F722E20446F6E65632072697375732E20536564207175616D206D657475732C20656765737461732065752C206375727375732075742C2076697665727261206E6F6E2C206F64696F2E205574206A7573746F206A7573746F2C206D616C6573756164612073697420616D65742C20626C616E6469742073757363697069742C206D6F6C657374696520696E2C206A7573746F2E20566573746962756C756D20636F6E7365717561742C207175616D20616320666575676961742074696E636964756E742C20697073756D206C696265726F20656C656966656E64206F64696F2C206E6F6E20656C656966656E64207065646520697073756D206E6F6E20616E74652E204E756C6C616D2061206D657475732E0A0A4E616D206163206E6973692061742066656C697320637572737573206D61747469732E2050656C6C656E74657371756520636F6E7365717561742073656D2071756973206F7263692E20517569737175652074656D7075732E2041656E65616E20696D70657264696574206D6F6C657374696520706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652065752074656C6C75732E204E756C6C61206469616D2065726F732C20736F64616C65732075742C20736F64616C6573206E65632C2074696E636964756E742061632C206E756E632E204E756E63206C6163696E696120666175636962757320697073756D2E20566976616D75732076656C206E6571756520696E2065726174206665726D656E74756D206C75637475732E204E756C6C612065676574206D65747573206E656320617567756520626962656E64756D20706C6163657261742E20566976616D75732074656D7075732E205072616573656E7420636F6E677565206F726E61726520697073756D2E20457469616D206D61747469732066657567696174206A7573746F2E0A0A416C697175616D206475692E2041656E65616E20636F6D6D6F646F20746F72746F72207669746165206E756C6C612E204D6F72626920657420697073756D2E204D617572697320616320697073756D2E204E616D2076656C207269737573207574206C6563747573206D6F6C6C697320766976657272612E2043757261626974757220656C656D656E74756D206D6F6C6C6973206573742E204E756C6C616D20656C69742E20566573746962756C756D207375736369706974207072657469756D20656E696D2E20566573746962756C756D207574206D617373612E2050726F696E206E65632066656C69732E204D616563656E617320677261766964612C2061726375206E656320636F6E7365717561742073616769747469732C2065726F732074656C6C7573207363656C65726973717565206D61757269732C20766974616520616363756D73616E207175616D207175616D207574206E756E632E20496E7465676572206567657420616E74652065752076656C6974206C616F72656574206D616C6573756164612E204E756E632073616769747469732C206D617572697320766974616520706861726574726120766F6C75747061742C2074656C6C75732074656C6C757320656C656966656E642065726F732C2073697420616D65742072757472756D20697073756D206E69736920612076656C69742E205072616573656E7420766172697573206C656F20657520657261742E20566976616D757320636F6E73657175617420706C6163657261742070757275732E20446F6E6563207072657469756D20656C656D656E74756D206E6962682E2050726F696E20617420656C6974206E6F6E2073656D20616C6971756574206D61747469732E2053656420756C6C616D636F7270657220697073756D2073697420616D657420656C69742E0A0A4D617572697320696E206D657475732E2053757370656E6469737365206D61676E61206C6F72656D2C2066617563696275732076656C2C2074696E636964756E7420717569732C207363656C65726973717565206E6F6E2C2074656C6C75732E2046757363652071756973206C6F72656D2E2050726F696E2061206C616375732073697420616D6574206D617572697320696163756C69732070756C76696E61722E2053757370656E64697373652072686F6E6375732065726F73206E6563206D692E205072616573656E7420657569736D6F642C207475727069732076697461652072757472756D207072657469756D2C206F64696F206D6574757320766F6C7574706174206E657175652C20656765742074656D7075732073617069656E206E657175652073656420657261742E20446F6E6563206665726D656E74756D207075727573206174206C65637475732E204E756C6C616D2073656D2E2046757363652076656C206D6920717569732065726174206C6F626F7274697320706F73756572652E2041656E65616E20656765742075726E612E2053757370656E6469737365206C6967756C612E204475697320696E206E6973692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A4375726162697475722076756C707574617465206C656374757320696420706564652E2050686173656C6C75732065752076656C69742E20457469616D2076656E656E617469732061646970697363696E67206E6962682E20416C697175616D206375727375732070756C76696E61722074656C6C75732E20566573746962756C756D206E657175652E204D6175726973206E6563206A7573746F20657420657261742073656D7065722070656C6C656E7465737175652E204675736365206D61747469732064696374756D20646F6C6F722E20457469616D2065676574207075727573206575206D617373612076617269757320656C656D656E74756D2E2050656C6C656E746573717565206D617373612E20557420756C74726963696573206469616D2073656420697073756D2E204E756C6C616D206469616D2E2050656C6C656E746573717565206964206D61676E61206964206C696265726F2074726973746971756520616C697175616D2E0A0A557420656C656966656E642C20707572757320696420706C6163657261742076656E656E617469732C2075726E6120617567756520616C6971756574206C6967756C612C20696E20756C74726963696573206C656F2072697375732065742074656C6C75732E204D6175726973206574206E756C6C612069642075726E61207472697374697175652074656D7075732E20557420666163696C697369732C2075726E6120657520766573746962756C756D2072686F6E6375732C206C616375732065726F7320636F6E736563746574756572206D657475732C2065742072757472756D20647569206C656374757320696E2070757275732E204E756E632076656C206E69736C206E6F6E20697073756D2074696E636964756E74206D6F6C6C69732E204E616D207175616D206C616375732C206F726E6172652076697461652C2072686F6E637573206E6F6E2C20636F6E677565207365642C206F64696F2E2050726F696E206E696268206475692C20706F7274612076656C2C2076656E656E61746973206E6F6E2C2070656C6C656E7465737175652075742C206E6973692E20536564207472697374697175652066656C69732061206D61676E612E2053757370656E646973736520656765742074656C6C75732E2043726173206772617669646120696D706572646965742076656C69742E20496E74656765722068656E6472657269742072697375732E2050726F696E206F7263692E20416C697175616D20756C6C616D636F72706572206D61757269732071756973206D61757269732E204E756E63206C6163696E696120766573746962756C756D206D657475732E20447569732074656C6C75732E204E756C6C616D2066617563696275732C206C656F2061632076756C70757461746520736F6C6C696369747564696E2C206C656F20646F6C6F7220666175636962757320657261742C207175697320626962656E64756D206F726369206F64696F206E6F6E20617263752E0A0A4E756C6C616D20616363756D73616E206D617474697320646F6C6F722E20446F6E6563206574206475692E205072616573656E7420612066656C6973206D6F6C6C6973206C616375732073656D706572206C6163696E69612E204375726162697475722070656C6C656E746573717565206C7563747573206573742E2050726F696E206E756C6C61206475692C20636F6E64696D656E74756D2076656C2C206661756369627573206E6F6E2C20696E74657264756D2061632C20657261742E204D616563656E6173207363656C657269737175652C206C656374757320696420766F6C757470617420616363756D73616E2C2073617069656E20746F72746F722070656C6C656E746573717565206475692C207365642073656D706572206D61676E612073656D207574206C656F2E2050726F696E206E756C6C612E204E756C6C616D206461706962757320756C6C616D636F727065722073656D2E2053757370656E6469737365207665686963756C61206D6574757320696E206E756E632E2050656C6C656E746573717565206E6F6E207175616D2076656C206172637520756C74726963657320756C6C616D636F727065722E2050686173656C6C757320717569732066656C69732073697420616D65742074656C6C757320756C6C616D636F72706572206665726D656E74756D2E20536564207665686963756C6120736F6C6C696369747564696E2075726E612E20437572616269747572207068617265747261207363656C657269737175652072697375732E2050656C6C656E746573717565206964206D617373612071756973206D6574757320616C697175616D20696D706572646965742E20496E206E756E63206C616375732C206665756769617420696E2C206772617669646120656765742C2076656E656E617469732075742C2074656C6C75732E2053757370656E646973736520706F74656E74692E204E616D20636F6E7365717561742061646970697363696E67206475692E20496E206E756C6C61206E6973692C20666575676961742075742C206665726D656E74756D2076656C2C2067726176696461206E65632C20746F72746F722E20496E207365642061756775652E0A0A457469616D20756C6C616D636F7270657220617567756520617420656E696D2E20496E7465676572206469676E697373696D2E20416C697175616D2070756C76696E617220636F6E677565206E756C6C612E204D6F72626920656E696D206D617373612C206672696E67696C6C6120612C20616363756D73616E20656765742C20636F6E64696D656E74756D206E65632C20657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2041656E65616E2070686172657472612E20457469616D20706F72747469746F722070757275732061206D657475732E20416C697175616D20696E74657264756D2073656D2065676574206A7573746F2E205175697371756520766F6C7574706174206C7563747573206573742E2041656E65616E2061756775652E2050686173656C6C757320647569206C65637475732C20756C747269636573206E65632C20636F6D6D6F646F2076656C2C20617563746F722076656C2C206E6973692E20557420756C7472696365732070656C6C656E746573717565206E6973692E20496E74656765722061632076656C69742065742073656D20696D70657264696574206C75637475732E20467573636520766974616520747572706973206964206175677565206D6F6C6C697320636F6E7365637465747565722E0A0A4D616563656E6173206E6563206C616375732E204D616563656E617320636F6E64696D656E74756D206F64696F2065752066656C69732E204D6175726973207574206E69736C207669766572726120657261742066617563696275732061646970697363696E672E20457469616D20656765737461732E204E756E6320657420646F6C6F72207669746165207269737573206469676E697373696D20636F6D6D6F646F2E204D6F726269206C65637475732076656C69742C2074696E636964756E74206E65632C20616C69717565742076656C2C206D61747469732076697461652C206C6967756C612E204D616563656E617320756C747269636965732073656D70657220646F6C6F722E2053757370656E6469737365206D616C6573756164612E20496E7465676572206D617474697320656C69742E20446F6E656320616363756D73616E2C206C6163757320666163696C69736973207661726975732074656D7075732C206E756C6C6120656C697420706F72746120657261742C2065742072757472756D20656C69742073656D2073697420616D6574206475692E0A0A4D616563656E6173206D6F6C6C6973206D69206E6F6E206E756C6C612E20566976616D7573207475727069732E2053757370656E64697373652061206D657475732E20496E2071756973206D6920696E2074757270697320636F6E67756520617563746F722E204D616563656E6173206C616375732E2053757370656E646973736520736F6C6C696369747564696E2E2050686173656C6C757320706F727461206E756E63206E6F6E206E69736C2070756C76696E617220656765737461732E20536564206E756C6C612E20566573746962756C756D206163206D692E204D617572697320756C7472696369657320636F6E64696D656E74756D206E657175652E204E756C6C612074656D707573206A7573746F2076656C206D617373612E204E756C6C6120737573636970697420636F6E67756520617263752E205072616573656E74206964207475727069732E204D6175726973206E69626820706564652C20657569736D6F642073656D7065722C206D6F6C65737469652061632C2072686F6E6375732076697461652C20616E74652E204D616563656E617320657261742066656C69732C207669766572726120736F6C6C696369747564696E2C20736167697474697320656765742C2070656C6C656E746573717565206E65632C206F7263692E20467573636520756C74726963657320636F6E736571756174206C616375732E20416C697175616D2065726174206D61676E612C20666575676961742061742C207669766572726120612C206D6F6C6C6973206E6F6E2C207475727069732E0A0A446F6E6563206D692E204E616D2064696374756D2070656C6C656E7465737175652073656D2E20446F6E6563206D6F6C6C69732072686F6E63757320656C69742E2050686173656C6C75732072686F6E63757320706564652073697420616D65742072697375732E20446F6E656320656765742061756775652E204D616563656E6173206E6F6E206C65637475732E2050686173656C6C757320736F6C6C696369747564696E206E697369206E65632066656C69732E20416C697175616D207072657469756D2C2065737420656765742073656D70657220636F6E76616C6C69732C206E696268206E756E6320736F6C6C696369747564696E2070757275732C2069642074656D706F722070656465206475692076656C206D61676E612E20566976616D7573206163206C6F72656D2E20457469616D206E69736C20746F72746F722C2061646970697363696E672064696374756D2C20656C656D656E74756D20696E2C20666163696C69736973207365642C206E6962682E2050726F696E206D61757269732E2050726F696E2072757472756D206D6173736120656765742073656D2E204375726162697475722074656D706F722061646970697363696E6720656C69742E204375726162697475722070757275732074656C6C75732C206665726D656E74756D20656765742C20616C69717565742076697461652C20636F6E76616C6C69732061632C206D61757269732E0A0A496E746567657220636F6E7365717561742076656C69742065752065726F732074696E636964756E74207665686963756C612E204E756C6C616D206C6F72656D2073617069656E2C2072686F6E637573206E6F6E2C206D617474697320717569732C20756C747269636965732073697420616D65742C20656E696D2E2043757261626974757220636F6D6D6F646F2C206C696265726F20696E20657569736D6F642073757363697069742C2073656D207075727573206672696E67696C6C6120656E696D2C206163206D6F6C657374696520746F72746F72206F7263692065742076656C69742E20446F6E656320706564652E20457469616D20706C61636572617420636F6E64696D656E74756D207475727069732E2050686173656C6C7573206567657374617320656E696D206E6563206D61676E612E20566976616D757320636F6E64696D656E74756D2C206E756C6C612076656C206C7563747573207472697374697175652C2065726F7320726973757320766573746962756C756D206E756C6C612C20696E207665686963756C61206172637520697073756D2061742066656C69732E20446F6E656320616C697175616D20656C69742061742061756775652E205175697371756520612065726F73206575206C6967756C6120616363756D73616E2064696374756D2E20457469616D207665686963756C61207475727069732071756973206C696265726F2E20416C697175616D206E6F6E206D692E20446F6E6563206574206C656F2E2050726F696E206C656F206C696265726F2C20616C697175616D2074696E636964756E742C20636F6E677565206E65632C2061646970697363696E6720706F7274612C20656E696D2E204E756C6C61206C6F626F727469732C20746F72746F722073697420616D657420696D7065726469657420756C6C616D636F727065722C20646F6C6F72206F726369206D616C65737561646120706564652C207365642067726176696461206E6962682075726E612076656C206C6F72656D2E20536564207068617265747261206D616C6573756164612065726F732E205175697371756520657569736D6F6420616C697175657420657261742E2053757370656E646973736520616C6971756574206D61747469732070757275732E0A0A4E756E63206964206E756C6C612071756973206A7573746F20636F6E67756520736F6C6C696369747564696E2E205072616573656E742065726174207475727069732C2072686F6E6375732065752C207072657469756D2065752C2070656C6C656E74657371756520612C206E6962682E20566976616D75732074656D7075732E2043726173206E65632072697375732061742074757270697320696D70657264696574206C6F626F727469732E205574206D61747469732E204D616563656E6173206573742066656C69732C2070656C6C656E746573717565206E6F6E2C20696D70657264696574207365642C20656C656966656E642074696E636964756E742C206C6F72656D2E20496E2074696E636964756E742E205365642076656C206C656F2E20446F6E65632065742075726E6120696E207475727069732068656E64726572697420626C616E6469742E20446F6E656320636F6E64696D656E74756D20616363756D73616E206573742E2055742070686172657472612C206D65747573207669746165206D617474697320636F6E7365637465747565722C206C656F207175616D2076756C707574617465206F64696F2C206E6563206C616F72656574206E6973692076656C697420657520657261742E20496E7465676572206C65637475732061756775652C206567657374617320696E2C20696E74657264756D2065752C2076656E656E617469732076656C2C2073617069656E2E2051756973717565206574206573742076697461652065726F73206C616F72656574206C6F626F727469732E204E756C6C616D207574207269737573206E6F6E206E756C6C6120706C6163657261742061646970697363696E672E205072616573656E7420646170696275732E20457469616D20612066656C69732E20557420736F64616C657320636F6E736571756174206D61757269732E2044756973206C6F72656D2066656C69732C206C756374757320612C2074726973746971756520696E2C206D6F6C65737469652061742C2072697375732E20536564207665686963756C6120626962656E64756D2074656C6C75732E204E616D20636F6E73657175617420657569736D6F64206C616375732E0A0A41656E65616E20746F72746F7220656C69742C2067726176696461206E65632C206665726D656E74756D2065752C206C6F626F727469732069642C20697073756D2E204D616563656E61732065752070757275732E204372617320616320747572706973207574206E69736920696163756C69732072686F6E6375732E204E756C6C61207075727573206D657475732C206469676E697373696D206E65632C2074696E636964756E742076697461652C20646170696275732065752C206E6962682E204675736365206C6F626F727469732C206E756E63206174207669766572726120656C656966656E642C206A7573746F20747572706973207363656C657269737175652065726F732C2061632070656C6C656E746573717565206D65747573206E69736C2061742070757275732E2053656420656C656D656E74756D2074656C6C75732073656420656E696D20696E74657264756D20626C616E6469742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E746567657220756C7472696369657320616C6971756574206F64696F2E204D61757269732065676574206E756E63206120697073756D20756C74726963657320736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2041656E65616E20616363756D73616E2E20446F6E65632073617069656E206C65637475732C20636F6E6775652061742C20706F7274612069642C2068656E6472657269742076697461652C206E69736C2E204375726162697475722076656C207175616D2076656C206E6571756520616363756D73616E206C616F726565742E204D6F7262692073617069656E206573742C207072657469756D20696E2C20636F6E7365637465747565722061632C206D6F6C6C69732075742C206C696265726F2E20446F6E65632074696E636964756E742061646970697363696E67206D657475732E204E756E6320766573746962756C756D20656765737461732061756775652E20446F6E6563207363656C65726973717565206475692075742073656D2E2053757370656E64697373652076656C206D6574757320696420657374206D6F6C657374696520696163756C69732E0A0A566976616D75732070686172657472612C20656C6974206575206D616C65737561646120626C616E6469742C206469616D20746F72746F72206D6F6C6C6973206475692C207365642070756C76696E6172206D61737361206E756E63206574206D61676E612E2053656420706C61636572617420656C697420617563746F7220746F72746F722E204E756C6C6120616320657261742E2050656C6C656E74657371756520636F6E7365637465747565722C2064756920636F6E76616C6C69732074696E636964756E7420636F6E64696D656E74756D2C2073656D206F64696F20766F6C7574706174206C696265726F2C206E6F6E20656C656D656E74756D2066656C6973206E65717565206E6563206F64696F2E204D616563656E61732068656E6472657269742065726F73206964206469616D2E204D61757269732076656C207075727573206163206F72636920636F6E76616C6C697320636F6E76616C6C69732E205365642073697420616D6574206C616375732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652064696374756D20766172697573206C616375732E204D61757269732065676574206E69736C2E2053757370656E646973736520706C6163657261742C206E756C6C61206E6F6E206F726E617265206469676E697373696D2C206E69736C206469616D2073616769747469732074656C6C75732C20696E2073656D706572206E69736920646F6C6F72206174206E6962682E204475697320756C6C616D636F7270657220766976657272612066656C69732E20496E746567657220612074656C6C75732E2053757370656E64697373652065676574206E756E632E2041656E65616E206469616D206573742C20616363756D73616E2069642C20737573636970697420696E74657264756D2C206672696E67696C6C612076697461652C206A7573746F2E2050726F696E20706564652E204D616563656E6173206174206E6571756520696E206E6571756520766573746962756C756D20656C656966656E642E0A0A566573746962756C756D206E756C6C61206C6F72656D2C20706F72747469746F7220656765742C20657569736D6F642061632C20616C697175616D2061742C206E69736C2E204D616563656E6173206574206573742065676574206D6173736120766172697573206C6F626F727469732E20496E206D692E204475697320706F72747469746F72206665726D656E74756D2070757275732E20446F6E65632063757273757320696D70657264696574206C6967756C612E204D6F726269206574206C6967756C6120657420616E7465206D6F6C6573746965207665686963756C612E204D61757269732073656420646F6C6F722E2053656420696D706572646965742066656C69732075742073656D2E20536564207669746165206E6571756520656C656D656E74756D206C656F20617563746F72206665726D656E74756D2E2044756973206665756769617420756C6C616D636F7270657220657261742E2041656E65616E2070757275732E204D6F726269206665726D656E74756D20766573746962756C756D206573742E2050656C6C656E7465737175652076656E656E61746973206D61757269732E2050686173656C6C75732070756C76696E61722E20496E746567657220697073756D206C65637475732C20696163756C697320612C206C6163696E69612069642C20616363756D73616E2069642C20617263752E2050686173656C6C7573206174206573742E204675736365206E65717565207175616D2C20756C747269636965732069642C20696163756C69732076656C2C20646170696275732076697461652C206C616375732E20496E206C6F626F7274697320636F6E76616C6C697320616E74652E204E756C6C61206E756E632070757275732C2076756C70757461746520696E2C2068656E6472657269742065742C20626C616E6469742065742C206C6967756C612E0A0A50656C6C656E746573717565206C656F206D657475732C20736167697474697320696E2C206D6F6C65737469652076697461652C2064696374756D20696E2C20706564652E204D6F726269207072657469756D2066656C6973206E6563207175616D2E2050656C6C656E746573717565206D617474697320616E746520736564207175616D20736167697474697320646170696275732E2053757370656E64697373652073617069656E2E205072616573656E7420626962656E64756D20696163756C697320746F72746F722E20447569732061206E69736C2E2041656E65616E206D692E20446F6E65632064696374756D206172637520696E206573742E204D6F72626920696E74657264756D2076756C70757461746520697073756D2E2041656E65616E2073697420616D6574206D61676E61206E6F6E206E69736C2074726973746971756520706F73756572652E2050686173656C6C75732076656C6974206D657475732C2074656D706F722061632C206665726D656E74756D20656765742C20636F6E64696D656E74756D206E6F6E2C2076656C69742E20566573746962756C756D2073697420706F73756572652E0A0A4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204372617320616C6971756574206D61737361206E6563206475692E20437261732061726375206E756E632C2068656E6472657269742061632C20656C656966656E642065752C20756C6C616D636F72706572206E65632C2074656C6C75732E205365642070686172657472612070757275732073697420616D6574207175616D2E20437572616269747572206D6F6C6C69732E204E616D20766974616520706564652E20457469616D207269737573206D617373612C207665686963756C612073697420616D65742C207068617265747261206E65632C20736F6C6C696369747564696E2075742C206475692E20446F6E65632065676573746173206A7573746F206174207175616D2E2050726F696E206E69736C2072697375732C20766573746962756C756D206E65632C207072657469756D2076697461652C207472697374697175652061632C206C6F72656D2E20416C697175616D206572617420766F6C75747061742E204372617320736564206E6962682E2050656C6C656E74657371756520736F6C6C696369747564696E20657569736D6F642061756775652E0A0A457469616D206672696E67696C6C6120736F6C6C696369747564696E206F7263692E204D61757269732063757273757320656C69742071756973206C616375732E204372617320746F72746F722E20496E2061646970697363696E672C206C656374757320696420617563746F7220766573746962756C756D2C206E65717565207065646520616363756D73616E20646F6C6F722C206E6F6E20696D70657264696574206D61676E61206469616D20616363756D73616E2076656C69742E2053757370656E6469737365206174206C696265726F207574206E69736920626C616E6469742073616769747469732E2050686173656C6C7573206E6F6E206D61757269732E20467573636520656C656D656E74756D2073616769747469732073656D2E2053757370656E646973736520616C697175616D20656C656966656E642074656C6C75732E2050726F696E206C6967756C61206C6F72656D2C20696D7065726469657420717569732C2076656E656E617469732069642C20696163756C6973206D6F6C6C69732C206E69736C2E20457469616D20636F6E76616C6C69732070656465206174206D617373612E204D6F72626920616363756D73616E20647569206574206D61757269732E0A0A53656420736564206F7263692E204E756E632070757275732E2053757370656E646973736520706F74656E74692E205574206C7563747573206672696E67696C6C61206D61757269732E20446F6E6563206E6962682E2050686173656C6C757320706F7274612E2050686173656C6C75732073697420616D6574206F64696F20736564206D61676E6120736F64616C65732070686172657472612E2043726173206C65637475732E2053757370656E6469737365206C696265726F20697073756D2C20636F6D6D6F646F206E65632C20666163696C6973697320696E2C207375736369706974206C6F626F727469732C206C6967756C612E2044756973206D61737361206E756C6C612C2073656D7065722065742C20636F6E736571756174206E65632C2070686172657472612065752C20656C69742E20566976616D757320756C7472696369657320616C697175616D206F64696F2E20566573746962756C756D2073697420616D6574206D617373612E2053656420636F6E736571756174206C61637573207365642075726E612E20457469616D2066617563696275732066656C69732076656C206F7263692E2050686173656C6C757320756C6C616D636F727065722E2041656E65616E20636F6E736563746574756572206C61637573206174206C696265726F2E0A0A436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204475697320666163696C697369732C206C6967756C6120766974616520636F6E64696D656E74756D207363656C657269737175652C2076656C6974206F72636920677261766964612066656C69732C2076656C20756C74726963696573207175616D206D69206E6F6E206469616D2E20566976616D757320617563746F72206D65747573206E6F6E206C696265726F2E205072616573656E74206C6967756C61206E6973692C20636F6D6D6F646F20636F6E64696D656E74756D2C206D6F6C65737469652065742C20766976657272612065742C206A7573746F2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320736F6C6C696369747564696E2E204E756E6320626C616E6469742063757273757320697073756D2E2041656E65616E206E6563206C6967756C612075742074656C6C757320736F64616C6573206D61747469732E20496E74656765722073656D2E20416C697175616D206964206C6967756C612E2053656420746F72746F72206D61757269732C20626C616E6469742076697461652C206375727375732076656C2C20656C656D656E74756D2065742C206E756C6C612E20416C697175616D207363656C65726973717565206D65747573206574206E69736C2E20447569732061646970697363696E67206D61676E61206174206E657175652E20517569737175652076756C70757461746520656C656966656E64206E756E632E20416C697175616D206567657420656C69742E2050686173656C6C757320647569206F64696F2C20626962656E64756D2073616769747469732C20766573746962756C756D2069642C206469676E697373696D20696D706572646965742C206F7263692E204E756C6C616D2065752066656C6973206E6F6E206E756E63206C6163696E696120736F64616C65732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A53757370656E64697373652070656C6C656E7465737175652C206C696265726F206D617474697320756C7472696369657320616363756D73616E2C20746F72746F7220746F72746F72206D616C6573756164612073656D2C20657420736F64616C6573206C696265726F206F64696F20616320697073756D2E20566976616D75732071756973206D61676E61206E656320657374207375736369706974206C6F626F727469732E20437261732074656D70757320706F7375657265206E756E632E205175697371756520757420656E696D20612066656C697320656765737461732073656D7065722E20536564207068617265747261206D6174746973206E657175652E20467573636520747572706973206E756E632C20636F6E677565207365642C20636F6E736571756174206E6F6E2C20636F6E677565207365642C206E756C6C612E2053757370656E646973736520766172697573206C6F72656D20696420726973757320706F72746120766573746962756C756D2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204675736365207365642070757275732E20496E20612066656C69732E20496E7465676572206567657374617320617563746F72206F7263692E204D617572697320756C747269636573207375736369706974206E69736C2E204E756C6C616D2070757275732E0A0A437261732074656D706F722061646970697363696E6720697073756D2E2055742071756973206D692E204D616563656E617320696E206A7573746F207574206E756C6C6120636F6E6775652070686172657472612E2050656C6C656E746573717565207574206C696265726F20657520646F6C6F722076656E656E617469732073757363697069742E205072616573656E74206665756769617420636F6E736563746574756572206E6962682E204D6F7262692066617563696275732073656D206E6F6E2066656C69732E20496E2068656E6472657269742061726375206163206D617373612E20496E20616363756D73616E20756C747269636573206D692E2050726F696E206D616C65737561646120617563746F722066656C69732E2043757261626974757220696E74657264756D2E20536564206469616D20697073756D2C20756C7472696369657320696E2C2074656D706F722073697420616D65742C207669766572726120696D706572646965742C20656C69742E204D6F726269206D6F6C6573746965206E6973692E204D617572697320697073756D2E2046757363652064696374756D206D6F6C6C6973206D61676E612E204475697320636F6D6D6F646F206469676E697373696D206E756C6C612E20566573746962756C756D20617567756520656E696D2C20756C7472696369657320717569732C20696163756C6973206E65632C2074696E636964756E742076697461652C206469616D2E204D6175726973206C6163696E69612074656D70757320697073756D2E20536564206174206D61757269732E205574206C6F72656D2E20446F6E6563206C696265726F2E0A0A4475697320696163756C6973206C6163696E6961206C65637475732E2041656E65616E20636F6E76616C6C69732065726F7320616320616E74652E205365642071756973206F726369206E656320726973757320617563746F72206672696E67696C6C612E2050686173656C6C757320666163696C6973697320656C656D656E74756D206E6973692E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E6320706F727461206C61637573206E656320616E74652E204D6F726269206D617572697320657261742C2061646970697363696E6720696E2C2070756C76696E6172206E65632C206C6F626F72746973206E65632C206F64696F2E20557420656C656966656E64206C656374757320736564207175616D2E204E756C6C616D206D6F6C6C69732E20496E206E6F6E20747572706973206574206E69736C2068656E64726572697420626C616E6469742E204475697320656C656D656E74756D2E204E756E63206E6563206C696265726F2E2053757370656E646973736520766573746962756C756D207269737573206E6F6E20706564652E204D6F72626920696D70657264696574206F64696F2073697420616D6574206C696265726F2E2053656420736564206D6173736120766974616520697073756D206D61747469732074696E636964756E742E204E756C6C61206E656320746F72746F72207669746165206C696265726F20766F6C75747061742074656D7075732E20446F6E656320616C697175616D2E0A0A4475697320736564206E756E632E2043757261626974757220747572706973206E756C6C612C207665686963756C61207365642C206C756374757320717569732C20656C656D656E74756D20656765742C2066656C69732E204D616563656E61732065742070757275732E204D616563656E6173206C656F2074656C6C75732C2074696E636964756E7420612C20666163696C697369732076697461652C206C6F626F727469732073697420616D65742C2076656C69742E20446F6E656320636F6E76616C6C69732073617069656E2E204D616563656E6173206D6F6C6C6973206F64696F206575206E6962682E20457469616D20677261766964612E20496E7465676572206D6F6C65737469652C2073617069656E206575206D6F6C6573746965206C6163696E69612C206E756E63206E69626820616C697175616D206C6967756C612C2065752073616769747469732074656C6C7573206572617420736F6C6C696369747564696E206F64696F2E20447569732065742072697375732E2050686173656C6C7573206E697369206E657175652C20706C616365726174206E65632C20636F6E64696D656E74756D206E6F6E2C20756C7472696365732065752C2073656D2E20557420706564652E20457469616D206E756C6C61206D657475732C20766F6C75747061742069642C20636F6E76616C6C6973207365642C2073757363697069742076656C2C2075726E612E20446F6E65632076656C20656C69742E205574206C656F206E657175652C2076656E656E617469732066617563696275732C206C6163696E6961206E65632C2074696E636964756E742065752C20656E696D2E2043726173206964206475692061206C696265726F207068617265747261206469676E697373696D2E20446F6E65632065726F73206C656F2C20706F72746120717569732C206C616F726565742075742C2070656C6C656E74657371756520766F6C75747061742C206C65637475732E0A0A4E756C6C616D20626C616E6469742E20416C697175616D206572617420766F6C75747061742E2046757363652061646970697363696E6720656E696D2E2053757370656E6469737365206E6F6E206475692071756973206C6967756C6120706F72746120766573746962756C756D2E20446F6E65632065752074656C6C75732076656C206C6F72656D207072657469756D20706F72747469746F722E205072616573656E74206C75637475732E20416C697175616D2061632065726F7320696E206D6173736120646170696275732074696E636964756E742E20446F6E6563207574206D61676E612E20457469616D20617563746F72206C616375732073697420616D6574206C616375732E2053656420756C7472696369657320697073756D206E656320656C69742E205175697371756520612065737420696E207075727573207375736369706974207472697374697175652E0A0A41656E65616E20736564206475692076656C20646F6C6F722070756C76696E6172206C616F726565742E20566976616D7573207665686963756C61206C6F72656D20696E20706564652E20566976616D7573206574206469616D2E20496E7465676572206163206F64696F2076656C206469616D2068656E64726572697420626962656E64756D2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E756C6C612061206E6973692E2050686173656C6C75732074696E636964756E74206475692076697461652061756775652E20447569732066617563696275732C2064756920696E74657264756D206672696E67696C6C612074696E636964756E742C206F64696F20656C697420766573746962756C756D206C696265726F2C206163206D6F6C6573746965206D61676E61206C6563747573206964206C616375732E2041656E65616E206C6967756C612E204E756C6C6120666163696C6973692E0A0A46757363652076656C2073656D2065752076656C6974206672696E67696C6C61206F726E6172652E2053656420666575676961742074696E636964756E742066656C69732E204E756C6C616D2066656C6973206D692C20657569736D6F642073697420616D65742C206D6F6C6C69732061742C20736F64616C657320656765742C2061756775652E204E616D20696D70657264696574206E6962682061742076656C69742E2053656420757420657261742E20496E206475692E204E756C6C6120666163696C6973692E204E756C6C616D206175677565206C696265726F2C2074696E636964756E74206E65632C207072657469756D2065752C2070756C76696E617220696E2C206475692E204D6F7262692076697461652066656C69732E2050656C6C656E7465737175652076656C206A7573746F2076656C2076656C6974207361676974746973206D616C6573756164612E2050726F696E207665686963756C6120626C616E646974206D617373612E20457469616D2074696E636964756E742070686172657472612075726E612E20496E206D65747573206573742C20617563746F72206E65632C20626C616E64697420612C20637572737573206E65632C207175616D2E204D6175726973206163206D657475732061206C696265726F20636F6E6775652066617563696275732E204D6175726973206D617572697320646F6C6F722C20736F64616C657320696E2C206375727375732075742C20736F64616C65732072757472756D2C2065726F732E2051756973717565206D61757269732065726F732C2073616769747469732076697461652C206C6F626F727469732075742C20656C656966656E642069642C206E6973692E0A0A41656E65616E206E657175652E20566573746962756C756D20656765737461732070656C6C656E746573717565206C6967756C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2050686173656C6C7573207361676974746973206A7573746F2076656C2072697375732E20536564207072657469756D206E657175652076697461652075726E612E2050656C6C656E74657371756520636F6E677565206C696265726F206964206C6F72656D2E204D6175726973206C656F206C6F72656D2C20626C616E6469742073697420616D65742C20636F6E76616C6C697320717569732C20636F6E736563746574756572207365642C2065726F732E204D61757269732074696E636964756E742C20656E696D2061206772617669646120657569736D6F642C206D61676E61206E756C6C61206665726D656E74756D206C696265726F2C207669766572726120656765737461732076656C6974207175616D20657420746F72746F722E20566976616D757320616C6971756574206D61737361207669746165206A7573746F2E204E756C6C6120636F6E677565206C6163757320616320656C69742E0A0A50686173656C6C757320636F6D6D6F646F207175616D2076656C206C6967756C612E2050726F696E206E6F6E206D657475732061742065726F732070756C76696E6172206C75637475732E204D6175726973206469616D206C6F72656D2C20706F737565726520717569732C20677261766964612065742C2074696E636964756E74206E65632C206C6967756C612E20536564206469616D2E20416C697175616D20656C6974206C65637475732C2068656E6472657269742075742C20696D706572646965742073697420616D65742C207072657469756D2073697420616D65742C20697073756D2E204D6175726973207665686963756C61206E69736C20696E206475692E204375726162697475722065676574207175616D207574206D61676E6120656C656D656E74756D206665726D656E74756D2E204D6175726973207363656C657269737175652E2051756973717565206C616F726565742E20457469616D2074656D707573207475727069732E2050656C6C656E746573717565206175677565207175616D2C2068656E647265726974207365642C2074696E636964756E742061742C2070686172657472612061742C206E69736C2E20416C697175616D206C616375732E2053757370656E646973736520706F74656E74692E2041656E65616E2076656C6974206C696265726F2C20756C74726963657320696E2C206C6163696E69612065752C206C75637475732076656C2C20616E74652E20457469616D2064696374756D206D6920696E2066656C69732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20467573636520677261766964612064617069627573206E69736C2E2043726173207669746165206E69736C2E0A0A4D616563656E6173206469676E697373696D2C206C6967756C61206E6F6E20706F727461206375727375732C20656E696D206E756E63206D616C6573756164612073656D2C20657520706F72747469746F72206E756C6C612075726E61206575207175616D2E2046757363652065726F732E20416C697175616D2065726F732E204E616D20617563746F722E204E756C6C61206D6F6C657374696520706F727461206573742E2053757370656E646973736520706F74656E74692E20566976616D7573206D6F6C6573746965206C6F72656D2073656420657261742E20536564206567657420697073756D2E20496E746567657220616C697175616D2070756C76696E6172206E756C6C612E204372617320616C69717565742073656D207574206E756E632E2046757363652066617563696275732074656D707573206C65637475732E204372617320736F64616C65732C206E69736920616320666163696C6973697320756C7472696365732C2065726F73206172637520646170696275732073617069656E2C20657420756C747269636573206D61757269732074656C6C7573206E6F6E20646F6C6F722E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20437261732063757273757320766172697573206D657475732E205574207475727069732E20566976616D7573206567657420746F72746F722E0A0A536564206C616F726565742C2076656C6974206E6F6E20616363756D73616E206375727375732C206E756E632075726E6120706F7375657265206A7573746F2C20696E2064696374756D206C6563747573207065646520696420616E74652E20437261732076756C7075746174652E204372617320636F6E677565206475692073656420656C69742E2050726F696E206C616375732073656D2C20756C7472696365732061742C20636F6E73657175617420696E2C2074656D706F7220717569732C206D657475732E2050726F696E2076656C20617263752E204E616D20657569736D6F642068656E64726572697420656C69742E20557420657261742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2053656420706F73756572652E204D6F7262692065726F732075726E612C2073656D7065722061742C2073656D706572206E6F6E2C20636F6E76616C6C697320717569732C2076656C69742E204D616563656E6173206F7263692E20566573746962756C756D206C6F626F7274697320747269737469717565206D657475732E20566573746962756C756D206C6F72656D206E756C6C612C20736F6C6C696369747564696E2076697461652C20636F6E64696D656E74756D20717569732C20617563746F722075742C206475692E20566976616D757320766573746962756C756D206D61676E61207574206E6973692E2043757261626974757220656C656966656E64206475692076656C206E756E632E20437572616269747572206D6175726973206C616375732C206D616C6573756164612073697420616D65742C207375736369706974207365642C2072757472756D206C75637475732C2074656C6C75732E20496E746567657220666163696C697369732075726E61207669746165206C65637475732E0A0A41656E65616E207175616D206C656F2C206C6F626F7274697320717569732C206D616C6573756164612065752C2076756C7075746174652076697461652C206E69736C2E205072616573656E7420656765742065726F732E205574206665726D656E74756D20747572706973206964207175616D2E204E616D20746F72746F722E205072616573656E74206E6563206F7263692E204E756C6C6120626962656E64756D2061646970697363696E672061756775652E20557420636F6D6D6F646F2C206D61676E61206964206D616C65737561646120677261766964612C206175677565206F64696F206D616C657375616461206D692C20706F727461206D616C65737561646120656C697420657374207669746165206469616D2E204D6175726973206E6F6E206E756C6C612E2053757370656E64697373652074696E636964756E742C206E756E6320756C7472696369657320706F7274612076656E656E617469732C206D6920706564652074696E636964756E74206C696265726F2C20656765742076617269757320616E7465206C696265726F207574206C6967756C612E20437572616269747572207072657469756D20706F72747469746F7220746F72746F722E0A0A4D616563656E617320766974616520656C69742065676574206E69736920646170696275732064696374756D2E204E756E6320696E206C696265726F2E204E756C6C612064696374756D206F726369206575206572617420617563746F72206C6F626F727469732E2050686173656C6C75732072697375732E2053757370656E646973736520706F74656E74692E2053757370656E646973736520706F74656E74692E205072616573656E742061646970697363696E6720636F6E73657175617420656C69742E20496E74656765722069642061756775652E205072616573656E7420696E206A7573746F206E6563206D61676E6120646170696275732070756C76696E61722E2044756973206E69736C2E2053757370656E6469737365206163206F64696F2E20566976616D757320696D706572646965742E20446F6E6563206E6F6E2076656C69742073697420616D6574207269737573206469676E697373696D20636F6E6775652E204E616D20616C697175657420706F73756572652076656C69742E2043726173207475727069732E204D6F726269206D616C657375616461206469676E697373696D206D692E0A0A536564206C656F206E657175652C2076617269757320717569732C2076656E656E61746973207365642C207068617265747261207365642C206573742E204D6F72626920626C616E6469742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D2073656D7065722070656C6C656E746573717565206D692E2055742076656C206C6F72656D2E204E756E63206D6920746F72746F722C206C616F726565742061742C2066617563696275732065752C2074696E636964756E742073697420616D65742C20657261742E20447569732074656D706F72206D616C65737561646120697073756D2E2050686173656C6C757320616C69717565742E20446F6E656320657420656C69742E2050656C6C656E7465737175652070757275732E20566573746962756C756D2072757472756D2073656D706572206E6962682E204E756C6C6120666163696C6973692E2050686173656C6C757320657420656E696D2073697420616D657420616E746520766573746962756C756D207665686963756C612E2050686173656C6C7573206964206E69736C2E20446F6E6563206D6F6C6C6973206C656F2061742065726F732E204D61757269732070656C6C656E746573717565206E657175652061742070757275732E204D6F726269207175697320646F6C6F7220617420697073756D207363656C6572697371756520736F64616C65732E20457469616D20766F6C7574706174207475727069732061206D657475732E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206C6F72656D206C6F72656D2C20766573746962756C756D2061632C20657569736D6F6420656765742C20756C6C616D636F72706572206469676E697373696D2C2076656C69742E0A0A43756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204372617320756C7472696365732C206E6962682076656C20616C697175616D20766573746962756C756D2C2065726F7320656E696D2076656E656E61746973206475692C20696420696163756C697320656E696D206E756E632076656C206D617373612E204D6F72626920656C656966656E64206F726369206574206D617373612E20416C697175616D206572617420766F6C75747061742E204E756C6C61206D6F6C6C69732065676573746173207475727069732E20496E20736F64616C6573206E756E63206567657420746F72746F722E2053656420697073756D2065726F732C2074656D706F7220717569732C20616C69717565742076697461652C20696D70657264696574206E6F6E2C206C6F72656D2E2050656C6C656E746573717565207175697320656C6974206964206D69206C756374757320646170696275732E20536564206E756E6320617263752C2072686F6E637573206E65632C20636F6E76616C6C697320717569732C206375727375732061742C206E657175652E204D617572697320636F6E76616C6C697320707572757320617420657261742E2050656C6C656E74657371756520766573746962756C756D2E20566976616D7573206672696E67696C6C6120656C697420617420617263752E204E756C6C616D20616C697175657420656E696D206E656320617263752E204E616D20696420746F72746F722E204E756C6C612071756973206E756E632E20557420617263752E2053757370656E646973736520706F74656E74692E2050656C6C656E74657371756520756C6C616D636F72706572206C6967756C6120696420617263752E0A0A4E616D206E6F6E206C696265726F207669746165206E69736C207363656C65726973717565206672696E67696C6C612E20517569737175652076617269757320616E7465206964206D657475732072686F6E637573206672696E67696C6C612E204E756C6C6120666163696C6973692E205072616573656E7420656C656966656E6420706F72747469746F72206C6967756C612E20457469616D207175697320646F6C6F72206E6F6E20617567756520636F6D6D6F646F20617563746F722E20446F6E65632061206D692E20566573746962756C756D2074656D706F722E20446F6E65632066656C69732075726E612C20617563746F722061742C206375727375732064696374756D2C20677261766964612069642C20617263752E2041656E65616E2064696374756D206D616C65737561646120646F6C6F722E20566976616D7573206D61747469732E2050686173656C6C757320657520706564652E2046757363652061646970697363696E67206A7573746F206672696E67696C6C61206D657475732E20457469616D20616E74652E20496E7465676572206D6F6C6C6973206D617373612071756973206E756E632E20496E74656765722064696374756D206E65717565206C756374757320656E696D2E0A0A536564206575206C696265726F2E20496E74656765722074656D706F72206C6967756C6120696E2076656C69742E2055742074696E636964756E74206C6163696E69612073656D2E204E756C6C616D2076656C2072697375732E2053656420736F64616C657320616E7465206120646F6C6F722E204375726162697475722065726F732E2053656420736F64616C65732E20536564206E6F6E206D657475732E20566573746962756C756D20656C656D656E74756D20666175636962757320616E74652E204E756C6C612076656C206E6962682E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206E6563206C6F72656D20757420697073756D206C6163696E696120696163756C69732E204475697320657261742E20416C697175616D20657261742E204372617320696163756C69732E20496E206861632068616269746173736520706C617465612064696374756D73742E0A0A4E756C6C616D20616E74652E2043726173207669746165206573742E2050656C6C656E7465737175652076656C206D657475732061206C6967756C612064617069627573206D61747469732E2044756973206665756769617420616C69717565742066656C69732E20457469616D206964206E69736C207175697320657374206469676E697373696D20636F6E64696D656E74756D2E2053757370656E646973736520706F74656E74692E204D6F7262692076656C6974206C6F72656D2C206F726E61726520717569732C2070656C6C656E7465737175652076656C2C20706C61636572617420656765742C20746F72746F722E20566573746962756C756D2074696E636964756E74206D6F6C6573746965206C696265726F2E204E756C6C61206E756C6C6120656E696D2C206D616C6573756164612069642C20756C6C616D636F727065722076697461652C2064696374756D2061742C2070757275732E20446F6E6563206469676E697373696D206F64696F20757420656E696D2E2053757370656E6469737365206174206C65637475732E0A0A5072616573656E74206C6F626F727469732061756775652076656C206C65637475732E20557420696E206C6967756C612075742066656C697320636F6E6775652073757363697069742E2051756973717565206469676E697373696D20746F72746F72207574206D692E204675736365206D61676E61206E6973692C20656C656966656E642061632C206F726E6172652076656C2C20706F72747469746F722076697461652C207175616D2E20566573746962756C756D20736F64616C6573206A7573746F2071756973207475727069732E2046757363652075726E61206E6973692C2072686F6E63757320717569732C20636F6E64696D656E74756D2076656C2C2064696374756D2065752C206E756E632E20467573636520736564206E696268207669746165206F64696F20706F73756572652061646970697363696E672E2053656420706F72746120656C6974207175697320646F6C6F722E204E616D206C696265726F206E756C6C612C20617563746F72207365642C2074696E636964756E7420717569732C2066617563696275732073697420616D65742C206D692E2051756973717565206F7263692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E756C6C616D2069642073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632076656C2065726F732E0A0A566976616D7573206C7563747573206C6F626F72746973206C656F2E2053757370656E64697373652076656C20656C6974206120656E696D20756C6C616D636F7270657220706F73756572652E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20446F6E656320717569732070656465206D6174746973206C6563747573206D6F6C6C69732061646970697363696E672E2053656420616363756D73616E20706F737565726520657261742E205072616573656E7420657569736D6F642074696E636964756E742066656C69732E20446F6E6563206D692E20557420636F6D6D6F646F2061726375206C6163696E69612074656C6C75732E20416C697175616D2061206C696265726F2071756973206C65637475732073656D70657220766976657272612E20437572616269747572206C6163696E6961206D61757269732061742074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E756E632073697420616D6574206D61676E61206D6F6C6573746965206F726369207375736369706974206672696E67696C6C612E204675736365207072657469756D206D65747573206E6F6E2073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642068656E6472657269742E204E756C6C612066656C69732E2053757370656E646973736520706F74656E74692E20416C697175616D20626C616E64697420747269737469717565206E657175652E20437572616269747572207175697320657261742076656C206E756E6320616363756D73616E206D6F6C6C69732E0A0A447569732073616769747469732C2074656C6C757320757420616C697175616D206672696E67696C6C612C20646F6C6F72206D6920756C6C616D636F72706572206E69736C2C20757420747269737469717565207065646520656C697420736564206D61757269732E204375726162697475722069642066656C69732E20446F6E65632070756C76696E6172206C61637573206574206C65637475732E20416C697175616D2076756C7075746174652076756C707574617465206D657475732E20437572616269747572206D61676E612066656C69732C2061646970697363696E672061632C20616363756D73616E2076656C2C206D6F6C657374696520717569732C207175616D2E204D617572697320656C697420617263752C207072657469756D2076697461652C206D6F6C6C69732073697420616D65742C20736F6C6C696369747564696E2075742C206D692E20446F6E656320696D70657264696574206469676E697373696D206D692E204E756C6C616D2073697420616D657420746F72746F722E20416C697175616D206E65717565206E756C6C612C2076656E656E6174697320612C20706F72746120696E2C20706C6163657261742074656D7075732C206C616375732E205175697371756520766573746962756C756D20647569206574206C616375732E2050726F696E206469676E697373696D20636F6E7365637465747565722070757275732E20457469616D206772617669646120746F72746F7220696E206E756E632E2055742074656D706F722074726973746971756520746F72746F722E20536564206C616F726565742074696E636964756E74207175616D2E20566573746962756C756D20706F7274612074757270697320757420656C69742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20446F6E6563206E696268206475692C2066657567696174206E65632C206C616F726565742069642C206D616C65737561646120656765742C206E6973692E205574206E65717565206D617373612C207665686963756C612065752C20636F6D6D6F646F206E6F6E2C20756C747269636965732076697461652C2070757275732E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204D617572697320657569736D6F642C2066656C69732076656C2074656D706F7220616C69717565742C20746F72746F72206D6175726973206D616C657375616461206E756E632C2076656C206665726D656E74756D2073656D206469616D206964206475692E204E616D2072757472756D2073617069656E2065676574206F64696F2E20416C697175616D20736564206C696265726F206E6F6E206D692066617563696275732074656D7075732E2046757363652068656E6472657269742C206469616D206E6F6E20766F6C75747061742072757472756D2C2065726174206D657475732076656E656E61746973206C6967756C612C206E6F6E207363656C657269737175652070656465206C6967756C612076656C207175616D2E204D6F7262692072686F6E6375732065726F7320616320647569206665756769617420656C656D656E74756D2E2044756973206575206C696265726F2065742074656C6C757320636F6E67756520766976657272612E204D6F726269207175616D207175616D2C20656C656D656E74756D207365642C20756C6C616D636F7270657220696D706572646965742C20636F6D6D6F646F206E6F6E2C206F64696F2E204E616D20616C697175657420656765737461732075726E612E204D6175726973206F64696F2066656C69732C207661726975732065752C206C6163696E69612065752C20636F6E64696D656E74756D20612C206C65637475732E20536564206A7573746F206D617373612C2070756C76696E61722069642C2076617269757320612C20706F72747469746F72206E65632C206C696265726F2E20457469616D207661726975732E2043757261626974757220736F64616C65732C206F64696F20617420706F73756572652073656D7065722C2065726F73206E6962682074696E636964756E74206C65637475732C2076656C2072757472756D2073617069656E206E69736920696E206C6967756C612E2053757370656E6469737365206567657420617263752E2050686173656C6C757320696D70657264696574206573742061632073617069656E2E20446F6E6563206E756C6C6120746F72746F722C20706C6163657261742076656C2C2074656D70757320612C206C6F626F727469732076656C2C206E6962682E20416C697175616D20766172697573206E6973692E204E756C6C6120657420656E696D2E20467573636520636F6E76616C6C6973206C616F72656574206C616375732E0A0A50686173656C6C757320697073756D20646F6C6F722C206D6F6C657374696520717569732C20636F6E64696D656E74756D20696E2C20636F6D6D6F646F2065752C206469616D2E205175697371756520626962656E64756D206C6163696E6961206475692E204E756C6C616D20626C616E6469742076756C707574617465206F7263692E205574206C6163696E6961206D617373612076656C2061756775652E20416C697175616D20677261766964612C207175616D207175697320696D7065726469657420696D706572646965742C2074656C6C7573206469616D20706861726574726120657261742C206174207068617265747261206C61637573206E6962682065676573746173206D61676E612E204E756C6C61207361676974746973206C6F72656D207574206C6F72656D2E204475697320636F6E64696D656E74756D2C2064756920766974616520616C697175616D20706F73756572652C206469616D207175616D20636F6E76616C6C69732076656C69742C2075742067726176696461206C656F20697073756D206E6F6E2072697375732E205574206665726D656E74756D20736F6C6C696369747564696E20657261742E20446F6E6563207361676974746973207363656C657269737175652066656C69732E204E756E6320617263752E20457469616D2074656D7075732C206D61676E612073697420616D657420737573636970697420657569736D6F642C2065726F732073656D2072757472756D206475692C207669746165207361676974746973206E696268207075727573206E6F6E206C616375732E20536564206D6F6C6C69732061726375206567657420646F6C6F722E20446F6E6563206F726E6172652C20617263752073697420616D6574206665726D656E74756D2076756C7075746174652C20726973757320656E696D206665726D656E74756D206C696265726F2C2061206C6163696E696120646F6C6F72206D69206E6F6E2076656C69742E20457469616D206C6F626F72746973207075727573206120656C69742E204E756E63206E756C6C61206475692C206D617474697320717569732C20626962656E64756D20612C20756C7472696365732061632C2061756775652E20496E20616C697175616D207665686963756C61207475727069732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A496E7465676572206964206E69736C2E20517569737175652064696374756D20656C656D656E74756D206F64696F2E2041656E65616E206C75637475732E205365642065752073656D206120706564652076756C70757461746520636F6E64696D656E74756D2E2051756973717565206D61676E612E20446F6E656320616C697175616D206D617474697320697073756D2E204375726162697475722064696374756D20736F6C6C696369747564696E2073656D2E20416C697175616D2070756C76696E61722E204E756E6320736F6C6C696369747564696E207269737573206120657261742E20566976616D757320717569732074656C6C75732073697420616D6574206E69626820766573746962756C756D20636F6E7365717561742E204E756C6C61207072657469756D20736F6C6C696369747564696E20646F6C6F722E20416C697175616D20696163756C69732074696E636964756E74207475727069732E2050686173656C6C757320697073756D206C656F2C2076656E656E6174697320696E2C20736167697474697320696E2C206F726E6172652061742C206E756E632E0A0A50656C6C656E74657371756520756C7472696365732C2064756920657520696163756C6973206C75637475732C2074656C6C757320617567756520766F6C75747061742073617069656E2C20696E206469676E697373696D2075726E612066656C6973207574206D692E205365642061726375206475692C206469676E697373696D2069642C20706F72747469746F722075742C20696D706572646965742076697461652C20616E74652E204E756C6C61206475692073656D2C20636F6D6D6F646F206E65632C2073616769747469732065742C206C6163696E69612065742C20706564652E20457469616D20656C656966656E6420647569207574206E69736C2E20446F6E656320616E7465206D61757269732C2074656D7075732073697420616D65742C207661726975732076697461652C206772617669646120717569732C206D692E20496E207363656C657269737175652C2066656C697320766974616520766976657272612073616769747469732C2076656C6974206D6574757320756C74726963696573206E657175652C207175697320696D706572646965742076656C697420656C6974206574206D61676E612E2053757370656E646973736520706F74656E74692E205365642076656C69742065726F732C20657569736D6F64207365642C20636F6E64696D656E74756D206E65632C206661756369627573207365642C2073617069656E2E204E616D20616363756D73616E206C6967756C612073697420616D6574206E657175652E20416C697175616D206572617420766F6C75747061742E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E616D20657520706564652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642065752066656C69732073656420746F72746F722074656D706F72206665726D656E74756D2E2050686173656C6C757320636F6D6D6F646F2073656D2076656C206E69736C2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050726F696E206C656374757320656C69742C2070686172657472612073697420616D65742C20616363756D73616E207365642C2074696E636964756E742065742C206D61757269732E204475697320646170696275732070686172657472612073656D2E20496E746567657220696E206A7573746F2E205072616573656E742065726F732E20566573746962756C756D20616320616E74652E20416C697175616D207363656C657269737175652073656D2070656C6C656E746573717565206E69626820636F6E73656374657475657220736F64616C65732E20416C697175616D20636F6E736563746574756572206F64696F2E2044756973206C6563747573206F64696F2C206C75637475732065752C20636F6D6D6F646F20717569732C206D6F6C6C69732076697461652C2076656C69742E2043726173206E6563206E756E63206E6F6E20656C697420696163756C6973206D61747469732E2041656E65616E206A7573746F206E657175652C20736F6C6C696369747564696E20656765742C20756C6C616D636F7270657220656765742C20656765737461732069642C2073656D2E20496E2065752072697375732E2053656420656765737461732E0A0A496E7465676572206174206E657175652E20536564207072657469756D207363656C65726973717565206E756C6C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20467573636520757420706564652E20457469616D207669746165207175616D20612075726E612076617269757320696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2044756973207665686963756C612E20467573636520756C6C616D636F72706572206E696268206E6F6E20657261742E205175697371756520696E206E657175652E205072616573656E74206573742E2050656C6C656E74657371756520617263752E0A0A50726F696E20706F73756572652E2053757370656E646973736520706F74656E74692E20496E74656765722066656C6973206C616375732C20616C697175616D207365642C2076756C70757461746520696E2C206D6F6C6C69732076656C2C2074656C6C75732E20496E7465676572207665686963756C6120626962656E64756D206573742E204E756E63206E6F6E20646F6C6F7220696E2074656C6C7573206D617474697320666163696C697369732E20496E746567657220766573746962756C756D2C20617567756520617420636F6D6D6F646F20616C697175616D2C2064756920657374206D6174746973206C6967756C612C2073697420616D65742061646970697363696E67206F7263692073656D207669746165206D61676E612E205072616573656E7420656E696D2076656C69742C206D616C6573756164612061742C20636F6E677565206E65632C206C756374757320696E2C206A7573746F2E20536564207661726975732E204D6F7262692070686172657472612E20446F6E6563206575206D61737361206E65632074656C6C75732076756C7075746174652070756C76696E61722E20557420636F6D6D6F646F20747572706973206E6F6E2073656D2E20557420636F6E76616C6C697320756C6C616D636F727065722072697375732E20457469616D20696E74657264756D2070656465206964206E6973692E2043726173206D61676E612073617069656E2C20737573636970697420612C206C616F72656574206E6F6E2C2072686F6E6375732065742C2066656C69732E20496E7465676572206F726369206C6F72656D2C20766573746962756C756D2064696374756D2C20756C6C616D636F7270657220612C20706F72747469746F722065742C206475692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A4E756E63206574206D61676E612E2053656420626962656E64756D2074656C6C757320696E206469616D2E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E616D20766974616520746F72746F722E20496E7465676572206D61676E612E20447569732076656E656E617469732C206C656F2061632074656D706F72206C616F726565742C20656C6974206E756C6C6120706861726574726120706564652C206E6F6E206665726D656E74756D206E756E63206F64696F2061206F64696F2E2050726F696E206E6F6E2076656C69742E2053656420696D706572646965742061756775652071756973206E69736C2E20496E746567657220636F6E64696D656E74756D206E69736C206E6563206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20566976616D757320706C616365726174206C696265726F2E204475697320636F6E6775652064696374756D206D61676E612E20416C697175616D206461706962757320626962656E64756D20656E696D2E204E756E6320656C656966656E6420706564652076656C20697073756D2E0A0A457469616D2076697461652076656C69742E204D61757269732065726174206E756E632C206D616C6573756164612075742C20666575676961742061632C20706C61636572617420636F6E64696D656E74756D2C2061756775652E204E616D20766F6C75747061742E20416C697175616D207665686963756C6120697073756D206964206F64696F2E20566976616D757320736F6C6C696369747564696E207475727069732069642073617069656E2E20467573636520612066656C6973207669746165206F64696F20636F6E76616C6C697320626C616E6469742E204375726162697475722076697461652065726F732069642065726F7320706F727461207072657469756D2E204E756C6C6120696E206D61676E6120656765742075726E61206C6163696E696120636F6E76616C6C69732E20416C697175616D206D61747469732076656E656E617469732070757275732E2053656420736564206D69206567657420657261742074726973746971756520706F7274612E20446F6E656320617563746F7220646F6C6F72206120657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20496E206E6563206C6967756C612E204E756E6320656C656966656E642E20566573746962756C756D2071756973206E697369206567657420656C697420706F72747469746F7220636F6E6775652E204D616563656E61732066617563696275732C206D61676E6120656765742061646970697363696E672074696E636964756E742C20646F6C6F7220616E7465206D616C65737561646120656C69742C206E6F6E20656C656D656E74756D206C616375732074757270697320696E20706564652E0A0A5574206D616C657375616461206D69206E6563206D657475732E205072616573656E7420617563746F72206175677565206163206E69736C20756C7472696369657320666163696C697369732E204E616D2070757275732073617069656E2C2070656C6C656E746573717565206469676E697373696D2C20706F73756572652065752C206375727375732069642C206469616D2E205175697371756520736F6C6C696369747564696E2C20656C697420612070656C6C656E746573717565207363656C657269737175652C206C6F72656D20726973757320617563746F72207175616D2C207175697320636F6E7365717561742074656C6C7573206E657175652069642075726E612E2053757370656E6469737365206469616D20746F72746F722C20656C656966656E64206469676E697373696D2C20656765737461732075742C206C756374757320696E2C20616E74652E204475697320616E74652E204D616563656E6173206C75637475732E20437572616269747572206375727375732070686172657472612075726E612E204D616563656E617320696D706572646965742C2065726174206E6F6E20656C656D656E74756D20657569736D6F642C20746F72746F72206F64696F20657569736D6F64206C65637475732C20616320666163696C697369732073656D206E696268207669746165206E756C6C612E204E756E6320677261766964612E204D6F72626920736F6C6C696369747564696E206F64696F2071756973206C616375732E20416C697175616D2061206E696268206E6F6E2075726E6120706F72746120696D706572646965742E20416C697175616D206572617420766F6C75747061742E20496E20696163756C6973206C6163696E69612076656C69742E20536564206C696265726F206C616375732C207472697374697175652065752C206C6163696E69612061632C20616C697175657420656765742C2075726E612E0A0A457469616D206174206E69736C2E2050686173656C6C7573206661756369627573206C7563747573206C65637475732E20557420706C6163657261742076756C70757461746520646F6C6F722E2050686173656C6C75732076656C2076656C69742E204D6F72626920766976657272612E2050686173656C6C7573206F7263692E20496E7465676572206469676E697373696D206D6174746973206D61757269732E2050656C6C656E74657371756520706F7375657265206C656F20706F7375657265207175616D2E2051756973717565206E6563206D61676E61206174206469616D20766976657272612070656C6C656E7465737175652E2053757370656E64697373652076656C697420617263752C20756C7472696369657320717569732C20636F6E67756520612C2076656E656E6174697320656765742C206C616375732E20496E74656765722073616769747469732068656E64726572697420646F6C6F722E2046757363652074696E636964756E7420616E746520612073656D2E0A0A4D616563656E617320636F6E7365637465747565722C206A7573746F207365642072686F6E6375732076656E656E617469732C206E69626820617263752072757472756D20646F6C6F722C2073656420636F6E64696D656E74756D206C696265726F206C696265726F20657420697073756D2E20566976616D7573206D6174746973206A7573746F207574206C6F72656D2074696E636964756E74206C6F626F727469732E205574206E6F6E2076656C6974206964206E6571756520616C697175657420616363756D73616E2E205365642074656D7075732076697665727261206E756C6C612E2043757261626974757220756C6C616D636F727065722C206E6571756520717569732064617069627573207363656C657269737175652C2066656C6973206469616D2067726176696461206F7263692C206E6F6E20637572737573207175616D206E6571756520766974616520656C69742E20457469616D2070686172657472612074696E636964756E74206C616375732E204475697320657569736D6F64206672696E67696C6C61206573742E20457469616D206F726E6172652074696E636964756E74206C65637475732E2050726F696E20696E207475727069732E204E756E6320626C616E64697420626C616E646974207475727069732E2041656E65616E2075742061756775652E2044756973206F726369206A7573746F2C2074696E636964756E742065752C2072757472756D207365642C2072757472756D2065742C207475727069732E2043757261626974757220666163696C69736973206F64696F20696E20616E74652E20496E206861632068616269746173736520706C617465612064696374756D73742E205365642065726F73206573742C2070656C6C656E7465737175652061742C2074696E636964756E742065752C20756C74726963657320717569732C206D657475732E204D6F7262692073697420616D6574206A7573746F2E204D616563656E617320616320617263752E204D6175726973206469676E697373696D2E0A0A50656C6C656E74657371756520756C747269636965732072757472756D206F7263692E2041656E65616E206F726E6172652E20566976616D75732065752072697375732076656C206D6175726973206C6F626F727469732064696374756D2E205365642065742074757270697320617563746F72206D692072686F6E6375732070756C76696E61722E20536564206E6563206E756E6320612070757275732074656D706F7220766976657272612E2050656C6C656E7465737175652073757363697069742E20446F6E656320747269737469717565207269737573206E6F6E206E6962682E20457469616D206E69736C206D61676E612C20736F6C6C696369747564696E2075742C20756C7472696365732073697420616D65742C20656765737461732065752C206E756C6C612E20416C697175616D206572617420766F6C75747061742E20566573746962756C756D2070686172657472612E2053656420656765737461732C206D657475732073697420616D6574206C6F626F7274697320636F6E7365717561742C206572617420656C697420696D70657264696574206C696265726F2C20657520696E74657264756D207175616D206D61737361206567657420646F6C6F722E2053757370656E6469737365207669746165206F64696F2E2050726F696E20626C616E646974206D617572697320696163756C6973206D657475732E0A0A566976616D757320766573746962756C756D2E20457469616D206574206E69736C2E20416C697175616D20696E206469616D2076656C20656C697420706C6163657261742073757363697069742E204475697320736F64616C6573207075727573206163206E6962682E204E756C6C6120696E206F64696F206567657420656E696D206C756374757320626C616E6469742E2043757261626974757220756C74726963657320697073756D206E6F6E206E65717565206567657374617320656C656966656E642E20536564207475727069732E2050726F696E20636F6E7365637465747565722E20566976616D7573206D61747469732E20496E20616C69717565742E0A0A4E756E632069642065726F732E20446F6E65632076656E656E617469732C206E756C6C61206574206D6174746973206C75637475732C20616E7465206C656F2073656D706572206A7573746F2C206E6F6E2061646970697363696E67206F64696F20726973757320736564206C616375732E205072616573656E7420766974616520726973757320636F6E677565206C696265726F20636F6E6775652074656D7075732E2050686173656C6C75732061632065726F732E204E756C6C61207665686963756C612C206C6F72656D20696E20616C69717565742073757363697069742C2061726375206572617420656765737461732073656D2C2071756973206C6F626F72746973207175616D20616E7465206575206D617373612E20437572616269747572206E6F6E206D617373612E2053656420626962656E64756D206C6163696E6961206F64696F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20566976616D757320766F6C757470617420626C616E646974206C616375732E2050726F696E20706F7274612C2074656C6C757320757420617563746F72206C616F726565742C206C65637475732065726F73206665726D656E74756D206C65637475732C2069642073616769747469732061726375206A7573746F20696E207475727069732E2050686173656C6C757320636F6E7365717561742E204E616D2070656C6C656E7465737175652C206D69206964207669766572726120636F6E76616C6C69732C206E756E63206C696265726F20706C616365726174206C656F2C20656C656966656E6420706F7274612073656D206E69736C2076697461652073617069656E2E2050656C6C656E746573717565206C6967756C61206C696265726F2C20747269737469717565206E6F6E2C20706F72747469746F722072757472756D2C20706F72747469746F72206E6F6E2C20657261742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E74656765722064696374756D2074656C6C7573206120746F72746F722E20566976616D75732066656C6973206E756E632C206D6F6C6573746965206E6F6E2C2072686F6E63757320717569732C2070686172657472612069642C206475692E20446F6E6563207269737573206D657475732C206672696E67696C6C612076656C2C20616C69717565742065752C20706C6163657261742069642C206E657175652E0A0A53757370656E646973736520697073756D2E20566976616D7573206C65637475732E2053656420766976657272612C206D61737361206567657420636F6E76616C6C6973206D61747469732C207175616D2074757270697320636F6E736563746574756572206E756E632C206567657420706F7375657265206D61676E612073656D2069642076656C69742E20496E206E6563206D61757269732E2041656E65616E206120707572757320736564207175616D206C6F626F72746973206672696E67696C6C612E2050726F696E20756C74726963696573206C6163696E696120616E74652E205365642061646970697363696E67206572617420717569732076656C69742E204E756C6C616D207669746165206E69736C206964206A7573746F20736F6C6C696369747564696E206D6F6C65737469652E204E756C6C6120666163696C6973692E20536564206E65632075726E6120736564206E69736C206672696E67696C6C6120646170696275732E204E756C6C61206174206469616D2E20416C697175616D2065676574206E6962682E204E756E63206163206E6973692073697420616D65742074656C6C757320656765737461732074656D7075732E204E616D207363656C657269737175652075726E61206574206E657175652E20446F6E656320657374206F7263692C207361676974746973206E6F6E2C2076756C70757461746520612C20636F6D6D6F646F2065742C2061756775652E205574206461706962757320746F72746F722E205574206E756E632E20446F6E65632064696374756D2064617069627573206F64696F2E204E616D20756C7472696369657320756C6C616D636F72706572206C6967756C612E2050656C6C656E74657371756520616363756D73616E20766172697573206C656F2E0A0A4D6F72626920657569736D6F64206C616F7265657420657261742E20566976616D7573207175697320697073756D2E204D6F72626920657569736D6F642E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2053757370656E64697373652076656C2070757275732E204E756C6C616D206174206D61676E612E20437572616269747572206C61637573206C6F72656D2C20696163756C697320717569732C2064617069627573206E6F6E2C20766F6C75747061742076656C2C206E756C6C612E20446F6E656320757420617263752072686F6E63757320646F6C6F72207072657469756D2064696374756D2E204E756C6C616D2076656C206D657475732E20557420617263752E2050656C6C656E746573717565206E697369206E756E632C20706C61636572617420656765742C2074696E636964756E742076656C2C207068617265747261206E6F6E2C206E756E632E20496E74656765722074696E636964756E7420756C74726963696573206C65637475732E20496E74656765722073656D7065722C2070757275732073656420756C74726963657320666575676961742C206E756C6C61207065646520736F6C6C696369747564696E20657261742C2076656C20617563746F72206E756C6C6120697073756D2076656C206C65637475732E2041656E65616E206D692E0A0A4E756C6C616D20736564206E697369206574206172637520696D70657264696574206665726D656E74756D2E204D6175726973206E6563206D657475732E20496E20616320646F6C6F722E20496E206D6920617263752C20636F6E6775652061632C207068617265747261206E65632C207363656C657269737175652073697420616D65742C206D61676E612E20437572616269747572206C616375732E2043757261626974757220657420656C69742E20416C697175616D20756C6C616D636F72706572206E756E6320657520656C69742E2053656420636F6E76616C6C697320646F6C6F722061742076656C69742E20566573746962756C756D20646170696275732C20617567756520696420636F6E73656374657475657220706C6163657261742C206E756E63206D6173736120626C616E6469742073617069656E2C20696420616C697175616D20656C6974206E697369206964206D692E2050686173656C6C75732073617069656E206573742C20677261766964612065752C20626962656E64756D2075742C2061646970697363696E6720717569732C206573742E205574206D6F6C6573746965207175616D207669746165206F64696F2E20446F6E65632071756973207269737573206964206572617420666175636962757320736F6C6C696369747564696E2E204E616D2069642066656C69732E204D61757269732073656420656E696D207669746165206C656F20616363756D73616E207072657469756D2E0A0A4E616D206A7573746F2E20446F6E656320747572706973206E69736C2C20636F6D6D6F646F2065742C20696E74657264756D2061632C20636F6E736563746574756572206E6F6E2C206D617373612E2046757363652073656D206D657475732C206C616F72656574206E65632C20706F73756572652069642C20696D7065726469657420696E2C2076656C69742E20446F6E65632076756C707574617465206A7573746F2065676574207475727069732E204E756C6C6120706564652E204D6F7262692074696E636964756E742E20467573636520616C69717565742C207175616D20657420616C697175616D206672696E67696C6C612C20616E746520616E746520696163756C6973206475692C206E656320616C697175616D20617263752070757275732073656420657261742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050686173656C6C7573207375736369706974207175616D206574206573742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B0A0A496E7465676572207365642074656C6C75732E20536564207365642076656C697420756C74726963696573206C656F2072757472756D206C616F726565742E20536564206E6F6E2065726F7320616320707572757320736167697474697320666575676961742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E205365642068656E647265726974206C6967756C612073697420616D6574206E6962682E204D616563656E6173207475727069732E204D6F72626920636F6E7365637465747565722C20646F6C6F722065742061646970697363696E6720696D706572646965742C20616E7465206E65717565206665756769617420646F6C6F722C20617420706F727461207175616D206E657175652071756973206C6967756C612E204D61757269732073656D7065722076656C69742073697420616D657420697073756D2E2050656C6C656E7465737175652074656D7075732C20707572757320696E2072757472756D20636F6E7365717561742C20656E696D2065726174207665686963756C61206D617373612C20696420616363756D73616E206C656F2073617069656E206E65632070757275732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E20646F6C6F722E20496E746567657220666163696C69736973206C696265726F2073697420616D657420706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2055742076617269757320616C697175657420656E696D2E204E756C6C6120666163696C6973692E2043757261626974757220636F6E7365637465747565722C206F64696F206575207072657469756D2074696E636964756E742C206E756E63206E69736920616C6971756574206E657175652C2076656C20696D7065726469657420656C6974206D617373612073697420616D6574207475727069732E2050656C6C656E7465737175652074656D7075732C206F72636920766F6C757470617420626C616E646974206672696E67696C6C612C206F64696F2073656D20706F737565726520616E74652C20766974616520626962656E64756D2075726E61206C6F72656D2076697461652065726F732E205072616573656E7420766976657272612072686F6E63757320617263752E2053656420617563746F722C206573742073697420616D6574206D6F6C6C6973206D6F6C6C69732C207175616D207175616D20677261766964612073617069656E2C20696E20636F6D6D6F646F206D65747573206E756C6C6120617563746F7220656E696D2E20446F6E656320666163696C697369732E0A0A50726F696E2074696E636964756E742C2073617069656E206567657420756C747269636965732061646970697363696E672C20657374206F64696F2064696374756D20617263752C207574206D6F6C6C69732065726174206475692073697420616D65742076656C69742E204D6F726269206573742073656D2C20696E74657264756D2061742C20636F6E67756520612C20656C656D656E74756D2076697461652C206D657475732E2053757370656E64697373652069642061756775652E204D617572697320656E696D2073656D2C2070756C76696E617220656765742C2074656D70757320612C2074656D7075732073697420616D65742C2073617069656E2E20467573636520766573746962756C756D20636F6E736563746574756572206475692E2050656C6C656E74657371756520657261742E20536564206469676E697373696D20706C616365726174206F64696F2E204D616563656E61732073656D7065722072686F6E637573206C65637475732E2050686173656C6C7573207072657469756D2E2044756973206C696265726F20656C69742C20656C656966656E64206E65632C20656765737461732075742C20637572737573207365642C2066656C69732E204E616D206E69736C20617263752C20616C69717565742065742C20666163696C697369732065752C206C75637475732075742C2072697375732E20457469616D20756C7472696365732C20646F6C6F722073656420766F6C7574706174206D616C6573756164612C20747572706973206172637520696D7065726469657420746F72746F722C20657569736D6F6420636F6D6D6F646F206C696265726F206D61737361207574207175616D2E20496E7465676572206D6F6C6573746965207075727573206E6F6E20656C69742E2055742076656E656E617469732073656D70657220746F72746F722E20457469616D20626962656E64756D206567657374617320697073756D2E204D617572697320736F6C6C696369747564696E2073656D206E6563206E6962682E204E756C6C61207072657469756D206D65747573206575206D657475732E2050656C6C656E7465737175652073697420616D65742073656D2E0A0A53757370656E6469737365206163206E6973692E205574206C656F2E20566573746962756C756D2068656E647265726974207072657469756D20646F6C6F722E204E756E632066657567696174206D616C6573756164612070757275732E2043726173206574206E6962682E20437572616269747572206E756E6320657261742C206D616C6573756164612076697461652C206C616F726565742061632C20756C7472696369657320696E2C2070757275732E20566976616D75732074656C6C757320617263752C20736F64616C65732065752C20666163696C6973697320612C206C6163696E6961206E65632C206E756E632E2050656C6C656E7465737175652069642076656C69742E20496E206575206E6962682E204E756E63206E656320657261742E205365642064696374756D206E65717565207574206E69736C2E0A0A4D6F726269206C65637475732074656C6C75732C2074696E636964756E742061632C20706F72747469746F722061632C2074726973746971756520696E2C2065726F732E20446F6E6563206C7563747573206C7563747573206C656F2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2046757363652075742065737420657420656E696D207363656C6572697371756520616363756D73616E2E20446F6E6563206C6967756C612066656C69732C206C6163696E696120717569732C2070656C6C656E74657371756520696E2C2073656D70657220766573746962756C756D2C20656C69742E204D61757269732065676574206F72636920612066656C697320636F6E677565207665686963756C612E20557420736F6C6C696369747564696E2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204E756C6C616D20696420646F6C6F72207574206C6F72656D206469676E697373696D2076656E656E617469732E2053757370656E64697373652076697461652073617069656E2E2050726F696E206E6F6E206D61676E612075742065726F7320766976657272612070756C76696E61722E20446F6E65632071756973206F64696F2E204E756C6C616D206E6F6E20617263752076656C206C6F72656D20737573636970697420616C697175616D2E20416C697175616D2072757472756D2074757270697320696E206C656F2E0A0A5574206C7563747573206E6962682074726973746971756520657261742E2053757370656E646973736520626962656E64756D206F64696F20766974616520746F72746F722E20446F6E6563206C6163696E69612E204372617320736F64616C65732066656C6973206C7563747573206E756C6C612E204E616D20656C656966656E64207361676974746973206C6967756C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E64697373652076656C206E657175652E204D6F72626920616C6971756574207665686963756C61206D61676E612E2041656E65616E206174206F64696F2E20447569732070656C6C656E746573717565206D61676E612E204E756C6C6120617420746F72746F72207574206469616D2064696374756D2066617563696275732E204D617572697320717569732076656C69742E20446F6E6563206E6F6E2074656C6C7573207669746165206C6F72656D206672696E67696C6C6120706F72747469746F722E2046757363652075742073617069656E207175697320746F72746F7220666575676961742073616769747469732E20446F6E656320766976657272612073656D2076697461652073617069656E2E205072616573656E7420736F64616C65732C206C6163757320696E206672696E67696C6C6120766976657272612C206F64696F2061756775652061646970697363696E672075726E612C20766974616520696E74657264756D20616E74652073656D206E6F6E206E6973692E204E756C6C616D20746F72746F72206C6F72656D2C20656C656966656E642061632C206D6F6C6C6973206E6F6E2C206C616F726565742061632C2072697375732E20496E7465676572206F726E617265206C656F20736564206A7573746F2E2051756973717565206375727375732C2073656D206E6F6E20666163696C6973697320626962656E64756D2C206E697369206D69207661726975732066656C69732C206665726D656E74756D2066657567696174206C6F72656D2065726F73206C616F726565742072697375732E0A0A517569737175652073697420616D657420657374206574206C6F72656D207665686963756C61206C6163696E69612E20446F6E6563206E656320746F72746F722E2043726173206F64696F2E204E616D207363656C657269737175652076756C7075746174652075726E612E205072616573656E74206475692E20457469616D206E6563206E69736C206C6F626F7274697320697073756D20616C69717565742074656D7075732E204D616563656E6173207072657469756D20736F6C6C696369747564696E206D61757269732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206175677565206D617373612C20636F6E67756520656765742C20636F6E76616C6C697320656765742C207472697374697175652073697420616D65742C2065726F732E2053656420636F6E736571756174206E6973692065752066656C69732E2050656C6C656E746573717565206A7573746F2E2053757370656E6469737365206E6F6E2061756775652E20496E206469676E697373696D206C6F626F72746973206D61757269732E204D61757269732073616769747469732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E0A0A5365642061646970697363696E672E20446F6E656320612074656C6C75732076697461652065737420637572737573207665686963756C612E204E616D20616E74652073656D2C20736F64616C65732069642C206672696E67696C6C612076656C2C20636F6E64696D656E74756D2076656C2C206E756C6C612E205175697371756520736F64616C65732E20457469616D20696D7065726469657420656C6974206964206F64696F2E20416C697175616D206572617420766F6C75747061742E204D616563656E617320706F7274612074656D706F7220617263752E204E756C6C612073656D2061756775652C2070656C6C656E7465737175652061632C20636F6E7365717561742075742C20636F6E64696D656E74756D20657569736D6F642C2072697375732E2053656420616C697175616D2074696E636964756E74206D692E20496E20696E74657264756D206C6F626F72746973206F7263692E0A0A536564207665686963756C612068656E6472657269742070757275732E20457469616D2061206469616D2E2043757261626974757220636F6E76616C6C69732E2053757370656E64697373652061206E6973692E20446F6E6563206964206D61676E6120696E207175616D20736F6C6C696369747564696E20756C747269636965732E20446F6E656320766976657272612E205175697371756520766F6C757470617420657374207365642073656D2E20416C697175616D206A7573746F2E20566573746962756C756D20746F72746F72206D617373612C20706F72747469746F72207365642C2076617269757320717569732C20696163756C697320717569732C206F64696F2E20416C697175616D2065676574206E657175652E0A0A4D6175726973206E756C6C612E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566573746962756C756D206575207175616D20696E206E6571756520756C7472696365732070656C6C656E7465737175652E204372617320696E20646F6C6F722071756973207175616D207661726975732068656E6472657269742E20416C697175616D206E697369206C616375732C206C6F626F727469732065752C20636F6E76616C6C69732073697420616D65742C20666163696C697369732075742C206D692E20416C697175616D206174206E657175652E204372617320736167697474697320656C656D656E74756D206A7573746F2E20566573746962756C756D207574206C656374757320616C6971756574207075727573206D616C65737561646120766F6C75747061742E2044756973206174206C616375732061646970697363696E67206C696265726F2074696E636964756E7420766573746962756C756D2E204D6F7262692061206C696265726F2E20437261732070757275732E204D6F72626920757420617567756520657420707572757320696E74657264756D207363656C657269737175652E20496E74656765722061206475692E20496E206861632068616269746173736520706C617465612064696374756D73742E2044756973207068617265747261206D657475732065676574206D61757269732E20416C697175616D20696E74657264756D20756C6C616D636F72706572206D617373612E0A0A457469616D206F726E6172652E204E756C6C616D20657569736D6F642E2041656E65616E20636F6E7365717561742067726176696461206C6967756C612E20416C697175616D206573742E2050726F696E207669746165206C616375732E205072616573656E7420612065726F732073697420616D657420647569206C756374757320636F6D6D6F646F2E2050686173656C6C7573207665686963756C612061726375206567657420646F6C6F722E205072616573656E74206665726D656E74756D20636F6E677565206C656F2E20416C697175616D20766F6C7574706174207075727573207574206C6F72656D2E2046757363652068656E64726572697420656E696D206174206C656F2E20416C697175616D2072686F6E637573206E69736C2E20566976616D75732064696374756D2065676573746173206D692E2053757370656E64697373652070656C6C656E74657371756520626962656E64756D20646F6C6F722E2050656C6C656E7465737175652074696E636964756E742C207475727069732073656D7065722070656C6C656E74657371756520636F6E64696D656E74756D2C20697073756D206D6574757320736F64616C6573206C6967756C612C20696420766F6C7574706174206469616D2074757270697320757420656C69742E0A0A5072616573656E7420736564206C616375732E204E616D20656C656966656E64206D6F6C6573746965206D61757269732E20446F6E65632064617069627573206665726D656E74756D206D617373612E20446F6E656320766976657272612066617563696275732070757275732E2043757261626974757220636F6E6775652C206C696265726F20766974616520766976657272612070656C6C656E7465737175652C206469616D2076656C697420736F64616C657320656E696D2C20736564207375736369706974206C6563747573206E697369206E6563206E657175652E20566573746962756C756D206D616C6573756164612C206C616375732061742063757273757320636F6E6775652C2076656C6974206C65637475732074726973746971756520646F6C6F722C2073697420616D657420736F64616C6573206E6571756520697073756D2061206C696265726F2E20566573746962756C756D206574207175616D2E2043757261626974757220706C6163657261742E20437572616269747572206E756E6320617263752C20657569736D6F64206E65632C2076756C7075746174652068656E6472657269742C20616C697175657420656765742C207175616D2E204375726162697475722076656C20656E696D2E2053757370656E646973736520706F74656E74692E0A0A4E756E6320636F6E736571756174206F726369207574206C616375732E2046757363652076656C697420646F6C6F722C2064617069627573207365642C20626C616E6469742073697420616D65742C2072686F6E6375732069642C2072697375732E20447569732075726E61206E6962682C207363656C6572697371756520717569732C206461706962757320612C207363656C65726973717565207365642C206E6962682E20446F6E6563206C75637475732E205574206575206D617572697320637572737573206469616D206C6163696E69612072686F6E6375732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20416C697175616D207665686963756C61206D6F6C6573746965206A7573746F2E204D616563656E617320696D70657264696574207065646520736564206D692E2053757370656E6469737365206E756C6C6120646F6C6F722C2068656E64726572697420656765742C2068656E6472657269742069642C2064696374756D2076656C2C206C656F2E204475697320616363756D73616E2E2043757261626974757220696E2066656C69732E204E756E63206C6F72656D2E205574206C656F20646F6C6F722C206C616F72656574206E65632C2076756C7075746174652061742C20656C656966656E6420696E2C206E756C6C612E2051756973717565206E756E632070757275732C2076617269757320656765742C20616363756D73616E206E65632C20616C69717565742065742C206E6962682E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20437261732061646970697363696E67207669766572726120646F6C6F722E204D617572697320706F72747469746F7220756C7472696365732070757275732E204E756C6C6120666163696C6973692E205072616573656E7420666175636962757320616E7465207669746165206D61757269732E0A0A5072616573656E74206C6163696E6961206C656374757320736564206E69736C2E20496E2074656D70757320636F6E677565206D61757269732E20496E746567657220666163696C69736973206F726E61726520656E696D2E204E756C6C61206964206D617373612E20446F6E656320636F6D6D6F646F206469616D2061742074656C6C75732E204E616D20646170696275732076697665727261206573742E204E616D2074656C6C75732E205072616573656E742061206C696265726F2E20496E206661756369627573206573742065676574206E6962682E204E756C6C612065726F73206F7263692C20696D70657264696574206E6F6E2C20626C616E646974206E6F6E2C2074656D706F7220656765742C206D692E2050656C6C656E74657371756520636F6E76616C6C69732E0A0A517569737175652065676574206D69206163206C656F20657569736D6F642066617563696275732E2050686173656C6C75732072686F6E637573207075727573206964206475692E20566573746962756C756D206D616C65737561646120656C656966656E6420616E74652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050656C6C656E74657371756520626C616E646974206D6174746973206F64696F2E2053757370656E646973736520636F6E7365717561742C206C65637475732061632073656D70657220736F6C6C696369747564696E2C206D692076656C69742064696374756D2061756775652C2061632074656D70757320646F6C6F7220657261742073697420616D6574206475692E2050726F696E2068656E6472657269742C2066656C6973207175697320766F6C757470617420706F73756572652C206469616D206F64696F206D616C657375616461206F64696F2C206120696E74657264756D206F726369206469616D20717569732073617069656E2E2050656C6C656E746573717565206F64696F206F64696F2C20766976657272612076656C2C20677261766964612065752C206D6F6C6573746965207365642C206E756C6C612E2050686173656C6C7573206D617572697320706564652C20636F6D6D6F646F2075742C20657569736D6F642065752C2068656E6472657269742065752C206573742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C6120656C656D656E74756D206C616375732065752061756775652E2053656420657261742E2050726F696E20706F7274612E204D616563656E61732071756973206D692E2050686173656C6C757320617420656E696D206163206A7573746F206772617669646120756C7472696365732E2043726173206C656F2E0A0A496E746567657220757420617263752E20446F6E656320736564206D61676E612E2050726F696E2066656C69732E20496E20696163756C69732C206C6967756C61206964206672696E67696C6C61207072657469756D2C206E696268206469616D20616363756D73616E2074656C6C75732C206567657420616363756D73616E206D657475732064756920766172697573207475727069732E2050686173656C6C7573206F726369206D657475732C20656C656966656E64207365642C2074656D706F722061632C207363656C657269737175652061632C2075726E612E20496E74656765722076697665727261206E657175652061206D61757269732E204D617572697320706F72747469746F7220646F6C6F722065752076656C69742E20496E7465676572206F64696F20656C69742C20766573746962756C756D2075742C20766F6C75747061742069642C2072686F6E63757320636F6D6D6F646F2C2075726E612E20457469616D20706C61636572617420706861726574726120657261742E2055742074656D706F72206573742E20496E7465676572206469676E697373696D20626C616E6469742074656C6C75732E204D6F726269206E69626820646F6C6F722C207363656C657269737175652069642C20636F6D6D6F646F206D616C6573756164612C206D61747469732061742C206D692E20437261732074696E636964756E7420636F6D6D6F646F2070757275732E20496E2074696E636964756E742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D20756C6C616D636F727065722E2055742068656E6472657269742E204D6F72626920756C7472696365732E0A0A5072616573656E7420696163756C69732C2065726F73206163206567657374617320736F64616C65732C2075726E61206C656F206665726D656E74756D206C6967756C612C2073697420616D657420616C697175616D2076656C69742073656D206E6F6E2070757275732E20446F6E65632072757472756D206172637520717569732070757275732E204E616D20706F73756572652C206C6163757320617420636F6E73657175617420706C6163657261742C206E756C6C61207065646520706F7375657265206F7263692C206E6F6E20657569736D6F6420747572706973206475692071756973206E69736C2E2050726F696E20706F7274612061646970697363696E67206E6962682E20446F6E65632074726973746971756520646F6C6F722061742074656C6C75732E20446F6E6563206E65717565206D617373612C20617563746F722069642C2066617563696275732076697461652C20756C6C616D636F727065722076656C2C206E6973692E2050726F696E206D6F6C6573746965206E6571756520736564206D617373612E204E616D2074656D706F722E204D6F72626920616C697175616D2073617069656E2061742074656C6C75732E2046757363652071756973207269737573206574206D69207072657469756D2070756C76696E61722E2046757363652073697420616D6574206C6967756C612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E646973736520657520656E696D2065742066656C6973207363656C65726973717565206C6F626F727469732E205072616573656E7420626962656E64756D2E20566976616D7573207665686963756C612E20496E7465676572206174206E696268207365642076656C69742072686F6E637573206D6F6C65737469652E2043726173206C616375732E2053656420756C6C616D636F727065722065726F732076656C20657261742E20467573636520657520746F72746F722073697420616D6574206469616D20657569736D6F642073616769747469732E204E756E632071756973206C61637573206964206E69626820636F6E76616C6C6973207661726975732E2053757370656E6469737365207669746165206D692E20566573746962756C756D207472697374697175652E20446F6E6563206D616C65737561646120697073756D206964206E657175652E204E756C6C616D20736564206C616375732E204475697320656765737461732C206A7573746F20757420636F6E677565206F726E6172652C2061756775652073617069656E206C7563747573206469616D2C20617420616363756D73616E20657261742073617069656E207574206C696265726F2E2050686173656C6C75732076656C206E756C6C612E2053757370656E646973736520617263752074656C6C75732C20706F72747469746F7220612C2070686172657472612066617563696275732C20616C697175616D2073697420616D65742C206D617373612E204E756C6C6120706F72747469746F722074696E636964756E74206C6F72656D2E204E756E6320646F6C6F72206F64696F2C20736167697474697320696E2C206C6F626F727469732076656C2C20766F6C7574706174207365642C206E6962682E0A0A5175697371756520626C616E646974206C656F2075742073617069656E2074656D70757320666163696C697369732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2041656E65616E20756C7472696369657320706F72747469746F72206A7573746F2E2046757363652072757472756D2065726F732075742075726E612E2050726F696E2071756973207175616D20656765742064756920616C697175616D20616363756D73616E2E20446F6E656320737573636970697420656C656966656E6420656C69742E2050656C6C656E746573717565206D61747469732C2066656C697320736F64616C657320696163756C697320696D706572646965742C206C616375732073656D20636F6E76616C6C69732061756775652C2073697420616D657420616C69717565742061726375207075727573206672696E67696C6C612072697375732E20496E206575206F64696F206964206D61676E61207068617265747261206F726E6172652E20416C697175616D20696E74657264756D2070756C76696E617220697073756D2E20536564206E657175652E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D2073697420616D6574206E6973692E2055742061742061756775652E204D617572697320766F6C757470617420626C616E646974206C6967756C612E204E756C6C61206575206D657475732E20566573746962756C756D206567657420656C69742E205072616573656E7420706F73756572652E20566573746962756C756D2069642073656D206E6F6E206C6563747573206D6F6C6C69732074696E636964756E742E20416C697175616D2069642066656C697320617420616E7465206F726E6172652074656D706F722E204E756C6C61206C61637573207475727069732C20666575676961742076697461652C2063757273757320717569732C20636F6E736563746574756572206E6F6E2C206D61757269732E204675736365206C61637573206D617373612C20706F72747469746F722075742C206D6F6C65737469652075742C2076656E656E6174697320612C206C6F72656D2E205072616573656E742073697420616D6574206F7263692E204D61757269732072686F6E6375732066656C69732076697461652066656C69732061646970697363696E6720696D706572646965742E204D616563656E6173206D6F6C6C6973206469616D206E6563206C656F2E0A0A467573636520656E696D20697073756D2C20756C7472696365732065752C206D6F6C65737469652069642C20656C656D656E74756D2069642C2073617069656E2E20496E746567657220612075726E612E204E616D2076656C6974206C696265726F2C2076656E656E6174697320656765742C2074656D706F722073697420616D65742C20666575676961742076697461652C20616E74652E204675736365206E756E632E205365642073656D706572206E69736C206E65632072697375732E20496E20736564206C696265726F2E2050726F696E20746F72746F72206E657175652C2074696E636964756E742061632C2074656D706F722061632C20706861726574726120717569732C2076656C69742E2044756973206C65637475732061756775652C20756C747269636965732076656C2C20636F6E7365717561742069642C20696163756C69732069642C20616E74652E20566976616D757320617563746F72206D65747573206120616E74652E204375726162697475722061726375206E6973692C20666163696C697369732061742C206C616F7265657420696E2C20636F6E736563746574756572207365642C206D61757269732E205175697371756520706C616365726174206469616D20736564206475692E20566976616D7573207072657469756D20636F6E64696D656E74756D206C6F72656D2E20437572616269747572206C616F726565742E2041656E65616E206F726369206C6967756C612C2063757273757320656765742C206C6163696E6961206E6F6E2C2066617563696275732076656C2C206C6F72656D2E0A0A416C697175616D206572617420766F6C75747061742E204375726162697475722065726F7320646F6C6F722C20636F6E67756520612C20636F6E64696D656E74756D207365642C206C75637475732075742C206E6962682E204D616563656E6173206E6F6E20746F72746F72206E65632074757270697320636F6D6D6F646F2070656C6C656E7465737175652E205072616573656E7420657569736D6F6420706C616365726174206D692E2053757370656E646973736520706F74656E74692E2050686173656C6C7573207574206E65717565207669746165206F726369206D617474697320696163756C69732E20496E746567657220656765742074656C6C75732E20446F6E656320617420616E74652E204E616D206C6163696E6961206C656F206567657420657261742E204D616563656E617320657569736D6F64206D61676E6120636F6E67756520746F72746F722E204D6F726269206E6563206D6173736120657520656E696D206D616C65737561646120736F6C6C696369747564696E2E2053656420616363756D73616E2E204E756C6C616D20697073756D2E205574206F64696F2E20416C697175616D206572617420766F6C75747061742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2050656C6C656E7465737175652069642076656C69742E204E616D206F64696F2073656D2C20616C69717565742075742C2074656D7075732073697420616D65742C20657569736D6F642065742C206E756E632E0A0A50656C6C656E746573717565206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205072616573656E74206D6175726973206E756E632C207661726975732075742C20636F6E76616C6C6973206D6F6C65737469652C206C75637475732073697420616D65742C206C656F2E205365642064696374756D206C6F72656D20657420617263752E204E756E632076656E656E617469732070656C6C656E746573717565206D617373612E204E756C6C6120666163696C6973692E2050686173656C6C757320696E20746F72746F722065676574207269737573207363656C657269737175652076756C7075746174652E20536564206E69626820656C69742C2073616769747469732061632C20636F6E64696D656E74756D206E65632C20636F6E76616C6C69732065742C206A7573746F2E20467573636520766F6C7574706174206D657475732E204E756E6320617563746F722E20566573746962756C756D206C656F2065726F732C2070656C6C656E7465737175652061632C206D6F6C6C697320756C7472696365732C2072686F6E637573206E6F6E2C20646F6C6F722E204D6175726973207665686963756C6120706C616365726174206E69736C2E20566573746962756C756D20626962656E64756D2C2061726375207175697320636F6E67756520656C656D656E74756D2C2076656C6974206E756E6320656C656966656E64207475727069732C206964206C7563747573207269737573206E69736C2073697420616D65742074656C6C75732E2050686173656C6C75732070656465206E657175652C20626C616E646974206E6F6E2C20636F6D6D6F646F2076697461652C20756C7472696369657320656765742C206D61676E612E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120666163696C6973692E20416C697175616D20616320616E74652E20437261732072697375732E204D6F726269206D6175726973206C616375732C20706F73756572652065752C20626C616E6469742065742C2070686172657472612061742C206D692E2050726F696E2061632070757275732E204475697320637572737573206E69736C2072757472756D207175616D2E20416C697175616D2061206F64696F206E6F6E206D61676E612070656C6C656E74657371756520756C747269636965732E204D616563656E6173206163206D6173736120717569732073617069656E20756C6C616D636F727065722074656D7075732E2043726173206375727375732076656C6974207365642073617069656E2E2050726F696E206E756C6C612E20566976616D757320736F64616C657320616C697175616D206E6962682E20457469616D206574206572617420757420616E7465206C6163696E696120657569736D6F642E204675736365206E6973692E2050726F696E2071756973206E756C6C612E0A0A517569737175652076656E656E617469732C2065726F7320736564206C616F7265657420736F6C6C696369747564696E2C206F72636920616E74652070656C6C656E746573717565206E69736C2C2073697420616D65742076697665727261207175616D2065726174206E6F6E2072697375732E20437261732065676574206C696265726F2E2053656420656C6974206D61676E612C2073656D7065722065752C206672696E67696C6C6120696E2C206469676E697373696D20736F64616C65732C20657261742E20566976616D757320666575676961742073656D2076656C206475692E20446F6E656320636F6E76616C6C697320736F6C6C696369747564696E206469616D2E2043726173207365642070757275732E20446F6E65632066656C69732065726F732C2073656D70657220656765742C2074656D706F7220636F6E7365637465747565722C20736167697474697320717569732C206E69736C2E204475697320696E20616E74652E2043726173206E6F6E207475727069732E204E756C6C612074656D706F722076656C697420616C697175657420747572706973206D6F6C657374696520706C6163657261742E2050726F696E20656C656D656E74756D206665726D656E74756D206D61757269732E20566976616D757320736564206F726369206C6163696E69612064756920706C6163657261742076656E656E617469732E20566573746962756C756D20666575676961742C2074656C6C757320696E20766F6C75747061742072757472756D2C206D61676E61206E69736920756C6C616D636F727065722065726F732C2069642070756C76696E6172206E657175652065726174207574206C616375732E20566976616D7573207365642061756775652E204E756C6C6120666163696C6973692E204D616563656E617320616E74652061756775652C20656C656D656E74756D2075742C20736F64616C65732076697461652C20636F6E64696D656E74756D206E65632C206C6F72656D2E20447569732070656465206F7263692C206672696E67696C6C612061742C20656C656966656E64206E65632C207072657469756D20696E2C20657261742E204E616D2073616769747469732C2074757270697320766974616520636F6E76616C6C69732070686172657472612C206F64696F2073656D207363656C65726973717565206C616375732C206E6563206C6F626F7274697320647569206469616D2076656C2065726F732E20496E2073656D7065722067726176696461206E657175652E0A0A496E7465676572206E756E632E205574207072657469756D20697073756D2073697420616D657420656C69742E20496E206E656320617263752E2053656420766573746962756C756D2076756C70757461746520697073756D2E2050656C6C656E7465737175652074696E636964756E742E204E756C6C61206772617669646120646F6C6F7220696E2074656C6C75732E2043726173207665686963756C612C20646F6C6F722075742070656C6C656E74657371756520616C697175616D2C206572617420656E696D20617563746F72206D617373612C207665686963756C61206C6F626F72746973206F64696F2065726F732071756973207175616D2E2050726F696E2064617069627573206E6571756520696E20656E696D2E2050726F696E20656C69742E20496E74656765722072686F6E6375732074696E636964756E7420656C69742E204675736365206C6F72656D206D657475732C2073656D7065722061632C20766F6C75747061742076697461652C20666163696C697369732075742C2074656C6C75732E20446F6E65632076656C20747572706973207669746165206E69736920706861726574726120706F72747469746F722E204D616563656E617320746F72746F722E204675736365206D692E204E756C6C616D206E6563207475727069732E2053656420736F64616C657320766573746962756C756D206E756E632E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A50656C6C656E74657371756520646F6C6F7220646F6C6F722C206C616F726565742065752C20616C697175657420717569732C207363656C657269737175652073697420616D65742C20617263752E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C616D206375727375732075726E61206567657420656C69742E205175697371756520626C616E6469742073617069656E20616320616E74652E2050726F696E206E756C6C612065726F732C206772617669646120766F6C75747061742C20736F64616C65732076656C2C206D6F6C6C69732065752C206D617373612E204E756C6C612074726973746971756520736F6C6C696369747564696E206E69736C2E20437572616269747572207669746165206C6F72656D2076697461652076656C69742065676573746173206F726E6172652E2041656E65616E20656765742065726F732E20416C697175616D206572617420766F6C75747061742E20467573636520612075726E61206964206F64696F20616C697175657420636F6E76616C6C69732E204375726162697475722073697420616D6574206E69736C20706F7375657265206C656F20706F737565726520646170696275732E2044756973206D6574757320657261742C206C75637475732076656C2C2072686F6E6375732061742C20636F6E76616C6C69732073697420616D65742C20656E696D2E20566976616D75732068656E6472657269742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D206567657420656C69742E0A0A4E756C6C616D2061206E756E632E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206D657475732075726E612C2074696E636964756E742065742C206C6163696E69612073697420616D65742C206C6F626F727469732076697461652C206C6967756C612E2050726F696E206574206D6175726973207669746165206D6920616363756D73616E2070656C6C656E7465737175652E20457469616D207175616D2070757275732C2068656E647265726974207365642C20666575676961742076697461652C20657569736D6F6420656765742C20746F72746F722E20557420616C697175616D206D61676E61207669746165206A7573746F2E2053757370656E6469737365206E6F6E206A7573746F2076656C2076656C697420636F6E64696D656E74756D2074656D7075732E20447569732074656D70757320697073756D2076697461652074656C6C75732E2050726F696E20696E206D617373612E20457469616D20756C6C616D636F727065722064696374756D2074656C6C75732E2050726F696E20616C69717565742066656C6973206174206C656F206C616F726565742070756C76696E61722E20566573746962756C756D20617263752070757275732C206D616C6573756164612073697420616D65742C206375727375732065752C20706C6163657261742073697420616D65742C206E756E632E204E616D206D61737361206F64696F2C20736F6C6C696369747564696E20696E2C2061646970697363696E6720612C20616C697175616D206E65632C2072697375732E20416C697175616D20626C616E6469742068656E647265726974206C696265726F2E204D617572697320677261766964612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204375726162697475722061206E6962682E20557420696E74657264756D206665726D656E74756D206E657175652E2050656C6C656E74657371756520736564206E756E632E204D6175726973207665686963756C61206E697369206574206E756E632E205072616573656E74206C6F72656D2E20446F6E65632073656D7065722E20496E7465676572206575206C6163757320696E2065737420616C697175616D2068656E6472657269742E20566573746962756C756D2065676574206E657175652E205365642073656D706572206C75637475732076656C69742E20437572616269747572206E6962682061756775652C20636F6E6775652065752C2068656E6472657269742069642C20636F6E6775652065742C20656E696D2E20496E746567657220706C61636572617420616C697175616D206C65637475732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20566976616D75732076697461652065726F732E20446F6E65632076656C206E69736C2E0A0A496E20766573746962756C756D20666163696C697369732075726E612E2055742072697375732E204D61757269732070686172657472612E2050656C6C656E746573717565206D61747469732E20496E746567657220737573636970697420616C697175616D20697073756D2E204475697320626C616E6469742C2073617069656E20657420756C7472696369657320636F6E64696D656E74756D2C2066656C6973206D6920656C656D656E74756D20706564652C206E6563207361676974746973206D65747573206D61757269732071756973207175616D2E205175697371756520616363756D73616E20617263752076656C206E756C6C612E20437261732073656D2073617069656E2C20706F72747469746F722069642C20756C747269636965732073616769747469732C206C75637475732065752C206E756C6C612E20496E746567657220717569732065726F732E204D6F726269207365642075726E6120612074656C6C7573207665686963756C612076756C7075746174652E20457469616D206E656320617567756520656765742066656C69732073656D706572207472697374697175652E205175697371756520757420646F6C6F722076656C2072697375732064696374756D20636F6E7365717561742E20536564206567657420646F6C6F7220736564206E756E63206C6163696E696120616C69717565742E2053757370656E646973736520616320746F72746F7220696E20697073756D20706F73756572652076656E656E617469732E20536564206567657420657261742E204E756C6C612066617563696275732E2044756973206C616F726565742C206D6173736120706F72747469746F7220616C697175657420656765737461732C20697073756D206C65637475732072686F6E637573207175616D2C20696E2061646970697363696E672065726F732073656D2075742074656C6C75732E2050656C6C656E74657371756520666575676961742074656D707573207175616D2E20566976616D757320696420646F6C6F7220656765742073617069656E20636F6E7365637465747565722074656D706F722E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120696163756C6973206665726D656E74756D206C696265726F2E204375726162697475722066617563696275732C206D61737361206D616C657375616461206375727375732074696E636964756E742C20657261742073656D20656C656966656E64206D61757269732C20736564206672696E67696C6C61206D6920616E74652061632070757275732E204475697320656C656D656E74756D206C65637475732E204E756E63206F726E617265206172637520657520746F72746F722E20566573746962756C756D2076656C20646F6C6F72206174207075727573206C6163696E6961206672696E67696C6C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E616D20696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204D616563656E61732074696E636964756E742C2065726F73206120656765737461732070656C6C656E7465737175652C2072697375732072697375732064696374756D206C696265726F2C20696420616C6971756574206D65747573206A7573746F20696E206D617373612E2050726F696E20612074656C6C75732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205365642070757275732E20536564206E6F6E20706564652E2041656E65616E206D617373612073617069656E2C20736F64616C65732073697420616D65742C20636F6E7365717561742064696374756D2C20656C656966656E642076697461652C20746F72746F722E20446F6E656320756C747269636573206C6163696E696120656C69742E0A0A4D6F7262692061646970697363696E6720736F64616C657320646F6C6F722E20557420756C6C616D636F7270657220756C74726963696573206573742E20496E2076656E656E617469732074656D7075732061756775652E2053757370656E646973736520746F72746F7220646F6C6F722C20616363756D73616E2065742C20737573636970697420612C2074696E636964756E742075742C206C696265726F2E20416C697175616D207363656C65726973717565206D61676E61207365642066656C69732E2051756973717565207574206E756E632061206D61676E612076756C70757461746520706C6163657261742E20416C697175616D2072686F6E637573207665686963756C61206475692E2053656420746F72746F722E204E756C6C616D2073697420616D6574206469616D2E204E756E63207365642065726F732E20536564206574206F64696F2074696E636964756E7420656C6974206772617669646120636F6E76616C6C69732E20437572616269747572207175697320746F72746F722061206C616375732073656D706572207661726975732E204D6175726973206174206175677565206E6F6E206D6920736F6C6C696369747564696E20616C697175616D2E20496E746567657220756C6C616D636F727065722E2050656C6C656E746573717565207375736369706974207175616D206E6F6E2070757275732E20416C697175616D2061632065726F73206174206172637520756C6C616D636F7270657220636F6E7365637465747565722E2053757370656E6469737365207072657469756D206D6174746973206C656F2E0A0A44756973206174206E756E632E2053656420646F6C6F72206573742C207661726975732061632C20706F7274612065742C2074696E636964756E742068656E6472657269742C2072697375732E20566976616D7573207574206D61676E612E205072616573656E74207574206D61757269732E20496E207075727573206C616375732C206D6174746973207365642C20766573746962756C756D206E65632C2074656D706F722061742C206E69736C2E204372617320756C6C616D636F727065722076656E656E617469732074656C6C75732E20557420646F6C6F722E204D616563656E6173206D616C6573756164612C207065646520612070756C76696E6172206D61747469732C2061726375206469616D207665686963756C612072697375732C207175697320706F72747469746F72206175677565206D6173736120696E2076656C69742E204E756E6320636F6E6775652E204D6F7262692076656C6974206D657475732C2072686F6E6375732065742C20616C697175616D20636F6E7365637465747565722C20756C74726963696573206D616C6573756164612C206C6967756C612E205365642076656C6974206E69736C2C2073616769747469732076697461652C20706861726574726120612C20706F7375657265207365642C206D617373612E204E756C6C6120666163696C6973692E20496E207661726975732C206C6967756C61206964206C6F626F7274697320736F64616C65732C206175677565206F726369206665726D656E74756D2074656C6C75732C2065752070756C76696E6172207269737573206C6967756C6120612073617069656E2E204D6F726269206C616F7265657420697073756D206E6F6E206D692E204E616D20637572737573206C6F72656D207574206D692E20566976616D7573206D61676E6120656E696D2C20706F7375657265206E6F6E2C2073656D70657220717569732C20736F64616C65732065752C20617263752E20457469616D206D692070757275732C207072657469756D20666575676961742C20766172697573207365642C2070656C6C656E74657371756520656765742C206C6967756C612E20496E206C656F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E6563207669746165206F726369206575206F72636920736F6C6C696369747564696E20666575676961742E0A0A5072616573656E74207075727573206D617373612C20657569736D6F642076697461652C2074656D707573206E65632C20636F6E7365717561742068656E6472657269742C206D657475732E2041656E65616E2066656C6973206573742C20656765737461732076697461652C20616363756D73616E20656765742C2070656C6C656E74657371756520696E2C2073617069656E2E204475697320646170696275732070656465206E6F6E2073617069656E2E204E756E632075726E612E20496E74656765722076656C206C696265726F2E204475697320617567756520617263752C2064617069627573206E6F6E2C20666163696C697369732076697461652C20706F73756572652075742C2065726F732E20446F6E6563207669746165206E756E632073697420616D6574206172637520696D706572646965742064696374756D2E204D6F72626920656C656966656E642C206C6F72656D20657520636F6E73656374657475657220766573746962756C756D2C206469616D206E756E63206F726E61726520617263752C2061632074656D706F722066656C697320646F6C6F7220656765742065726F732E2050686173656C6C7573206D617373612073656D2C20736F6C6C696369747564696E2061632C20736F64616C657320677261766964612C206C756374757320612C207175616D2E204E616D206E65717565207175616D2C20766976657272612061742C2076656E656E6174697320717569732C207361676974746973206E6F6E2C20656E696D2E0A0A4E756C6C6120666163696C6973692E2050656C6C656E7465737175652065676573746173206C6163696E6961206573742E205365642074696E636964756E742C2070656465207365642074696E636964756E7420766573746962756C756D2C2075726E6120646F6C6F722061646970697363696E672070757275732C207669746165206672696E67696C6C612066656C697320656C697420696E206E6962682E204E756C6C6120736564206E6973692E204D6175726973207375736369706974207363656C6572697371756520617263752E20457469616D206E6F6E20656E696D2076656C2065726F7320616363756D73616E206D616C6573756164612E204E756E632074696E636964756E7420636F6D6D6F646F206D61757269732E20496E2074696E636964756E7420726973757320717569732075726E612E204E756C6C61206469616D20746F72746F722C20616C69717565742065742C2074696E636964756E7420717569732C20736F6C6C696369747564696E2061632C20746F72746F722E2043726173206E69736C206E657175652C2076756C7075746174652073757363697069742C206D6F6C657374696520717569732C2070756C76696E61722061742C206E756C6C612E204E756C6C616D206163206D65747573206E6563206F64696F20706F7375657265207661726975732E2043726173207365642070656465206E65632064756920706F737565726520626962656E64756D2E204475697320657569736D6F6420756C6C616D636F72706572206C696265726F2E20416C697175616D2066617563696275732070756C76696E6172207475727069732E0A0A496E207574206E65717565206964206E756E63206665756769617420636F6D6D6F646F2E20437572616269747572206469676E697373696D2C2066656C697320617420736F6C6C696369747564696E206C6163696E69612C20656E696D20656C6974207375736369706974206E657175652C20736564206C7563747573206C6F72656D20697073756D20696E206C656F2E204475697320646170696275732C206F64696F207175697320617563746F7220636F6D6D6F646F2C206E69736C206F64696F206D61747469732074656C6C75732C206E65632074696E636964756E7420747572706973206469616D20696E20617263752E2043757261626974757220612073656D2E204E756C6C616D20766F6C7574706174206D61676E612E2050656C6C656E7465737175652073616769747469732C206E6571756520636F6E736571756174207072657469756D206375727375732C20646F6C6F72206C6163757320636F6E73656374657475657220617263752C20736564206C616F72656574206573742075726E61206574206D657475732E2053757370656E646973736520706C6163657261742C20647569206120706F7274612074656D706F722C206C6F72656D20647569206C6F626F72746973206E657175652C207365642076656E656E61746973206469616D20656E696D2069642065726F732E20457469616D206574206E69736C206E6F6E206C656374757320666175636962757320636F6E7365637465747565722E204D6F726269207363656C657269737175652C2073656D206E65632074656D70757320756C6C616D636F727065722C20697073756D206469616D2066657567696174206C6F72656D2C2061206672696E67696C6C612073617069656E20656C69742071756973206E6962682E204E756C6C616D206469616D2075726E612C2076697665727261207365642C2070686172657472612072686F6E6375732C2074696E636964756E742076656C2C206F7263692E20496E746567657220616363756D73616E206D617474697320657261742E204E616D2064696374756D2E204D6175726973206E6563206C656F2E204E756C6C6120696163756C69732E204E756C6C61206E69736C206D692C206461706962757320717569732C207665686963756C6120612C2063757273757320656765742C206F64696F2E0A0A50686173656C6C7573206461706962757320657569736D6F64206E6962682E20566976616D757320696D7065726469657420616E746520696E206C6967756C612E2050656C6C656E74657371756520616363756D73616E2E20496E20696D706572646965742C20647569206120617563746F72206672696E67696C6C612C206D65747573206E6973692063757273757320646F6C6F722C2076656C206C7563747573206C6967756C61206C6F72656D207669746165206D61757269732E205072616573656E74206D617474697320766573746962756C756D20656C69742E20416C697175616D20656E696D206C616375732C2070756C76696E6172206E6F6E2C206C6163696E69612073697420616D65742C20656C656966656E64206E6F6E2C2076656C69742E20566573746962756C756D206163206C656F2E204D617572697320696D70657264696574206A7573746F206163206C65637475732E20536564206D6F6C6573746965206C656374757320736564206475692E20536564206665726D656E74756D2074656D707573206D61757269732E204E616D206F726E617265206F7263692061632074656C6C75732E205574206D616C6573756164612C206C61637573206964206C6163696E696120616363756D73616E2C206469616D20656C69742061646970697363696E67206D657475732C20657420626962656E64756D2073617069656E206E69626820626C616E646974206F7263692E2053757370656E646973736520697073756D2074656C6C75732C20736167697474697320717569732C20766573746962756C756D206E6F6E2C2076756C7075746174652065752C2065726F732E205072616573656E74206174206E756C6C612069642070656465207363656C6572697371756520756C747269636965732E204372617320626C616E646974207072657469756D2074656C6C75732E204D616563656E6173206461706962757320636F6E64696D656E74756D2061756775652E2050686173656C6C75732074696E636964756E74207068617265747261206C6F72656D2E204D6F726269206E6F6E2065726F732E205365642074656D706F722C206E69736C20612074696E636964756E742074696E636964756E742C2065726F73206469616D2064696374756D2073656D2C2076656C206469676E697373696D20616E7465206469616D20736564206D61676E612E205072616573656E74206E6F6E206C6967756C61206964206D65747573206D6F6C657374696520636F6E7365637465747565722E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E64697373652076656C206D692E2043757261626974757220616E7465206E756C6C612C2072757472756D20612C20636F6E76616C6C69732076656C2C207665686963756C612061632C206E756E632E204E756E632073616769747469732C20656E696D2073697420616D657420617563746F722072757472756D2C206D617572697320617263752076756C707574617465206E657175652C20657420657569736D6F64206573742066656C6973207175697320616E74652E20566573746962756C756D207475727069732074656C6C75732C2068656E64726572697420696E2C206C6163696E696120636F6D6D6F646F2C20756C6C616D636F7270657220677261766964612C2072697375732E204D61757269732072686F6E637573206C6163696E69612072697375732E204D616563656E617320736F6C6C696369747564696E2065726174207669746165206E756E632E205072616573656E74207072657469756D2070656C6C656E7465737175652061756775652E20446F6E656320696E74657264756D2E205072616573656E742061632065726F732076697461652065726174206C6F626F72746973206672696E67696C6C612E2041656E65616E20636F6E7365717561742074656C6C75732E204E756C6C6120616363756D73616E20626962656E64756D2066656C69732E204D616563656E6173207072657469756D20616E7465206964206E6973692E2041656E65616E206D6920617263752C2073656D706572207365642C206D61747469732065752C2076656E656E617469732073697420616D65742C20617263752E20446F6E656320616C697175657420657569736D6F64206C656F2E2050726F696E206D61676E61206A7573746F2C2074726973746971756520612C2073656D7065722061632C20736F6C6C696369747564696E20612C206C6967756C612E204D6F7262692076656C69742E20416C697175616D2076656C206E6973692E0A0A496E2061206C6F72656D207574206E756E63206665756769617420636F6E6775652E20446F6E6563206665726D656E74756D20626962656E64756D206475692E2050726F696E207661726975732065737420717569732076656C69742E20446F6E656320616C69717565742073656D20616363756D73616E206D692E2053656420706C6163657261742E204E756C6C616D206163206E6973692061206D61737361206C6F626F727469732073757363697069742E204E756E63206964206C656F2E20416C697175616D206574206D617373612E204E756C6C616D20766573746962756C756D20656C656D656E74756D206D657475732E20496E20636F6E736563746574756572206E6973692076656C206A7573746F2E204D616563656E6173206567657420707572757320736564206D61737361207661726975732070656C6C656E7465737175652E2050686173656C6C75732066617563696275732066656C697320717569732066656C69732E2041656E65616E206F64696F20617263752C20626C616E64697420717569732C20666163696C6973697320696E2C20696D706572646965742065752C206C6F72656D2E204E616D20706F73756572652070756C76696E6172206D692E204675736365207472697374697175652C206D617572697320657420636F6E73656374657475657220756C747269636965732C206D6175726973206C65637475732074656D706F72206A7573746F2C206174206672696E67696C6C61206573742065737420736564206E6973692E20517569737175652066617563696275732E2053656420696E20746F72746F722074696E636964756E7420657374206C6163696E696120696163756C69732E204D616563656E61732061206D617373612E2050656C6C656E7465737175652061206E69626820617420707572757320706F7274612068656E6472657269742E0A0A4E756C6C616D207475727069732E2046757363652061632073656D20736564206F64696F2070656C6C656E74657371756520696D706572646965742E2043757261626974757220696E20617263752E205072616573656E74206C61637573206C616375732C20666575676961742069642C2070756C76696E617220696E2C2074696E636964756E74207365642C206E657175652E204D616563656E61732076697665727261206F64696F206567657420746F72746F722E20496E746567657220616C697175616D2C206C6F72656D2072757472756D2076656E656E61746973206469676E697373696D2C206C6967756C61206D61676E61206D616C65737561646120617263752C2076656C2066657567696174206C6F72656D20697073756D2071756973206D617373612E204D6F72626920616E74652E20566573746962756C756D206D6175726973206C696265726F2C20756C6C616D636F7270657220717569732C20756C74726963657320717569732C20666163696C69736973206E6F6E2C206D617373612E204D616563656E617320696D706572646965742E20416C697175616D206572617420766F6C75747061742E2050656C6C656E746573717565206469676E697373696D2067726176696461206C65637475732E20496E206E696268206F64696F2C20617563746F7220656765742C206461706962757320717569732C206469676E697373696D2076656E656E617469732C20617263752E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20447569732070656C6C656E746573717565206C6967756C612071756973206D617373612E2043757261626974757220636F6E64696D656E74756D2C206A7573746F2065676574206F726E617265206C75637475732C206C6F72656D206C6967756C6120736167697474697320706564652C206120706F727461206E756E63206E756E6320696E206E657175652E20517569737175652066656C6973206D61757269732C20636F6E64696D656E74756D2076697461652C20617563746F722076697461652C2074696E636964756E7420717569732C20706564652E204E756E63206C6163696E696120616E746520696E206C656F2E2050656C6C656E746573717565206C696265726F2E2041656E65616E2061206C6967756C61206574206E756E6320766573746962756C756D20636F6E7365637465747565722E0A0A4675736365206F726E6172652E205072616573656E742069642075726E612E20496E74656765722076656E656E617469732C207175616D206E6F6E20736167697474697320616363756D73616E2C20616E7465206E6962682073616769747469732061756775652C20736F6C6C696369747564696E2061646970697363696E6720646F6C6F722076656C697420657520657261742E2050726F696E207175697320656E696D206575207075727573207665686963756C6120616C697175616D2E204E756C6C612076656C20656E696D2076656C20656C697420736F6C6C696369747564696E206672696E67696C6C612E20416C697175616D206572617420766F6C75747061742E205365642073757363697069742066656C6973207574207475727069732E20457469616D2072757472756D20726973757320696D70657264696574206573742E20416C697175616D20612074656C6C75732061742074656C6C757320636F6D6D6F646F20646170696275732E204D61757269732072757472756D206D61676E61206574206F64696F2E20496E20617420646F6C6F722E20437572616269747572207665686963756C61206C656374757320696E20746F72746F722E204675736365206A7573746F2070757275732C206C75637475732076697461652C206D6F6C6C697320696E2C2070686172657472612061632C2070757275732E204E756C6C616D20706F737565726520696E74657264756D206A7573746F2E20437572616269747572207669746165206C616375732076656C206C656F20636F6E6775652070756C76696E61722E0A0A41656E65616E20656C656966656E64206E6962682076617269757320746F72746F722E2053757370656E64697373652076656C2065726F732E2050726F696E206E6563206469616D206120746F72746F7220756C747269636573206F726E6172652E20416C697175616D207363656C657269737175652066657567696174206A7573746F2E20566976616D757320616E74652075726E612C2061646970697363696E672076697461652C20706F72747469746F722065752C20736F64616C65732065742C2066656C69732E2053757370656E646973736520706F74656E74692E20437572616269747572206163206D6173736120696E206E69736C207361676974746973206D6F6C6C69732E204E616D207175616D206C6967756C612C20636F6E73656374657475657220656765742C20696163756C69732061742C207661726975732065752C206C656F2E204475697320646F6C6F72206C6967756C612C2074696E636964756E742061742C20756C6C616D636F72706572207365642C20616363756D73616E20616C697175616D2C206C6967756C612E2050686173656C6C75732076756C7075746174652C206C6F72656D2061742074696E636964756E742070686172657472612C207269737573206C6563747573206C6163696E6961206D61676E612C20717569732072757472756D20656E696D206D61676E612061742073656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E20447569732069642073656D2061206D617572697320736F6C6C696369747564696E2074696E636964756E742E20457469616D2065752070757275732065752061726375206672696E67696C6C612061646970697363696E672E20566976616D7573206F726E6172652074656D707573206469616D2E2050726F696E20747572706973207175616D2C206C6163696E6961206E6F6E2C20656765737461732061742C20636F6D6D6F646F20656765742C20706564652E205072616573656E742076756C70757461746520726973757320696E206573742E204E756C6C6120666163696C6973692E0A0A557420656C656D656E74756D206C6163696E69612070757275732E2050726F696E2076697461652061726375206163206E756C6C6120636F6E76616C6C697320616C697175616D2E204E756C6C6120636F6E6775652C206C696265726F2069642070656C6C656E746573717565206D61747469732C207175616D206C656374757320706F72747469746F72206469616D2C2061207363656C6572697371756520647569206C696265726F20696E2073617069656E2E204E756C6C616D2066656C6973206469616D2C207665686963756C612076656C2C206D6F6C65737469652075742C20766573746962756C756D20616C697175616D2C2073617069656E2E20446F6E656320636F6E76616C6C69732C2065737420757420656C656D656E74756D20766F6C75747061742C206D617572697320697073756D20677261766964612073656D2C20636F6D6D6F646F20666163696C697369732073617069656E206C65637475732073656D706572206C65637475732E205175697371756520706F72747469746F722065726F73207574206E6962682E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20457469616D206D617474697320726973757320736564206F64696F2E20566573746962756C756D206574206F64696F2E20496E206861632068616269746173736520706C617465612064696374756D73742E204E616D20747269737469717565206D61737361207574206C6967756C612E2051756973717565206E6962682074656C6C75732C207665686963756C612073697420616D65742C2061646970697363696E672061742C20636F6E76616C6C6973206E65632C206C6967756C612E20566573746962756C756D207072657469756D2C206D69206E6563206672696E67696C6C6120626962656E64756D2C20647569206E756E6320736F64616C657320706564652C20612073656D706572206D61676E61206E696268206E6F6E206469616D2E20446F6E6563206D61737361206E756E632C20766976657272612076656C2C20636F6E73656374657475657220706F7274612C2064617069627573206E6F6E2C20697073756D2E2044756973206E69736C206D61757269732C206375727375732076656C2C2073656D706572206E6F6E2C20736F6C6C696369747564696E20626962656E64756D2C2066656C69732E20566573746962756C756D206575206E657175652E0A0A43726173206E656320646F6C6F722E20446F6E6563206C616F726565742074656D707573206C65637475732E20437261732073656420746F72746F7220696E74657264756D206C6163757320656C656966656E64206469676E697373696D2E204D616563656E61732073697420616D657420656C69742E204E756C6C616D207175697320646F6C6F722076656C20647569207068617265747261206C75637475732E20496E2073697420616D6574207175616D2073697420616D6574207065646520756C74726963657320756C7472696365732E204D616563656E6173206469616D2E20496E74656765722075726E612E204375726162697475722064696374756D2C2076656C69742073656420706C6163657261742073757363697069742C206572617420747572706973206665726D656E74756D206A7573746F2C2073656420696E74657264756D206E657175652073656D206574206E6962682E20566976616D757320636F6E73657175617420636F6E76616C6C6973206D61676E612E204E616D20616C697175616D2C2065737420616320626962656E64756D20636F6D6D6F646F2C206D61676E61206573742064696374756D206D692C207669746165206D616C65737561646120656C6974206D61676E61207669746165206F64696F2E204D616563656E61732074656D706F722076756C7075746174652074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206475692E20457469616D20616363756D73616E207065646520636F6E67756520746F72746F722E0A0A4D6F7262692074656D706F72206C696265726F206163206C6F72656D2E20496E20616C697175657420766172697573206D61676E612E20496E20617263752E2050686173656C6C7573206F64696F2E2046757363652074696E636964756E7420616C69717565742066656C69732E20517569737175652076656C69742E20536564206C75637475732E20416C697175616D2066657567696174206672696E67696C6C61206D692E20416C697175616D206D6F6C657374696520766976657272612072697375732E2050726F696E20617263752E20566573746962756C756D206C6F626F727469732074656D707573206E6973692E205072616573656E742061206172637520696E2076656C697420766976657272612072757472756D2E0A0A496E20736564206C65637475732E20446F6E656320726973757320646F6C6F722C20626C616E6469742073697420616D65742C20656C656D656E74756D20636F6E76616C6C69732C20706861726574726120717569732C20706564652E20496E7465676572206F726E6172652E2041656E65616E20656765737461732064617069627573206A7573746F2E20536564207175616D206C656F2C20706F73756572652061742C20656C656D656E74756D2076697461652C20636F6D6D6F646F20656765742C206573742E20416C697175616D206D6F6C65737469652072686F6E63757320656E696D2E2043757261626974757220696163756C697320756C74726963657320706564652E204D6F72626920616C69717565742072757472756D206C616375732E20416C697175616D207175616D2E2053656420636F6D6D6F646F2C2074757270697320696E20706861726574726120706F73756572652C206D6920726973757320696D7065726469657420657261742C206120766573746962756C756D206D617373612074656C6C7573207665686963756C612073656D2E204D6175726973206672696E67696C6C6120756C747269636573206E756E632E204E616D206E69736920656E696D2C20656C656966656E642073697420616D65742C20756C747269636573207365642C206665726D656E74756D206E6F6E2C2061756775652E2050726F696E20636F6E677565206C6F626F72746973206E6973692E204D616563656E61732068656E6472657269742E204E616D20736564206E69736C2E204E756E6320656C656D656E74756D206F64696F2065752072697375732E20496E206D657475732E2050686173656C6C75732067726176696461207072657469756D206C6967756C612E204E756C6C61207669746165206E657175652E204E616D206E69736920746F72746F722C206F726E617265206E6F6E2C20626C616E6469742061742C206375727375732065752C20746F72746F722E0A0A4475697320626962656E64756D20697073756D20696E206E756E6320637572737573206D6F6C65737469652E204E756E63206F7263692E204E756C6C616D206E656320616E7465206E6F6E20657374206469676E697373696D20766976657272612E204D617572697320626C616E6469742C2076656C69742069642066657567696174207072657469756D2C20656C6974206D61676E612070656C6C656E74657371756520646F6C6F722C206174207361676974746973206C616375732076656C69742065676573746173206D61676E612E2050656C6C656E746573717565206375727375732C206469616D20636F6E736563746574756572207361676974746973206672696E67696C6C612C20746F72746F72206E6973692061646970697363696E67206E756E632C20657520766172697573206C6163757320726973757320616320656C69742E204D6175726973206964206E6973692071756973206C656F20657569736D6F642076656E656E617469732E2050656C6C656E74657371756520616320616E74652E204D617572697320617263752073617069656E2C2074656D706F722061742C20706F72747469746F722069642C20636F6E64696D656E74756D2075742C206475692E20457469616D206665726D656E74756D20756C747269636965732061756775652E20437261732075742065726F73206174206A7573746F20756C7472696369657320696163756C69732E2044756973206469676E697373696D2C206E69736C20657420666163696C69736973206665726D656E74756D2C2065726174207075727573206D6F6C65737469652074656C6C75732C20717569732074656D70757320697073756D206C656374757320617420656C69742E204E756C6C61207669746165206C6F72656D2E0A0A41656E65616E2076656C2073656D206574206469616D2073656D70657220636F6E6775652E20496E20626962656E64756D206469616D20717569732074656C6C75732E204E756E6320666163696C6973697320756C74726963696573206E6962682E2043726173206E756E6320656E696D2C2066657567696174207365642C20756C7472696365732076697461652C2073616769747469732076697461652C20697073756D2E204675736365207669746165206E756C6C612E20446F6E65632070656C6C656E7465737175652C2076656C697420696E20706F72747469746F7220656C656966656E642C20657374206E65717565206C6F626F727469732076656C69742C2073697420616D65742072757472756D20616E746520746F72746F72206E656320646F6C6F722E20446F6E6563207665686963756C612E204E756C6C6120666163696C6973692E20536564206567657374617320756C747269636573206E6962682E20446F6E656320656C6974206C65637475732C20636F6E76616C6C697320706F72747469746F722C20616C697175657420646170696275732C206665756769617420656765742C206C6967756C612E2053656420636F6E736563746574756572206A7573746F2E204D616563656E617320612073617069656E2073697420616D6574206E6973692064617069627573206C6F626F727469732E20566976616D7573206C7563747573206C6F72656D206E6F6E206E756C6C612E2053656420656765742065726174207669746165206C696265726F20696E74657264756D20706F73756572652E20437261732070756C76696E61722E204E756C6C616D20696D706572646965742C20646F6C6F722074656D706F72206469676E697373696D20626C616E6469742C206475692073617069656E2072686F6E637573206E657175652C206964206D616C657375616461206175677565206D61676E612073697420616D65742075726E612E204475697320736564206D61757269732E0A0A4D6F72626920616363756D73616E2E20536564206D61757269732061756775652C206672696E67696C6C61206E6F6E2C20617563746F722075742C20617563746F722065742C206F7263692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320757420706564652E20446F6E6563207669766572726120656E696D2076656C206C6F72656D2E2050656C6C656E746573717565206E65717565206D61757269732C20696E74657264756D2065752C2076656E656E617469732069642C20636F6E64696D656E74756D2065752C2073617069656E2E20446F6E656320697073756D20617263752C206C6163696E69612061646970697363696E672C206C616F726565742065742C206375727375732076656C2C2076656C69742E205574207361676974746973206D617572697320717569732072697375732E20496E7465676572206575206F64696F207669746165206C61637573207669766572726120616363756D73616E2E204D6F726269206C656F20616E74652C206469676E697373696D207365642C2076617269757320717569732C20766F6C75747061742076697461652C206E6973692E204E756C6C6120706C61636572617420696E74657264756D20656C69742E20446F6E6563206E65717565206475692C2073616769747469732076697461652C20736F6C6C696369747564696E20717569732C20636F6D6D6F646F2076697461652C206E657175652E204E756C6C612071756973206C6967756C61206F726E617265206C6967756C612064696374756D206F726E6172652E204D61757269732072757472756D2072757472756D206E657175652E2041656E65616E207665686963756C612074656D707573206573742E20446F6E656320766172697573207363656C6572697371756520706564652E20446F6E656320706C6163657261742076756C707574617465206C656F2E204E756C6C616D206E756E63206E69736C2C20706F7375657265206E6F6E2C20666575676961742076697461652C2070656C6C656E74657371756520717569732C206D61757269732E20496E20647569206E657175652C2063757273757320656765742C20736167697474697320656765742C20646170696275732076697461652C206D692E2050726F696E2065676574206573742E0A0A467573636520706F727461206573742E204D6175726973206D61676E612E20416C697175616D20697073756D206C616375732C20756C747269636965732069642C20766573746962756C756D206C75637475732C20616363756D73616E2075742C20616E74652E20536564206D61757269732E205365642061646970697363696E67206C656F2073697420616D6574206D61676E612E2053757370656E646973736520706F74656E74692E204E756E63206D6173736120656C69742C206672696E67696C6C6120656765742C20656765737461732076697461652C206C75637475732076697461652C20646F6C6F722E2050686173656C6C75732071756973206E756C6C61206575206E69736920696E74657264756D20736F6C6C696369747564696E2E204E756C6C616D2069642074656C6C75732E20496E746567657220696163756C697320646F6C6F722061632070757275732E205365642076656C206D692E20437572616269747572206E6F6E206D61676E612073697420616D6574206A7573746F20636F6E64696D656E74756D2076756C7075746174652E20517569737175652074696E636964756E742070656465206575206E69736C2E20566976616D7573206C6F626F727469732E204E756E63206D65747573206D657475732C20636F6E677565207365642C2074696E636964756E74207365642C207072657469756D2061742C206F64696F2E20446F6E6563206120617263752E20496E2073656D206A7573746F2C207665686963756C61207365642C207661726975732069642C20766F6C75747061742061742C2072697375732E205072616573656E7420696163756C6973206D617373612E20496E206172637520656C69742C2068656E64726572697420656765742C20756C6C616D636F7270657220696E2C20706F7274612069642C2074656C6C75732E20446F6E65632073616769747469732068656E647265726974206469616D2E0A0A53757370656E646973736520706F74656E74692E20536564206574206469616D206574206175677565207361676974746973206C6F626F727469732E2050686173656C6C757320646F6C6F722E2055742065742061726375206567657420616E74652074656D706F7220706F73756572652E20416C697175616D206665726D656E74756D207363656C65726973717565206475692E204D61757269732061742070757275732E20446F6E656320657261742073656D2C20766573746962756C756D206E65632C2066617563696275732061632C206D617474697320612C206C656F2E2053757370656E64697373652061646970697363696E67206C6163696E69612073656D2E204E756C6C616D206F72636920617263752C2064696374756D2065742C20666175636962757320766976657272612C20646170696275732065742C206E657175652E2043726173206E756E63206469616D2C2061646970697363696E67206E6F6E2C20736F6C6C696369747564696E20696E2C20696E74657264756D2076656C2C206D617373612E204D61757269732073616769747469732C206A7573746F206174207472697374697175652074656D7075732C206D6175726973206D617572697320616C697175616D20616E74652C2073697420616D657420706F7375657265206469616D206475692065676574206C6967756C612E20496E206469676E697373696D2C206E69736C207574206C6163696E696120636F6E64696D656E74756D2C2065726174206A7573746F20706F72747469746F72206E756C6C612C206E6F6E2067726176696461206C6967756C61206D61676E612065676574206D617373612E20566573746962756C756D207669746165206C6967756C61206174206D6920766573746962756C756D2073757363697069742E2044756973206C616F726565742E204E756C6C6120636F6D6D6F646F206C696265726F2073697420616D6574206C6F72656D2E20557420656C656D656E74756D2073656D2E20496E74656765722076656C20646F6C6F722E204E616D20666163696C69736973206D6920717569732073656D20756C7472696365732073616769747469732E205365642071756973207175616D206174206D65747573206D6F6C657374696520626962656E64756D2E0A0A50726F696E2064756920656E696D2C206C6163696E696120612C20666575676961742061632C20706C6163657261742076697461652C20706564652E205175697371756520656765737461732C206C656F206567657420616C697175616D207072657469756D2C206C696265726F206A7573746F2074696E636964756E742065726F732C2075742065676573746173206175677565207065646520656C656D656E74756D206E6962682E20437572616269747572206D6F6C6C697320736F64616C657320656E696D2E20446F6E65632061756775652E2050686173656C6C757320696420697073756D20706F737565726520647569207072657469756D2066617563696275732E204D6175726973206C756374757320616E74652073656D706572206E69736920696E74657264756D2061646970697363696E672E204475697320646170696275732C206F64696F207175697320766976657272612072686F6E6375732C206A7573746F207175616D20626962656E64756D20646F6C6F722C20696420646170696275732076656C697420657261742076656C20657261742E2046757363652073697420616D6574206E69736C2076656E656E61746973207175616D20756C74726963657320636F6E64696D656E74756D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632072686F6E637573207363656C65726973717565206C6967756C612E20566573746962756C756D206D69206F64696F2C20616363756D73616E2065742C2061646970697363696E6720656765742C206F726E6172652075742C207175616D2E204E756C6C616D20626C616E646974206D6F6C6573746965206D61757269732E20437572616269747572206469676E697373696D206D6175726973206574206C6F72656D2E2053757370656E64697373652061206A7573746F2E204E616D206D617474697320666175636962757320617263752E204475697320626C616E64697420656E696D206E6F6E206D617373612E0A0A4E756C6C616D206C6F72656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E204D617572697320636F6E73656374657475657220706F7375657265206D61757269732E204D616563656E61732074696E636964756E74206D617572697320696E2065726F732E204E756C6C61206575206D65747573206575206F72636920736F6C6C696369747564696E2066617563696275732E2053757370656E646973736520616C697175616D206D6175726973206964206573742E204372617320626C616E646974206475692065742075726E612E204E756C6C6120617263752E2053656420612075726E612E204E756C6C612064617069627573207665686963756C6120746F72746F722E20446F6E65632072697375732E20536564207175616D206D657475732C20656765737461732065752C206375727375732075742C2076697665727261206E6F6E2C206F64696F2E205574206A7573746F206A7573746F2C206D616C6573756164612073697420616D65742C20626C616E6469742073757363697069742C206D6F6C657374696520696E2C206A7573746F2E20566573746962756C756D20636F6E7365717561742C207175616D20616320666575676961742074696E636964756E742C20697073756D206C696265726F20656C656966656E64206F64696F2C206E6F6E20656C656966656E64207065646520697073756D206E6F6E20616E74652E204E756C6C616D2061206D657475732E0A0A4E616D206163206E6973692061742066656C697320637572737573206D61747469732E2050656C6C656E74657371756520636F6E7365717561742073656D2071756973206F7263692E20517569737175652074656D7075732E2041656E65616E20696D70657264696574206D6F6C657374696520706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652065752074656C6C75732E204E756C6C61206469616D2065726F732C20736F64616C65732075742C20736F64616C6573206E65632C2074696E636964756E742061632C206E756E632E204E756E63206C6163696E696120666175636962757320697073756D2E20566976616D75732076656C206E6571756520696E2065726174206665726D656E74756D206C75637475732E204E756C6C612065676574206D65747573206E656320617567756520626962656E64756D20706C6163657261742E20566976616D75732074656D7075732E205072616573656E7420636F6E677565206F726E61726520697073756D2E20457469616D206D61747469732066657567696174206A7573746F2E0A0A416C697175616D206475692E2041656E65616E20636F6D6D6F646F20746F72746F72207669746165206E756C6C612E204D6F72626920657420697073756D2E204D617572697320616320697073756D2E204E616D2076656C207269737573207574206C6563747573206D6F6C6C697320766976657272612E2043757261626974757220656C656D656E74756D206D6F6C6C6973206573742E204E756C6C616D20656C69742E20566573746962756C756D207375736369706974207072657469756D20656E696D2E20566573746962756C756D207574206D617373612E2050726F696E206E65632066656C69732E204D616563656E617320677261766964612C2061726375206E656320636F6E7365717561742073616769747469732C2065726F732074656C6C7573207363656C65726973717565206D61757269732C20766974616520616363756D73616E207175616D207175616D207574206E756E632E20496E7465676572206567657420616E74652065752076656C6974206C616F72656574206D616C6573756164612E204E756E632073616769747469732C206D617572697320766974616520706861726574726120766F6C75747061742C2074656C6C75732074656C6C757320656C656966656E642065726F732C2073697420616D65742072757472756D20697073756D206E69736920612076656C69742E205072616573656E7420766172697573206C656F20657520657261742E20566976616D757320636F6E73657175617420706C6163657261742070757275732E20446F6E6563207072657469756D20656C656D656E74756D206E6962682E2050726F696E20617420656C6974206E6F6E2073656D20616C6971756574206D61747469732E2053656420756C6C616D636F7270657220697073756D2073697420616D657420656C69742E0A0A4D617572697320696E206D657475732E2053757370656E6469737365206D61676E61206C6F72656D2C2066617563696275732076656C2C2074696E636964756E7420717569732C207363656C65726973717565206E6F6E2C2074656C6C75732E2046757363652071756973206C6F72656D2E2050726F696E2061206C616375732073697420616D6574206D617572697320696163756C69732070756C76696E61722E2053757370656E64697373652072686F6E6375732065726F73206E6563206D692E205072616573656E7420657569736D6F642C207475727069732076697461652072757472756D207072657469756D2C206F64696F206D6574757320766F6C7574706174206E657175652C20656765742074656D7075732073617069656E206E657175652073656420657261742E20446F6E6563206665726D656E74756D207075727573206174206C65637475732E204E756C6C616D2073656D2E2046757363652076656C206D6920717569732065726174206C6F626F7274697320706F73756572652E2041656E65616E20656765742075726E612E2053757370656E6469737365206C6967756C612E204475697320696E206E6973692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A4375726162697475722076756C707574617465206C656374757320696420706564652E2050686173656C6C75732065752076656C69742E20457469616D2076656E656E617469732061646970697363696E67206E6962682E20416C697175616D206375727375732070756C76696E61722074656C6C75732E20566573746962756C756D206E657175652E204D6175726973206E6563206A7573746F20657420657261742073656D7065722070656C6C656E7465737175652E204675736365206D61747469732064696374756D20646F6C6F722E20457469616D2065676574207075727573206575206D617373612076617269757320656C656D656E74756D2E2050656C6C656E746573717565206D617373612E20557420756C74726963696573206469616D2073656420697073756D2E204E756C6C616D206469616D2E2050656C6C656E746573717565206964206D61676E61206964206C696265726F2074726973746971756520616C697175616D2E0A0A557420656C656966656E642C20707572757320696420706C6163657261742076656E656E617469732C2075726E6120617567756520616C6971756574206C6967756C612C20696E20756C74726963696573206C656F2072697375732065742074656C6C75732E204D6175726973206574206E756C6C612069642075726E61207472697374697175652074656D7075732E20557420666163696C697369732C2075726E6120657520766573746962756C756D2072686F6E6375732C206C616375732065726F7320636F6E736563746574756572206D657475732C2065742072757472756D20647569206C656374757320696E2070757275732E204E756E632076656C206E69736C206E6F6E20697073756D2074696E636964756E74206D6F6C6C69732E204E616D207175616D206C616375732C206F726E6172652076697461652C2072686F6E637573206E6F6E2C20636F6E677565207365642C206F64696F2E2050726F696E206E696268206475692C20706F7274612076656C2C2076656E656E61746973206E6F6E2C2070656C6C656E7465737175652075742C206E6973692E20536564207472697374697175652066656C69732061206D61676E612E2053757370656E646973736520656765742074656C6C75732E2043726173206772617669646120696D706572646965742076656C69742E20496E74656765722068656E6472657269742072697375732E2050726F696E206F7263692E20416C697175616D20756C6C616D636F72706572206D61757269732071756973206D61757269732E204E756E63206C6163696E696120766573746962756C756D206D657475732E20447569732074656C6C75732E204E756C6C616D2066617563696275732C206C656F2061632076756C70757461746520736F6C6C696369747564696E2C206C656F20646F6C6F7220666175636962757320657261742C207175697320626962656E64756D206F726369206F64696F206E6F6E20617263752E0A0A4E756C6C616D20616363756D73616E206D617474697320646F6C6F722E20446F6E6563206574206475692E205072616573656E7420612066656C6973206D6F6C6C6973206C616375732073656D706572206C6163696E69612E204375726162697475722070656C6C656E746573717565206C7563747573206573742E2050726F696E206E756C6C61206475692C20636F6E64696D656E74756D2076656C2C206661756369627573206E6F6E2C20696E74657264756D2061632C20657261742E204D616563656E6173207363656C657269737175652C206C656374757320696420766F6C757470617420616363756D73616E2C2073617069656E20746F72746F722070656C6C656E746573717565206475692C207365642073656D706572206D61676E612073656D207574206C656F2E2050726F696E206E756C6C612E204E756C6C616D206461706962757320756C6C616D636F727065722073656D2E2053757370656E6469737365207665686963756C61206D6574757320696E206E756E632E2050656C6C656E746573717565206E6F6E207175616D2076656C206172637520756C74726963657320756C6C616D636F727065722E2050686173656C6C757320717569732066656C69732073697420616D65742074656C6C757320756C6C616D636F72706572206665726D656E74756D2E20536564207665686963756C6120736F6C6C696369747564696E2075726E612E20437572616269747572207068617265747261207363656C657269737175652072697375732E2050656C6C656E746573717565206964206D617373612071756973206D6574757320616C697175616D20696D706572646965742E20496E206E756E63206C616375732C206665756769617420696E2C206772617669646120656765742C2076656E656E617469732075742C2074656C6C75732E2053757370656E646973736520706F74656E74692E204E616D20636F6E7365717561742061646970697363696E67206475692E20496E206E756C6C61206E6973692C20666575676961742075742C206665726D656E74756D2076656C2C2067726176696461206E65632C20746F72746F722E20496E207365642061756775652E0A0A457469616D20756C6C616D636F7270657220617567756520617420656E696D2E20496E7465676572206469676E697373696D2E20416C697175616D2070756C76696E617220636F6E677565206E756C6C612E204D6F72626920656E696D206D617373612C206672696E67696C6C6120612C20616363756D73616E20656765742C20636F6E64696D656E74756D206E65632C20657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2041656E65616E2070686172657472612E20457469616D20706F72747469746F722070757275732061206D657475732E20416C697175616D20696E74657264756D2073656D2065676574206A7573746F2E205175697371756520766F6C7574706174206C7563747573206573742E2041656E65616E2061756775652E2050686173656C6C757320647569206C65637475732C20756C747269636573206E65632C20636F6D6D6F646F2076656C2C20617563746F722076656C2C206E6973692E20557420756C7472696365732070656C6C656E746573717565206E6973692E20496E74656765722061632076656C69742065742073656D20696D70657264696574206C75637475732E20467573636520766974616520747572706973206964206175677565206D6F6C6C697320636F6E7365637465747565722E0A0A4D616563656E6173206E6563206C616375732E204D616563656E617320636F6E64696D656E74756D206F64696F2065752066656C69732E204D6175726973207574206E69736C207669766572726120657261742066617563696275732061646970697363696E672E20457469616D20656765737461732E204E756E6320657420646F6C6F72207669746165207269737573206469676E697373696D20636F6D6D6F646F2E204D6F726269206C65637475732076656C69742C2074696E636964756E74206E65632C20616C69717565742076656C2C206D61747469732076697461652C206C6967756C612E204D616563656E617320756C747269636965732073656D70657220646F6C6F722E2053757370656E6469737365206D616C6573756164612E20496E7465676572206D617474697320656C69742E20446F6E656320616363756D73616E2C206C6163757320666163696C69736973207661726975732074656D7075732C206E756C6C6120656C697420706F72746120657261742C2065742072757472756D20656C69742073656D2073697420616D6574206475692E0A0A4D616563656E6173206D6F6C6C6973206D69206E6F6E206E756C6C612E20566976616D7573207475727069732E2053757370656E64697373652061206D657475732E20496E2071756973206D6920696E2074757270697320636F6E67756520617563746F722E204D616563656E6173206C616375732E2053757370656E646973736520736F6C6C696369747564696E2E2050686173656C6C757320706F727461206E756E63206E6F6E206E69736C2070756C76696E617220656765737461732E20536564206E756C6C612E20566573746962756C756D206163206D692E204D617572697320756C7472696369657320636F6E64696D656E74756D206E657175652E204E756C6C612074656D707573206A7573746F2076656C206D617373612E204E756C6C6120737573636970697420636F6E67756520617263752E205072616573656E74206964207475727069732E204D6175726973206E69626820706564652C20657569736D6F642073656D7065722C206D6F6C65737469652061632C2072686F6E6375732076697461652C20616E74652E204D616563656E617320657261742066656C69732C207669766572726120736F6C6C696369747564696E2C20736167697474697320656765742C2070656C6C656E746573717565206E65632C206F7263692E20467573636520756C74726963657320636F6E736571756174206C616375732E20416C697175616D2065726174206D61676E612C20666575676961742061742C207669766572726120612C206D6F6C6C6973206E6F6E2C207475727069732E0A0A446F6E6563206D692E204E616D2064696374756D2070656C6C656E7465737175652073656D2E20446F6E6563206D6F6C6C69732072686F6E63757320656C69742E2050686173656C6C75732072686F6E63757320706564652073697420616D65742072697375732E20446F6E656320656765742061756775652E204D616563656E6173206E6F6E206C65637475732E2050686173656C6C757320736F6C6C696369747564696E206E697369206E65632066656C69732E20416C697175616D207072657469756D2C2065737420656765742073656D70657220636F6E76616C6C69732C206E696268206E756E6320736F6C6C696369747564696E2070757275732C2069642074656D706F722070656465206475692076656C206D61676E612E20566976616D7573206163206C6F72656D2E20457469616D206E69736C20746F72746F722C2061646970697363696E672064696374756D2C20656C656D656E74756D20696E2C20666163696C69736973207365642C206E6962682E2050726F696E206D61757269732E2050726F696E2072757472756D206D6173736120656765742073656D2E204375726162697475722074656D706F722061646970697363696E6720656C69742E204375726162697475722070757275732074656C6C75732C206665726D656E74756D20656765742C20616C69717565742076697461652C20636F6E76616C6C69732061632C206D61757269732E0A0A496E746567657220636F6E7365717561742076656C69742065752065726F732074696E636964756E74207665686963756C612E204E756C6C616D206C6F72656D2073617069656E2C2072686F6E637573206E6F6E2C206D617474697320717569732C20756C747269636965732073697420616D65742C20656E696D2E2043757261626974757220636F6D6D6F646F2C206C696265726F20696E20657569736D6F642073757363697069742C2073656D207075727573206672696E67696C6C6120656E696D2C206163206D6F6C657374696520746F72746F72206F7263692065742076656C69742E20446F6E656320706564652E20457469616D20706C61636572617420636F6E64696D656E74756D207475727069732E2050686173656C6C7573206567657374617320656E696D206E6563206D61676E612E20566976616D757320636F6E64696D656E74756D2C206E756C6C612076656C206C7563747573207472697374697175652C2065726F7320726973757320766573746962756C756D206E756C6C612C20696E207665686963756C61206172637520697073756D2061742066656C69732E20446F6E656320616C697175616D20656C69742061742061756775652E205175697371756520612065726F73206575206C6967756C6120616363756D73616E2064696374756D2E20457469616D207665686963756C61207475727069732071756973206C696265726F2E20416C697175616D206E6F6E206D692E20446F6E6563206574206C656F2E2050726F696E206C656F206C696265726F2C20616C697175616D2074696E636964756E742C20636F6E677565206E65632C2061646970697363696E6720706F7274612C20656E696D2E204E756C6C61206C6F626F727469732C20746F72746F722073697420616D657420696D7065726469657420756C6C616D636F727065722C20646F6C6F72206F726369206D616C65737561646120706564652C207365642067726176696461206E6962682075726E612076656C206C6F72656D2E20536564207068617265747261206D616C6573756164612065726F732E205175697371756520657569736D6F6420616C697175657420657261742E2053757370656E646973736520616C6971756574206D61747469732070757275732E0A0A4E756E63206964206E756C6C612071756973206A7573746F20636F6E67756520736F6C6C696369747564696E2E205072616573656E742065726174207475727069732C2072686F6E6375732065752C207072657469756D2065752C2070656C6C656E74657371756520612C206E6962682E20566976616D75732074656D7075732E2043726173206E65632072697375732061742074757270697320696D70657264696574206C6F626F727469732E205574206D61747469732E204D616563656E6173206573742066656C69732C2070656C6C656E746573717565206E6F6E2C20696D70657264696574207365642C20656C656966656E642074696E636964756E742C206C6F72656D2E20496E2074696E636964756E742E205365642076656C206C656F2E20446F6E65632065742075726E6120696E207475727069732068656E64726572697420626C616E6469742E20446F6E656320636F6E64696D656E74756D20616363756D73616E206573742E2055742070686172657472612C206D65747573207669746165206D617474697320636F6E7365637465747565722C206C656F207175616D2076756C707574617465206F64696F2C206E6563206C616F72656574206E6973692076656C697420657520657261742E20496E7465676572206C65637475732061756775652C206567657374617320696E2C20696E74657264756D2065752C2076656E656E617469732076656C2C2073617069656E2E2051756973717565206574206573742076697461652065726F73206C616F72656574206C6F626F727469732E204E756C6C616D207574207269737573206E6F6E206E756C6C6120706C6163657261742061646970697363696E672E205072616573656E7420646170696275732E20457469616D20612066656C69732E20557420736F64616C657320636F6E736571756174206D61757269732E2044756973206C6F72656D2066656C69732C206C756374757320612C2074726973746971756520696E2C206D6F6C65737469652061742C2072697375732E20536564207665686963756C6120626962656E64756D2074656C6C75732E204E616D20636F6E73657175617420657569736D6F64206C616375732E0A0A41656E65616E20746F72746F7220656C69742C2067726176696461206E65632C206665726D656E74756D2065752C206C6F626F727469732069642C20697073756D2E204D616563656E61732065752070757275732E204372617320616320747572706973207574206E69736920696163756C69732072686F6E6375732E204E756C6C61207075727573206D657475732C206469676E697373696D206E65632C2074696E636964756E742076697461652C20646170696275732065752C206E6962682E204675736365206C6F626F727469732C206E756E63206174207669766572726120656C656966656E642C206A7573746F20747572706973207363656C657269737175652065726F732C2061632070656C6C656E746573717565206D65747573206E69736C2061742070757275732E2053656420656C656D656E74756D2074656C6C75732073656420656E696D20696E74657264756D20626C616E6469742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E746567657220756C7472696369657320616C6971756574206F64696F2E204D61757269732065676574206E756E63206120697073756D20756C74726963657320736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2041656E65616E20616363756D73616E2E20446F6E65632073617069656E206C65637475732C20636F6E6775652061742C20706F7274612069642C2068656E6472657269742076697461652C206E69736C2E204375726162697475722076656C207175616D2076656C206E6571756520616363756D73616E206C616F726565742E204D6F7262692073617069656E206573742C207072657469756D20696E2C20636F6E7365637465747565722061632C206D6F6C6C69732075742C206C696265726F2E20446F6E65632074696E636964756E742061646970697363696E67206D657475732E204E756E6320766573746962756C756D20656765737461732061756775652E20446F6E6563207363656C65726973717565206475692075742073656D2E2053757370656E64697373652076656C206D6574757320696420657374206D6F6C657374696520696163756C69732E0A0A566976616D75732070686172657472612C20656C6974206575206D616C65737561646120626C616E6469742C206469616D20746F72746F72206D6F6C6C6973206475692C207365642070756C76696E6172206D61737361206E756E63206574206D61676E612E2053656420706C61636572617420656C697420617563746F7220746F72746F722E204E756C6C6120616320657261742E2050656C6C656E74657371756520636F6E7365637465747565722C2064756920636F6E76616C6C69732074696E636964756E7420636F6E64696D656E74756D2C2073656D206F64696F20766F6C7574706174206C696265726F2C206E6F6E20656C656D656E74756D2066656C6973206E65717565206E6563206F64696F2E204D616563656E61732068656E6472657269742065726F73206964206469616D2E204D61757269732076656C207075727573206163206F72636920636F6E76616C6C697320636F6E76616C6C69732E205365642073697420616D6574206C616375732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652064696374756D20766172697573206C616375732E204D61757269732065676574206E69736C2E2053757370656E646973736520706C6163657261742C206E756C6C61206E6F6E206F726E617265206469676E697373696D2C206E69736C206469616D2073616769747469732074656C6C75732C20696E2073656D706572206E69736920646F6C6F72206174206E6962682E204475697320756C6C616D636F7270657220766976657272612066656C69732E20496E746567657220612074656C6C75732E2053757370656E64697373652065676574206E756E632E2041656E65616E206469616D206573742C20616363756D73616E2069642C20737573636970697420696E74657264756D2C206672696E67696C6C612076697461652C206A7573746F2E2050726F696E20706564652E204D616563656E6173206174206E6571756520696E206E6571756520766573746962756C756D20656C656966656E642E0A0A566573746962756C756D206E756C6C61206C6F72656D2C20706F72747469746F7220656765742C20657569736D6F642061632C20616C697175616D2061742C206E69736C2E204D616563656E6173206574206573742065676574206D6173736120766172697573206C6F626F727469732E20496E206D692E204475697320706F72747469746F72206665726D656E74756D2070757275732E20446F6E65632063757273757320696D70657264696574206C6967756C612E204D6F726269206574206C6967756C6120657420616E7465206D6F6C6573746965207665686963756C612E204D61757269732073656420646F6C6F722E2053656420696D706572646965742066656C69732075742073656D2E20536564207669746165206E6571756520656C656D656E74756D206C656F20617563746F72206665726D656E74756D2E2044756973206665756769617420756C6C616D636F7270657220657261742E2041656E65616E2070757275732E204D6F726269206665726D656E74756D20766573746962756C756D206573742E2050656C6C656E7465737175652076656E656E61746973206D61757269732E2050686173656C6C75732070756C76696E61722E20496E746567657220697073756D206C65637475732C20696163756C697320612C206C6163696E69612069642C20616363756D73616E2069642C20617263752E2050686173656C6C7573206174206573742E204675736365206E65717565207175616D2C20756C747269636965732069642C20696163756C69732076656C2C20646170696275732076697461652C206C616375732E20496E206C6F626F7274697320636F6E76616C6C697320616E74652E204E756C6C61206E756E632070757275732C2076756C70757461746520696E2C2068656E6472657269742065742C20626C616E6469742065742C206C6967756C612E0A0A50656C6C656E746573717565206C656F206D657475732C20736167697474697320696E2C206D6F6C65737469652076697461652C2064696374756D20696E2C20706564652E204D6F726269207072657469756D2066656C6973206E6563207175616D2E2050656C6C656E746573717565206D617474697320616E746520736564207175616D20736167697474697320646170696275732E2053757370656E64697373652073617069656E2E205072616573656E7420626962656E64756D20696163756C697320746F72746F722E20447569732061206E69736C2E2041656E65616E206D692E20446F6E65632064696374756D206172637520696E206573742E204D6F72626920696E74657264756D2076756C70757461746520697073756D2E2041656E65616E2073697420616D6574206D61676E61206E6F6E206E69736C2074726973746971756520706F73756572652E2050686173656C6C75732076656C6974206D657475732C2074656D706F722061632C206665726D656E74756D20656765742C20636F6E64696D656E74756D206E6F6E2C2076656C69742E20566573746962756C756D2073697420706F73756572652E0A0A4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204372617320616C6971756574206D61737361206E6563206475692E20437261732061726375206E756E632C2068656E6472657269742061632C20656C656966656E642065752C20756C6C616D636F72706572206E65632C2074656C6C75732E205365642070686172657472612070757275732073697420616D6574207175616D2E20437572616269747572206D6F6C6C69732E204E616D20766974616520706564652E20457469616D207269737573206D617373612C207665686963756C612073697420616D65742C207068617265747261206E65632C20736F6C6C696369747564696E2075742C206475692E20446F6E65632065676573746173206A7573746F206174207175616D2E2050726F696E206E69736C2072697375732C20766573746962756C756D206E65632C207072657469756D2076697461652C207472697374697175652061632C206C6F72656D2E20416C697175616D206572617420766F6C75747061742E204372617320736564206E6962682E2050656C6C656E74657371756520736F6C6C696369747564696E20657569736D6F642061756775652E0A0A457469616D206672696E67696C6C6120736F6C6C696369747564696E206F7263692E204D61757269732063757273757320656C69742071756973206C616375732E204372617320746F72746F722E20496E2061646970697363696E672C206C656374757320696420617563746F7220766573746962756C756D2C206E65717565207065646520616363756D73616E20646F6C6F722C206E6F6E20696D70657264696574206D61676E61206469616D20616363756D73616E2076656C69742E2053757370656E6469737365206174206C696265726F207574206E69736920626C616E6469742073616769747469732E2050686173656C6C7573206E6F6E206D61757269732E20467573636520656C656D656E74756D2073616769747469732073656D2E2053757370656E646973736520616C697175616D20656C656966656E642074656C6C75732E2050726F696E206C6967756C61206C6F72656D2C20696D7065726469657420717569732C2076656E656E617469732069642C20696163756C6973206D6F6C6C69732C206E69736C2E20457469616D20636F6E76616C6C69732070656465206174206D617373612E204D6F72626920616363756D73616E20647569206574206D61757269732E0A0A53656420736564206F7263692E204E756E632070757275732E2053757370656E646973736520706F74656E74692E205574206C7563747573206672696E67696C6C61206D61757269732E20446F6E6563206E6962682E2050686173656C6C757320706F7274612E2050686173656C6C75732073697420616D6574206F64696F20736564206D61676E6120736F64616C65732070686172657472612E2043726173206C65637475732E2053757370656E6469737365206C696265726F20697073756D2C20636F6D6D6F646F206E65632C20666163696C6973697320696E2C207375736369706974206C6F626F727469732C206C6967756C612E2044756973206D61737361206E756C6C612C2073656D7065722065742C20636F6E736571756174206E65632C2070686172657472612065752C20656C69742E20566976616D757320756C7472696369657320616C697175616D206F64696F2E20566573746962756C756D2073697420616D6574206D617373612E2053656420636F6E736571756174206C61637573207365642075726E612E20457469616D2066617563696275732066656C69732076656C206F7263692E2050686173656C6C757320756C6C616D636F727065722E2041656E65616E20636F6E736563746574756572206C61637573206174206C696265726F2E0A0A436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204475697320666163696C697369732C206C6967756C6120766974616520636F6E64696D656E74756D207363656C657269737175652C2076656C6974206F72636920677261766964612066656C69732C2076656C20756C74726963696573207175616D206D69206E6F6E206469616D2E20566976616D757320617563746F72206D65747573206E6F6E206C696265726F2E205072616573656E74206C6967756C61206E6973692C20636F6D6D6F646F20636F6E64696D656E74756D2C206D6F6C65737469652065742C20766976657272612065742C206A7573746F2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320736F6C6C696369747564696E2E204E756E6320626C616E6469742063757273757320697073756D2E2041656E65616E206E6563206C6967756C612075742074656C6C757320736F64616C6573206D61747469732E20496E74656765722073656D2E20416C697175616D206964206C6967756C612E2053656420746F72746F72206D61757269732C20626C616E6469742076697461652C206375727375732076656C2C20656C656D656E74756D2065742C206E756C6C612E20416C697175616D207363656C65726973717565206D65747573206574206E69736C2E20447569732061646970697363696E67206D61676E61206174206E657175652E20517569737175652076756C70757461746520656C656966656E64206E756E632E20416C697175616D206567657420656C69742E2050686173656C6C757320647569206F64696F2C20626962656E64756D2073616769747469732C20766573746962756C756D2069642C206469676E697373696D20696D706572646965742C206F7263692E204E756C6C616D2065752066656C6973206E6F6E206E756E63206C6163696E696120736F64616C65732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A53757370656E64697373652070656C6C656E7465737175652C206C696265726F206D617474697320756C7472696369657320616363756D73616E2C20746F72746F7220746F72746F72206D616C6573756164612073656D2C20657420736F64616C6573206C696265726F206F64696F20616320697073756D2E20566976616D75732071756973206D61676E61206E656320657374207375736369706974206C6F626F727469732E20437261732074656D70757320706F7375657265206E756E632E205175697371756520757420656E696D20612066656C697320656765737461732073656D7065722E20536564207068617265747261206D6174746973206E657175652E20467573636520747572706973206E756E632C20636F6E677565207365642C20636F6E736571756174206E6F6E2C20636F6E677565207365642C206E756C6C612E2053757370656E646973736520766172697573206C6F72656D20696420726973757320706F72746120766573746962756C756D2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204675736365207365642070757275732E20496E20612066656C69732E20496E7465676572206567657374617320617563746F72206F7263692E204D617572697320756C747269636573207375736369706974206E69736C2E204E756C6C616D2070757275732E0A0A437261732074656D706F722061646970697363696E6720697073756D2E2055742071756973206D692E204D616563656E617320696E206A7573746F207574206E756C6C6120636F6E6775652070686172657472612E2050656C6C656E746573717565207574206C696265726F20657520646F6C6F722076656E656E617469732073757363697069742E205072616573656E74206665756769617420636F6E736563746574756572206E6962682E204D6F7262692066617563696275732073656D206E6F6E2066656C69732E20496E2068656E6472657269742061726375206163206D617373612E20496E20616363756D73616E20756C747269636573206D692E2050726F696E206D616C65737561646120617563746F722066656C69732E2043757261626974757220696E74657264756D2E20536564206469616D20697073756D2C20756C7472696369657320696E2C2074656D706F722073697420616D65742C207669766572726120696D706572646965742C20656C69742E204D6F726269206D6F6C6573746965206E6973692E204D617572697320697073756D2E2046757363652064696374756D206D6F6C6C6973206D61676E612E204475697320636F6D6D6F646F206469676E697373696D206E756C6C612E20566573746962756C756D20617567756520656E696D2C20756C7472696369657320717569732C20696163756C6973206E65632C2074696E636964756E742076697461652C206469616D2E204D6175726973206C6163696E69612074656D70757320697073756D2E20536564206174206D61757269732E205574206C6F72656D2E20446F6E6563206C696265726F2E0A0A4475697320696163756C6973206C6163696E6961206C65637475732E2041656E65616E20636F6E76616C6C69732065726F7320616320616E74652E205365642071756973206F726369206E656320726973757320617563746F72206672696E67696C6C612E2050686173656C6C757320666163696C6973697320656C656D656E74756D206E6973692E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E6320706F727461206C61637573206E656320616E74652E204D6F726269206D617572697320657261742C2061646970697363696E6720696E2C2070756C76696E6172206E65632C206C6F626F72746973206E65632C206F64696F2E20557420656C656966656E64206C656374757320736564207175616D2E204E756C6C616D206D6F6C6C69732E20496E206E6F6E20747572706973206574206E69736C2068656E64726572697420626C616E6469742E204475697320656C656D656E74756D2E204E756E63206E6563206C696265726F2E2053757370656E646973736520766573746962756C756D207269737573206E6F6E20706564652E204D6F72626920696D70657264696574206F64696F2073697420616D6574206C696265726F2E2053656420736564206D6173736120766974616520697073756D206D61747469732074696E636964756E742E204E756C6C61206E656320746F72746F72207669746165206C696265726F20766F6C75747061742074656D7075732E20446F6E656320616C697175616D2E0A0A4475697320736564206E756E632E2043757261626974757220747572706973206E756C6C612C207665686963756C61207365642C206C756374757320717569732C20656C656D656E74756D20656765742C2066656C69732E204D616563656E61732065742070757275732E204D616563656E6173206C656F2074656C6C75732C2074696E636964756E7420612C20666163696C697369732076697461652C206C6F626F727469732073697420616D65742C2076656C69742E20446F6E656320636F6E76616C6C69732073617069656E2E204D616563656E6173206D6F6C6C6973206F64696F206575206E6962682E20457469616D20677261766964612E20496E7465676572206D6F6C65737469652C2073617069656E206575206D6F6C6573746965206C6163696E69612C206E756E63206E69626820616C697175616D206C6967756C612C2065752073616769747469732074656C6C7573206572617420736F6C6C696369747564696E206F64696F2E20447569732065742072697375732E2050686173656C6C7573206E697369206E657175652C20706C616365726174206E65632C20636F6E64696D656E74756D206E6F6E2C20756C7472696365732065752C2073656D2E20557420706564652E20457469616D206E756C6C61206D657475732C20766F6C75747061742069642C20636F6E76616C6C6973207365642C2073757363697069742076656C2C2075726E612E20446F6E65632076656C20656C69742E205574206C656F206E657175652C2076656E656E617469732066617563696275732C206C6163696E6961206E65632C2074696E636964756E742065752C20656E696D2E2043726173206964206475692061206C696265726F207068617265747261206469676E697373696D2E20446F6E65632065726F73206C656F2C20706F72746120717569732C206C616F726565742075742C2070656C6C656E74657371756520766F6C75747061742C206C65637475732E0A0A4E756C6C616D20626C616E6469742E20416C697175616D206572617420766F6C75747061742E2046757363652061646970697363696E6720656E696D2E2053757370656E6469737365206E6F6E206475692071756973206C6967756C6120706F72746120766573746962756C756D2E20446F6E65632065752074656C6C75732076656C206C6F72656D207072657469756D20706F72747469746F722E205072616573656E74206C75637475732E20416C697175616D2061632065726F7320696E206D6173736120646170696275732074696E636964756E742E20446F6E6563207574206D61676E612E20457469616D20617563746F72206C616375732073697420616D6574206C616375732E2053656420756C7472696369657320697073756D206E656320656C69742E205175697371756520612065737420696E207075727573207375736369706974207472697374697175652E0A0A41656E65616E20736564206475692076656C20646F6C6F722070756C76696E6172206C616F726565742E20566976616D7573207665686963756C61206C6F72656D20696E20706564652E20566976616D7573206574206469616D2E20496E7465676572206163206F64696F2076656C206469616D2068656E64726572697420626962656E64756D2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E756C6C612061206E6973692E2050686173656C6C75732074696E636964756E74206475692076697461652061756775652E20447569732066617563696275732C2064756920696E74657264756D206672696E67696C6C612074696E636964756E742C206F64696F20656C697420766573746962756C756D206C696265726F2C206163206D6F6C6573746965206D61676E61206C6563747573206964206C616375732E2041656E65616E206C6967756C612E204E756C6C6120666163696C6973692E0A0A46757363652076656C2073656D2065752076656C6974206672696E67696C6C61206F726E6172652E2053656420666575676961742074696E636964756E742066656C69732E204E756C6C616D2066656C6973206D692C20657569736D6F642073697420616D65742C206D6F6C6C69732061742C20736F64616C657320656765742C2061756775652E204E616D20696D70657264696574206E6962682061742076656C69742E2053656420757420657261742E20496E206475692E204E756C6C6120666163696C6973692E204E756C6C616D206175677565206C696265726F2C2074696E636964756E74206E65632C207072657469756D2065752C2070756C76696E617220696E2C206475692E204D6F7262692076697461652066656C69732E2050656C6C656E7465737175652076656C206A7573746F2076656C2076656C6974207361676974746973206D616C6573756164612E2050726F696E207665686963756C6120626C616E646974206D617373612E20457469616D2074696E636964756E742070686172657472612075726E612E20496E206D65747573206573742C20617563746F72206E65632C20626C616E64697420612C20637572737573206E65632C207175616D2E204D6175726973206163206D657475732061206C696265726F20636F6E6775652066617563696275732E204D6175726973206D617572697320646F6C6F722C20736F64616C657320696E2C206375727375732075742C20736F64616C65732072757472756D2C2065726F732E2051756973717565206D61757269732065726F732C2073616769747469732076697461652C206C6F626F727469732075742C20656C656966656E642069642C206E6973692E0A0A41656E65616E206E657175652E20566573746962756C756D20656765737461732070656C6C656E746573717565206C6967756C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2050686173656C6C7573207361676974746973206A7573746F2076656C2072697375732E20536564207072657469756D206E657175652076697461652075726E612E2050656C6C656E74657371756520636F6E677565206C696265726F206964206C6F72656D2E204D6175726973206C656F206C6F72656D2C20626C616E6469742073697420616D65742C20636F6E76616C6C697320717569732C20636F6E736563746574756572207365642C2065726F732E204D61757269732074696E636964756E742C20656E696D2061206772617669646120657569736D6F642C206D61676E61206E756C6C61206665726D656E74756D206C696265726F2C207669766572726120656765737461732076656C6974207175616D20657420746F72746F722E20566976616D757320616C6971756574206D61737361207669746165206A7573746F2E204E756C6C6120636F6E677565206C6163757320616320656C69742E0A0A50686173656C6C757320636F6D6D6F646F207175616D2076656C206C6967756C612E2050726F696E206E6F6E206D657475732061742065726F732070756C76696E6172206C75637475732E204D6175726973206469616D206C6F72656D2C20706F737565726520717569732C20677261766964612065742C2074696E636964756E74206E65632C206C6967756C612E20536564206469616D2E20416C697175616D20656C6974206C65637475732C2068656E6472657269742075742C20696D706572646965742073697420616D65742C207072657469756D2073697420616D65742C20697073756D2E204D6175726973207665686963756C61206E69736C20696E206475692E204375726162697475722065676574207175616D207574206D61676E6120656C656D656E74756D206665726D656E74756D2E204D6175726973207363656C657269737175652E2051756973717565206C616F726565742E20457469616D2074656D707573207475727069732E2050656C6C656E746573717565206175677565207175616D2C2068656E647265726974207365642C2074696E636964756E742061742C2070686172657472612061742C206E69736C2E20416C697175616D206C616375732E2053757370656E646973736520706F74656E74692E2041656E65616E2076656C6974206C696265726F2C20756C74726963657320696E2C206C6163696E69612065752C206C75637475732076656C2C20616E74652E20457469616D2064696374756D206D6920696E2066656C69732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20467573636520677261766964612064617069627573206E69736C2E2043726173207669746165206E69736C2E0A0A4D616563656E6173206469676E697373696D2C206C6967756C61206E6F6E20706F727461206375727375732C20656E696D206E756E63206D616C6573756164612073656D2C20657520706F72747469746F72206E756C6C612075726E61206575207175616D2E2046757363652065726F732E20416C697175616D2065726F732E204E616D20617563746F722E204E756C6C61206D6F6C657374696520706F727461206573742E2053757370656E646973736520706F74656E74692E20566976616D7573206D6F6C6573746965206C6F72656D2073656420657261742E20536564206567657420697073756D2E20496E746567657220616C697175616D2070756C76696E6172206E756C6C612E204372617320616C69717565742073656D207574206E756E632E2046757363652066617563696275732074656D707573206C65637475732E204372617320736F64616C65732C206E69736920616320666163696C6973697320756C7472696365732C2065726F73206172637520646170696275732073617069656E2C20657420756C747269636573206D61757269732074656C6C7573206E6F6E20646F6C6F722E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20437261732063757273757320766172697573206D657475732E205574207475727069732E20566976616D7573206567657420746F72746F722E0A0A536564206C616F726565742C2076656C6974206E6F6E20616363756D73616E206375727375732C206E756E632075726E6120706F7375657265206A7573746F2C20696E2064696374756D206C6563747573207065646520696420616E74652E20437261732076756C7075746174652E204372617320636F6E677565206475692073656420656C69742E2050726F696E206C616375732073656D2C20756C7472696365732061742C20636F6E73657175617420696E2C2074656D706F7220717569732C206D657475732E2050726F696E2076656C20617263752E204E616D20657569736D6F642068656E64726572697420656C69742E20557420657261742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2053656420706F73756572652E204D6F7262692065726F732075726E612C2073656D7065722061742C2073656D706572206E6F6E2C20636F6E76616C6C697320717569732C2076656C69742E204D616563656E6173206F7263692E20566573746962756C756D206C6F626F7274697320747269737469717565206D657475732E20566573746962756C756D206C6F72656D206E756C6C612C20736F6C6C696369747564696E2076697461652C20636F6E64696D656E74756D20717569732C20617563746F722075742C206475692E20566976616D757320766573746962756C756D206D61676E61207574206E6973692E2043757261626974757220656C656966656E64206475692076656C206E756E632E20437572616269747572206D6175726973206C616375732C206D616C6573756164612073697420616D65742C207375736369706974207365642C2072757472756D206C75637475732C2074656C6C75732E20496E746567657220666163696C697369732075726E61207669746165206C65637475732E0A0A41656E65616E207175616D206C656F2C206C6F626F7274697320717569732C206D616C6573756164612065752C2076756C7075746174652076697461652C206E69736C2E205072616573656E7420656765742065726F732E205574206665726D656E74756D20747572706973206964207175616D2E204E616D20746F72746F722E205072616573656E74206E6563206F7263692E204E756C6C6120626962656E64756D2061646970697363696E672061756775652E20557420636F6D6D6F646F2C206D61676E61206964206D616C65737561646120677261766964612C206175677565206F64696F206D616C657375616461206D692C20706F727461206D616C65737561646120656C697420657374207669746165206469616D2E204D6175726973206E6F6E206E756C6C612E2053757370656E64697373652074696E636964756E742C206E756E6320756C7472696369657320706F7274612076656E656E617469732C206D6920706564652074696E636964756E74206C696265726F2C20656765742076617269757320616E7465206C696265726F207574206C6967756C612E20437572616269747572207072657469756D20706F72747469746F7220746F72746F722E0A0A4D616563656E617320766974616520656C69742065676574206E69736920646170696275732064696374756D2E204E756E6320696E206C696265726F2E204E756C6C612064696374756D206F726369206575206572617420617563746F72206C6F626F727469732E2050686173656C6C75732072697375732E2053757370656E646973736520706F74656E74692E2053757370656E646973736520706F74656E74692E205072616573656E742061646970697363696E6720636F6E73657175617420656C69742E20496E74656765722069642061756775652E205072616573656E7420696E206A7573746F206E6563206D61676E6120646170696275732070756C76696E61722E2044756973206E69736C2E2053757370656E6469737365206163206F64696F2E20566976616D757320696D706572646965742E20446F6E6563206E6F6E2076656C69742073697420616D6574207269737573206469676E697373696D20636F6E6775652E204E616D20616C697175657420706F73756572652076656C69742E2043726173207475727069732E204D6F726269206D616C657375616461206469676E697373696D206D692E0A0A536564206C656F206E657175652C2076617269757320717569732C2076656E656E61746973207365642C207068617265747261207365642C206573742E204D6F72626920626C616E6469742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D2073656D7065722070656C6C656E746573717565206D692E2055742076656C206C6F72656D2E204E756E63206D6920746F72746F722C206C616F726565742061742C2066617563696275732065752C2074696E636964756E742073697420616D65742C20657261742E20447569732074656D706F72206D616C65737561646120697073756D2E2050686173656C6C757320616C69717565742E20446F6E656320657420656C69742E2050656C6C656E7465737175652070757275732E20566573746962756C756D2072757472756D2073656D706572206E6962682E204E756C6C6120666163696C6973692E2050686173656C6C757320657420656E696D2073697420616D657420616E746520766573746962756C756D207665686963756C612E2050686173656C6C7573206964206E69736C2E20446F6E6563206D6F6C6C6973206C656F2061742065726F732E204D61757269732070656C6C656E746573717565206E657175652061742070757275732E204D6F726269207175697320646F6C6F7220617420697073756D207363656C6572697371756520736F64616C65732E20457469616D20766F6C7574706174207475727069732061206D657475732E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206C6F72656D206C6F72656D2C20766573746962756C756D2061632C20657569736D6F6420656765742C20756C6C616D636F72706572206469676E697373696D2C2076656C69742E0A0A43756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204372617320756C7472696365732C206E6962682076656C20616C697175616D20766573746962756C756D2C2065726F7320656E696D2076656E656E61746973206475692C20696420696163756C697320656E696D206E756E632076656C206D617373612E204D6F72626920656C656966656E64206F726369206574206D617373612E20416C697175616D206572617420766F6C75747061742E204E756C6C61206D6F6C6C69732065676573746173207475727069732E20496E20736F64616C6573206E756E63206567657420746F72746F722E2053656420697073756D2065726F732C2074656D706F7220717569732C20616C69717565742076697461652C20696D70657264696574206E6F6E2C206C6F72656D2E2050656C6C656E746573717565207175697320656C6974206964206D69206C756374757320646170696275732E20536564206E756E6320617263752C2072686F6E637573206E65632C20636F6E76616C6C697320717569732C206375727375732061742C206E657175652E204D617572697320636F6E76616C6C697320707572757320617420657261742E2050656C6C656E74657371756520766573746962756C756D2E20566976616D7573206672696E67696C6C6120656C697420617420617263752E204E756C6C616D20616C697175657420656E696D206E656320617263752E204E616D20696420746F72746F722E204E756C6C612071756973206E756E632E20557420617263752E2053757370656E646973736520706F74656E74692E2050656C6C656E74657371756520756C6C616D636F72706572206C6967756C6120696420617263752E0A0A4E616D206E6F6E206C696265726F207669746165206E69736C207363656C65726973717565206672696E67696C6C612E20517569737175652076617269757320616E7465206964206D657475732072686F6E637573206672696E67696C6C612E204E756C6C6120666163696C6973692E205072616573656E7420656C656966656E6420706F72747469746F72206C6967756C612E20457469616D207175697320646F6C6F72206E6F6E20617567756520636F6D6D6F646F20617563746F722E20446F6E65632061206D692E20566573746962756C756D2074656D706F722E20446F6E65632066656C69732075726E612C20617563746F722061742C206375727375732064696374756D2C20677261766964612069642C20617263752E2041656E65616E2064696374756D206D616C65737561646120646F6C6F722E20566976616D7573206D61747469732E2050686173656C6C757320657520706564652E2046757363652061646970697363696E67206A7573746F206672696E67696C6C61206D657475732E20457469616D20616E74652E20496E7465676572206D6F6C6C6973206D617373612071756973206E756E632E20496E74656765722064696374756D206E65717565206C756374757320656E696D2E0A0A536564206575206C696265726F2E20496E74656765722074656D706F72206C6967756C6120696E2076656C69742E2055742074696E636964756E74206C6163696E69612073656D2E204E756C6C616D2076656C2072697375732E2053656420736F64616C657320616E7465206120646F6C6F722E204375726162697475722065726F732E2053656420736F64616C65732E20536564206E6F6E206D657475732E20566573746962756C756D20656C656D656E74756D20666175636962757320616E74652E204E756C6C612076656C206E6962682E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206E6563206C6F72656D20757420697073756D206C6163696E696120696163756C69732E204475697320657261742E20416C697175616D20657261742E204372617320696163756C69732E20496E206861632068616269746173736520706C617465612064696374756D73742E0A0A4E756C6C616D20616E74652E2043726173207669746165206573742E2050656C6C656E7465737175652076656C206D657475732061206C6967756C612064617069627573206D61747469732E2044756973206665756769617420616C69717565742066656C69732E20457469616D206964206E69736C207175697320657374206469676E697373696D20636F6E64696D656E74756D2E2053757370656E646973736520706F74656E74692E204D6F7262692076656C6974206C6F72656D2C206F726E61726520717569732C2070656C6C656E7465737175652076656C2C20706C61636572617420656765742C20746F72746F722E20566573746962756C756D2074696E636964756E74206D6F6C6573746965206C696265726F2E204E756C6C61206E756C6C6120656E696D2C206D616C6573756164612069642C20756C6C616D636F727065722076697461652C2064696374756D2061742C2070757275732E20446F6E6563206469676E697373696D206F64696F20757420656E696D2E2053757370656E6469737365206174206C65637475732E0A0A5072616573656E74206C6F626F727469732061756775652076656C206C65637475732E20557420696E206C6967756C612075742066656C697320636F6E6775652073757363697069742E2051756973717565206469676E697373696D20746F72746F72207574206D692E204675736365206D61676E61206E6973692C20656C656966656E642061632C206F726E6172652076656C2C20706F72747469746F722076697461652C207175616D2E20566573746962756C756D20736F64616C6573206A7573746F2071756973207475727069732E2046757363652075726E61206E6973692C2072686F6E63757320717569732C20636F6E64696D656E74756D2076656C2C2064696374756D2065752C206E756E632E20467573636520736564206E696268207669746165206F64696F20706F73756572652061646970697363696E672E2053656420706F72746120656C6974207175697320646F6C6F722E204E616D206C696265726F206E756C6C612C20617563746F72207365642C2074696E636964756E7420717569732C2066617563696275732073697420616D65742C206D692E2051756973717565206F7263692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E756C6C616D2069642073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632076656C2065726F732E0A0A566976616D7573206C7563747573206C6F626F72746973206C656F2E2053757370656E64697373652076656C20656C6974206120656E696D20756C6C616D636F7270657220706F73756572652E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20446F6E656320717569732070656465206D6174746973206C6563747573206D6F6C6C69732061646970697363696E672E2053656420616363756D73616E20706F737565726520657261742E205072616573656E7420657569736D6F642074696E636964756E742066656C69732E20446F6E6563206D692E20557420636F6D6D6F646F2061726375206C6163696E69612074656C6C75732E20416C697175616D2061206C696265726F2071756973206C65637475732073656D70657220766976657272612E20437572616269747572206C6163696E6961206D61757269732061742074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E756E632073697420616D6574206D61676E61206D6F6C6573746965206F726369207375736369706974206672696E67696C6C612E204675736365207072657469756D206D65747573206E6F6E2073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642068656E6472657269742E204E756C6C612066656C69732E2053757370656E646973736520706F74656E74692E20416C697175616D20626C616E64697420747269737469717565206E657175652E20437572616269747572207175697320657261742076656C206E756E6320616363756D73616E206D6F6C6C69732E0A0A447569732073616769747469732C2074656C6C757320757420616C697175616D206672696E67696C6C612C20646F6C6F72206D6920756C6C616D636F72706572206E69736C2C20757420747269737469717565207065646520656C697420736564206D61757269732E204375726162697475722069642066656C69732E20446F6E65632070756C76696E6172206C61637573206574206C65637475732E20416C697175616D2076756C7075746174652076756C707574617465206D657475732E20437572616269747572206D61676E612066656C69732C2061646970697363696E672061632C20616363756D73616E2076656C2C206D6F6C657374696520717569732C207175616D2E204D617572697320656C697420617263752C207072657469756D2076697461652C206D6F6C6C69732073697420616D65742C20736F6C6C696369747564696E2075742C206D692E20446F6E656320696D70657264696574206469676E697373696D206D692E204E756C6C616D2073697420616D657420746F72746F722E20416C697175616D206E65717565206E756C6C612C2076656E656E6174697320612C20706F72746120696E2C20706C6163657261742074656D7075732C206C616375732E205175697371756520766573746962756C756D20647569206574206C616375732E2050726F696E206469676E697373696D20636F6E7365637465747565722070757275732E20457469616D206772617669646120746F72746F7220696E206E756E632E2055742074656D706F722074726973746971756520746F72746F722E20536564206C616F726565742074696E636964756E74207175616D2E20566573746962756C756D20706F7274612074757270697320757420656C69742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20446F6E6563206E696268206475692C2066657567696174206E65632C206C616F726565742069642C206D616C65737561646120656765742C206E6973692E205574206E65717565206D617373612C207665686963756C612065752C20636F6D6D6F646F206E6F6E2C20756C747269636965732076697461652C2070757275732E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204D617572697320657569736D6F642C2066656C69732076656C2074656D706F7220616C69717565742C20746F72746F72206D6175726973206D616C657375616461206E756E632C2076656C206665726D656E74756D2073656D206469616D206964206475692E204E616D2072757472756D2073617069656E2065676574206F64696F2E20416C697175616D20736564206C696265726F206E6F6E206D692066617563696275732074656D7075732E2046757363652068656E6472657269742C206469616D206E6F6E20766F6C75747061742072757472756D2C2065726174206D657475732076656E656E61746973206C6967756C612C206E6F6E207363656C657269737175652070656465206C6967756C612076656C207175616D2E204D6F7262692072686F6E6375732065726F7320616320647569206665756769617420656C656D656E74756D2E2044756973206575206C696265726F2065742074656C6C757320636F6E67756520766976657272612E204D6F726269207175616D207175616D2C20656C656D656E74756D207365642C20756C6C616D636F7270657220696D706572646965742C20636F6D6D6F646F206E6F6E2C206F64696F2E204E616D20616C697175657420656765737461732075726E612E204D6175726973206F64696F2066656C69732C207661726975732065752C206C6163696E69612065752C20636F6E64696D656E74756D20612C206C65637475732E20536564206A7573746F206D617373612C2070756C76696E61722069642C2076617269757320612C20706F72747469746F72206E65632C206C696265726F2E20457469616D207661726975732E2043757261626974757220736F64616C65732C206F64696F20617420706F73756572652073656D7065722C2065726F73206E6962682074696E636964756E74206C65637475732C2076656C2072757472756D2073617069656E206E69736920696E206C6967756C612E2053757370656E6469737365206567657420617263752E2050686173656C6C757320696D70657264696574206573742061632073617069656E2E20446F6E6563206E756C6C6120746F72746F722C20706C6163657261742076656C2C2074656D70757320612C206C6F626F727469732076656C2C206E6962682E20416C697175616D20766172697573206E6973692E204E756C6C6120657420656E696D2E20467573636520636F6E76616C6C6973206C616F72656574206C616375732E0A0A50686173656C6C757320697073756D20646F6C6F722C206D6F6C657374696520717569732C20636F6E64696D656E74756D20696E2C20636F6D6D6F646F2065752C206469616D2E205175697371756520626962656E64756D206C6163696E6961206475692E204E756C6C616D20626C616E6469742076756C707574617465206F7263692E205574206C6163696E6961206D617373612076656C2061756775652E20416C697175616D20677261766964612C207175616D207175697320696D7065726469657420696D706572646965742C2074656C6C7573206469616D20706861726574726120657261742C206174207068617265747261206C61637573206E6962682065676573746173206D61676E612E204E756C6C61207361676974746973206C6F72656D207574206C6F72656D2E204475697320636F6E64696D656E74756D2C2064756920766974616520616C697175616D20706F73756572652C206469616D207175616D20636F6E76616C6C69732076656C69742C2075742067726176696461206C656F20697073756D206E6F6E2072697375732E205574206665726D656E74756D20736F6C6C696369747564696E20657261742E20446F6E6563207361676974746973207363656C657269737175652066656C69732E204E756E6320617263752E20457469616D2074656D7075732C206D61676E612073697420616D657420737573636970697420657569736D6F642C2065726F732073656D2072757472756D206475692C207669746165207361676974746973206E696268207075727573206E6F6E206C616375732E20536564206D6F6C6C69732061726375206567657420646F6C6F722E20446F6E6563206F726E6172652C20617263752073697420616D6574206665726D656E74756D2076756C7075746174652C20726973757320656E696D206665726D656E74756D206C696265726F2C2061206C6163696E696120646F6C6F72206D69206E6F6E2076656C69742E20457469616D206C6F626F72746973207075727573206120656C69742E204E756E63206E756C6C61206475692C206D617474697320717569732C20626962656E64756D20612C20756C7472696365732061632C2061756775652E20496E20616C697175616D207665686963756C61207475727069732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A496E7465676572206964206E69736C2E20517569737175652064696374756D20656C656D656E74756D206F64696F2E2041656E65616E206C75637475732E205365642065752073656D206120706564652076756C70757461746520636F6E64696D656E74756D2E2051756973717565206D61676E612E20446F6E656320616C697175616D206D617474697320697073756D2E204375726162697475722064696374756D20736F6C6C696369747564696E2073656D2E20416C697175616D2070756C76696E61722E204E756E6320736F6C6C696369747564696E207269737573206120657261742E20566976616D757320717569732074656C6C75732073697420616D6574206E69626820766573746962756C756D20636F6E7365717561742E204E756C6C61207072657469756D20736F6C6C696369747564696E20646F6C6F722E20416C697175616D20696163756C69732074696E636964756E74207475727069732E2050686173656C6C757320697073756D206C656F2C2076656E656E6174697320696E2C20736167697474697320696E2C206F726E6172652061742C206E756E632E0A0A50656C6C656E74657371756520756C7472696365732C2064756920657520696163756C6973206C75637475732C2074656C6C757320617567756520766F6C75747061742073617069656E2C20696E206469676E697373696D2075726E612066656C6973207574206D692E205365642061726375206475692C206469676E697373696D2069642C20706F72747469746F722075742C20696D706572646965742076697461652C20616E74652E204E756C6C61206475692073656D2C20636F6D6D6F646F206E65632C2073616769747469732065742C206C6163696E69612065742C20706564652E20457469616D20656C656966656E6420647569207574206E69736C2E20446F6E656320616E7465206D61757269732C2074656D7075732073697420616D65742C207661726975732076697461652C206772617669646120717569732C206D692E20496E207363656C657269737175652C2066656C697320766974616520766976657272612073616769747469732C2076656C6974206D6574757320756C74726963696573206E657175652C207175697320696D706572646965742076656C697420656C6974206574206D61676E612E2053757370656E646973736520706F74656E74692E205365642076656C69742065726F732C20657569736D6F64207365642C20636F6E64696D656E74756D206E65632C206661756369627573207365642C2073617069656E2E204E616D20616363756D73616E206C6967756C612073697420616D6574206E657175652E20416C697175616D206572617420766F6C75747061742E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E616D20657520706564652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642065752066656C69732073656420746F72746F722074656D706F72206665726D656E74756D2E2050686173656C6C757320636F6D6D6F646F2073656D2076656C206E69736C2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050726F696E206C656374757320656C69742C2070686172657472612073697420616D65742C20616363756D73616E207365642C2074696E636964756E742065742C206D61757269732E204475697320646170696275732070686172657472612073656D2E20496E746567657220696E206A7573746F2E205072616573656E742065726F732E20566573746962756C756D20616320616E74652E20416C697175616D207363656C657269737175652073656D2070656C6C656E746573717565206E69626820636F6E73656374657475657220736F64616C65732E20416C697175616D20636F6E736563746574756572206F64696F2E2044756973206C6563747573206F64696F2C206C75637475732065752C20636F6D6D6F646F20717569732C206D6F6C6C69732076697461652C2076656C69742E2043726173206E6563206E756E63206E6F6E20656C697420696163756C6973206D61747469732E2041656E65616E206A7573746F206E657175652C20736F6C6C696369747564696E20656765742C20756C6C616D636F7270657220656765742C20656765737461732069642C2073656D2E20496E2065752072697375732E2053656420656765737461732E0A0A496E7465676572206174206E657175652E20536564207072657469756D207363656C65726973717565206E756C6C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20467573636520757420706564652E20457469616D207669746165207175616D20612075726E612076617269757320696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2044756973207665686963756C612E20467573636520756C6C616D636F72706572206E696268206E6F6E20657261742E205175697371756520696E206E657175652E205072616573656E74206573742E2050656C6C656E74657371756520617263752E0A0A50726F696E20706F73756572652E2053757370656E646973736520706F74656E74692E20496E74656765722066656C6973206C616375732C20616C697175616D207365642C2076756C70757461746520696E2C206D6F6C6C69732076656C2C2074656C6C75732E20496E7465676572207665686963756C6120626962656E64756D206573742E204E756E63206E6F6E20646F6C6F7220696E2074656C6C7573206D617474697320666163696C697369732E20496E746567657220766573746962756C756D2C20617567756520617420636F6D6D6F646F20616C697175616D2C2064756920657374206D6174746973206C6967756C612C2073697420616D65742061646970697363696E67206F7263692073656D207669746165206D61676E612E205072616573656E7420656E696D2076656C69742C206D616C6573756164612061742C20636F6E677565206E65632C206C756374757320696E2C206A7573746F2E20536564207661726975732E204D6F7262692070686172657472612E20446F6E6563206575206D61737361206E65632074656C6C75732076756C7075746174652070756C76696E61722E20557420636F6D6D6F646F20747572706973206E6F6E2073656D2E20557420636F6E76616C6C697320756C6C616D636F727065722072697375732E20457469616D20696E74657264756D2070656465206964206E6973692E2043726173206D61676E612073617069656E2C20737573636970697420612C206C616F72656574206E6F6E2C2072686F6E6375732065742C2066656C69732E20496E7465676572206F726369206C6F72656D2C20766573746962756C756D2064696374756D2C20756C6C616D636F7270657220612C20706F72747469746F722065742C206475692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A4E756E63206574206D61676E612E2053656420626962656E64756D2074656C6C757320696E206469616D2E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E616D20766974616520746F72746F722E20496E7465676572206D61676E612E20447569732076656E656E617469732C206C656F2061632074656D706F72206C616F726565742C20656C6974206E756C6C6120706861726574726120706564652C206E6F6E206665726D656E74756D206E756E63206F64696F2061206F64696F2E2050726F696E206E6F6E2076656C69742E2053656420696D706572646965742061756775652071756973206E69736C2E20496E746567657220636F6E64696D656E74756D206E69736C206E6563206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20566976616D757320706C616365726174206C696265726F2E204475697320636F6E6775652064696374756D206D61676E612E20416C697175616D206461706962757320626962656E64756D20656E696D2E204E756E6320656C656966656E6420706564652076656C20697073756D2E0A0A457469616D2076697461652076656C69742E204D61757269732065726174206E756E632C206D616C6573756164612075742C20666575676961742061632C20706C61636572617420636F6E64696D656E74756D2C2061756775652E204E616D20766F6C75747061742E20416C697175616D207665686963756C6120697073756D206964206F64696F2E20566976616D757320736F6C6C696369747564696E207475727069732069642073617069656E2E20467573636520612066656C6973207669746165206F64696F20636F6E76616C6C697320626C616E6469742E204375726162697475722076697461652065726F732069642065726F7320706F727461207072657469756D2E204E756C6C6120696E206D61676E6120656765742075726E61206C6163696E696120636F6E76616C6C69732E20416C697175616D206D61747469732076656E656E617469732070757275732E2053656420736564206D69206567657420657261742074726973746971756520706F7274612E20446F6E656320617563746F7220646F6C6F72206120657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20496E206E6563206C6967756C612E204E756E6320656C656966656E642E20566573746962756C756D2071756973206E697369206567657420656C697420706F72747469746F7220636F6E6775652E204D616563656E61732066617563696275732C206D61676E6120656765742061646970697363696E672074696E636964756E742C20646F6C6F7220616E7465206D616C65737561646120656C69742C206E6F6E20656C656D656E74756D206C616375732074757270697320696E20706564652E0A0A5574206D616C657375616461206D69206E6563206D657475732E205072616573656E7420617563746F72206175677565206163206E69736C20756C7472696369657320666163696C697369732E204E616D2070757275732073617069656E2C2070656C6C656E746573717565206469676E697373696D2C20706F73756572652065752C206375727375732069642C206469616D2E205175697371756520736F6C6C696369747564696E2C20656C697420612070656C6C656E746573717565207363656C657269737175652C206C6F72656D20726973757320617563746F72207175616D2C207175697320636F6E7365717561742074656C6C7573206E657175652069642075726E612E2053757370656E6469737365206469616D20746F72746F722C20656C656966656E64206469676E697373696D2C20656765737461732075742C206C756374757320696E2C20616E74652E204475697320616E74652E204D616563656E6173206C75637475732E20437572616269747572206375727375732070686172657472612075726E612E204D616563656E617320696D706572646965742C2065726174206E6F6E20656C656D656E74756D20657569736D6F642C20746F72746F72206F64696F20657569736D6F64206C65637475732C20616320666163696C697369732073656D206E696268207669746165206E756C6C612E204E756E6320677261766964612E204D6F72626920736F6C6C696369747564696E206F64696F2071756973206C616375732E20416C697175616D2061206E696268206E6F6E2075726E6120706F72746120696D706572646965742E20416C697175616D206572617420766F6C75747061742E20496E20696163756C6973206C6163696E69612076656C69742E20536564206C696265726F206C616375732C207472697374697175652065752C206C6163696E69612061632C20616C697175657420656765742C2075726E612E0A0A457469616D206174206E69736C2E2050686173656C6C7573206661756369627573206C7563747573206C65637475732E20557420706C6163657261742076756C70757461746520646F6C6F722E2050686173656C6C75732076656C2076656C69742E204D6F72626920766976657272612E2050686173656C6C7573206F7263692E20496E7465676572206469676E697373696D206D6174746973206D61757269732E2050656C6C656E74657371756520706F7375657265206C656F20706F7375657265207175616D2E2051756973717565206E6563206D61676E61206174206469616D20766976657272612070656C6C656E7465737175652E2053757370656E64697373652076656C697420617263752C20756C7472696369657320717569732C20636F6E67756520612C2076656E656E6174697320656765742C206C616375732E20496E74656765722073616769747469732068656E64726572697420646F6C6F722E2046757363652074696E636964756E7420616E746520612073656D2E0A0A4D616563656E617320636F6E7365637465747565722C206A7573746F207365642072686F6E6375732076656E656E617469732C206E69626820617263752072757472756D20646F6C6F722C2073656420636F6E64696D656E74756D206C696265726F206C696265726F20657420697073756D2E20566976616D7573206D6174746973206A7573746F207574206C6F72656D2074696E636964756E74206C6F626F727469732E205574206E6F6E2076656C6974206964206E6571756520616C697175657420616363756D73616E2E205365642074656D7075732076697665727261206E756C6C612E2043757261626974757220756C6C616D636F727065722C206E6571756520717569732064617069627573207363656C657269737175652C2066656C6973206469616D2067726176696461206F7263692C206E6F6E20637572737573207175616D206E6571756520766974616520656C69742E20457469616D2070686172657472612074696E636964756E74206C616375732E204475697320657569736D6F64206672696E67696C6C61206573742E20457469616D206F726E6172652074696E636964756E74206C65637475732E2050726F696E20696E207475727069732E204E756E6320626C616E64697420626C616E646974207475727069732E2041656E65616E2075742061756775652E2044756973206F726369206A7573746F2C2074696E636964756E742065752C2072757472756D207365642C2072757472756D2065742C207475727069732E2043757261626974757220666163696C69736973206F64696F20696E20616E74652E20496E206861632068616269746173736520706C617465612064696374756D73742E205365642065726F73206573742C2070656C6C656E7465737175652061742C2074696E636964756E742065752C20756C74726963657320717569732C206D657475732E204D6F7262692073697420616D6574206A7573746F2E204D616563656E617320616320617263752E204D6175726973206469676E697373696D2E0A0A50656C6C656E74657371756520756C747269636965732072757472756D206F7263692E2041656E65616E206F726E6172652E20566976616D75732065752072697375732076656C206D6175726973206C6F626F727469732064696374756D2E205365642065742074757270697320617563746F72206D692072686F6E6375732070756C76696E61722E20536564206E6563206E756E6320612070757275732074656D706F7220766976657272612E2050656C6C656E7465737175652073757363697069742E20446F6E656320747269737469717565207269737573206E6F6E206E6962682E20457469616D206E69736C206D61676E612C20736F6C6C696369747564696E2075742C20756C7472696365732073697420616D65742C20656765737461732065752C206E756C6C612E20416C697175616D206572617420766F6C75747061742E20566573746962756C756D2070686172657472612E2053656420656765737461732C206D657475732073697420616D6574206C6F626F7274697320636F6E7365717561742C206572617420656C697420696D70657264696574206C696265726F2C20657520696E74657264756D207175616D206D61737361206567657420646F6C6F722E2053757370656E6469737365207669746165206F64696F2E2050726F696E20626C616E646974206D617572697320696163756C6973206D657475732E0A0A566976616D757320766573746962756C756D2E20457469616D206574206E69736C2E20416C697175616D20696E206469616D2076656C20656C697420706C6163657261742073757363697069742E204475697320736F64616C6573207075727573206163206E6962682E204E756C6C6120696E206F64696F206567657420656E696D206C756374757320626C616E6469742E2043757261626974757220756C74726963657320697073756D206E6F6E206E65717565206567657374617320656C656966656E642E20536564207475727069732E2050726F696E20636F6E7365637465747565722E20566976616D7573206D61747469732E20496E20616C69717565742E0A0A4E756E632069642065726F732E20446F6E65632076656E656E617469732C206E756C6C61206574206D6174746973206C75637475732C20616E7465206C656F2073656D706572206A7573746F2C206E6F6E2061646970697363696E67206F64696F20726973757320736564206C616375732E205072616573656E7420766974616520726973757320636F6E677565206C696265726F20636F6E6775652074656D7075732E2050686173656C6C75732061632065726F732E204E756C6C61207665686963756C612C206C6F72656D20696E20616C69717565742073757363697069742C2061726375206572617420656765737461732073656D2C2071756973206C6F626F72746973207175616D20616E7465206575206D617373612E20437572616269747572206E6F6E206D617373612E2053656420626962656E64756D206C6163696E6961206F64696F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20566976616D757320766F6C757470617420626C616E646974206C616375732E2050726F696E20706F7274612C2074656C6C757320757420617563746F72206C616F726565742C206C65637475732065726F73206665726D656E74756D206C65637475732C2069642073616769747469732061726375206A7573746F20696E207475727069732E2050686173656C6C757320636F6E7365717561742E204E616D2070656C6C656E7465737175652C206D69206964207669766572726120636F6E76616C6C69732C206E756E63206C696265726F20706C616365726174206C656F2C20656C656966656E6420706F7274612073656D206E69736C2076697461652073617069656E2E2050656C6C656E746573717565206C6967756C61206C696265726F2C20747269737469717565206E6F6E2C20706F72747469746F722072757472756D2C20706F72747469746F72206E6F6E2C20657261742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E74656765722064696374756D2074656C6C7573206120746F72746F722E20566976616D75732066656C6973206E756E632C206D6F6C6573746965206E6F6E2C2072686F6E63757320717569732C2070686172657472612069642C206475692E20446F6E6563207269737573206D657475732C206672696E67696C6C612076656C2C20616C69717565742065752C20706C6163657261742069642C206E657175652E0A0A53757370656E646973736520697073756D2E20566976616D7573206C65637475732E2053656420766976657272612C206D61737361206567657420636F6E76616C6C6973206D61747469732C207175616D2074757270697320636F6E736563746574756572206E756E632C206567657420706F7375657265206D61676E612073656D2069642076656C69742E20496E206E6563206D61757269732E2041656E65616E206120707572757320736564207175616D206C6F626F72746973206672696E67696C6C612E2050726F696E20756C74726963696573206C6163696E696120616E74652E205365642061646970697363696E67206572617420717569732076656C69742E204E756C6C616D207669746165206E69736C206964206A7573746F20736F6C6C696369747564696E206D6F6C65737469652E204E756C6C6120666163696C6973692E20536564206E65632075726E6120736564206E69736C206672696E67696C6C6120646170696275732E204E756C6C61206174206469616D2E20416C697175616D2065676574206E6962682E204E756E63206163206E6973692073697420616D65742074656C6C757320656765737461732074656D7075732E204E616D207363656C657269737175652075726E61206574206E657175652E20446F6E656320657374206F7263692C207361676974746973206E6F6E2C2076756C70757461746520612C20636F6D6D6F646F2065742C2061756775652E205574206461706962757320746F72746F722E205574206E756E632E20446F6E65632064696374756D2064617069627573206F64696F2E204E616D20756C7472696369657320756C6C616D636F72706572206C6967756C612E2050656C6C656E74657371756520616363756D73616E20766172697573206C656F2E0A0A4D6F72626920657569736D6F64206C616F7265657420657261742E20566976616D7573207175697320697073756D2E204D6F72626920657569736D6F642E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2053757370656E64697373652076656C2070757275732E204E756C6C616D206174206D61676E612E20437572616269747572206C61637573206C6F72656D2C20696163756C697320717569732C2064617069627573206E6F6E2C20766F6C75747061742076656C2C206E756C6C612E20446F6E656320757420617263752072686F6E63757320646F6C6F72207072657469756D2064696374756D2E204E756C6C616D2076656C206D657475732E20557420617263752E2050656C6C656E746573717565206E697369206E756E632C20706C61636572617420656765742C2074696E636964756E742076656C2C207068617265747261206E6F6E2C206E756E632E20496E74656765722074696E636964756E7420756C74726963696573206C65637475732E20496E74656765722073656D7065722C2070757275732073656420756C74726963657320666575676961742C206E756C6C61207065646520736F6C6C696369747564696E20657261742C2076656C20617563746F72206E756C6C6120697073756D2076656C206C65637475732E2041656E65616E206D692E0A0A4E756C6C616D20736564206E697369206574206172637520696D70657264696574206665726D656E74756D2E204D6175726973206E6563206D657475732E20496E20616320646F6C6F722E20496E206D6920617263752C20636F6E6775652061632C207068617265747261206E65632C207363656C657269737175652073697420616D65742C206D61676E612E20437572616269747572206C616375732E2043757261626974757220657420656C69742E20416C697175616D20756C6C616D636F72706572206E756E6320657520656C69742E2053656420636F6E76616C6C697320646F6C6F722061742076656C69742E20566573746962756C756D20646170696275732C20617567756520696420636F6E73656374657475657220706C6163657261742C206E756E63206D6173736120626C616E6469742073617069656E2C20696420616C697175616D20656C6974206E697369206964206D692E2050686173656C6C75732073617069656E206573742C20677261766964612065752C20626962656E64756D2075742C2061646970697363696E6720717569732C206573742E205574206D6F6C6573746965207175616D207669746165206F64696F2E20446F6E65632071756973207269737573206964206572617420666175636962757320736F6C6C696369747564696E2E204E616D2069642066656C69732E204D61757269732073656420656E696D207669746165206C656F20616363756D73616E207072657469756D2E0A0A4E616D206A7573746F2E20446F6E656320747572706973206E69736C2C20636F6D6D6F646F2065742C20696E74657264756D2061632C20636F6E736563746574756572206E6F6E2C206D617373612E2046757363652073656D206D657475732C206C616F72656574206E65632C20706F73756572652069642C20696D7065726469657420696E2C2076656C69742E20446F6E65632076756C707574617465206A7573746F2065676574207475727069732E204E756C6C6120706564652E204D6F7262692074696E636964756E742E20467573636520616C69717565742C207175616D20657420616C697175616D206672696E67696C6C612C20616E746520616E746520696163756C6973206475692C206E656320616C697175616D20617263752070757275732073656420657261742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050686173656C6C7573207375736369706974207175616D206574206573742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B0A0A496E7465676572207365642074656C6C75732E20536564207365642076656C697420756C74726963696573206C656F2072757472756D206C616F726565742E20536564206E6F6E2065726F7320616320707572757320736167697474697320666575676961742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E205365642068656E647265726974206C6967756C612073697420616D6574206E6962682E204D616563656E6173207475727069732E204D6F72626920636F6E7365637465747565722C20646F6C6F722065742061646970697363696E6720696D706572646965742C20616E7465206E65717565206665756769617420646F6C6F722C20617420706F727461207175616D206E657175652071756973206C6967756C612E204D61757269732073656D7065722076656C69742073697420616D657420697073756D2E2050656C6C656E7465737175652074656D7075732C20707572757320696E2072757472756D20636F6E7365717561742C20656E696D2065726174207665686963756C61206D617373612C20696420616363756D73616E206C656F2073617069656E206E65632070757275732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E20646F6C6F722E20496E746567657220666163696C69736973206C696265726F2073697420616D657420706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2055742076617269757320616C697175657420656E696D2E204E756C6C6120666163696C6973692E2043757261626974757220636F6E7365637465747565722C206F64696F206575207072657469756D2074696E636964756E742C206E756E63206E69736920616C6971756574206E657175652C2076656C20696D7065726469657420656C6974206D617373612073697420616D6574207475727069732E2050656C6C656E7465737175652074656D7075732C206F72636920766F6C757470617420626C616E646974206672696E67696C6C612C206F64696F2073656D20706F737565726520616E74652C20766974616520626962656E64756D2075726E61206C6F72656D2076697461652065726F732E205072616573656E7420766976657272612072686F6E63757320617263752E2053656420617563746F722C206573742073697420616D6574206D6F6C6C6973206D6F6C6C69732C207175616D207175616D20677261766964612073617069656E2C20696E20636F6D6D6F646F206D65747573206E756C6C6120617563746F7220656E696D2E20446F6E656320666163696C697369732E0A0A50726F696E2074696E636964756E742C2073617069656E206567657420756C747269636965732061646970697363696E672C20657374206F64696F2064696374756D20617263752C207574206D6F6C6C69732065726174206475692073697420616D65742076656C69742E204D6F726269206573742073656D2C20696E74657264756D2061742C20636F6E67756520612C20656C656D656E74756D2076697461652C206D657475732E2053757370656E64697373652069642061756775652E204D617572697320656E696D2073656D2C2070756C76696E617220656765742C2074656D70757320612C2074656D7075732073697420616D65742C2073617069656E2E20467573636520766573746962756C756D20636F6E736563746574756572206475692E2050656C6C656E74657371756520657261742E20536564206469676E697373696D20706C616365726174206F64696F2E204D616563656E61732073656D7065722072686F6E637573206C65637475732E2050686173656C6C7573207072657469756D2E2044756973206C696265726F20656C69742C20656C656966656E64206E65632C20656765737461732075742C20637572737573207365642C2066656C69732E204E616D206E69736C20617263752C20616C69717565742065742C20666163696C697369732065752C206C75637475732075742C2072697375732E20457469616D20756C7472696365732C20646F6C6F722073656420766F6C7574706174206D616C6573756164612C20747572706973206172637520696D7065726469657420746F72746F722C20657569736D6F6420636F6D6D6F646F206C696265726F206D61737361207574207175616D2E20496E7465676572206D6F6C6573746965207075727573206E6F6E20656C69742E2055742076656E656E617469732073656D70657220746F72746F722E20457469616D20626962656E64756D206567657374617320697073756D2E204D617572697320736F6C6C696369747564696E2073656D206E6563206E6962682E204E756C6C61207072657469756D206D65747573206575206D657475732E2050656C6C656E7465737175652073697420616D65742073656D2E0A0A53757370656E6469737365206163206E6973692E205574206C656F2E20566573746962756C756D2068656E647265726974207072657469756D20646F6C6F722E204E756E632066657567696174206D616C6573756164612070757275732E2043726173206574206E6962682E20437572616269747572206E756E6320657261742C206D616C6573756164612076697461652C206C616F726565742061632C20756C7472696369657320696E2C2070757275732E20566976616D75732074656C6C757320617263752C20736F64616C65732065752C20666163696C6973697320612C206C6163696E6961206E65632C206E756E632E2050656C6C656E7465737175652069642076656C69742E20496E206575206E6962682E204E756E63206E656320657261742E205365642064696374756D206E65717565207574206E69736C2E0A0A4D6F726269206C65637475732074656C6C75732C2074696E636964756E742061632C20706F72747469746F722061632C2074726973746971756520696E2C2065726F732E20446F6E6563206C7563747573206C7563747573206C656F2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2046757363652075742065737420657420656E696D207363656C6572697371756520616363756D73616E2E20446F6E6563206C6967756C612066656C69732C206C6163696E696120717569732C2070656C6C656E74657371756520696E2C2073656D70657220766573746962756C756D2C20656C69742E204D61757269732065676574206F72636920612066656C697320636F6E677565207665686963756C612E20557420736F6C6C696369747564696E2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204E756C6C616D20696420646F6C6F72207574206C6F72656D206469676E697373696D2076656E656E617469732E2053757370656E64697373652076697461652073617069656E2E2050726F696E206E6F6E206D61676E612075742065726F7320766976657272612070756C76696E61722E20446F6E65632071756973206F64696F2E204E756C6C616D206E6F6E20617263752076656C206C6F72656D20737573636970697420616C697175616D2E20416C697175616D2072757472756D2074757270697320696E206C656F2E0A0A5574206C7563747573206E6962682074726973746971756520657261742E2053757370656E646973736520626962656E64756D206F64696F20766974616520746F72746F722E20446F6E6563206C6163696E69612E204372617320736F64616C65732066656C6973206C7563747573206E756C6C612E204E616D20656C656966656E64207361676974746973206C6967756C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E64697373652076656C206E657175652E204D6F72626920616C6971756574207665686963756C61206D61676E612E2041656E65616E206174206F64696F2E20447569732070656C6C656E746573717565206D61676E612E204E756C6C6120617420746F72746F72207574206469616D2064696374756D2066617563696275732E204D617572697320717569732076656C69742E20446F6E6563206E6F6E2074656C6C7573207669746165206C6F72656D206672696E67696C6C6120706F72747469746F722E2046757363652075742073617069656E207175697320746F72746F7220666575676961742073616769747469732E20446F6E656320766976657272612073656D2076697461652073617069656E2E205072616573656E7420736F64616C65732C206C6163757320696E206672696E67696C6C6120766976657272612C206F64696F2061756775652061646970697363696E672075726E612C20766974616520696E74657264756D20616E74652073656D206E6F6E206E6973692E204E756C6C616D20746F72746F72206C6F72656D2C20656C656966656E642061632C206D6F6C6C6973206E6F6E2C206C616F726565742061632C2072697375732E20496E7465676572206F726E617265206C656F20736564206A7573746F2E2051756973717565206375727375732C2073656D206E6F6E20666163696C6973697320626962656E64756D2C206E697369206D69207661726975732066656C69732C206665726D656E74756D2066657567696174206C6F72656D2065726F73206C616F726565742072697375732E0A0A517569737175652073697420616D657420657374206574206C6F72656D207665686963756C61206C6163696E69612E20446F6E6563206E656320746F72746F722E2043726173206F64696F2E204E616D207363656C657269737175652076756C7075746174652075726E612E205072616573656E74206475692E20457469616D206E6563206E69736C206C6F626F7274697320697073756D20616C69717565742074656D7075732E204D616563656E6173207072657469756D20736F6C6C696369747564696E206D61757269732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206175677565206D617373612C20636F6E67756520656765742C20636F6E76616C6C697320656765742C207472697374697175652073697420616D65742C2065726F732E2053656420636F6E736571756174206E6973692065752066656C69732E2050656C6C656E746573717565206A7573746F2E2053757370656E6469737365206E6F6E2061756775652E20496E206469676E697373696D206C6F626F72746973206D61757269732E204D61757269732073616769747469732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E0A0A5365642061646970697363696E672E20446F6E656320612074656C6C75732076697461652065737420637572737573207665686963756C612E204E616D20616E74652073656D2C20736F64616C65732069642C206672696E67696C6C612076656C2C20636F6E64696D656E74756D2076656C2C206E756C6C612E205175697371756520736F64616C65732E20457469616D20696D7065726469657420656C6974206964206F64696F2E20416C697175616D206572617420766F6C75747061742E204D616563656E617320706F7274612074656D706F7220617263752E204E756C6C612073656D2061756775652C2070656C6C656E7465737175652061632C20636F6E7365717561742075742C20636F6E64696D656E74756D20657569736D6F642C2072697375732E2053656420616C697175616D2074696E636964756E74206D692E20496E20696E74657264756D206C6F626F72746973206F7263692E0A0A536564207665686963756C612068656E6472657269742070757275732E20457469616D2061206469616D2E2043757261626974757220636F6E76616C6C69732E2053757370656E64697373652061206E6973692E20446F6E6563206964206D61676E6120696E207175616D20736F6C6C696369747564696E20756C747269636965732E20446F6E656320766976657272612E205175697371756520766F6C757470617420657374207365642073656D2E20416C697175616D206A7573746F2E20566573746962756C756D20746F72746F72206D617373612C20706F72747469746F72207365642C2076617269757320717569732C20696163756C697320717569732C206F64696F2E20416C697175616D2065676574206E657175652E0A0A4D6175726973206E756C6C612E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566573746962756C756D206575207175616D20696E206E6571756520756C7472696365732070656C6C656E7465737175652E204372617320696E20646F6C6F722071756973207175616D207661726975732068656E6472657269742E20416C697175616D206E697369206C616375732C206C6F626F727469732065752C20636F6E76616C6C69732073697420616D65742C20666163696C697369732075742C206D692E20416C697175616D206174206E657175652E204372617320736167697474697320656C656D656E74756D206A7573746F2E20566573746962756C756D207574206C656374757320616C6971756574207075727573206D616C65737561646120766F6C75747061742E2044756973206174206C616375732061646970697363696E67206C696265726F2074696E636964756E7420766573746962756C756D2E204D6F7262692061206C696265726F2E20437261732070757275732E204D6F72626920757420617567756520657420707572757320696E74657264756D207363656C657269737175652E20496E74656765722061206475692E20496E206861632068616269746173736520706C617465612064696374756D73742E2044756973207068617265747261206D657475732065676574206D61757269732E20416C697175616D20696E74657264756D20756C6C616D636F72706572206D617373612E0A0A457469616D206F726E6172652E204E756C6C616D20657569736D6F642E2041656E65616E20636F6E7365717561742067726176696461206C6967756C612E20416C697175616D206573742E2050726F696E207669746165206C616375732E205072616573656E7420612065726F732073697420616D657420647569206C756374757320636F6D6D6F646F2E2050686173656C6C7573207665686963756C612061726375206567657420646F6C6F722E205072616573656E74206665726D656E74756D20636F6E677565206C656F2E20416C697175616D20766F6C7574706174207075727573207574206C6F72656D2E2046757363652068656E64726572697420656E696D206174206C656F2E20416C697175616D2072686F6E637573206E69736C2E20566976616D75732064696374756D2065676573746173206D692E2053757370656E64697373652070656C6C656E74657371756520626962656E64756D20646F6C6F722E2050656C6C656E7465737175652074696E636964756E742C207475727069732073656D7065722070656C6C656E74657371756520636F6E64696D656E74756D2C20697073756D206D6574757320736F64616C6573206C6967756C612C20696420766F6C7574706174206469616D2074757270697320757420656C69742E0A0A5072616573656E7420736564206C616375732E204E616D20656C656966656E64206D6F6C6573746965206D61757269732E20446F6E65632064617069627573206665726D656E74756D206D617373612E20446F6E656320766976657272612066617563696275732070757275732E2043757261626974757220636F6E6775652C206C696265726F20766974616520766976657272612070656C6C656E7465737175652C206469616D2076656C697420736F64616C657320656E696D2C20736564207375736369706974206C6563747573206E697369206E6563206E657175652E20566573746962756C756D206D616C6573756164612C206C616375732061742063757273757320636F6E6775652C2076656C6974206C65637475732074726973746971756520646F6C6F722C2073697420616D657420736F64616C6573206E6571756520697073756D2061206C696265726F2E20566573746962756C756D206574207175616D2E2043757261626974757220706C6163657261742E20437572616269747572206E756E6320617263752C20657569736D6F64206E65632C2076756C7075746174652068656E6472657269742C20616C697175657420656765742C207175616D2E204375726162697475722076656C20656E696D2E2053757370656E646973736520706F74656E74692E0A0A4E756E6320636F6E736571756174206F726369207574206C616375732E2046757363652076656C697420646F6C6F722C2064617069627573207365642C20626C616E6469742073697420616D65742C2072686F6E6375732069642C2072697375732E20447569732075726E61206E6962682C207363656C6572697371756520717569732C206461706962757320612C207363656C65726973717565207365642C206E6962682E20446F6E6563206C75637475732E205574206575206D617572697320637572737573206469616D206C6163696E69612072686F6E6375732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20416C697175616D207665686963756C61206D6F6C6573746965206A7573746F2E204D616563656E617320696D70657264696574207065646520736564206D692E2053757370656E6469737365206E756C6C6120646F6C6F722C2068656E64726572697420656765742C2068656E6472657269742069642C2064696374756D2076656C2C206C656F2E204475697320616363756D73616E2E2043757261626974757220696E2066656C69732E204E756E63206C6F72656D2E205574206C656F20646F6C6F722C206C616F72656574206E65632C2076756C7075746174652061742C20656C656966656E6420696E2C206E756C6C612E2051756973717565206E756E632070757275732C2076617269757320656765742C20616363756D73616E206E65632C20616C69717565742065742C206E6962682E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20437261732061646970697363696E67207669766572726120646F6C6F722E204D617572697320706F72747469746F7220756C7472696365732070757275732E204E756C6C6120666163696C6973692E205072616573656E7420666175636962757320616E7465207669746165206D61757269732E0A0A5072616573656E74206C6163696E6961206C656374757320736564206E69736C2E20496E2074656D70757320636F6E677565206D61757269732E20496E746567657220666163696C69736973206F726E61726520656E696D2E204E756C6C61206964206D617373612E20446F6E656320636F6D6D6F646F206469616D2061742074656C6C75732E204E616D20646170696275732076697665727261206573742E204E616D2074656C6C75732E205072616573656E742061206C696265726F2E20496E206661756369627573206573742065676574206E6962682E204E756C6C612065726F73206F7263692C20696D70657264696574206E6F6E2C20626C616E646974206E6F6E2C2074656D706F7220656765742C206D692E2050656C6C656E74657371756520636F6E76616C6C69732E0A0A517569737175652065676574206D69206163206C656F20657569736D6F642066617563696275732E2050686173656C6C75732072686F6E637573207075727573206964206475692E20566573746962756C756D206D616C65737561646120656C656966656E6420616E74652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050656C6C656E74657371756520626C616E646974206D6174746973206F64696F2E2053757370656E646973736520636F6E7365717561742C206C65637475732061632073656D70657220736F6C6C696369747564696E2C206D692076656C69742064696374756D2061756775652C2061632074656D70757320646F6C6F7220657261742073697420616D6574206475692E2050726F696E2068656E6472657269742C2066656C6973207175697320766F6C757470617420706F73756572652C206469616D206F64696F206D616C657375616461206F64696F2C206120696E74657264756D206F726369206469616D20717569732073617069656E2E2050656C6C656E746573717565206F64696F206F64696F2C20766976657272612076656C2C20677261766964612065752C206D6F6C6573746965207365642C206E756C6C612E2050686173656C6C7573206D617572697320706564652C20636F6D6D6F646F2075742C20657569736D6F642065752C2068656E6472657269742065752C206573742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C6120656C656D656E74756D206C616375732065752061756775652E2053656420657261742E2050726F696E20706F7274612E204D616563656E61732071756973206D692E2050686173656C6C757320617420656E696D206163206A7573746F206772617669646120756C7472696365732E2043726173206C656F2E0A0A496E746567657220757420617263752E20446F6E656320736564206D61676E612E2050726F696E2066656C69732E20496E20696163756C69732C206C6967756C61206964206672696E67696C6C61207072657469756D2C206E696268206469616D20616363756D73616E2074656C6C75732C206567657420616363756D73616E206D657475732064756920766172697573207475727069732E2050686173656C6C7573206F726369206D657475732C20656C656966656E64207365642C2074656D706F722061632C207363656C657269737175652061632C2075726E612E20496E74656765722076697665727261206E657175652061206D61757269732E204D617572697320706F72747469746F7220646F6C6F722065752076656C69742E20496E7465676572206F64696F20656C69742C20766573746962756C756D2075742C20766F6C75747061742069642C2072686F6E63757320636F6D6D6F646F2C2075726E612E20457469616D20706C61636572617420706861726574726120657261742E2055742074656D706F72206573742E20496E7465676572206469676E697373696D20626C616E6469742074656C6C75732E204D6F726269206E69626820646F6C6F722C207363656C657269737175652069642C20636F6D6D6F646F206D616C6573756164612C206D61747469732061742C206D692E20437261732074696E636964756E7420636F6D6D6F646F2070757275732E20496E2074696E636964756E742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D20756C6C616D636F727065722E2055742068656E6472657269742E204D6F72626920756C7472696365732E0A0A5072616573656E7420696163756C69732C2065726F73206163206567657374617320736F64616C65732C2075726E61206C656F206665726D656E74756D206C6967756C612C2073697420616D657420616C697175616D2076656C69742073656D206E6F6E2070757275732E20446F6E65632072757472756D206172637520717569732070757275732E204E616D20706F73756572652C206C6163757320617420636F6E73657175617420706C6163657261742C206E756C6C61207065646520706F7375657265206F7263692C206E6F6E20657569736D6F6420747572706973206475692071756973206E69736C2E2050726F696E20706F7274612061646970697363696E67206E6962682E20446F6E65632074726973746971756520646F6C6F722061742074656C6C75732E20446F6E6563206E65717565206D617373612C20617563746F722069642C2066617563696275732076697461652C20756C6C616D636F727065722076656C2C206E6973692E2050726F696E206D6F6C6573746965206E6571756520736564206D617373612E204E616D2074656D706F722E204D6F72626920616C697175616D2073617069656E2061742074656C6C75732E2046757363652071756973207269737573206574206D69207072657469756D2070756C76696E61722E2046757363652073697420616D6574206C6967756C612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E646973736520657520656E696D2065742066656C6973207363656C65726973717565206C6F626F727469732E205072616573656E7420626962656E64756D2E20566976616D7573207665686963756C612E20496E7465676572206174206E696268207365642076656C69742072686F6E637573206D6F6C65737469652E2043726173206C616375732E2053656420756C6C616D636F727065722065726F732076656C20657261742E20467573636520657520746F72746F722073697420616D6574206469616D20657569736D6F642073616769747469732E204E756E632071756973206C61637573206964206E69626820636F6E76616C6C6973207661726975732E2053757370656E6469737365207669746165206D692E20566573746962756C756D207472697374697175652E20446F6E6563206D616C65737561646120697073756D206964206E657175652E204E756C6C616D20736564206C616375732E204475697320656765737461732C206A7573746F20757420636F6E677565206F726E6172652C2061756775652073617069656E206C7563747573206469616D2C20617420616363756D73616E20657261742073617069656E207574206C696265726F2E2050686173656C6C75732076656C206E756C6C612E2053757370656E646973736520617263752074656C6C75732C20706F72747469746F7220612C2070686172657472612066617563696275732C20616C697175616D2073697420616D65742C206D617373612E204E756C6C6120706F72747469746F722074696E636964756E74206C6F72656D2E204E756E6320646F6C6F72206F64696F2C20736167697474697320696E2C206C6F626F727469732076656C2C20766F6C7574706174207365642C206E6962682E0A0A5175697371756520626C616E646974206C656F2075742073617069656E2074656D70757320666163696C697369732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2041656E65616E20756C7472696369657320706F72747469746F72206A7573746F2E2046757363652072757472756D2065726F732075742075726E612E2050726F696E2071756973207175616D20656765742064756920616C697175616D20616363756D73616E2E20446F6E656320737573636970697420656C656966656E6420656C69742E2050656C6C656E746573717565206D61747469732C2066656C697320736F64616C657320696163756C697320696D706572646965742C206C616375732073656D20636F6E76616C6C69732061756775652C2073697420616D657420616C69717565742061726375207075727573206672696E67696C6C612072697375732E20496E206575206F64696F206964206D61676E61207068617265747261206F726E6172652E20416C697175616D20696E74657264756D2070756C76696E617220697073756D2E20536564206E657175652E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D2073697420616D6574206E6973692E2055742061742061756775652E204D617572697320766F6C757470617420626C616E646974206C6967756C612E204E756C6C61206575206D657475732E20566573746962756C756D206567657420656C69742E205072616573656E7420706F73756572652E20566573746962756C756D2069642073656D206E6F6E206C6563747573206D6F6C6C69732074696E636964756E742E20416C697175616D2069642066656C697320617420616E7465206F726E6172652074656D706F722E204E756C6C61206C61637573207475727069732C20666575676961742076697461652C2063757273757320717569732C20636F6E736563746574756572206E6F6E2C206D61757269732E204675736365206C61637573206D617373612C20706F72747469746F722075742C206D6F6C65737469652075742C2076656E656E6174697320612C206C6F72656D2E205072616573656E742073697420616D6574206F7263692E204D61757269732072686F6E6375732066656C69732076697461652066656C69732061646970697363696E6720696D706572646965742E204D616563656E6173206D6F6C6C6973206469616D206E6563206C656F2E0A0A467573636520656E696D20697073756D2C20756C7472696365732065752C206D6F6C65737469652069642C20656C656D656E74756D2069642C2073617069656E2E20496E746567657220612075726E612E204E616D2076656C6974206C696265726F2C2076656E656E6174697320656765742C2074656D706F722073697420616D65742C20666575676961742076697461652C20616E74652E204675736365206E756E632E205365642073656D706572206E69736C206E65632072697375732E20496E20736564206C696265726F2E2050726F696E20746F72746F72206E657175652C2074696E636964756E742061632C2074656D706F722061632C20706861726574726120717569732C2076656C69742E2044756973206C65637475732061756775652C20756C747269636965732076656C2C20636F6E7365717561742069642C20696163756C69732069642C20616E74652E20566976616D757320617563746F72206D65747573206120616E74652E204375726162697475722061726375206E6973692C20666163696C697369732061742C206C616F7265657420696E2C20636F6E736563746574756572207365642C206D61757269732E205175697371756520706C616365726174206469616D20736564206475692E20566976616D7573207072657469756D20636F6E64696D656E74756D206C6F72656D2E20437572616269747572206C616F726565742E2041656E65616E206F726369206C6967756C612C2063757273757320656765742C206C6163696E6961206E6F6E2C2066617563696275732076656C2C206C6F72656D2E0A0A416C697175616D206572617420766F6C75747061742E204375726162697475722065726F7320646F6C6F722C20636F6E67756520612C20636F6E64696D656E74756D207365642C206C75637475732075742C206E6962682E204D616563656E6173206E6F6E20746F72746F72206E65632074757270697320636F6D6D6F646F2070656C6C656E7465737175652E205072616573656E7420657569736D6F6420706C616365726174206D692E2053757370656E646973736520706F74656E74692E2050686173656C6C7573207574206E65717565207669746165206F726369206D617474697320696163756C69732E20496E746567657220656765742074656C6C75732E20446F6E656320617420616E74652E204E616D206C6163696E6961206C656F206567657420657261742E204D616563656E617320657569736D6F64206D61676E6120636F6E67756520746F72746F722E204D6F726269206E6563206D6173736120657520656E696D206D616C65737561646120736F6C6C696369747564696E2E2053656420616363756D73616E2E204E756C6C616D20697073756D2E205574206F64696F2E20416C697175616D206572617420766F6C75747061742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2050656C6C656E7465737175652069642076656C69742E204E616D206F64696F2073656D2C20616C69717565742075742C2074656D7075732073697420616D65742C20657569736D6F642065742C206E756E632E0A0A50656C6C656E746573717565206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205072616573656E74206D6175726973206E756E632C207661726975732075742C20636F6E76616C6C6973206D6F6C65737469652C206C75637475732073697420616D65742C206C656F2E205365642064696374756D206C6F72656D20657420617263752E204E756E632076656E656E617469732070656C6C656E746573717565206D617373612E204E756C6C6120666163696C6973692E2050686173656C6C757320696E20746F72746F722065676574207269737573207363656C657269737175652076756C7075746174652E20536564206E69626820656C69742C2073616769747469732061632C20636F6E64696D656E74756D206E65632C20636F6E76616C6C69732065742C206A7573746F2E20467573636520766F6C7574706174206D657475732E204E756E6320617563746F722E20566573746962756C756D206C656F2065726F732C2070656C6C656E7465737175652061632C206D6F6C6C697320756C7472696365732C2072686F6E637573206E6F6E2C20646F6C6F722E204D6175726973207665686963756C6120706C616365726174206E69736C2E20566573746962756C756D20626962656E64756D2C2061726375207175697320636F6E67756520656C656D656E74756D2C2076656C6974206E756E6320656C656966656E64207475727069732C206964206C7563747573207269737573206E69736C2073697420616D65742074656C6C75732E2050686173656C6C75732070656465206E657175652C20626C616E646974206E6F6E2C20636F6D6D6F646F2076697461652C20756C7472696369657320656765742C206D61676E612E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120666163696C6973692E20416C697175616D20616320616E74652E20437261732072697375732E204D6F726269206D6175726973206C616375732C20706F73756572652065752C20626C616E6469742065742C2070686172657472612061742C206D692E2050726F696E2061632070757275732E204475697320637572737573206E69736C2072757472756D207175616D2E20416C697175616D2061206F64696F206E6F6E206D61676E612070656C6C656E74657371756520756C747269636965732E204D616563656E6173206163206D6173736120717569732073617069656E20756C6C616D636F727065722074656D7075732E2043726173206375727375732076656C6974207365642073617069656E2E2050726F696E206E756C6C612E20566976616D757320736F64616C657320616C697175616D206E6962682E20457469616D206574206572617420757420616E7465206C6163696E696120657569736D6F642E204675736365206E6973692E2050726F696E2071756973206E756C6C612E0A0A517569737175652076656E656E617469732C2065726F7320736564206C616F7265657420736F6C6C696369747564696E2C206F72636920616E74652070656C6C656E746573717565206E69736C2C2073697420616D65742076697665727261207175616D2065726174206E6F6E2072697375732E20437261732065676574206C696265726F2E2053656420656C6974206D61676E612C2073656D7065722065752C206672696E67696C6C6120696E2C206469676E697373696D20736F64616C65732C20657261742E20566976616D757320666575676961742073656D2076656C206475692E20446F6E656320636F6E76616C6C697320736F6C6C696369747564696E206469616D2E2043726173207365642070757275732E20446F6E65632066656C69732065726F732C2073656D70657220656765742C2074656D706F7220636F6E7365637465747565722C20736167697474697320717569732C206E69736C2E204475697320696E20616E74652E2043726173206E6F6E207475727069732E204E756C6C612074656D706F722076656C697420616C697175657420747572706973206D6F6C657374696520706C6163657261742E2050726F696E20656C656D656E74756D206665726D656E74756D206D61757269732E20566976616D757320736564206F726369206C6163696E69612064756920706C6163657261742076656E656E617469732E20566573746962756C756D20666575676961742C2074656C6C757320696E20766F6C75747061742072757472756D2C206D61676E61206E69736920756C6C616D636F727065722065726F732C2069642070756C76696E6172206E657175652065726174207574206C616375732E20566976616D7573207365642061756775652E204E756C6C6120666163696C6973692E204D616563656E617320616E74652061756775652C20656C656D656E74756D2075742C20736F64616C65732076697461652C20636F6E64696D656E74756D206E65632C206C6F72656D2E20447569732070656465206F7263692C206672696E67696C6C612061742C20656C656966656E64206E65632C207072657469756D20696E2C20657261742E204E616D2073616769747469732C2074757270697320766974616520636F6E76616C6C69732070686172657472612C206F64696F2073656D207363656C65726973717565206C616375732C206E6563206C6F626F7274697320647569206469616D2076656C2065726F732E20496E2073656D7065722067726176696461206E657175652E0A0A496E7465676572206E756E632E205574207072657469756D20697073756D2073697420616D657420656C69742E20496E206E656320617263752E2053656420766573746962756C756D2076756C70757461746520697073756D2E2050656C6C656E7465737175652074696E636964756E742E204E756C6C61206772617669646120646F6C6F7220696E2074656C6C75732E2043726173207665686963756C612C20646F6C6F722075742070656C6C656E74657371756520616C697175616D2C206572617420656E696D20617563746F72206D617373612C207665686963756C61206C6F626F72746973206F64696F2065726F732071756973207175616D2E2050726F696E2064617069627573206E6571756520696E20656E696D2E2050726F696E20656C69742E20496E74656765722072686F6E6375732074696E636964756E7420656C69742E204675736365206C6F72656D206D657475732C2073656D7065722061632C20766F6C75747061742076697461652C20666163696C697369732075742C2074656C6C75732E20446F6E65632076656C20747572706973207669746165206E69736920706861726574726120706F72747469746F722E204D616563656E617320746F72746F722E204675736365206D692E204E756C6C616D206E6563207475727069732E2053656420736F64616C657320766573746962756C756D206E756E632E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A50656C6C656E74657371756520646F6C6F7220646F6C6F722C206C616F726565742065752C20616C697175657420717569732C207363656C657269737175652073697420616D65742C20617263752E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C616D206375727375732075726E61206567657420656C69742E205175697371756520626C616E6469742073617069656E20616320616E74652E2050726F696E206E756C6C612065726F732C206772617669646120766F6C75747061742C20736F64616C65732076656C2C206D6F6C6C69732065752C206D617373612E204E756C6C612074726973746971756520736F6C6C696369747564696E206E69736C2E20437572616269747572207669746165206C6F72656D2076697461652076656C69742065676573746173206F726E6172652E2041656E65616E20656765742065726F732E20416C697175616D206572617420766F6C75747061742E20467573636520612075726E61206964206F64696F20616C697175657420636F6E76616C6C69732E204375726162697475722073697420616D6574206E69736C20706F7375657265206C656F20706F737565726520646170696275732E2044756973206D6574757320657261742C206C75637475732076656C2C2072686F6E6375732061742C20636F6E76616C6C69732073697420616D65742C20656E696D2E20566976616D75732068656E6472657269742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D206567657420656C69742E0A0A4E756C6C616D2061206E756E632E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206D657475732075726E612C2074696E636964756E742065742C206C6163696E69612073697420616D65742C206C6F626F727469732076697461652C206C6967756C612E2050726F696E206574206D6175726973207669746165206D6920616363756D73616E2070656C6C656E7465737175652E20457469616D207175616D2070757275732C2068656E647265726974207365642C20666575676961742076697461652C20657569736D6F6420656765742C20746F72746F722E20557420616C697175616D206D61676E61207669746165206A7573746F2E2053757370656E6469737365206E6F6E206A7573746F2076656C2076656C697420636F6E64696D656E74756D2074656D7075732E20447569732074656D70757320697073756D2076697461652074656C6C75732E2050726F696E20696E206D617373612E20457469616D20756C6C616D636F727065722064696374756D2074656C6C75732E2050726F696E20616C69717565742066656C6973206174206C656F206C616F726565742070756C76696E61722E20566573746962756C756D20617263752070757275732C206D616C6573756164612073697420616D65742C206375727375732065752C20706C6163657261742073697420616D65742C206E756E632E204E616D206D61737361206F64696F2C20736F6C6C696369747564696E20696E2C2061646970697363696E6720612C20616C697175616D206E65632C2072697375732E20416C697175616D20626C616E6469742068656E647265726974206C696265726F2E204D617572697320677261766964612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204375726162697475722061206E6962682E20557420696E74657264756D206665726D656E74756D206E657175652E2050656C6C656E74657371756520736564206E756E632E204D6175726973207665686963756C61206E697369206574206E756E632E205072616573656E74206C6F72656D2E20446F6E65632073656D7065722E20496E7465676572206575206C6163757320696E2065737420616C697175616D2068656E6472657269742E20566573746962756C756D2065676574206E657175652E205365642073656D706572206C75637475732076656C69742E20437572616269747572206E6962682061756775652C20636F6E6775652065752C2068656E6472657269742069642C20636F6E6775652065742C20656E696D2E20496E746567657220706C61636572617420616C697175616D206C65637475732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20566976616D75732076697461652065726F732E20446F6E65632076656C206E69736C2E0A0A496E20766573746962756C756D20666163696C697369732075726E612E2055742072697375732E204D61757269732070686172657472612E2050656C6C656E746573717565206D61747469732E20496E746567657220737573636970697420616C697175616D20697073756D2E204475697320626C616E6469742C2073617069656E20657420756C7472696369657320636F6E64696D656E74756D2C2066656C6973206D6920656C656D656E74756D20706564652C206E6563207361676974746973206D65747573206D61757269732071756973207175616D2E205175697371756520616363756D73616E20617263752076656C206E756C6C612E20437261732073656D2073617069656E2C20706F72747469746F722069642C20756C747269636965732073616769747469732C206C75637475732065752C206E756C6C612E20496E746567657220717569732065726F732E204D6F726269207365642075726E6120612074656C6C7573207665686963756C612076756C7075746174652E20457469616D206E656320617567756520656765742066656C69732073656D706572207472697374697175652E205175697371756520757420646F6C6F722076656C2072697375732064696374756D20636F6E7365717561742E20536564206567657420646F6C6F7220736564206E756E63206C6163696E696120616C69717565742E2053757370656E646973736520616320746F72746F7220696E20697073756D20706F73756572652076656E656E617469732E20536564206567657420657261742E204E756C6C612066617563696275732E2044756973206C616F726565742C206D6173736120706F72747469746F7220616C697175657420656765737461732C20697073756D206C65637475732072686F6E637573207175616D2C20696E2061646970697363696E672065726F732073656D2075742074656C6C75732E2050656C6C656E74657371756520666575676961742074656D707573207175616D2E20566976616D757320696420646F6C6F7220656765742073617069656E20636F6E7365637465747565722074656D706F722E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120696163756C6973206665726D656E74756D206C696265726F2E204375726162697475722066617563696275732C206D61737361206D616C657375616461206375727375732074696E636964756E742C20657261742073656D20656C656966656E64206D61757269732C20736564206672696E67696C6C61206D6920616E74652061632070757275732E204475697320656C656D656E74756D206C65637475732E204E756E63206F726E617265206172637520657520746F72746F722E20566573746962756C756D2076656C20646F6C6F72206174207075727573206C6163696E6961206672696E67696C6C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E616D20696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204D616563656E61732074696E636964756E742C2065726F73206120656765737461732070656C6C656E7465737175652C2072697375732072697375732064696374756D206C696265726F2C20696420616C6971756574206D65747573206A7573746F20696E206D617373612E2050726F696E20612074656C6C75732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205365642070757275732E20536564206E6F6E20706564652E2041656E65616E206D617373612073617069656E2C20736F64616C65732073697420616D65742C20636F6E7365717561742064696374756D2C20656C656966656E642076697461652C20746F72746F722E20446F6E656320756C747269636573206C6163696E696120656C69742E0A0A4D6F7262692061646970697363696E6720736F64616C657320646F6C6F722E20557420756C6C616D636F7270657220756C74726963696573206573742E20496E2076656E656E617469732074656D7075732061756775652E2053757370656E646973736520746F72746F7220646F6C6F722C20616363756D73616E2065742C20737573636970697420612C2074696E636964756E742075742C206C696265726F2E20416C697175616D207363656C65726973717565206D61676E61207365642066656C69732E2051756973717565207574206E756E632061206D61676E612076756C70757461746520706C6163657261742E20416C697175616D2072686F6E637573207665686963756C61206475692E2053656420746F72746F722E204E756C6C616D2073697420616D6574206469616D2E204E756E63207365642065726F732E20536564206574206F64696F2074696E636964756E7420656C6974206772617669646120636F6E76616C6C69732E20437572616269747572207175697320746F72746F722061206C616375732073656D706572207661726975732E204D6175726973206174206175677565206E6F6E206D6920736F6C6C696369747564696E20616C697175616D2E20496E746567657220756C6C616D636F727065722E2050656C6C656E746573717565207375736369706974207175616D206E6F6E2070757275732E20416C697175616D2061632065726F73206174206172637520756C6C616D636F7270657220636F6E7365637465747565722E2053757370656E6469737365207072657469756D206D6174746973206C656F2E0A0A44756973206174206E756E632E2053656420646F6C6F72206573742C207661726975732061632C20706F7274612065742C2074696E636964756E742068656E6472657269742C2072697375732E20566976616D7573207574206D61676E612E205072616573656E74207574206D61757269732E20496E207075727573206C616375732C206D6174746973207365642C20766573746962756C756D206E65632C2074656D706F722061742C206E69736C2E204372617320756C6C616D636F727065722076656E656E617469732074656C6C75732E20557420646F6C6F722E204D616563656E6173206D616C6573756164612C207065646520612070756C76696E6172206D61747469732C2061726375206469616D207665686963756C612072697375732C207175697320706F72747469746F72206175677565206D6173736120696E2076656C69742E204E756E6320636F6E6775652E204D6F7262692076656C6974206D657475732C2072686F6E6375732065742C20616C697175616D20636F6E7365637465747565722C20756C74726963696573206D616C6573756164612C206C6967756C612E205365642076656C6974206E69736C2C2073616769747469732076697461652C20706861726574726120612C20706F7375657265207365642C206D617373612E204E756C6C6120666163696C6973692E20496E207661726975732C206C6967756C61206964206C6F626F7274697320736F64616C65732C206175677565206F726369206665726D656E74756D2074656C6C75732C2065752070756C76696E6172207269737573206C6967756C6120612073617069656E2E204D6F726269206C616F7265657420697073756D206E6F6E206D692E204E616D20637572737573206C6F72656D207574206D692E20566976616D7573206D61676E6120656E696D2C20706F7375657265206E6F6E2C2073656D70657220717569732C20736F64616C65732065752C20617263752E20457469616D206D692070757275732C207072657469756D20666575676961742C20766172697573207365642C2070656C6C656E74657371756520656765742C206C6967756C612E20496E206C656F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E6563207669746165206F726369206575206F72636920736F6C6C696369747564696E20666575676961742E0A0A5072616573656E74207075727573206D617373612C20657569736D6F642076697461652C2074656D707573206E65632C20636F6E7365717561742068656E6472657269742C206D657475732E2041656E65616E2066656C6973206573742C20656765737461732076697461652C20616363756D73616E20656765742C2070656C6C656E74657371756520696E2C2073617069656E2E204475697320646170696275732070656465206E6F6E2073617069656E2E204E756E632075726E612E20496E74656765722076656C206C696265726F2E204475697320617567756520617263752C2064617069627573206E6F6E2C20666163696C697369732076697461652C20706F73756572652075742C2065726F732E20446F6E6563207669746165206E756E632073697420616D6574206172637520696D706572646965742064696374756D2E204D6F72626920656C656966656E642C206C6F72656D20657520636F6E73656374657475657220766573746962756C756D2C206469616D206E756E63206F726E61726520617263752C2061632074656D706F722066656C697320646F6C6F7220656765742065726F732E2050686173656C6C7573206D617373612073656D2C20736F6C6C696369747564696E2061632C20736F64616C657320677261766964612C206C756374757320612C207175616D2E204E616D206E65717565207175616D2C20766976657272612061742C2076656E656E6174697320717569732C207361676974746973206E6F6E2C20656E696D2E0A0A4E756C6C6120666163696C6973692E2050656C6C656E7465737175652065676573746173206C6163696E6961206573742E205365642074696E636964756E742C2070656465207365642074696E636964756E7420766573746962756C756D2C2075726E6120646F6C6F722061646970697363696E672070757275732C207669746165206672696E67696C6C612066656C697320656C697420696E206E6962682E204E756C6C6120736564206E6973692E204D6175726973207375736369706974207363656C6572697371756520617263752E20457469616D206E6F6E20656E696D2076656C2065726F7320616363756D73616E206D616C6573756164612E204E756E632074696E636964756E7420636F6D6D6F646F206D61757269732E20496E2074696E636964756E7420726973757320717569732075726E612E204E756C6C61206469616D20746F72746F722C20616C69717565742065742C2074696E636964756E7420717569732C20736F6C6C696369747564696E2061632C20746F72746F722E2043726173206E69736C206E657175652C2076756C7075746174652073757363697069742C206D6F6C657374696520717569732C2070756C76696E61722061742C206E756C6C612E204E756C6C616D206163206D65747573206E6563206F64696F20706F7375657265207661726975732E2043726173207365642070656465206E65632064756920706F737565726520626962656E64756D2E204475697320657569736D6F6420756C6C616D636F72706572206C696265726F2E20416C697175616D2066617563696275732070756C76696E6172207475727069732E0A0A496E207574206E65717565206964206E756E63206665756769617420636F6D6D6F646F2E20437572616269747572206469676E697373696D2C2066656C697320617420736F6C6C696369747564696E206C6163696E69612C20656E696D20656C6974207375736369706974206E657175652C20736564206C7563747573206C6F72656D20697073756D20696E206C656F2E204475697320646170696275732C206F64696F207175697320617563746F7220636F6D6D6F646F2C206E69736C206F64696F206D61747469732074656C6C75732C206E65632074696E636964756E7420747572706973206469616D20696E20617263752E2043757261626974757220612073656D2E204E756C6C616D20766F6C7574706174206D61676E612E2050656C6C656E7465737175652073616769747469732C206E6571756520636F6E736571756174207072657469756D206375727375732C20646F6C6F72206C6163757320636F6E73656374657475657220617263752C20736564206C616F72656574206573742075726E61206574206D657475732E2053757370656E646973736520706C6163657261742C20647569206120706F7274612074656D706F722C206C6F72656D20647569206C6F626F72746973206E657175652C207365642076656E656E61746973206469616D20656E696D2069642065726F732E20457469616D206574206E69736C206E6F6E206C656374757320666175636962757320636F6E7365637465747565722E204D6F726269207363656C657269737175652C2073656D206E65632074656D70757320756C6C616D636F727065722C20697073756D206469616D2066657567696174206C6F72656D2C2061206672696E67696C6C612073617069656E20656C69742071756973206E6962682E204E756C6C616D206469616D2075726E612C2076697665727261207365642C2070686172657472612072686F6E6375732C2074696E636964756E742076656C2C206F7263692E20496E746567657220616363756D73616E206D617474697320657261742E204E616D2064696374756D2E204D6175726973206E6563206C656F2E204E756C6C6120696163756C69732E204E756C6C61206E69736C206D692C206461706962757320717569732C207665686963756C6120612C2063757273757320656765742C206F64696F2E0A0A50686173656C6C7573206461706962757320657569736D6F64206E6962682E20566976616D757320696D7065726469657420616E746520696E206C6967756C612E2050656C6C656E74657371756520616363756D73616E2E20496E20696D706572646965742C20647569206120617563746F72206672696E67696C6C612C206D65747573206E6973692063757273757320646F6C6F722C2076656C206C7563747573206C6967756C61206C6F72656D207669746165206D61757269732E205072616573656E74206D617474697320766573746962756C756D20656C69742E20416C697175616D20656E696D206C616375732C2070756C76696E6172206E6F6E2C206C6163696E69612073697420616D65742C20656C656966656E64206E6F6E2C2076656C69742E20566573746962756C756D206163206C656F2E204D617572697320696D70657264696574206A7573746F206163206C65637475732E20536564206D6F6C6573746965206C656374757320736564206475692E20536564206665726D656E74756D2074656D707573206D61757269732E204E616D206F726E617265206F7263692061632074656C6C75732E205574206D616C6573756164612C206C61637573206964206C6163696E696120616363756D73616E2C206469616D20656C69742061646970697363696E67206D657475732C20657420626962656E64756D2073617069656E206E69626820626C616E646974206F7263692E2053757370656E646973736520697073756D2074656C6C75732C20736167697474697320717569732C20766573746962756C756D206E6F6E2C2076756C7075746174652065752C2065726F732E205072616573656E74206174206E756C6C612069642070656465207363656C6572697371756520756C747269636965732E204372617320626C616E646974207072657469756D2074656C6C75732E204D616563656E6173206461706962757320636F6E64696D656E74756D2061756775652E2050686173656C6C75732074696E636964756E74207068617265747261206C6F72656D2E204D6F726269206E6F6E2065726F732E205365642074656D706F722C206E69736C20612074696E636964756E742074696E636964756E742C2065726F73206469616D2064696374756D2073656D2C2076656C206469676E697373696D20616E7465206469616D20736564206D61676E612E205072616573656E74206E6F6E206C6967756C61206964206D65747573206D6F6C657374696520636F6E7365637465747565722E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E64697373652076656C206D692E2043757261626974757220616E7465206E756C6C612C2072757472756D20612C20636F6E76616C6C69732076656C2C207665686963756C612061632C206E756E632E204E756E632073616769747469732C20656E696D2073697420616D657420617563746F722072757472756D2C206D617572697320617263752076756C707574617465206E657175652C20657420657569736D6F64206573742066656C6973207175697320616E74652E20566573746962756C756D207475727069732074656C6C75732C2068656E64726572697420696E2C206C6163696E696120636F6D6D6F646F2C20756C6C616D636F7270657220677261766964612C2072697375732E204D61757269732072686F6E637573206C6163696E69612072697375732E204D616563656E617320736F6C6C696369747564696E2065726174207669746165206E756E632E205072616573656E74207072657469756D2070656C6C656E7465737175652061756775652E20446F6E656320696E74657264756D2E205072616573656E742061632065726F732076697461652065726174206C6F626F72746973206672696E67696C6C612E2041656E65616E20636F6E7365717561742074656C6C75732E204E756C6C6120616363756D73616E20626962656E64756D2066656C69732E204D616563656E6173207072657469756D20616E7465206964206E6973692E2041656E65616E206D6920617263752C2073656D706572207365642C206D61747469732065752C2076656E656E617469732073697420616D65742C20617263752E20446F6E656320616C697175657420657569736D6F64206C656F2E2050726F696E206D61676E61206A7573746F2C2074726973746971756520612C2073656D7065722061632C20736F6C6C696369747564696E20612C206C6967756C612E204D6F7262692076656C69742E20416C697175616D2076656C206E6973692E0A0A496E2061206C6F72656D207574206E756E63206665756769617420636F6E6775652E20446F6E6563206665726D656E74756D20626962656E64756D206475692E2050726F696E207661726975732065737420717569732076656C69742E20446F6E656320616C69717565742073656D20616363756D73616E206D692E2053656420706C6163657261742E204E756C6C616D206163206E6973692061206D61737361206C6F626F727469732073757363697069742E204E756E63206964206C656F2E20416C697175616D206574206D617373612E204E756C6C616D20766573746962756C756D20656C656D656E74756D206D657475732E20496E20636F6E736563746574756572206E6973692076656C206A7573746F2E204D616563656E6173206567657420707572757320736564206D61737361207661726975732070656C6C656E7465737175652E2050686173656C6C75732066617563696275732066656C697320717569732066656C69732E2041656E65616E206F64696F20617263752C20626C616E64697420717569732C20666163696C6973697320696E2C20696D706572646965742065752C206C6F72656D2E204E616D20706F73756572652070756C76696E6172206D692E204675736365207472697374697175652C206D617572697320657420636F6E73656374657475657220756C747269636965732C206D6175726973206C65637475732074656D706F72206A7573746F2C206174206672696E67696C6C61206573742065737420736564206E6973692E20517569737175652066617563696275732E2053656420696E20746F72746F722074696E636964756E7420657374206C6163696E696120696163756C69732E204D616563656E61732061206D617373612E2050656C6C656E7465737175652061206E69626820617420707572757320706F7274612068656E6472657269742E0A0A4E756C6C616D207475727069732E2046757363652061632073656D20736564206F64696F2070656C6C656E74657371756520696D706572646965742E2043757261626974757220696E20617263752E205072616573656E74206C61637573206C616375732C20666575676961742069642C2070756C76696E617220696E2C2074696E636964756E74207365642C206E657175652E204D616563656E61732076697665727261206F64696F206567657420746F72746F722E20496E746567657220616C697175616D2C206C6F72656D2072757472756D2076656E656E61746973206469676E697373696D2C206C6967756C61206D61676E61206D616C65737561646120617263752C2076656C2066657567696174206C6F72656D20697073756D2071756973206D617373612E204D6F72626920616E74652E20566573746962756C756D206D6175726973206C696265726F2C20756C6C616D636F7270657220717569732C20756C74726963657320717569732C20666163696C69736973206E6F6E2C206D617373612E204D616563656E617320696D706572646965742E20416C697175616D206572617420766F6C75747061742E2050656C6C656E746573717565206469676E697373696D2067726176696461206C65637475732E20496E206E696268206F64696F2C20617563746F7220656765742C206461706962757320717569732C206469676E697373696D2076656E656E617469732C20617263752E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20447569732070656C6C656E746573717565206C6967756C612071756973206D617373612E2043757261626974757220636F6E64696D656E74756D2C206A7573746F2065676574206F726E617265206C75637475732C206C6F72656D206C6967756C6120736167697474697320706564652C206120706F727461206E756E63206E756E6320696E206E657175652E20517569737175652066656C6973206D61757269732C20636F6E64696D656E74756D2076697461652C20617563746F722076697461652C2074696E636964756E7420717569732C20706564652E204E756E63206C6163696E696120616E746520696E206C656F2E2050656C6C656E746573717565206C696265726F2E2041656E65616E2061206C6967756C61206574206E756E6320766573746962756C756D20636F6E7365637465747565722E0A0A4675736365206F726E6172652E205072616573656E742069642075726E612E20496E74656765722076656E656E617469732C207175616D206E6F6E20736167697474697320616363756D73616E2C20616E7465206E6962682073616769747469732061756775652C20736F6C6C696369747564696E2061646970697363696E6720646F6C6F722076656C697420657520657261742E2050726F696E207175697320656E696D206575207075727573207665686963756C6120616C697175616D2E204E756C6C612076656C20656E696D2076656C20656C697420736F6C6C696369747564696E206672696E67696C6C612E20416C697175616D206572617420766F6C75747061742E205365642073757363697069742066656C6973207574207475727069732E20457469616D2072757472756D20726973757320696D70657264696574206573742E20416C697175616D20612074656C6C75732061742074656C6C757320636F6D6D6F646F20646170696275732E204D61757269732072757472756D206D61676E61206574206F64696F2E20496E20617420646F6C6F722E20437572616269747572207665686963756C61206C656374757320696E20746F72746F722E204675736365206A7573746F2070757275732C206C75637475732076697461652C206D6F6C6C697320696E2C2070686172657472612061632C2070757275732E204E756C6C616D20706F737565726520696E74657264756D206A7573746F2E20437572616269747572207669746165206C616375732076656C206C656F20636F6E6775652070756C76696E61722E0A0A41656E65616E20656C656966656E64206E6962682076617269757320746F72746F722E2053757370656E64697373652076656C2065726F732E2050726F696E206E6563206469616D206120746F72746F7220756C747269636573206F726E6172652E20416C697175616D207363656C657269737175652066657567696174206A7573746F2E20566976616D757320616E74652075726E612C2061646970697363696E672076697461652C20706F72747469746F722065752C20736F64616C65732065742C2066656C69732E2053757370656E646973736520706F74656E74692E20437572616269747572206163206D6173736120696E206E69736C207361676974746973206D6F6C6C69732E204E616D207175616D206C6967756C612C20636F6E73656374657475657220656765742C20696163756C69732061742C207661726975732065752C206C656F2E204475697320646F6C6F72206C6967756C612C2074696E636964756E742061742C20756C6C616D636F72706572207365642C20616363756D73616E20616C697175616D2C206C6967756C612E2050686173656C6C75732076756C7075746174652C206C6F72656D2061742074696E636964756E742070686172657472612C207269737573206C6563747573206C6163696E6961206D61676E612C20717569732072757472756D20656E696D206D61676E612061742073656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E20447569732069642073656D2061206D617572697320736F6C6C696369747564696E2074696E636964756E742E20457469616D2065752070757275732065752061726375206672696E67696C6C612061646970697363696E672E20566976616D7573206F726E6172652074656D707573206469616D2E2050726F696E20747572706973207175616D2C206C6163696E6961206E6F6E2C20656765737461732061742C20636F6D6D6F646F20656765742C20706564652E205072616573656E742076756C70757461746520726973757320696E206573742E204E756C6C6120666163696C6973692E0A0A557420656C656D656E74756D206C6163696E69612070757275732E2050726F696E2076697461652061726375206163206E756C6C6120636F6E76616C6C697320616C697175616D2E204E756C6C6120636F6E6775652C206C696265726F2069642070656C6C656E746573717565206D61747469732C207175616D206C656374757320706F72747469746F72206469616D2C2061207363656C6572697371756520647569206C696265726F20696E2073617069656E2E204E756C6C616D2066656C6973206469616D2C207665686963756C612076656C2C206D6F6C65737469652075742C20766573746962756C756D20616C697175616D2C2073617069656E2E20446F6E656320636F6E76616C6C69732C2065737420757420656C656D656E74756D20766F6C75747061742C206D617572697320697073756D20677261766964612073656D2C20636F6D6D6F646F20666163696C697369732073617069656E206C65637475732073656D706572206C65637475732E205175697371756520706F72747469746F722065726F73207574206E6962682E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20457469616D206D617474697320726973757320736564206F64696F2E20566573746962756C756D206574206F64696F2E20496E206861632068616269746173736520706C617465612064696374756D73742E204E616D20747269737469717565206D61737361207574206C6967756C612E2051756973717565206E6962682074656C6C75732C207665686963756C612073697420616D65742C2061646970697363696E672061742C20636F6E76616C6C6973206E65632C206C6967756C612E20566573746962756C756D207072657469756D2C206D69206E6563206672696E67696C6C6120626962656E64756D2C20647569206E756E6320736F64616C657320706564652C20612073656D706572206D61676E61206E696268206E6F6E206469616D2E20446F6E6563206D61737361206E756E632C20766976657272612076656C2C20636F6E73656374657475657220706F7274612C2064617069627573206E6F6E2C20697073756D2E2044756973206E69736C206D61757269732C206375727375732076656C2C2073656D706572206E6F6E2C20736F6C6C696369747564696E20626962656E64756D2C2066656C69732E20566573746962756C756D206575206E657175652E0A0A43726173206E656320646F6C6F722E20446F6E6563206C616F726565742074656D707573206C65637475732E20437261732073656420746F72746F7220696E74657264756D206C6163757320656C656966656E64206469676E697373696D2E204D616563656E61732073697420616D657420656C69742E204E756C6C616D207175697320646F6C6F722076656C20647569207068617265747261206C75637475732E20496E2073697420616D6574207175616D2073697420616D6574207065646520756C74726963657320756C7472696365732E204D616563656E6173206469616D2E20496E74656765722075726E612E204375726162697475722064696374756D2C2076656C69742073656420706C6163657261742073757363697069742C206572617420747572706973206665726D656E74756D206A7573746F2C2073656420696E74657264756D206E657175652073656D206574206E6962682E20566976616D757320636F6E73657175617420636F6E76616C6C6973206D61676E612E204E616D20616C697175616D2C2065737420616320626962656E64756D20636F6D6D6F646F2C206D61676E61206573742064696374756D206D692C207669746165206D616C65737561646120656C6974206D61676E61207669746165206F64696F2E204D616563656E61732074656D706F722076756C7075746174652074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206475692E20457469616D20616363756D73616E207065646520636F6E67756520746F72746F722E0A0A4D6F7262692074656D706F72206C696265726F206163206C6F72656D2E20496E20616C697175657420766172697573206D61676E612E20496E20617263752E2050686173656C6C7573206F64696F2E2046757363652074696E636964756E7420616C69717565742066656C69732E20517569737175652076656C69742E20536564206C75637475732E20416C697175616D2066657567696174206672696E67696C6C61206D692E20416C697175616D206D6F6C657374696520766976657272612072697375732E2050726F696E20617263752E20566573746962756C756D206C6F626F727469732074656D707573206E6973692E205072616573656E742061206172637520696E2076656C697420766976657272612072757472756D2E0A0A496E20736564206C65637475732E20446F6E656320726973757320646F6C6F722C20626C616E6469742073697420616D65742C20656C656D656E74756D20636F6E76616C6C69732C20706861726574726120717569732C20706564652E20496E7465676572206F726E6172652E2041656E65616E20656765737461732064617069627573206A7573746F2E20536564207175616D206C656F2C20706F73756572652061742C20656C656D656E74756D2076697461652C20636F6D6D6F646F20656765742C206573742E20416C697175616D206D6F6C65737469652072686F6E63757320656E696D2E2043757261626974757220696163756C697320756C74726963657320706564652E204D6F72626920616C69717565742072757472756D206C616375732E20416C697175616D207175616D2E2053656420636F6D6D6F646F2C2074757270697320696E20706861726574726120706F73756572652C206D6920726973757320696D7065726469657420657261742C206120766573746962756C756D206D617373612074656C6C7573207665686963756C612073656D2E204D6175726973206672696E67696C6C6120756C747269636573206E756E632E204E616D206E69736920656E696D2C20656C656966656E642073697420616D65742C20756C747269636573207365642C206665726D656E74756D206E6F6E2C2061756775652E2050726F696E20636F6E677565206C6F626F72746973206E6973692E204D616563656E61732068656E6472657269742E204E616D20736564206E69736C2E204E756E6320656C656D656E74756D206F64696F2065752072697375732E20496E206D657475732E2050686173656C6C75732067726176696461207072657469756D206C6967756C612E204E756C6C61207669746165206E657175652E204E616D206E69736920746F72746F722C206F726E617265206E6F6E2C20626C616E6469742061742C206375727375732065752C20746F72746F722E0A0A4475697320626962656E64756D20697073756D20696E206E756E6320637572737573206D6F6C65737469652E204E756E63206F7263692E204E756C6C616D206E656320616E7465206E6F6E20657374206469676E697373696D20766976657272612E204D617572697320626C616E6469742C2076656C69742069642066657567696174207072657469756D2C20656C6974206D61676E612070656C6C656E74657371756520646F6C6F722C206174207361676974746973206C616375732076656C69742065676573746173206D61676E612E2050656C6C656E746573717565206375727375732C206469616D20636F6E736563746574756572207361676974746973206672696E67696C6C612C20746F72746F72206E6973692061646970697363696E67206E756E632C20657520766172697573206C6163757320726973757320616320656C69742E204D6175726973206964206E6973692071756973206C656F20657569736D6F642076656E656E617469732E2050656C6C656E74657371756520616320616E74652E204D617572697320617263752073617069656E2C2074656D706F722061742C20706F72747469746F722069642C20636F6E64696D656E74756D2075742C206475692E20457469616D206665726D656E74756D20756C747269636965732061756775652E20437261732075742065726F73206174206A7573746F20756C7472696369657320696163756C69732E2044756973206469676E697373696D2C206E69736C20657420666163696C69736973206665726D656E74756D2C2065726174207075727573206D6F6C65737469652074656C6C75732C20717569732074656D70757320697073756D206C656374757320617420656C69742E204E756C6C61207669746165206C6F72656D2E0A0A41656E65616E2076656C2073656D206574206469616D2073656D70657220636F6E6775652E20496E20626962656E64756D206469616D20717569732074656C6C75732E204E756E6320666163696C6973697320756C74726963696573206E6962682E2043726173206E756E6320656E696D2C2066657567696174207365642C20756C7472696365732076697461652C2073616769747469732076697461652C20697073756D2E204675736365207669746165206E756C6C612E20446F6E65632070656C6C656E7465737175652C2076656C697420696E20706F72747469746F7220656C656966656E642C20657374206E65717565206C6F626F727469732076656C69742C2073697420616D65742072757472756D20616E746520746F72746F72206E656320646F6C6F722E20446F6E6563207665686963756C612E204E756C6C6120666163696C6973692E20536564206567657374617320756C747269636573206E6962682E20446F6E656320656C6974206C65637475732C20636F6E76616C6C697320706F72747469746F722C20616C697175657420646170696275732C206665756769617420656765742C206C6967756C612E2053656420636F6E736563746574756572206A7573746F2E204D616563656E617320612073617069656E2073697420616D6574206E6973692064617069627573206C6F626F727469732E20566976616D7573206C7563747573206C6F72656D206E6F6E206E756C6C612E2053656420656765742065726174207669746165206C696265726F20696E74657264756D20706F73756572652E20437261732070756C76696E61722E204E756C6C616D20696D706572646965742C20646F6C6F722074656D706F72206469676E697373696D20626C616E6469742C206475692073617069656E2072686F6E637573206E657175652C206964206D616C657375616461206175677565206D61676E612073697420616D65742075726E612E204475697320736564206D61757269732E0A0A4D6F72626920616363756D73616E2E20536564206D61757269732061756775652C206672696E67696C6C61206E6F6E2C20617563746F722075742C20617563746F722065742C206F7263692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320757420706564652E20446F6E6563207669766572726120656E696D2076656C206C6F72656D2E2050656C6C656E746573717565206E65717565206D61757269732C20696E74657264756D2065752C2076656E656E617469732069642C20636F6E64696D656E74756D2065752C2073617069656E2E20446F6E656320697073756D20617263752C206C6163696E69612061646970697363696E672C206C616F726565742065742C206375727375732076656C2C2076656C69742E205574207361676974746973206D617572697320717569732072697375732E20496E7465676572206575206F64696F207669746165206C61637573207669766572726120616363756D73616E2E204D6F726269206C656F20616E74652C206469676E697373696D207365642C2076617269757320717569732C20766F6C75747061742076697461652C206E6973692E204E756C6C6120706C61636572617420696E74657264756D20656C69742E20446F6E6563206E65717565206475692C2073616769747469732076697461652C20736F6C6C696369747564696E20717569732C20636F6D6D6F646F2076697461652C206E657175652E204E756C6C612071756973206C6967756C61206F726E617265206C6967756C612064696374756D206F726E6172652E204D61757269732072757472756D2072757472756D206E657175652E2041656E65616E207665686963756C612074656D707573206573742E20446F6E656320766172697573207363656C6572697371756520706564652E20446F6E656320706C6163657261742076756C707574617465206C656F2E204E756C6C616D206E756E63206E69736C2C20706F7375657265206E6F6E2C20666575676961742076697461652C2070656C6C656E74657371756520717569732C206D61757269732E20496E20647569206E657175652C2063757273757320656765742C20736167697474697320656765742C20646170696275732076697461652C206D692E2050726F696E2065676574206573742E0A0A467573636520706F727461206573742E204D6175726973206D61676E612E20416C697175616D20697073756D206C616375732C20756C747269636965732069642C20766573746962756C756D206C75637475732C20616363756D73616E2075742C20616E74652E20536564206D61757269732E205365642061646970697363696E67206C656F2073697420616D6574206D61676E612E2053757370656E646973736520706F74656E74692E204E756E63206D6173736120656C69742C206672696E67696C6C6120656765742C20656765737461732076697461652C206C75637475732076697461652C20646F6C6F722E2050686173656C6C75732071756973206E756C6C61206575206E69736920696E74657264756D20736F6C6C696369747564696E2E204E756C6C616D2069642074656C6C75732E20496E746567657220696163756C697320646F6C6F722061632070757275732E205365642076656C206D692E20437572616269747572206E6F6E206D61676E612073697420616D6574206A7573746F20636F6E64696D656E74756D2076756C7075746174652E20517569737175652074696E636964756E742070656465206575206E69736C2E20566976616D7573206C6F626F727469732E204E756E63206D65747573206D657475732C20636F6E677565207365642C2074696E636964756E74207365642C207072657469756D2061742C206F64696F2E20446F6E6563206120617263752E20496E2073656D206A7573746F2C207665686963756C61207365642C207661726975732069642C20766F6C75747061742061742C2072697375732E205072616573656E7420696163756C6973206D617373612E20496E206172637520656C69742C2068656E64726572697420656765742C20756C6C616D636F7270657220696E2C20706F7274612069642C2074656C6C75732E20446F6E65632073616769747469732068656E647265726974206469616D2E0A0A53757370656E646973736520706F74656E74692E20536564206574206469616D206574206175677565207361676974746973206C6F626F727469732E2050686173656C6C757320646F6C6F722E2055742065742061726375206567657420616E74652074656D706F7220706F73756572652E20416C697175616D206665726D656E74756D207363656C65726973717565206475692E204D61757269732061742070757275732E20446F6E656320657261742073656D2C20766573746962756C756D206E65632C2066617563696275732061632C206D617474697320612C206C656F2E2053757370656E64697373652061646970697363696E67206C6163696E69612073656D2E204E756C6C616D206F72636920617263752C2064696374756D2065742C20666175636962757320766976657272612C20646170696275732065742C206E657175652E2043726173206E756E63206469616D2C2061646970697363696E67206E6F6E2C20736F6C6C696369747564696E20696E2C20696E74657264756D2076656C2C206D617373612E204D61757269732073616769747469732C206A7573746F206174207472697374697175652074656D7075732C206D6175726973206D617572697320616C697175616D20616E74652C2073697420616D657420706F7375657265206469616D206475692065676574206C6967756C612E20496E206469676E697373696D2C206E69736C207574206C6163696E696120636F6E64696D656E74756D2C2065726174206A7573746F20706F72747469746F72206E756C6C612C206E6F6E2067726176696461206C6967756C61206D61676E612065676574206D617373612E20566573746962756C756D207669746165206C6967756C61206174206D6920766573746962756C756D2073757363697069742E2044756973206C616F726565742E204E756C6C6120636F6D6D6F646F206C696265726F2073697420616D6574206C6F72656D2E20557420656C656D656E74756D2073656D2E20496E74656765722076656C20646F6C6F722E204E616D20666163696C69736973206D6920717569732073656D20756C7472696365732073616769747469732E205365642071756973207175616D206174206D65747573206D6F6C657374696520626962656E64756D2E0A0A50726F696E2064756920656E696D2C206C6163696E696120612C20666575676961742061632C20706C6163657261742076697461652C20706564652E205175697371756520656765737461732C206C656F206567657420616C697175616D207072657469756D2C206C696265726F206A7573746F2074696E636964756E742065726F732C2075742065676573746173206175677565207065646520656C656D656E74756D206E6962682E20437572616269747572206D6F6C6C697320736F64616C657320656E696D2E20446F6E65632061756775652E2050686173656C6C757320696420697073756D20706F737565726520647569207072657469756D2066617563696275732E204D6175726973206C756374757320616E74652073656D706572206E69736920696E74657264756D2061646970697363696E672E204475697320646170696275732C206F64696F207175697320766976657272612072686F6E6375732C206A7573746F207175616D20626962656E64756D20646F6C6F722C20696420646170696275732076656C697420657261742076656C20657261742E2046757363652073697420616D6574206E69736C2076656E656E61746973207175616D20756C74726963657320636F6E64696D656E74756D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632072686F6E637573207363656C65726973717565206C6967756C612E20566573746962756C756D206D69206F64696F2C20616363756D73616E2065742C2061646970697363696E6720656765742C206F726E6172652075742C207175616D2E204E756C6C616D20626C616E646974206D6F6C6573746965206D61757269732E20437572616269747572206469676E697373696D206D6175726973206574206C6F72656D2E2053757370656E64697373652061206A7573746F2E204E616D206D617474697320666175636962757320617263752E204475697320626C616E64697420656E696D206E6F6E206D617373612E0A0A4E756C6C616D206C6F72656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E204D617572697320636F6E73656374657475657220706F7375657265206D61757269732E204D616563656E61732074696E636964756E74206D617572697320696E2065726F732E204E756C6C61206575206D65747573206575206F72636920736F6C6C696369747564696E2066617563696275732E2053757370656E646973736520616C697175616D206D6175726973206964206573742E204372617320626C616E646974206475692065742075726E612E204E756C6C6120617263752E2053656420612075726E612E204E756C6C612064617069627573207665686963756C6120746F72746F722E20446F6E65632072697375732E20536564207175616D206D657475732C20656765737461732065752C206375727375732075742C2076697665727261206E6F6E2C206F64696F2E205574206A7573746F206A7573746F2C206D616C6573756164612073697420616D65742C20626C616E6469742073757363697069742C206D6F6C657374696520696E2C206A7573746F2E20566573746962756C756D20636F6E7365717561742C207175616D20616320666575676961742074696E636964756E742C20697073756D206C696265726F20656C656966656E64206F64696F2C206E6F6E20656C656966656E64207065646520697073756D206E6F6E20616E74652E204E756C6C616D2061206D657475732E0A0A4E616D206163206E6973692061742066656C697320637572737573206D61747469732E2050656C6C656E74657371756520636F6E7365717561742073656D2071756973206F7263692E20517569737175652074656D7075732E2041656E65616E20696D70657264696574206D6F6C657374696520706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652065752074656C6C75732E204E756C6C61206469616D2065726F732C20736F64616C65732075742C20736F64616C6573206E65632C2074696E636964756E742061632C206E756E632E204E756E63206C6163696E696120666175636962757320697073756D2E20566976616D75732076656C206E6571756520696E2065726174206665726D656E74756D206C75637475732E204E756C6C612065676574206D65747573206E656320617567756520626962656E64756D20706C6163657261742E20566976616D75732074656D7075732E205072616573656E7420636F6E677565206F726E61726520697073756D2E20457469616D206D61747469732066657567696174206A7573746F2E0A0A416C697175616D206475692E2041656E65616E20636F6D6D6F646F20746F72746F72207669746165206E756C6C612E204D6F72626920657420697073756D2E204D617572697320616320697073756D2E204E616D2076656C207269737573207574206C6563747573206D6F6C6C697320766976657272612E2043757261626974757220656C656D656E74756D206D6F6C6C6973206573742E204E756C6C616D20656C69742E20566573746962756C756D207375736369706974207072657469756D20656E696D2E20566573746962756C756D207574206D617373612E2050726F696E206E65632066656C69732E204D616563656E617320677261766964612C2061726375206E656320636F6E7365717561742073616769747469732C2065726F732074656C6C7573207363656C65726973717565206D61757269732C20766974616520616363756D73616E207175616D207175616D207574206E756E632E20496E7465676572206567657420616E74652065752076656C6974206C616F72656574206D616C6573756164612E204E756E632073616769747469732C206D617572697320766974616520706861726574726120766F6C75747061742C2074656C6C75732074656C6C757320656C656966656E642065726F732C2073697420616D65742072757472756D20697073756D206E69736920612076656C69742E205072616573656E7420766172697573206C656F20657520657261742E20566976616D757320636F6E73657175617420706C6163657261742070757275732E20446F6E6563207072657469756D20656C656D656E74756D206E6962682E2050726F696E20617420656C6974206E6F6E2073656D20616C6971756574206D61747469732E2053656420756C6C616D636F7270657220697073756D2073697420616D657420656C69742E0A0A4D617572697320696E206D657475732E2053757370656E6469737365206D61676E61206C6F72656D2C2066617563696275732076656C2C2074696E636964756E7420717569732C207363656C65726973717565206E6F6E2C2074656C6C75732E2046757363652071756973206C6F72656D2E2050726F696E2061206C616375732073697420616D6574206D617572697320696163756C69732070756C76696E61722E2053757370656E64697373652072686F6E6375732065726F73206E6563206D692E205072616573656E7420657569736D6F642C207475727069732076697461652072757472756D207072657469756D2C206F64696F206D6574757320766F6C7574706174206E657175652C20656765742074656D7075732073617069656E206E657175652073656420657261742E20446F6E6563206665726D656E74756D207075727573206174206C65637475732E204E756C6C616D2073656D2E2046757363652076656C206D6920717569732065726174206C6F626F7274697320706F73756572652E2041656E65616E20656765742075726E612E2053757370656E6469737365206C6967756C612E204475697320696E206E6973692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A4375726162697475722076756C707574617465206C656374757320696420706564652E2050686173656C6C75732065752076656C69742E20457469616D2076656E656E617469732061646970697363696E67206E6962682E20416C697175616D206375727375732070756C76696E61722074656C6C75732E20566573746962756C756D206E657175652E204D6175726973206E6563206A7573746F20657420657261742073656D7065722070656C6C656E7465737175652E204675736365206D61747469732064696374756D20646F6C6F722E20457469616D2065676574207075727573206575206D617373612076617269757320656C656D656E74756D2E2050656C6C656E746573717565206D617373612E20557420756C74726963696573206469616D2073656420697073756D2E204E756C6C616D206469616D2E2050656C6C656E746573717565206964206D61676E61206964206C696265726F2074726973746971756520616C697175616D2E0A0A557420656C656966656E642C20707572757320696420706C6163657261742076656E656E617469732C2075726E6120617567756520616C6971756574206C6967756C612C20696E20756C74726963696573206C656F2072697375732065742074656C6C75732E204D6175726973206574206E756C6C612069642075726E61207472697374697175652074656D7075732E20557420666163696C697369732C2075726E6120657520766573746962756C756D2072686F6E6375732C206C616375732065726F7320636F6E736563746574756572206D657475732C2065742072757472756D20647569206C656374757320696E2070757275732E204E756E632076656C206E69736C206E6F6E20697073756D2074696E636964756E74206D6F6C6C69732E204E616D207175616D206C616375732C206F726E6172652076697461652C2072686F6E637573206E6F6E2C20636F6E677565207365642C206F64696F2E2050726F696E206E696268206475692C20706F7274612076656C2C2076656E656E61746973206E6F6E2C2070656C6C656E7465737175652075742C206E6973692E20536564207472697374697175652066656C69732061206D61676E612E2053757370656E646973736520656765742074656C6C75732E2043726173206772617669646120696D706572646965742076656C69742E20496E74656765722068656E6472657269742072697375732E2050726F696E206F7263692E20416C697175616D20756C6C616D636F72706572206D61757269732071756973206D61757269732E204E756E63206C6163696E696120766573746962756C756D206D657475732E20447569732074656C6C75732E204E756C6C616D2066617563696275732C206C656F2061632076756C70757461746520736F6C6C696369747564696E2C206C656F20646F6C6F7220666175636962757320657261742C207175697320626962656E64756D206F726369206F64696F206E6F6E20617263752E0A0A4E756C6C616D20616363756D73616E206D617474697320646F6C6F722E20446F6E6563206574206475692E205072616573656E7420612066656C6973206D6F6C6C6973206C616375732073656D706572206C6163696E69612E204375726162697475722070656C6C656E746573717565206C7563747573206573742E2050726F696E206E756C6C61206475692C20636F6E64696D656E74756D2076656C2C206661756369627573206E6F6E2C20696E74657264756D2061632C20657261742E204D616563656E6173207363656C657269737175652C206C656374757320696420766F6C757470617420616363756D73616E2C2073617069656E20746F72746F722070656C6C656E746573717565206475692C207365642073656D706572206D61676E612073656D207574206C656F2E2050726F696E206E756C6C612E204E756C6C616D206461706962757320756C6C616D636F727065722073656D2E2053757370656E6469737365207665686963756C61206D6574757320696E206E756E632E2050656C6C656E746573717565206E6F6E207175616D2076656C206172637520756C74726963657320756C6C616D636F727065722E2050686173656C6C757320717569732066656C69732073697420616D65742074656C6C757320756C6C616D636F72706572206665726D656E74756D2E20536564207665686963756C6120736F6C6C696369747564696E2075726E612E20437572616269747572207068617265747261207363656C657269737175652072697375732E2050656C6C656E746573717565206964206D617373612071756973206D6574757320616C697175616D20696D706572646965742E20496E206E756E63206C616375732C206665756769617420696E2C206772617669646120656765742C2076656E656E617469732075742C2074656C6C75732E2053757370656E646973736520706F74656E74692E204E616D20636F6E7365717561742061646970697363696E67206475692E20496E206E756C6C61206E6973692C20666575676961742075742C206665726D656E74756D2076656C2C2067726176696461206E65632C20746F72746F722E20496E207365642061756775652E0A0A457469616D20756C6C616D636F7270657220617567756520617420656E696D2E20496E7465676572206469676E697373696D2E20416C697175616D2070756C76696E617220636F6E677565206E756C6C612E204D6F72626920656E696D206D617373612C206672696E67696C6C6120612C20616363756D73616E20656765742C20636F6E64696D656E74756D206E65632C20657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2041656E65616E2070686172657472612E20457469616D20706F72747469746F722070757275732061206D657475732E20416C697175616D20696E74657264756D2073656D2065676574206A7573746F2E205175697371756520766F6C7574706174206C7563747573206573742E2041656E65616E2061756775652E2050686173656C6C757320647569206C65637475732C20756C747269636573206E65632C20636F6D6D6F646F2076656C2C20617563746F722076656C2C206E6973692E20557420756C7472696365732070656C6C656E746573717565206E6973692E20496E74656765722061632076656C69742065742073656D20696D70657264696574206C75637475732E20467573636520766974616520747572706973206964206175677565206D6F6C6C697320636F6E7365637465747565722E0A0A4D616563656E6173206E6563206C616375732E204D616563656E617320636F6E64696D656E74756D206F64696F2065752066656C69732E204D6175726973207574206E69736C207669766572726120657261742066617563696275732061646970697363696E672E20457469616D20656765737461732E204E756E6320657420646F6C6F72207669746165207269737573206469676E697373696D20636F6D6D6F646F2E204D6F726269206C65637475732076656C69742C2074696E636964756E74206E65632C20616C69717565742076656C2C206D61747469732076697461652C206C6967756C612E204D616563656E617320756C747269636965732073656D70657220646F6C6F722E2053757370656E6469737365206D616C6573756164612E20496E7465676572206D617474697320656C69742E20446F6E656320616363756D73616E2C206C6163757320666163696C69736973207661726975732074656D7075732C206E756C6C6120656C697420706F72746120657261742C2065742072757472756D20656C69742073656D2073697420616D6574206475692E0A0A4D616563656E6173206D6F6C6C6973206D69206E6F6E206E756C6C612E20566976616D7573207475727069732E2053757370656E64697373652061206D657475732E20496E2071756973206D6920696E2074757270697320636F6E67756520617563746F722E204D616563656E6173206C616375732E2053757370656E646973736520736F6C6C696369747564696E2E2050686173656C6C757320706F727461206E756E63206E6F6E206E69736C2070756C76696E617220656765737461732E20536564206E756C6C612E20566573746962756C756D206163206D692E204D617572697320756C7472696369657320636F6E64696D656E74756D206E657175652E204E756C6C612074656D707573206A7573746F2076656C206D617373612E204E756C6C6120737573636970697420636F6E67756520617263752E205072616573656E74206964207475727069732E204D6175726973206E69626820706564652C20657569736D6F642073656D7065722C206D6F6C65737469652061632C2072686F6E6375732076697461652C20616E74652E204D616563656E617320657261742066656C69732C207669766572726120736F6C6C696369747564696E2C20736167697474697320656765742C2070656C6C656E746573717565206E65632C206F7263692E20467573636520756C74726963657320636F6E736571756174206C616375732E20416C697175616D2065726174206D61676E612C20666575676961742061742C207669766572726120612C206D6F6C6C6973206E6F6E2C207475727069732E0A0A446F6E6563206D692E204E616D2064696374756D2070656C6C656E7465737175652073656D2E20446F6E6563206D6F6C6C69732072686F6E63757320656C69742E2050686173656C6C75732072686F6E63757320706564652073697420616D65742072697375732E20446F6E656320656765742061756775652E204D616563656E6173206E6F6E206C65637475732E2050686173656C6C757320736F6C6C696369747564696E206E697369206E65632066656C69732E20416C697175616D207072657469756D2C2065737420656765742073656D70657220636F6E76616C6C69732C206E696268206E756E6320736F6C6C696369747564696E2070757275732C2069642074656D706F722070656465206475692076656C206D61676E612E20566976616D7573206163206C6F72656D2E20457469616D206E69736C20746F72746F722C2061646970697363696E672064696374756D2C20656C656D656E74756D20696E2C20666163696C69736973207365642C206E6962682E2050726F696E206D61757269732E2050726F696E2072757472756D206D6173736120656765742073656D2E204375726162697475722074656D706F722061646970697363696E6720656C69742E204375726162697475722070757275732074656C6C75732C206665726D656E74756D20656765742C20616C69717565742076697461652C20636F6E76616C6C69732061632C206D61757269732E0A0A496E746567657220636F6E7365717561742076656C69742065752065726F732074696E636964756E74207665686963756C612E204E756C6C616D206C6F72656D2073617069656E2C2072686F6E637573206E6F6E2C206D617474697320717569732C20756C747269636965732073697420616D65742C20656E696D2E2043757261626974757220636F6D6D6F646F2C206C696265726F20696E20657569736D6F642073757363697069742C2073656D207075727573206672696E67696C6C6120656E696D2C206163206D6F6C657374696520746F72746F72206F7263692065742076656C69742E20446F6E656320706564652E20457469616D20706C61636572617420636F6E64696D656E74756D207475727069732E2050686173656C6C7573206567657374617320656E696D206E6563206D61676E612E20566976616D757320636F6E64696D656E74756D2C206E756C6C612076656C206C7563747573207472697374697175652C2065726F7320726973757320766573746962756C756D206E756C6C612C20696E207665686963756C61206172637520697073756D2061742066656C69732E20446F6E656320616C697175616D20656C69742061742061756775652E205175697371756520612065726F73206575206C6967756C6120616363756D73616E2064696374756D2E20457469616D207665686963756C61207475727069732071756973206C696265726F2E20416C697175616D206E6F6E206D692E20446F6E6563206574206C656F2E2050726F696E206C656F206C696265726F2C20616C697175616D2074696E636964756E742C20636F6E677565206E65632C2061646970697363696E6720706F7274612C20656E696D2E204E756C6C61206C6F626F727469732C20746F72746F722073697420616D657420696D7065726469657420756C6C616D636F727065722C20646F6C6F72206F726369206D616C65737561646120706564652C207365642067726176696461206E6962682075726E612076656C206C6F72656D2E20536564207068617265747261206D616C6573756164612065726F732E205175697371756520657569736D6F6420616C697175657420657261742E2053757370656E646973736520616C6971756574206D61747469732070757275732E0A0A4E756E63206964206E756C6C612071756973206A7573746F20636F6E67756520736F6C6C696369747564696E2E205072616573656E742065726174207475727069732C2072686F6E6375732065752C207072657469756D2065752C2070656C6C656E74657371756520612C206E6962682E20566976616D75732074656D7075732E2043726173206E65632072697375732061742074757270697320696D70657264696574206C6F626F727469732E205574206D61747469732E204D616563656E6173206573742066656C69732C2070656C6C656E746573717565206E6F6E2C20696D70657264696574207365642C20656C656966656E642074696E636964756E742C206C6F72656D2E20496E2074696E636964756E742E205365642076656C206C656F2E20446F6E65632065742075726E6120696E207475727069732068656E64726572697420626C616E6469742E20446F6E656320636F6E64696D656E74756D20616363756D73616E206573742E2055742070686172657472612C206D65747573207669746165206D617474697320636F6E7365637465747565722C206C656F207175616D2076756C707574617465206F64696F2C206E6563206C616F72656574206E6973692076656C697420657520657261742E20496E7465676572206C65637475732061756775652C206567657374617320696E2C20696E74657264756D2065752C2076656E656E617469732076656C2C2073617069656E2E2051756973717565206574206573742076697461652065726F73206C616F72656574206C6F626F727469732E204E756C6C616D207574207269737573206E6F6E206E756C6C6120706C6163657261742061646970697363696E672E205072616573656E7420646170696275732E20457469616D20612066656C69732E20557420736F64616C657320636F6E736571756174206D61757269732E2044756973206C6F72656D2066656C69732C206C756374757320612C2074726973746971756520696E2C206D6F6C65737469652061742C2072697375732E20536564207665686963756C6120626962656E64756D2074656C6C75732E204E616D20636F6E73657175617420657569736D6F64206C616375732E0A0A41656E65616E20746F72746F7220656C69742C2067726176696461206E65632C206665726D656E74756D2065752C206C6F626F727469732069642C20697073756D2E204D616563656E61732065752070757275732E204372617320616320747572706973207574206E69736920696163756C69732072686F6E6375732E204E756C6C61207075727573206D657475732C206469676E697373696D206E65632C2074696E636964756E742076697461652C20646170696275732065752C206E6962682E204675736365206C6F626F727469732C206E756E63206174207669766572726120656C656966656E642C206A7573746F20747572706973207363656C657269737175652065726F732C2061632070656C6C656E746573717565206D65747573206E69736C2061742070757275732E2053656420656C656D656E74756D2074656C6C75732073656420656E696D20696E74657264756D20626C616E6469742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E746567657220756C7472696369657320616C6971756574206F64696F2E204D61757269732065676574206E756E63206120697073756D20756C74726963657320736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2041656E65616E20616363756D73616E2E20446F6E65632073617069656E206C65637475732C20636F6E6775652061742C20706F7274612069642C2068656E6472657269742076697461652C206E69736C2E204375726162697475722076656C207175616D2076656C206E6571756520616363756D73616E206C616F726565742E204D6F7262692073617069656E206573742C207072657469756D20696E2C20636F6E7365637465747565722061632C206D6F6C6C69732075742C206C696265726F2E20446F6E65632074696E636964756E742061646970697363696E67206D657475732E204E756E6320766573746962756C756D20656765737461732061756775652E20446F6E6563207363656C65726973717565206475692075742073656D2E2053757370656E64697373652076656C206D6574757320696420657374206D6F6C657374696520696163756C69732E0A0A566976616D75732070686172657472612C20656C6974206575206D616C65737561646120626C616E6469742C206469616D20746F72746F72206D6F6C6C6973206475692C207365642070756C76696E6172206D61737361206E756E63206574206D61676E612E2053656420706C61636572617420656C697420617563746F7220746F72746F722E204E756C6C6120616320657261742E2050656C6C656E74657371756520636F6E7365637465747565722C2064756920636F6E76616C6C69732074696E636964756E7420636F6E64696D656E74756D2C2073656D206F64696F20766F6C7574706174206C696265726F2C206E6F6E20656C656D656E74756D2066656C6973206E65717565206E6563206F64696F2E204D616563656E61732068656E6472657269742065726F73206964206469616D2E204D61757269732076656C207075727573206163206F72636920636F6E76616C6C697320636F6E76616C6C69732E205365642073697420616D6574206C616375732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652064696374756D20766172697573206C616375732E204D61757269732065676574206E69736C2E2053757370656E646973736520706C6163657261742C206E756C6C61206E6F6E206F726E617265206469676E697373696D2C206E69736C206469616D2073616769747469732074656C6C75732C20696E2073656D706572206E69736920646F6C6F72206174206E6962682E204475697320756C6C616D636F7270657220766976657272612066656C69732E20496E746567657220612074656C6C75732E2053757370656E64697373652065676574206E756E632E2041656E65616E206469616D206573742C20616363756D73616E2069642C20737573636970697420696E74657264756D2C206672696E67696C6C612076697461652C206A7573746F2E2050726F696E20706564652E204D616563656E6173206174206E6571756520696E206E6571756520766573746962756C756D20656C656966656E642E0A0A566573746962756C756D206E756C6C61206C6F72656D2C20706F72747469746F7220656765742C20657569736D6F642061632C20616C697175616D2061742C206E69736C2E204D616563656E6173206574206573742065676574206D6173736120766172697573206C6F626F727469732E20496E206D692E204475697320706F72747469746F72206665726D656E74756D2070757275732E20446F6E65632063757273757320696D70657264696574206C6967756C612E204D6F726269206574206C6967756C6120657420616E7465206D6F6C6573746965207665686963756C612E204D61757269732073656420646F6C6F722E2053656420696D706572646965742066656C69732075742073656D2E20536564207669746165206E6571756520656C656D656E74756D206C656F20617563746F72206665726D656E74756D2E2044756973206665756769617420756C6C616D636F7270657220657261742E2041656E65616E2070757275732E204D6F726269206665726D656E74756D20766573746962756C756D206573742E2050656C6C656E7465737175652076656E656E61746973206D61757269732E2050686173656C6C75732070756C76696E61722E20496E746567657220697073756D206C65637475732C20696163756C697320612C206C6163696E69612069642C20616363756D73616E2069642C20617263752E2050686173656C6C7573206174206573742E204675736365206E65717565207175616D2C20756C747269636965732069642C20696163756C69732076656C2C20646170696275732076697461652C206C616375732E20496E206C6F626F7274697320636F6E76616C6C697320616E74652E204E756C6C61206E756E632070757275732C2076756C70757461746520696E2C2068656E6472657269742065742C20626C616E6469742065742C206C6967756C612E0A0A50656C6C656E746573717565206C656F206D657475732C20736167697474697320696E2C206D6F6C65737469652076697461652C2064696374756D20696E2C20706564652E204D6F726269207072657469756D2066656C6973206E6563207175616D2E2050656C6C656E746573717565206D617474697320616E746520736564207175616D20736167697474697320646170696275732E2053757370656E64697373652073617069656E2E205072616573656E7420626962656E64756D20696163756C697320746F72746F722E20447569732061206E69736C2E2041656E65616E206D692E20446F6E65632064696374756D206172637520696E206573742E204D6F72626920696E74657264756D2076756C70757461746520697073756D2E2041656E65616E2073697420616D6574206D61676E61206E6F6E206E69736C2074726973746971756520706F73756572652E2050686173656C6C75732076656C6974206D657475732C2074656D706F722061632C206665726D656E74756D20656765742C20636F6E64696D656E74756D206E6F6E2C2076656C69742E20566573746962756C756D2073697420706F73756572652E0A0A4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204372617320616C6971756574206D61737361206E6563206475692E20437261732061726375206E756E632C2068656E6472657269742061632C20656C656966656E642065752C20756C6C616D636F72706572206E65632C2074656C6C75732E205365642070686172657472612070757275732073697420616D6574207175616D2E20437572616269747572206D6F6C6C69732E204E616D20766974616520706564652E20457469616D207269737573206D617373612C207665686963756C612073697420616D65742C207068617265747261206E65632C20736F6C6C696369747564696E2075742C206475692E20446F6E65632065676573746173206A7573746F206174207175616D2E2050726F696E206E69736C2072697375732C20766573746962756C756D206E65632C207072657469756D2076697461652C207472697374697175652061632C206C6F72656D2E20416C697175616D206572617420766F6C75747061742E204372617320736564206E6962682E2050656C6C656E74657371756520736F6C6C696369747564696E20657569736D6F642061756775652E0A0A457469616D206672696E67696C6C6120736F6C6C696369747564696E206F7263692E204D61757269732063757273757320656C69742071756973206C616375732E204372617320746F72746F722E20496E2061646970697363696E672C206C656374757320696420617563746F7220766573746962756C756D2C206E65717565207065646520616363756D73616E20646F6C6F722C206E6F6E20696D70657264696574206D61676E61206469616D20616363756D73616E2076656C69742E2053757370656E6469737365206174206C696265726F207574206E69736920626C616E6469742073616769747469732E2050686173656C6C7573206E6F6E206D61757269732E20467573636520656C656D656E74756D2073616769747469732073656D2E2053757370656E646973736520616C697175616D20656C656966656E642074656C6C75732E2050726F696E206C6967756C61206C6F72656D2C20696D7065726469657420717569732C2076656E656E617469732069642C20696163756C6973206D6F6C6C69732C206E69736C2E20457469616D20636F6E76616C6C69732070656465206174206D617373612E204D6F72626920616363756D73616E20647569206574206D61757269732E0A0A53656420736564206F7263692E204E756E632070757275732E2053757370656E646973736520706F74656E74692E205574206C7563747573206672696E67696C6C61206D61757269732E20446F6E6563206E6962682E2050686173656C6C757320706F7274612E2050686173656C6C75732073697420616D6574206F64696F20736564206D61676E6120736F64616C65732070686172657472612E2043726173206C65637475732E2053757370656E6469737365206C696265726F20697073756D2C20636F6D6D6F646F206E65632C20666163696C6973697320696E2C207375736369706974206C6F626F727469732C206C6967756C612E2044756973206D61737361206E756C6C612C2073656D7065722065742C20636F6E736571756174206E65632C2070686172657472612065752C20656C69742E20566976616D757320756C7472696369657320616C697175616D206F64696F2E20566573746962756C756D2073697420616D6574206D617373612E2053656420636F6E736571756174206C61637573207365642075726E612E20457469616D2066617563696275732066656C69732076656C206F7263692E2050686173656C6C757320756C6C616D636F727065722E2041656E65616E20636F6E736563746574756572206C61637573206174206C696265726F2E0A0A436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204475697320666163696C697369732C206C6967756C6120766974616520636F6E64696D656E74756D207363656C657269737175652C2076656C6974206F72636920677261766964612066656C69732C2076656C20756C74726963696573207175616D206D69206E6F6E206469616D2E20566976616D757320617563746F72206D65747573206E6F6E206C696265726F2E205072616573656E74206C6967756C61206E6973692C20636F6D6D6F646F20636F6E64696D656E74756D2C206D6F6C65737469652065742C20766976657272612065742C206A7573746F2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320736F6C6C696369747564696E2E204E756E6320626C616E6469742063757273757320697073756D2E2041656E65616E206E6563206C6967756C612075742074656C6C757320736F64616C6573206D61747469732E20496E74656765722073656D2E20416C697175616D206964206C6967756C612E2053656420746F72746F72206D61757269732C20626C616E6469742076697461652C206375727375732076656C2C20656C656D656E74756D2065742C206E756C6C612E20416C697175616D207363656C65726973717565206D65747573206574206E69736C2E20447569732061646970697363696E67206D61676E61206174206E657175652E20517569737175652076756C70757461746520656C656966656E64206E756E632E20416C697175616D206567657420656C69742E2050686173656C6C757320647569206F64696F2C20626962656E64756D2073616769747469732C20766573746962756C756D2069642C206469676E697373696D20696D706572646965742C206F7263692E204E756C6C616D2065752066656C6973206E6F6E206E756E63206C6163696E696120736F64616C65732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A53757370656E64697373652070656C6C656E7465737175652C206C696265726F206D617474697320756C7472696369657320616363756D73616E2C20746F72746F7220746F72746F72206D616C6573756164612073656D2C20657420736F64616C6573206C696265726F206F64696F20616320697073756D2E20566976616D75732071756973206D61676E61206E656320657374207375736369706974206C6F626F727469732E20437261732074656D70757320706F7375657265206E756E632E205175697371756520757420656E696D20612066656C697320656765737461732073656D7065722E20536564207068617265747261206D6174746973206E657175652E20467573636520747572706973206E756E632C20636F6E677565207365642C20636F6E736571756174206E6F6E2C20636F6E677565207365642C206E756C6C612E2053757370656E646973736520766172697573206C6F72656D20696420726973757320706F72746120766573746962756C756D2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204675736365207365642070757275732E20496E20612066656C69732E20496E7465676572206567657374617320617563746F72206F7263692E204D617572697320756C747269636573207375736369706974206E69736C2E204E756C6C616D2070757275732E0A0A437261732074656D706F722061646970697363696E6720697073756D2E2055742071756973206D692E204D616563656E617320696E206A7573746F207574206E756C6C6120636F6E6775652070686172657472612E2050656C6C656E746573717565207574206C696265726F20657520646F6C6F722076656E656E617469732073757363697069742E205072616573656E74206665756769617420636F6E736563746574756572206E6962682E204D6F7262692066617563696275732073656D206E6F6E2066656C69732E20496E2068656E6472657269742061726375206163206D617373612E20496E20616363756D73616E20756C747269636573206D692E2050726F696E206D616C65737561646120617563746F722066656C69732E2043757261626974757220696E74657264756D2E20536564206469616D20697073756D2C20756C7472696369657320696E2C2074656D706F722073697420616D65742C207669766572726120696D706572646965742C20656C69742E204D6F726269206D6F6C6573746965206E6973692E204D617572697320697073756D2E2046757363652064696374756D206D6F6C6C6973206D61676E612E204475697320636F6D6D6F646F206469676E697373696D206E756C6C612E20566573746962756C756D20617567756520656E696D2C20756C7472696369657320717569732C20696163756C6973206E65632C2074696E636964756E742076697461652C206469616D2E204D6175726973206C6163696E69612074656D70757320697073756D2E20536564206174206D61757269732E205574206C6F72656D2E20446F6E6563206C696265726F2E0A0A4475697320696163756C6973206C6163696E6961206C65637475732E2041656E65616E20636F6E76616C6C69732065726F7320616320616E74652E205365642071756973206F726369206E656320726973757320617563746F72206672696E67696C6C612E2050686173656C6C757320666163696C6973697320656C656D656E74756D206E6973692E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E6320706F727461206C61637573206E656320616E74652E204D6F726269206D617572697320657261742C2061646970697363696E6720696E2C2070756C76696E6172206E65632C206C6F626F72746973206E65632C206F64696F2E20557420656C656966656E64206C656374757320736564207175616D2E204E756C6C616D206D6F6C6C69732E20496E206E6F6E20747572706973206574206E69736C2068656E64726572697420626C616E6469742E204475697320656C656D656E74756D2E204E756E63206E6563206C696265726F2E2053757370656E646973736520766573746962756C756D207269737573206E6F6E20706564652E204D6F72626920696D70657264696574206F64696F2073697420616D6574206C696265726F2E2053656420736564206D6173736120766974616520697073756D206D61747469732074696E636964756E742E204E756C6C61206E656320746F72746F72207669746165206C696265726F20766F6C75747061742074656D7075732E20446F6E656320616C697175616D2E0A0A4475697320736564206E756E632E2043757261626974757220747572706973206E756C6C612C207665686963756C61207365642C206C756374757320717569732C20656C656D656E74756D20656765742C2066656C69732E204D616563656E61732065742070757275732E204D616563656E6173206C656F2074656C6C75732C2074696E636964756E7420612C20666163696C697369732076697461652C206C6F626F727469732073697420616D65742C2076656C69742E20446F6E656320636F6E76616C6C69732073617069656E2E204D616563656E6173206D6F6C6C6973206F64696F206575206E6962682E20457469616D20677261766964612E20496E7465676572206D6F6C65737469652C2073617069656E206575206D6F6C6573746965206C6163696E69612C206E756E63206E69626820616C697175616D206C6967756C612C2065752073616769747469732074656C6C7573206572617420736F6C6C696369747564696E206F64696F2E20447569732065742072697375732E2050686173656C6C7573206E697369206E657175652C20706C616365726174206E65632C20636F6E64696D656E74756D206E6F6E2C20756C7472696365732065752C2073656D2E20557420706564652E20457469616D206E756C6C61206D657475732C20766F6C75747061742069642C20636F6E76616C6C6973207365642C2073757363697069742076656C2C2075726E612E20446F6E65632076656C20656C69742E205574206C656F206E657175652C2076656E656E617469732066617563696275732C206C6163696E6961206E65632C2074696E636964756E742065752C20656E696D2E2043726173206964206475692061206C696265726F207068617265747261206469676E697373696D2E20446F6E65632065726F73206C656F2C20706F72746120717569732C206C616F726565742075742C2070656C6C656E74657371756520766F6C75747061742C206C65637475732E0A0A4E756C6C616D20626C616E6469742E20416C697175616D206572617420766F6C75747061742E2046757363652061646970697363696E6720656E696D2E2053757370656E6469737365206E6F6E206475692071756973206C6967756C6120706F72746120766573746962756C756D2E20446F6E65632065752074656C6C75732076656C206C6F72656D207072657469756D20706F72747469746F722E205072616573656E74206C75637475732E20416C697175616D2061632065726F7320696E206D6173736120646170696275732074696E636964756E742E20446F6E6563207574206D61676E612E20457469616D20617563746F72206C616375732073697420616D6574206C616375732E2053656420756C7472696369657320697073756D206E656320656C69742E205175697371756520612065737420696E207075727573207375736369706974207472697374697175652E0A0A41656E65616E20736564206475692076656C20646F6C6F722070756C76696E6172206C616F726565742E20566976616D7573207665686963756C61206C6F72656D20696E20706564652E20566976616D7573206574206469616D2E20496E7465676572206163206F64696F2076656C206469616D2068656E64726572697420626962656E64756D2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E756C6C612061206E6973692E2050686173656C6C75732074696E636964756E74206475692076697461652061756775652E20447569732066617563696275732C2064756920696E74657264756D206672696E67696C6C612074696E636964756E742C206F64696F20656C697420766573746962756C756D206C696265726F2C206163206D6F6C6573746965206D61676E61206C6563747573206964206C616375732E2041656E65616E206C6967756C612E204E756C6C6120666163696C6973692E0A0A46757363652076656C2073656D2065752076656C6974206672696E67696C6C61206F726E6172652E2053656420666575676961742074696E636964756E742066656C69732E204E756C6C616D2066656C6973206D692C20657569736D6F642073697420616D65742C206D6F6C6C69732061742C20736F64616C657320656765742C2061756775652E204E616D20696D70657264696574206E6962682061742076656C69742E2053656420757420657261742E20496E206475692E204E756C6C6120666163696C6973692E204E756C6C616D206175677565206C696265726F2C2074696E636964756E74206E65632C207072657469756D2065752C2070756C76696E617220696E2C206475692E204D6F7262692076697461652066656C69732E2050656C6C656E7465737175652076656C206A7573746F2076656C2076656C6974207361676974746973206D616C6573756164612E2050726F696E207665686963756C6120626C616E646974206D617373612E20457469616D2074696E636964756E742070686172657472612075726E612E20496E206D65747573206573742C20617563746F72206E65632C20626C616E64697420612C20637572737573206E65632C207175616D2E204D6175726973206163206D657475732061206C696265726F20636F6E6775652066617563696275732E204D6175726973206D617572697320646F6C6F722C20736F64616C657320696E2C206375727375732075742C20736F64616C65732072757472756D2C2065726F732E2051756973717565206D61757269732065726F732C2073616769747469732076697461652C206C6F626F727469732075742C20656C656966656E642069642C206E6973692E0A0A41656E65616E206E657175652E20566573746962756C756D20656765737461732070656C6C656E746573717565206C6967756C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2050686173656C6C7573207361676974746973206A7573746F2076656C2072697375732E20536564207072657469756D206E657175652076697461652075726E612E2050656C6C656E74657371756520636F6E677565206C696265726F206964206C6F72656D2E204D6175726973206C656F206C6F72656D2C20626C616E6469742073697420616D65742C20636F6E76616C6C697320717569732C20636F6E736563746574756572207365642C2065726F732E204D61757269732074696E636964756E742C20656E696D2061206772617669646120657569736D6F642C206D61676E61206E756C6C61206665726D656E74756D206C696265726F2C207669766572726120656765737461732076656C6974207175616D20657420746F72746F722E20566976616D757320616C6971756574206D61737361207669746165206A7573746F2E204E756C6C6120636F6E677565206C6163757320616320656C69742E0A0A50686173656C6C757320636F6D6D6F646F207175616D2076656C206C6967756C612E2050726F696E206E6F6E206D657475732061742065726F732070756C76696E6172206C75637475732E204D6175726973206469616D206C6F72656D2C20706F737565726520717569732C20677261766964612065742C2074696E636964756E74206E65632C206C6967756C612E20536564206469616D2E20416C697175616D20656C6974206C65637475732C2068656E6472657269742075742C20696D706572646965742073697420616D65742C207072657469756D2073697420616D65742C20697073756D2E204D6175726973207665686963756C61206E69736C20696E206475692E204375726162697475722065676574207175616D207574206D61676E6120656C656D656E74756D206665726D656E74756D2E204D6175726973207363656C657269737175652E2051756973717565206C616F726565742E20457469616D2074656D707573207475727069732E2050656C6C656E746573717565206175677565207175616D2C2068656E647265726974207365642C2074696E636964756E742061742C2070686172657472612061742C206E69736C2E20416C697175616D206C616375732E2053757370656E646973736520706F74656E74692E2041656E65616E2076656C6974206C696265726F2C20756C74726963657320696E2C206C6163696E69612065752C206C75637475732076656C2C20616E74652E20457469616D2064696374756D206D6920696E2066656C69732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20467573636520677261766964612064617069627573206E69736C2E2043726173207669746165206E69736C2E0A0A4D616563656E6173206469676E697373696D2C206C6967756C61206E6F6E20706F727461206375727375732C20656E696D206E756E63206D616C6573756164612073656D2C20657520706F72747469746F72206E756C6C612075726E61206575207175616D2E2046757363652065726F732E20416C697175616D2065726F732E204E616D20617563746F722E204E756C6C61206D6F6C657374696520706F727461206573742E2053757370656E646973736520706F74656E74692E20566976616D7573206D6F6C6573746965206C6F72656D2073656420657261742E20536564206567657420697073756D2E20496E746567657220616C697175616D2070756C76696E6172206E756C6C612E204372617320616C69717565742073656D207574206E756E632E2046757363652066617563696275732074656D707573206C65637475732E204372617320736F64616C65732C206E69736920616320666163696C6973697320756C7472696365732C2065726F73206172637520646170696275732073617069656E2C20657420756C747269636573206D61757269732074656C6C7573206E6F6E20646F6C6F722E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20437261732063757273757320766172697573206D657475732E205574207475727069732E20566976616D7573206567657420746F72746F722E0A0A536564206C616F726565742C2076656C6974206E6F6E20616363756D73616E206375727375732C206E756E632075726E6120706F7375657265206A7573746F2C20696E2064696374756D206C6563747573207065646520696420616E74652E20437261732076756C7075746174652E204372617320636F6E677565206475692073656420656C69742E2050726F696E206C616375732073656D2C20756C7472696365732061742C20636F6E73657175617420696E2C2074656D706F7220717569732C206D657475732E2050726F696E2076656C20617263752E204E616D20657569736D6F642068656E64726572697420656C69742E20557420657261742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2053656420706F73756572652E204D6F7262692065726F732075726E612C2073656D7065722061742C2073656D706572206E6F6E2C20636F6E76616C6C697320717569732C2076656C69742E204D616563656E6173206F7263692E20566573746962756C756D206C6F626F7274697320747269737469717565206D657475732E20566573746962756C756D206C6F72656D206E756C6C612C20736F6C6C696369747564696E2076697461652C20636F6E64696D656E74756D20717569732C20617563746F722075742C206475692E20566976616D757320766573746962756C756D206D61676E61207574206E6973692E2043757261626974757220656C656966656E64206475692076656C206E756E632E20437572616269747572206D6175726973206C616375732C206D616C6573756164612073697420616D65742C207375736369706974207365642C2072757472756D206C75637475732C2074656C6C75732E20496E746567657220666163696C697369732075726E61207669746165206C65637475732E0A0A41656E65616E207175616D206C656F2C206C6F626F7274697320717569732C206D616C6573756164612065752C2076756C7075746174652076697461652C206E69736C2E205072616573656E7420656765742065726F732E205574206665726D656E74756D20747572706973206964207175616D2E204E616D20746F72746F722E205072616573656E74206E6563206F7263692E204E756C6C6120626962656E64756D2061646970697363696E672061756775652E20557420636F6D6D6F646F2C206D61676E61206964206D616C65737561646120677261766964612C206175677565206F64696F206D616C657375616461206D692C20706F727461206D616C65737561646120656C697420657374207669746165206469616D2E204D6175726973206E6F6E206E756C6C612E2053757370656E64697373652074696E636964756E742C206E756E6320756C7472696369657320706F7274612076656E656E617469732C206D6920706564652074696E636964756E74206C696265726F2C20656765742076617269757320616E7465206C696265726F207574206C6967756C612E20437572616269747572207072657469756D20706F72747469746F7220746F72746F722E0A0A4D616563656E617320766974616520656C69742065676574206E69736920646170696275732064696374756D2E204E756E6320696E206C696265726F2E204E756C6C612064696374756D206F726369206575206572617420617563746F72206C6F626F727469732E2050686173656C6C75732072697375732E2053757370656E646973736520706F74656E74692E2053757370656E646973736520706F74656E74692E205072616573656E742061646970697363696E6720636F6E73657175617420656C69742E20496E74656765722069642061756775652E205072616573656E7420696E206A7573746F206E6563206D61676E6120646170696275732070756C76696E61722E2044756973206E69736C2E2053757370656E6469737365206163206F64696F2E20566976616D757320696D706572646965742E20446F6E6563206E6F6E2076656C69742073697420616D6574207269737573206469676E697373696D20636F6E6775652E204E616D20616C697175657420706F73756572652076656C69742E2043726173207475727069732E204D6F726269206D616C657375616461206469676E697373696D206D692E0A0A536564206C656F206E657175652C2076617269757320717569732C2076656E656E61746973207365642C207068617265747261207365642C206573742E204D6F72626920626C616E6469742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D2073656D7065722070656C6C656E746573717565206D692E2055742076656C206C6F72656D2E204E756E63206D6920746F72746F722C206C616F726565742061742C2066617563696275732065752C2074696E636964756E742073697420616D65742C20657261742E20447569732074656D706F72206D616C65737561646120697073756D2E2050686173656C6C757320616C69717565742E20446F6E656320657420656C69742E2050656C6C656E7465737175652070757275732E20566573746962756C756D2072757472756D2073656D706572206E6962682E204E756C6C6120666163696C6973692E2050686173656C6C757320657420656E696D2073697420616D657420616E746520766573746962756C756D207665686963756C612E2050686173656C6C7573206964206E69736C2E20446F6E6563206D6F6C6C6973206C656F2061742065726F732E204D61757269732070656C6C656E746573717565206E657175652061742070757275732E204D6F726269207175697320646F6C6F7220617420697073756D207363656C6572697371756520736F64616C65732E20457469616D20766F6C7574706174207475727069732061206D657475732E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206C6F72656D206C6F72656D2C20766573746962756C756D2061632C20657569736D6F6420656765742C20756C6C616D636F72706572206469676E697373696D2C2076656C69742E0A0A43756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204372617320756C7472696365732C206E6962682076656C20616C697175616D20766573746962756C756D2C2065726F7320656E696D2076656E656E61746973206475692C20696420696163756C697320656E696D206E756E632076656C206D617373612E204D6F72626920656C656966656E64206F726369206574206D617373612E20416C697175616D206572617420766F6C75747061742E204E756C6C61206D6F6C6C69732065676573746173207475727069732E20496E20736F64616C6573206E756E63206567657420746F72746F722E2053656420697073756D2065726F732C2074656D706F7220717569732C20616C69717565742076697461652C20696D70657264696574206E6F6E2C206C6F72656D2E2050656C6C656E746573717565207175697320656C6974206964206D69206C756374757320646170696275732E20536564206E756E6320617263752C2072686F6E637573206E65632C20636F6E76616C6C697320717569732C206375727375732061742C206E657175652E204D617572697320636F6E76616C6C697320707572757320617420657261742E2050656C6C656E74657371756520766573746962756C756D2E20566976616D7573206672696E67696C6C6120656C697420617420617263752E204E756C6C616D20616C697175657420656E696D206E656320617263752E204E616D20696420746F72746F722E204E756C6C612071756973206E756E632E20557420617263752E2053757370656E646973736520706F74656E74692E2050656C6C656E74657371756520756C6C616D636F72706572206C6967756C6120696420617263752E0A0A4E616D206E6F6E206C696265726F207669746165206E69736C207363656C65726973717565206672696E67696C6C612E20517569737175652076617269757320616E7465206964206D657475732072686F6E637573206672696E67696C6C612E204E756C6C6120666163696C6973692E205072616573656E7420656C656966656E6420706F72747469746F72206C6967756C612E20457469616D207175697320646F6C6F72206E6F6E20617567756520636F6D6D6F646F20617563746F722E20446F6E65632061206D692E20566573746962756C756D2074656D706F722E20446F6E65632066656C69732075726E612C20617563746F722061742C206375727375732064696374756D2C20677261766964612069642C20617263752E2041656E65616E2064696374756D206D616C65737561646120646F6C6F722E20566976616D7573206D61747469732E2050686173656C6C757320657520706564652E2046757363652061646970697363696E67206A7573746F206672696E67696C6C61206D657475732E20457469616D20616E74652E20496E7465676572206D6F6C6C6973206D617373612071756973206E756E632E20496E74656765722064696374756D206E65717565206C756374757320656E696D2E0A0A536564206575206C696265726F2E20496E74656765722074656D706F72206C6967756C6120696E2076656C69742E2055742074696E636964756E74206C6163696E69612073656D2E204E756C6C616D2076656C2072697375732E2053656420736F64616C657320616E7465206120646F6C6F722E204375726162697475722065726F732E2053656420736F64616C65732E20536564206E6F6E206D657475732E20566573746962756C756D20656C656D656E74756D20666175636962757320616E74652E204E756C6C612076656C206E6962682E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206E6563206C6F72656D20757420697073756D206C6163696E696120696163756C69732E204475697320657261742E20416C697175616D20657261742E204372617320696163756C69732E20496E206861632068616269746173736520706C617465612064696374756D73742E0A0A4E756C6C616D20616E74652E2043726173207669746165206573742E2050656C6C656E7465737175652076656C206D657475732061206C6967756C612064617069627573206D61747469732E2044756973206665756769617420616C69717565742066656C69732E20457469616D206964206E69736C207175697320657374206469676E697373696D20636F6E64696D656E74756D2E2053757370656E646973736520706F74656E74692E204D6F7262692076656C6974206C6F72656D2C206F726E61726520717569732C2070656C6C656E7465737175652076656C2C20706C61636572617420656765742C20746F72746F722E20566573746962756C756D2074696E636964756E74206D6F6C6573746965206C696265726F2E204E756C6C61206E756C6C6120656E696D2C206D616C6573756164612069642C20756C6C616D636F727065722076697461652C2064696374756D2061742C2070757275732E20446F6E6563206469676E697373696D206F64696F20757420656E696D2E2053757370656E6469737365206174206C65637475732E0A0A5072616573656E74206C6F626F727469732061756775652076656C206C65637475732E20557420696E206C6967756C612075742066656C697320636F6E6775652073757363697069742E2051756973717565206469676E697373696D20746F72746F72207574206D692E204675736365206D61676E61206E6973692C20656C656966656E642061632C206F726E6172652076656C2C20706F72747469746F722076697461652C207175616D2E20566573746962756C756D20736F64616C6573206A7573746F2071756973207475727069732E2046757363652075726E61206E6973692C2072686F6E63757320717569732C20636F6E64696D656E74756D2076656C2C2064696374756D2065752C206E756E632E20467573636520736564206E696268207669746165206F64696F20706F73756572652061646970697363696E672E2053656420706F72746120656C6974207175697320646F6C6F722E204E616D206C696265726F206E756C6C612C20617563746F72207365642C2074696E636964756E7420717569732C2066617563696275732073697420616D65742C206D692E2051756973717565206F7263692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E756C6C616D2069642073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632076656C2065726F732E0A0A566976616D7573206C7563747573206C6F626F72746973206C656F2E2053757370656E64697373652076656C20656C6974206120656E696D20756C6C616D636F7270657220706F73756572652E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20446F6E656320717569732070656465206D6174746973206C6563747573206D6F6C6C69732061646970697363696E672E2053656420616363756D73616E20706F737565726520657261742E205072616573656E7420657569736D6F642074696E636964756E742066656C69732E20446F6E6563206D692E20557420636F6D6D6F646F2061726375206C6163696E69612074656C6C75732E20416C697175616D2061206C696265726F2071756973206C65637475732073656D70657220766976657272612E20437572616269747572206C6163696E6961206D61757269732061742074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E756E632073697420616D6574206D61676E61206D6F6C6573746965206F726369207375736369706974206672696E67696C6C612E204675736365207072657469756D206D65747573206E6F6E2073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642068656E6472657269742E204E756C6C612066656C69732E2053757370656E646973736520706F74656E74692E20416C697175616D20626C616E64697420747269737469717565206E657175652E20437572616269747572207175697320657261742076656C206E756E6320616363756D73616E206D6F6C6C69732E0A0A447569732073616769747469732C2074656C6C757320757420616C697175616D206672696E67696C6C612C20646F6C6F72206D6920756C6C616D636F72706572206E69736C2C20757420747269737469717565207065646520656C697420736564206D61757269732E204375726162697475722069642066656C69732E20446F6E65632070756C76696E6172206C61637573206574206C65637475732E20416C697175616D2076756C7075746174652076756C707574617465206D657475732E20437572616269747572206D61676E612066656C69732C2061646970697363696E672061632C20616363756D73616E2076656C2C206D6F6C657374696520717569732C207175616D2E204D617572697320656C697420617263752C207072657469756D2076697461652C206D6F6C6C69732073697420616D65742C20736F6C6C696369747564696E2075742C206D692E20446F6E656320696D70657264696574206469676E697373696D206D692E204E756C6C616D2073697420616D657420746F72746F722E20416C697175616D206E65717565206E756C6C612C2076656E656E6174697320612C20706F72746120696E2C20706C6163657261742074656D7075732C206C616375732E205175697371756520766573746962756C756D20647569206574206C616375732E2050726F696E206469676E697373696D20636F6E7365637465747565722070757275732E20457469616D206772617669646120746F72746F7220696E206E756E632E2055742074656D706F722074726973746971756520746F72746F722E20536564206C616F726565742074696E636964756E74207175616D2E20566573746962756C756D20706F7274612074757270697320757420656C69742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20446F6E6563206E696268206475692C2066657567696174206E65632C206C616F726565742069642C206D616C65737561646120656765742C206E6973692E205574206E65717565206D617373612C207665686963756C612065752C20636F6D6D6F646F206E6F6E2C20756C747269636965732076697461652C2070757275732E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204D617572697320657569736D6F642C2066656C69732076656C2074656D706F7220616C69717565742C20746F72746F72206D6175726973206D616C657375616461206E756E632C2076656C206665726D656E74756D2073656D206469616D206964206475692E204E616D2072757472756D2073617069656E2065676574206F64696F2E20416C697175616D20736564206C696265726F206E6F6E206D692066617563696275732074656D7075732E2046757363652068656E6472657269742C206469616D206E6F6E20766F6C75747061742072757472756D2C2065726174206D657475732076656E656E61746973206C6967756C612C206E6F6E207363656C657269737175652070656465206C6967756C612076656C207175616D2E204D6F7262692072686F6E6375732065726F7320616320647569206665756769617420656C656D656E74756D2E2044756973206575206C696265726F2065742074656C6C757320636F6E67756520766976657272612E204D6F726269207175616D207175616D2C20656C656D656E74756D207365642C20756C6C616D636F7270657220696D706572646965742C20636F6D6D6F646F206E6F6E2C206F64696F2E204E616D20616C697175657420656765737461732075726E612E204D6175726973206F64696F2066656C69732C207661726975732065752C206C6163696E69612065752C20636F6E64696D656E74756D20612C206C65637475732E20536564206A7573746F206D617373612C2070756C76696E61722069642C2076617269757320612C20706F72747469746F72206E65632C206C696265726F2E20457469616D207661726975732E2043757261626974757220736F64616C65732C206F64696F20617420706F73756572652073656D7065722C2065726F73206E6962682074696E636964756E74206C65637475732C2076656C2072757472756D2073617069656E206E69736920696E206C6967756C612E2053757370656E6469737365206567657420617263752E2050686173656C6C757320696D70657264696574206573742061632073617069656E2E20446F6E6563206E756C6C6120746F72746F722C20706C6163657261742076656C2C2074656D70757320612C206C6F626F727469732076656C2C206E6962682E20416C697175616D20766172697573206E6973692E204E756C6C6120657420656E696D2E20467573636520636F6E76616C6C6973206C616F72656574206C616375732E0A0A50686173656C6C757320697073756D20646F6C6F722C206D6F6C657374696520717569732C20636F6E64696D656E74756D20696E2C20636F6D6D6F646F2065752C206469616D2E205175697371756520626962656E64756D206C6163696E6961206475692E204E756C6C616D20626C616E6469742076756C707574617465206F7263692E205574206C6163696E6961206D617373612076656C2061756775652E20416C697175616D20677261766964612C207175616D207175697320696D7065726469657420696D706572646965742C2074656C6C7573206469616D20706861726574726120657261742C206174207068617265747261206C61637573206E6962682065676573746173206D61676E612E204E756C6C61207361676974746973206C6F72656D207574206C6F72656D2E204475697320636F6E64696D656E74756D2C2064756920766974616520616C697175616D20706F73756572652C206469616D207175616D20636F6E76616C6C69732076656C69742C2075742067726176696461206C656F20697073756D206E6F6E2072697375732E205574206665726D656E74756D20736F6C6C696369747564696E20657261742E20446F6E6563207361676974746973207363656C657269737175652066656C69732E204E756E6320617263752E20457469616D2074656D7075732C206D61676E612073697420616D657420737573636970697420657569736D6F642C2065726F732073656D2072757472756D206475692C207669746165207361676974746973206E696268207075727573206E6F6E206C616375732E20536564206D6F6C6C69732061726375206567657420646F6C6F722E20446F6E6563206F726E6172652C20617263752073697420616D6574206665726D656E74756D2076756C7075746174652C20726973757320656E696D206665726D656E74756D206C696265726F2C2061206C6163696E696120646F6C6F72206D69206E6F6E2076656C69742E20457469616D206C6F626F72746973207075727573206120656C69742E204E756E63206E756C6C61206475692C206D617474697320717569732C20626962656E64756D20612C20756C7472696365732061632C2061756775652E20496E20616C697175616D207665686963756C61207475727069732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A496E7465676572206964206E69736C2E20517569737175652064696374756D20656C656D656E74756D206F64696F2E2041656E65616E206C75637475732E205365642065752073656D206120706564652076756C70757461746520636F6E64696D656E74756D2E2051756973717565206D61676E612E20446F6E656320616C697175616D206D617474697320697073756D2E204375726162697475722064696374756D20736F6C6C696369747564696E2073656D2E20416C697175616D2070756C76696E61722E204E756E6320736F6C6C696369747564696E207269737573206120657261742E20566976616D757320717569732074656C6C75732073697420616D6574206E69626820766573746962756C756D20636F6E7365717561742E204E756C6C61207072657469756D20736F6C6C696369747564696E20646F6C6F722E20416C697175616D20696163756C69732074696E636964756E74207475727069732E2050686173656C6C757320697073756D206C656F2C2076656E656E6174697320696E2C20736167697474697320696E2C206F726E6172652061742C206E756E632E0A0A50656C6C656E74657371756520756C7472696365732C2064756920657520696163756C6973206C75637475732C2074656C6C757320617567756520766F6C75747061742073617069656E2C20696E206469676E697373696D2075726E612066656C6973207574206D692E205365642061726375206475692C206469676E697373696D2069642C20706F72747469746F722075742C20696D706572646965742076697461652C20616E74652E204E756C6C61206475692073656D2C20636F6D6D6F646F206E65632C2073616769747469732065742C206C6163696E69612065742C20706564652E20457469616D20656C656966656E6420647569207574206E69736C2E20446F6E656320616E7465206D61757269732C2074656D7075732073697420616D65742C207661726975732076697461652C206772617669646120717569732C206D692E20496E207363656C657269737175652C2066656C697320766974616520766976657272612073616769747469732C2076656C6974206D6574757320756C74726963696573206E657175652C207175697320696D706572646965742076656C697420656C6974206574206D61676E612E2053757370656E646973736520706F74656E74692E205365642076656C69742065726F732C20657569736D6F64207365642C20636F6E64696D656E74756D206E65632C206661756369627573207365642C2073617069656E2E204E616D20616363756D73616E206C6967756C612073697420616D6574206E657175652E20416C697175616D206572617420766F6C75747061742E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E616D20657520706564652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642065752066656C69732073656420746F72746F722074656D706F72206665726D656E74756D2E2050686173656C6C757320636F6D6D6F646F2073656D2076656C206E69736C2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050726F696E206C656374757320656C69742C2070686172657472612073697420616D65742C20616363756D73616E207365642C2074696E636964756E742065742C206D61757269732E204475697320646170696275732070686172657472612073656D2E20496E746567657220696E206A7573746F2E205072616573656E742065726F732E20566573746962756C756D20616320616E74652E20416C697175616D207363656C657269737175652073656D2070656C6C656E746573717565206E69626820636F6E73656374657475657220736F64616C65732E20416C697175616D20636F6E736563746574756572206F64696F2E2044756973206C6563747573206F64696F2C206C75637475732065752C20636F6D6D6F646F20717569732C206D6F6C6C69732076697461652C2076656C69742E2043726173206E6563206E756E63206E6F6E20656C697420696163756C6973206D61747469732E2041656E65616E206A7573746F206E657175652C20736F6C6C696369747564696E20656765742C20756C6C616D636F7270657220656765742C20656765737461732069642C2073656D2E20496E2065752072697375732E2053656420656765737461732E0A0A496E7465676572206174206E657175652E20536564207072657469756D207363656C65726973717565206E756C6C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20467573636520757420706564652E20457469616D207669746165207175616D20612075726E612076617269757320696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2044756973207665686963756C612E20467573636520756C6C616D636F72706572206E696268206E6F6E20657261742E205175697371756520696E206E657175652E205072616573656E74206573742E2050656C6C656E74657371756520617263752E0A0A50726F696E20706F73756572652E2053757370656E646973736520706F74656E74692E20496E74656765722066656C6973206C616375732C20616C697175616D207365642C2076756C70757461746520696E2C206D6F6C6C69732076656C2C2074656C6C75732E20496E7465676572207665686963756C6120626962656E64756D206573742E204E756E63206E6F6E20646F6C6F7220696E2074656C6C7573206D617474697320666163696C697369732E20496E746567657220766573746962756C756D2C20617567756520617420636F6D6D6F646F20616C697175616D2C2064756920657374206D6174746973206C6967756C612C2073697420616D65742061646970697363696E67206F7263692073656D207669746165206D61676E612E205072616573656E7420656E696D2076656C69742C206D616C6573756164612061742C20636F6E677565206E65632C206C756374757320696E2C206A7573746F2E20536564207661726975732E204D6F7262692070686172657472612E20446F6E6563206575206D61737361206E65632074656C6C75732076756C7075746174652070756C76696E61722E20557420636F6D6D6F646F20747572706973206E6F6E2073656D2E20557420636F6E76616C6C697320756C6C616D636F727065722072697375732E20457469616D20696E74657264756D2070656465206964206E6973692E2043726173206D61676E612073617069656E2C20737573636970697420612C206C616F72656574206E6F6E2C2072686F6E6375732065742C2066656C69732E20496E7465676572206F726369206C6F72656D2C20766573746962756C756D2064696374756D2C20756C6C616D636F7270657220612C20706F72747469746F722065742C206475692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A4E756E63206574206D61676E612E2053656420626962656E64756D2074656C6C757320696E206469616D2E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E616D20766974616520746F72746F722E20496E7465676572206D61676E612E20447569732076656E656E617469732C206C656F2061632074656D706F72206C616F726565742C20656C6974206E756C6C6120706861726574726120706564652C206E6F6E206665726D656E74756D206E756E63206F64696F2061206F64696F2E2050726F696E206E6F6E2076656C69742E2053656420696D706572646965742061756775652071756973206E69736C2E20496E746567657220636F6E64696D656E74756D206E69736C206E6563206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20566976616D757320706C616365726174206C696265726F2E204475697320636F6E6775652064696374756D206D61676E612E20416C697175616D206461706962757320626962656E64756D20656E696D2E204E756E6320656C656966656E6420706564652076656C20697073756D2E0A0A457469616D2076697461652076656C69742E204D61757269732065726174206E756E632C206D616C6573756164612075742C20666575676961742061632C20706C61636572617420636F6E64696D656E74756D2C2061756775652E204E616D20766F6C75747061742E20416C697175616D207665686963756C6120697073756D206964206F64696F2E20566976616D757320736F6C6C696369747564696E207475727069732069642073617069656E2E20467573636520612066656C6973207669746165206F64696F20636F6E76616C6C697320626C616E6469742E204375726162697475722076697461652065726F732069642065726F7320706F727461207072657469756D2E204E756C6C6120696E206D61676E6120656765742075726E61206C6163696E696120636F6E76616C6C69732E20416C697175616D206D61747469732076656E656E617469732070757275732E2053656420736564206D69206567657420657261742074726973746971756520706F7274612E20446F6E656320617563746F7220646F6C6F72206120657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20496E206E6563206C6967756C612E204E756E6320656C656966656E642E20566573746962756C756D2071756973206E697369206567657420656C697420706F72747469746F7220636F6E6775652E204D616563656E61732066617563696275732C206D61676E6120656765742061646970697363696E672074696E636964756E742C20646F6C6F7220616E7465206D616C65737561646120656C69742C206E6F6E20656C656D656E74756D206C616375732074757270697320696E20706564652E0A0A5574206D616C657375616461206D69206E6563206D657475732E205072616573656E7420617563746F72206175677565206163206E69736C20756C7472696369657320666163696C697369732E204E616D2070757275732073617069656E2C2070656C6C656E746573717565206469676E697373696D2C20706F73756572652065752C206375727375732069642C206469616D2E205175697371756520736F6C6C696369747564696E2C20656C697420612070656C6C656E746573717565207363656C657269737175652C206C6F72656D20726973757320617563746F72207175616D2C207175697320636F6E7365717561742074656C6C7573206E657175652069642075726E612E2053757370656E6469737365206469616D20746F72746F722C20656C656966656E64206469676E697373696D2C20656765737461732075742C206C756374757320696E2C20616E74652E204475697320616E74652E204D616563656E6173206C75637475732E20437572616269747572206375727375732070686172657472612075726E612E204D616563656E617320696D706572646965742C2065726174206E6F6E20656C656D656E74756D20657569736D6F642C20746F72746F72206F64696F20657569736D6F64206C65637475732C20616320666163696C697369732073656D206E696268207669746165206E756C6C612E204E756E6320677261766964612E204D6F72626920736F6C6C696369747564696E206F64696F2071756973206C616375732E20416C697175616D2061206E696268206E6F6E2075726E6120706F72746120696D706572646965742E20416C697175616D206572617420766F6C75747061742E20496E20696163756C6973206C6163696E69612076656C69742E20536564206C696265726F206C616375732C207472697374697175652065752C206C6163696E69612061632C20616C697175657420656765742C2075726E612E0A0A457469616D206174206E69736C2E2050686173656C6C7573206661756369627573206C7563747573206C65637475732E20557420706C6163657261742076756C70757461746520646F6C6F722E2050686173656C6C75732076656C2076656C69742E204D6F72626920766976657272612E2050686173656C6C7573206F7263692E20496E7465676572206469676E697373696D206D6174746973206D61757269732E2050656C6C656E74657371756520706F7375657265206C656F20706F7375657265207175616D2E2051756973717565206E6563206D61676E61206174206469616D20766976657272612070656C6C656E7465737175652E2053757370656E64697373652076656C697420617263752C20756C7472696369657320717569732C20636F6E67756520612C2076656E656E6174697320656765742C206C616375732E20496E74656765722073616769747469732068656E64726572697420646F6C6F722E2046757363652074696E636964756E7420616E746520612073656D2E0A0A4D616563656E617320636F6E7365637465747565722C206A7573746F207365642072686F6E6375732076656E656E617469732C206E69626820617263752072757472756D20646F6C6F722C2073656420636F6E64696D656E74756D206C696265726F206C696265726F20657420697073756D2E20566976616D7573206D6174746973206A7573746F207574206C6F72656D2074696E636964756E74206C6F626F727469732E205574206E6F6E2076656C6974206964206E6571756520616C697175657420616363756D73616E2E205365642074656D7075732076697665727261206E756C6C612E2043757261626974757220756C6C616D636F727065722C206E6571756520717569732064617069627573207363656C657269737175652C2066656C6973206469616D2067726176696461206F7263692C206E6F6E20637572737573207175616D206E6571756520766974616520656C69742E20457469616D2070686172657472612074696E636964756E74206C616375732E204475697320657569736D6F64206672696E67696C6C61206573742E20457469616D206F726E6172652074696E636964756E74206C65637475732E2050726F696E20696E207475727069732E204E756E6320626C616E64697420626C616E646974207475727069732E2041656E65616E2075742061756775652E2044756973206F726369206A7573746F2C2074696E636964756E742065752C2072757472756D207365642C2072757472756D2065742C207475727069732E2043757261626974757220666163696C69736973206F64696F20696E20616E74652E20496E206861632068616269746173736520706C617465612064696374756D73742E205365642065726F73206573742C2070656C6C656E7465737175652061742C2074696E636964756E742065752C20756C74726963657320717569732C206D657475732E204D6F7262692073697420616D6574206A7573746F2E204D616563656E617320616320617263752E204D6175726973206469676E697373696D2E0A0A50656C6C656E74657371756520756C747269636965732072757472756D206F7263692E2041656E65616E206F726E6172652E20566976616D75732065752072697375732076656C206D6175726973206C6F626F727469732064696374756D2E205365642065742074757270697320617563746F72206D692072686F6E6375732070756C76696E61722E20536564206E6563206E756E6320612070757275732074656D706F7220766976657272612E2050656C6C656E7465737175652073757363697069742E20446F6E656320747269737469717565207269737573206E6F6E206E6962682E20457469616D206E69736C206D61676E612C20736F6C6C696369747564696E2075742C20756C7472696365732073697420616D65742C20656765737461732065752C206E756C6C612E20416C697175616D206572617420766F6C75747061742E20566573746962756C756D2070686172657472612E2053656420656765737461732C206D657475732073697420616D6574206C6F626F7274697320636F6E7365717561742C206572617420656C697420696D70657264696574206C696265726F2C20657520696E74657264756D207175616D206D61737361206567657420646F6C6F722E2053757370656E6469737365207669746165206F64696F2E2050726F696E20626C616E646974206D617572697320696163756C6973206D657475732E0A0A566976616D757320766573746962756C756D2E20457469616D206574206E69736C2E20416C697175616D20696E206469616D2076656C20656C697420706C6163657261742073757363697069742E204475697320736F64616C6573207075727573206163206E6962682E204E756C6C6120696E206F64696F206567657420656E696D206C756374757320626C616E6469742E2043757261626974757220756C74726963657320697073756D206E6F6E206E65717565206567657374617320656C656966656E642E20536564207475727069732E2050726F696E20636F6E7365637465747565722E20566976616D7573206D61747469732E20496E20616C69717565742E0A0A4E756E632069642065726F732E20446F6E65632076656E656E617469732C206E756C6C61206574206D6174746973206C75637475732C20616E7465206C656F2073656D706572206A7573746F2C206E6F6E2061646970697363696E67206F64696F20726973757320736564206C616375732E205072616573656E7420766974616520726973757320636F6E677565206C696265726F20636F6E6775652074656D7075732E2050686173656C6C75732061632065726F732E204E756C6C61207665686963756C612C206C6F72656D20696E20616C69717565742073757363697069742C2061726375206572617420656765737461732073656D2C2071756973206C6F626F72746973207175616D20616E7465206575206D617373612E20437572616269747572206E6F6E206D617373612E2053656420626962656E64756D206C6163696E6961206F64696F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20566976616D757320766F6C757470617420626C616E646974206C616375732E2050726F696E20706F7274612C2074656C6C757320757420617563746F72206C616F726565742C206C65637475732065726F73206665726D656E74756D206C65637475732C2069642073616769747469732061726375206A7573746F20696E207475727069732E2050686173656C6C757320636F6E7365717561742E204E616D2070656C6C656E7465737175652C206D69206964207669766572726120636F6E76616C6C69732C206E756E63206C696265726F20706C616365726174206C656F2C20656C656966656E6420706F7274612073656D206E69736C2076697461652073617069656E2E2050656C6C656E746573717565206C6967756C61206C696265726F2C20747269737469717565206E6F6E2C20706F72747469746F722072757472756D2C20706F72747469746F72206E6F6E2C20657261742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E74656765722064696374756D2074656C6C7573206120746F72746F722E20566976616D75732066656C6973206E756E632C206D6F6C6573746965206E6F6E2C2072686F6E63757320717569732C2070686172657472612069642C206475692E20446F6E6563207269737573206D657475732C206672696E67696C6C612076656C2C20616C69717565742065752C20706C6163657261742069642C206E657175652E0A0A53757370656E646973736520697073756D2E20566976616D7573206C65637475732E2053656420766976657272612C206D61737361206567657420636F6E76616C6C6973206D61747469732C207175616D2074757270697320636F6E736563746574756572206E756E632C206567657420706F7375657265206D61676E612073656D2069642076656C69742E20496E206E6563206D61757269732E2041656E65616E206120707572757320736564207175616D206C6F626F72746973206672696E67696C6C612E2050726F696E20756C74726963696573206C6163696E696120616E74652E205365642061646970697363696E67206572617420717569732076656C69742E204E756C6C616D207669746165206E69736C206964206A7573746F20736F6C6C696369747564696E206D6F6C65737469652E204E756C6C6120666163696C6973692E20536564206E65632075726E6120736564206E69736C206672696E67696C6C6120646170696275732E204E756C6C61206174206469616D2E20416C697175616D2065676574206E6962682E204E756E63206163206E6973692073697420616D65742074656C6C757320656765737461732074656D7075732E204E616D207363656C657269737175652075726E61206574206E657175652E20446F6E656320657374206F7263692C207361676974746973206E6F6E2C2076756C70757461746520612C20636F6D6D6F646F2065742C2061756775652E205574206461706962757320746F72746F722E205574206E756E632E20446F6E65632064696374756D2064617069627573206F64696F2E204E616D20756C7472696369657320756C6C616D636F72706572206C6967756C612E2050656C6C656E74657371756520616363756D73616E20766172697573206C656F2E0A0A4D6F72626920657569736D6F64206C616F7265657420657261742E20566976616D7573207175697320697073756D2E204D6F72626920657569736D6F642E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2053757370656E64697373652076656C2070757275732E204E756C6C616D206174206D61676E612E20437572616269747572206C61637573206C6F72656D2C20696163756C697320717569732C2064617069627573206E6F6E2C20766F6C75747061742076656C2C206E756C6C612E20446F6E656320757420617263752072686F6E63757320646F6C6F72207072657469756D2064696374756D2E204E756C6C616D2076656C206D657475732E20557420617263752E2050656C6C656E746573717565206E697369206E756E632C20706C61636572617420656765742C2074696E636964756E742076656C2C207068617265747261206E6F6E2C206E756E632E20496E74656765722074696E636964756E7420756C74726963696573206C65637475732E20496E74656765722073656D7065722C2070757275732073656420756C74726963657320666575676961742C206E756C6C61207065646520736F6C6C696369747564696E20657261742C2076656C20617563746F72206E756C6C6120697073756D2076656C206C65637475732E2041656E65616E206D692E0A0A4E756C6C616D20736564206E697369206574206172637520696D70657264696574206665726D656E74756D2E204D6175726973206E6563206D657475732E20496E20616320646F6C6F722E20496E206D6920617263752C20636F6E6775652061632C207068617265747261206E65632C207363656C657269737175652073697420616D65742C206D61676E612E20437572616269747572206C616375732E2043757261626974757220657420656C69742E20416C697175616D20756C6C616D636F72706572206E756E6320657520656C69742E2053656420636F6E76616C6C697320646F6C6F722061742076656C69742E20566573746962756C756D20646170696275732C20617567756520696420636F6E73656374657475657220706C6163657261742C206E756E63206D6173736120626C616E6469742073617069656E2C20696420616C697175616D20656C6974206E697369206964206D692E2050686173656C6C75732073617069656E206573742C20677261766964612065752C20626962656E64756D2075742C2061646970697363696E6720717569732C206573742E205574206D6F6C6573746965207175616D207669746165206F64696F2E20446F6E65632071756973207269737573206964206572617420666175636962757320736F6C6C696369747564696E2E204E616D2069642066656C69732E204D61757269732073656420656E696D207669746165206C656F20616363756D73616E207072657469756D2E0A0A4E616D206A7573746F2E20446F6E656320747572706973206E69736C2C20636F6D6D6F646F2065742C20696E74657264756D2061632C20636F6E736563746574756572206E6F6E2C206D617373612E2046757363652073656D206D657475732C206C616F72656574206E65632C20706F73756572652069642C20696D7065726469657420696E2C2076656C69742E20446F6E65632076756C707574617465206A7573746F2065676574207475727069732E204E756C6C6120706564652E204D6F7262692074696E636964756E742E20467573636520616C69717565742C207175616D20657420616C697175616D206672696E67696C6C612C20616E746520616E746520696163756C6973206475692C206E656320616C697175616D20617263752070757275732073656420657261742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050686173656C6C7573207375736369706974207175616D206574206573742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B0A0A496E7465676572207365642074656C6C75732E20536564207365642076656C697420756C74726963696573206C656F2072757472756D206C616F726565742E20536564206E6F6E2065726F7320616320707572757320736167697474697320666575676961742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E205365642068656E647265726974206C6967756C612073697420616D6574206E6962682E204D616563656E6173207475727069732E204D6F72626920636F6E7365637465747565722C20646F6C6F722065742061646970697363696E6720696D706572646965742C20616E7465206E65717565206665756769617420646F6C6F722C20617420706F727461207175616D206E657175652071756973206C6967756C612E204D61757269732073656D7065722076656C69742073697420616D657420697073756D2E2050656C6C656E7465737175652074656D7075732C20707572757320696E2072757472756D20636F6E7365717561742C20656E696D2065726174207665686963756C61206D617373612C20696420616363756D73616E206C656F2073617069656E206E65632070757275732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E20646F6C6F722E20496E746567657220666163696C69736973206C696265726F2073697420616D657420706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2055742076617269757320616C697175657420656E696D2E204E756C6C6120666163696C6973692E2043757261626974757220636F6E7365637465747565722C206F64696F206575207072657469756D2074696E636964756E742C206E756E63206E69736920616C6971756574206E657175652C2076656C20696D7065726469657420656C6974206D617373612073697420616D6574207475727069732E2050656C6C656E7465737175652074656D7075732C206F72636920766F6C757470617420626C616E646974206672696E67696C6C612C206F64696F2073656D20706F737565726520616E74652C20766974616520626962656E64756D2075726E61206C6F72656D2076697461652065726F732E205072616573656E7420766976657272612072686F6E63757320617263752E2053656420617563746F722C206573742073697420616D6574206D6F6C6C6973206D6F6C6C69732C207175616D207175616D20677261766964612073617069656E2C20696E20636F6D6D6F646F206D65747573206E756C6C6120617563746F7220656E696D2E20446F6E656320666163696C697369732E0A0A50726F696E2074696E636964756E742C2073617069656E206567657420756C747269636965732061646970697363696E672C20657374206F64696F2064696374756D20617263752C207574206D6F6C6C69732065726174206475692073697420616D65742076656C69742E204D6F726269206573742073656D2C20696E74657264756D2061742C20636F6E67756520612C20656C656D656E74756D2076697461652C206D657475732E2053757370656E64697373652069642061756775652E204D617572697320656E696D2073656D2C2070756C76696E617220656765742C2074656D70757320612C2074656D7075732073697420616D65742C2073617069656E2E20467573636520766573746962756C756D20636F6E736563746574756572206475692E2050656C6C656E74657371756520657261742E20536564206469676E697373696D20706C616365726174206F64696F2E204D616563656E61732073656D7065722072686F6E637573206C65637475732E2050686173656C6C7573207072657469756D2E2044756973206C696265726F20656C69742C20656C656966656E64206E65632C20656765737461732075742C20637572737573207365642C2066656C69732E204E616D206E69736C20617263752C20616C69717565742065742C20666163696C697369732065752C206C75637475732075742C2072697375732E20457469616D20756C7472696365732C20646F6C6F722073656420766F6C7574706174206D616C6573756164612C20747572706973206172637520696D7065726469657420746F72746F722C20657569736D6F6420636F6D6D6F646F206C696265726F206D61737361207574207175616D2E20496E7465676572206D6F6C6573746965207075727573206E6F6E20656C69742E2055742076656E656E617469732073656D70657220746F72746F722E20457469616D20626962656E64756D206567657374617320697073756D2E204D617572697320736F6C6C696369747564696E2073656D206E6563206E6962682E204E756C6C61207072657469756D206D65747573206575206D657475732E2050656C6C656E7465737175652073697420616D65742073656D2E0A0A53757370656E6469737365206163206E6973692E205574206C656F2E20566573746962756C756D2068656E647265726974207072657469756D20646F6C6F722E204E756E632066657567696174206D616C6573756164612070757275732E2043726173206574206E6962682E20437572616269747572206E756E6320657261742C206D616C6573756164612076697461652C206C616F726565742061632C20756C7472696369657320696E2C2070757275732E20566976616D75732074656C6C757320617263752C20736F64616C65732065752C20666163696C6973697320612C206C6163696E6961206E65632C206E756E632E2050656C6C656E7465737175652069642076656C69742E20496E206575206E6962682E204E756E63206E656320657261742E205365642064696374756D206E65717565207574206E69736C2E0A0A4D6F726269206C65637475732074656C6C75732C2074696E636964756E742061632C20706F72747469746F722061632C2074726973746971756520696E2C2065726F732E20446F6E6563206C7563747573206C7563747573206C656F2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2046757363652075742065737420657420656E696D207363656C6572697371756520616363756D73616E2E20446F6E6563206C6967756C612066656C69732C206C6163696E696120717569732C2070656C6C656E74657371756520696E2C2073656D70657220766573746962756C756D2C20656C69742E204D61757269732065676574206F72636920612066656C697320636F6E677565207665686963756C612E20557420736F6C6C696369747564696E2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204E756C6C616D20696420646F6C6F72207574206C6F72656D206469676E697373696D2076656E656E617469732E2053757370656E64697373652076697461652073617069656E2E2050726F696E206E6F6E206D61676E612075742065726F7320766976657272612070756C76696E61722E20446F6E65632071756973206F64696F2E204E756C6C616D206E6F6E20617263752076656C206C6F72656D20737573636970697420616C697175616D2E20416C697175616D2072757472756D2074757270697320696E206C656F2E0A0A5574206C7563747573206E6962682074726973746971756520657261742E2053757370656E646973736520626962656E64756D206F64696F20766974616520746F72746F722E20446F6E6563206C6163696E69612E204372617320736F64616C65732066656C6973206C7563747573206E756C6C612E204E616D20656C656966656E64207361676974746973206C6967756C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E64697373652076656C206E657175652E204D6F72626920616C6971756574207665686963756C61206D61676E612E2041656E65616E206174206F64696F2E20447569732070656C6C656E746573717565206D61676E612E204E756C6C6120617420746F72746F72207574206469616D2064696374756D2066617563696275732E204D617572697320717569732076656C69742E20446F6E6563206E6F6E2074656C6C7573207669746165206C6F72656D206672696E67696C6C6120706F72747469746F722E2046757363652075742073617069656E207175697320746F72746F7220666575676961742073616769747469732E20446F6E656320766976657272612073656D2076697461652073617069656E2E205072616573656E7420736F64616C65732C206C6163757320696E206672696E67696C6C6120766976657272612C206F64696F2061756775652061646970697363696E672075726E612C20766974616520696E74657264756D20616E74652073656D206E6F6E206E6973692E204E756C6C616D20746F72746F72206C6F72656D2C20656C656966656E642061632C206D6F6C6C6973206E6F6E2C206C616F726565742061632C2072697375732E20496E7465676572206F726E617265206C656F20736564206A7573746F2E2051756973717565206375727375732C2073656D206E6F6E20666163696C6973697320626962656E64756D2C206E697369206D69207661726975732066656C69732C206665726D656E74756D2066657567696174206C6F72656D2065726F73206C616F726565742072697375732E0A0A517569737175652073697420616D657420657374206574206C6F72656D207665686963756C61206C6163696E69612E20446F6E6563206E656320746F72746F722E2043726173206F64696F2E204E616D207363656C657269737175652076756C7075746174652075726E612E205072616573656E74206475692E20457469616D206E6563206E69736C206C6F626F7274697320697073756D20616C69717565742074656D7075732E204D616563656E6173207072657469756D20736F6C6C696369747564696E206D61757269732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206175677565206D617373612C20636F6E67756520656765742C20636F6E76616C6C697320656765742C207472697374697175652073697420616D65742C2065726F732E2053656420636F6E736571756174206E6973692065752066656C69732E2050656C6C656E746573717565206A7573746F2E2053757370656E6469737365206E6F6E2061756775652E20496E206469676E697373696D206C6F626F72746973206D61757269732E204D61757269732073616769747469732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E0A0A5365642061646970697363696E672E20446F6E656320612074656C6C75732076697461652065737420637572737573207665686963756C612E204E616D20616E74652073656D2C20736F64616C65732069642C206672696E67696C6C612076656C2C20636F6E64696D656E74756D2076656C2C206E756C6C612E205175697371756520736F64616C65732E20457469616D20696D7065726469657420656C6974206964206F64696F2E20416C697175616D206572617420766F6C75747061742E204D616563656E617320706F7274612074656D706F7220617263752E204E756C6C612073656D2061756775652C2070656C6C656E7465737175652061632C20636F6E7365717561742075742C20636F6E64696D656E74756D20657569736D6F642C2072697375732E2053656420616C697175616D2074696E636964756E74206D692E20496E20696E74657264756D206C6F626F72746973206F7263692E0A0A536564207665686963756C612068656E6472657269742070757275732E20457469616D2061206469616D2E2043757261626974757220636F6E76616C6C69732E2053757370656E64697373652061206E6973692E20446F6E6563206964206D61676E6120696E207175616D20736F6C6C696369747564696E20756C747269636965732E20446F6E656320766976657272612E205175697371756520766F6C757470617420657374207365642073656D2E20416C697175616D206A7573746F2E20566573746962756C756D20746F72746F72206D617373612C20706F72747469746F72207365642C2076617269757320717569732C20696163756C697320717569732C206F64696F2E20416C697175616D2065676574206E657175652E0A0A4D6175726973206E756C6C612E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566573746962756C756D206575207175616D20696E206E6571756520756C7472696365732070656C6C656E7465737175652E204372617320696E20646F6C6F722071756973207175616D207661726975732068656E6472657269742E20416C697175616D206E697369206C616375732C206C6F626F727469732065752C20636F6E76616C6C69732073697420616D65742C20666163696C697369732075742C206D692E20416C697175616D206174206E657175652E204372617320736167697474697320656C656D656E74756D206A7573746F2E20566573746962756C756D207574206C656374757320616C6971756574207075727573206D616C65737561646120766F6C75747061742E2044756973206174206C616375732061646970697363696E67206C696265726F2074696E636964756E7420766573746962756C756D2E204D6F7262692061206C696265726F2E20437261732070757275732E204D6F72626920757420617567756520657420707572757320696E74657264756D207363656C657269737175652E20496E74656765722061206475692E20496E206861632068616269746173736520706C617465612064696374756D73742E2044756973207068617265747261206D657475732065676574206D61757269732E20416C697175616D20696E74657264756D20756C6C616D636F72706572206D617373612E0A0A457469616D206F726E6172652E204E756C6C616D20657569736D6F642E2041656E65616E20636F6E7365717561742067726176696461206C6967756C612E20416C697175616D206573742E2050726F696E207669746165206C616375732E205072616573656E7420612065726F732073697420616D657420647569206C756374757320636F6D6D6F646F2E2050686173656C6C7573207665686963756C612061726375206567657420646F6C6F722E205072616573656E74206665726D656E74756D20636F6E677565206C656F2E20416C697175616D20766F6C7574706174207075727573207574206C6F72656D2E2046757363652068656E64726572697420656E696D206174206C656F2E20416C697175616D2072686F6E637573206E69736C2E20566976616D75732064696374756D2065676573746173206D692E2053757370656E64697373652070656C6C656E74657371756520626962656E64756D20646F6C6F722E2050656C6C656E7465737175652074696E636964756E742C207475727069732073656D7065722070656C6C656E74657371756520636F6E64696D656E74756D2C20697073756D206D6574757320736F64616C6573206C6967756C612C20696420766F6C7574706174206469616D2074757270697320757420656C69742E0A0A5072616573656E7420736564206C616375732E204E616D20656C656966656E64206D6F6C6573746965206D61757269732E20446F6E65632064617069627573206665726D656E74756D206D617373612E20446F6E656320766976657272612066617563696275732070757275732E2043757261626974757220636F6E6775652C206C696265726F20766974616520766976657272612070656C6C656E7465737175652C206469616D2076656C697420736F64616C657320656E696D2C20736564207375736369706974206C6563747573206E697369206E6563206E657175652E20566573746962756C756D206D616C6573756164612C206C616375732061742063757273757320636F6E6775652C2076656C6974206C65637475732074726973746971756520646F6C6F722C2073697420616D657420736F64616C6573206E6571756520697073756D2061206C696265726F2E20566573746962756C756D206574207175616D2E2043757261626974757220706C6163657261742E20437572616269747572206E756E6320617263752C20657569736D6F64206E65632C2076756C7075746174652068656E6472657269742C20616C697175657420656765742C207175616D2E204375726162697475722076656C20656E696D2E2053757370656E646973736520706F74656E74692E0A0A4E756E6320636F6E736571756174206F726369207574206C616375732E2046757363652076656C697420646F6C6F722C2064617069627573207365642C20626C616E6469742073697420616D65742C2072686F6E6375732069642C2072697375732E20447569732075726E61206E6962682C207363656C6572697371756520717569732C206461706962757320612C207363656C65726973717565207365642C206E6962682E20446F6E6563206C75637475732E205574206575206D617572697320637572737573206469616D206C6163696E69612072686F6E6375732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20416C697175616D207665686963756C61206D6F6C6573746965206A7573746F2E204D616563656E617320696D70657264696574207065646520736564206D692E2053757370656E6469737365206E756C6C6120646F6C6F722C2068656E64726572697420656765742C2068656E6472657269742069642C2064696374756D2076656C2C206C656F2E204475697320616363756D73616E2E2043757261626974757220696E2066656C69732E204E756E63206C6F72656D2E205574206C656F20646F6C6F722C206C616F72656574206E65632C2076756C7075746174652061742C20656C656966656E6420696E2C206E756C6C612E2051756973717565206E756E632070757275732C2076617269757320656765742C20616363756D73616E206E65632C20616C69717565742065742C206E6962682E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20437261732061646970697363696E67207669766572726120646F6C6F722E204D617572697320706F72747469746F7220756C7472696365732070757275732E204E756C6C6120666163696C6973692E205072616573656E7420666175636962757320616E7465207669746165206D61757269732E0A0A5072616573656E74206C6163696E6961206C656374757320736564206E69736C2E20496E2074656D70757320636F6E677565206D61757269732E20496E746567657220666163696C69736973206F726E61726520656E696D2E204E756C6C61206964206D617373612E20446F6E656320636F6D6D6F646F206469616D2061742074656C6C75732E204E616D20646170696275732076697665727261206573742E204E616D2074656C6C75732E205072616573656E742061206C696265726F2E20496E206661756369627573206573742065676574206E6962682E204E756C6C612065726F73206F7263692C20696D70657264696574206E6F6E2C20626C616E646974206E6F6E2C2074656D706F7220656765742C206D692E2050656C6C656E74657371756520636F6E76616C6C69732E0A0A517569737175652065676574206D69206163206C656F20657569736D6F642066617563696275732E2050686173656C6C75732072686F6E637573207075727573206964206475692E20566573746962756C756D206D616C65737561646120656C656966656E6420616E74652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050656C6C656E74657371756520626C616E646974206D6174746973206F64696F2E2053757370656E646973736520636F6E7365717561742C206C65637475732061632073656D70657220736F6C6C696369747564696E2C206D692076656C69742064696374756D2061756775652C2061632074656D70757320646F6C6F7220657261742073697420616D6574206475692E2050726F696E2068656E6472657269742C2066656C6973207175697320766F6C757470617420706F73756572652C206469616D206F64696F206D616C657375616461206F64696F2C206120696E74657264756D206F726369206469616D20717569732073617069656E2E2050656C6C656E746573717565206F64696F206F64696F2C20766976657272612076656C2C20677261766964612065752C206D6F6C6573746965207365642C206E756C6C612E2050686173656C6C7573206D617572697320706564652C20636F6D6D6F646F2075742C20657569736D6F642065752C2068656E6472657269742065752C206573742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C6120656C656D656E74756D206C616375732065752061756775652E2053656420657261742E2050726F696E20706F7274612E204D616563656E61732071756973206D692E2050686173656C6C757320617420656E696D206163206A7573746F206772617669646120756C7472696365732E2043726173206C656F2E0A0A496E746567657220757420617263752E20446F6E656320736564206D61676E612E2050726F696E2066656C69732E20496E20696163756C69732C206C6967756C61206964206672696E67696C6C61207072657469756D2C206E696268206469616D20616363756D73616E2074656C6C75732C206567657420616363756D73616E206D657475732064756920766172697573207475727069732E2050686173656C6C7573206F726369206D657475732C20656C656966656E64207365642C2074656D706F722061632C207363656C657269737175652061632C2075726E612E20496E74656765722076697665727261206E657175652061206D61757269732E204D617572697320706F72747469746F7220646F6C6F722065752076656C69742E20496E7465676572206F64696F20656C69742C20766573746962756C756D2075742C20766F6C75747061742069642C2072686F6E63757320636F6D6D6F646F2C2075726E612E20457469616D20706C61636572617420706861726574726120657261742E2055742074656D706F72206573742E20496E7465676572206469676E697373696D20626C616E6469742074656C6C75732E204D6F726269206E69626820646F6C6F722C207363656C657269737175652069642C20636F6D6D6F646F206D616C6573756164612C206D61747469732061742C206D692E20437261732074696E636964756E7420636F6D6D6F646F2070757275732E20496E2074696E636964756E742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D20756C6C616D636F727065722E2055742068656E6472657269742E204D6F72626920756C7472696365732E0A0A5072616573656E7420696163756C69732C2065726F73206163206567657374617320736F64616C65732C2075726E61206C656F206665726D656E74756D206C6967756C612C2073697420616D657420616C697175616D2076656C69742073656D206E6F6E2070757275732E20446F6E65632072757472756D206172637520717569732070757275732E204E616D20706F73756572652C206C6163757320617420636F6E73657175617420706C6163657261742C206E756C6C61207065646520706F7375657265206F7263692C206E6F6E20657569736D6F6420747572706973206475692071756973206E69736C2E2050726F696E20706F7274612061646970697363696E67206E6962682E20446F6E65632074726973746971756520646F6C6F722061742074656C6C75732E20446F6E6563206E65717565206D617373612C20617563746F722069642C2066617563696275732076697461652C20756C6C616D636F727065722076656C2C206E6973692E2050726F696E206D6F6C6573746965206E6571756520736564206D617373612E204E616D2074656D706F722E204D6F72626920616C697175616D2073617069656E2061742074656C6C75732E2046757363652071756973207269737573206574206D69207072657469756D2070756C76696E61722E2046757363652073697420616D6574206C6967756C612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E646973736520657520656E696D2065742066656C6973207363656C65726973717565206C6F626F727469732E205072616573656E7420626962656E64756D2E20566976616D7573207665686963756C612E20496E7465676572206174206E696268207365642076656C69742072686F6E637573206D6F6C65737469652E2043726173206C616375732E2053656420756C6C616D636F727065722065726F732076656C20657261742E20467573636520657520746F72746F722073697420616D6574206469616D20657569736D6F642073616769747469732E204E756E632071756973206C61637573206964206E69626820636F6E76616C6C6973207661726975732E2053757370656E6469737365207669746165206D692E20566573746962756C756D207472697374697175652E20446F6E6563206D616C65737561646120697073756D206964206E657175652E204E756C6C616D20736564206C616375732E204475697320656765737461732C206A7573746F20757420636F6E677565206F726E6172652C2061756775652073617069656E206C7563747573206469616D2C20617420616363756D73616E20657261742073617069656E207574206C696265726F2E2050686173656C6C75732076656C206E756C6C612E2053757370656E646973736520617263752074656C6C75732C20706F72747469746F7220612C2070686172657472612066617563696275732C20616C697175616D2073697420616D65742C206D617373612E204E756C6C6120706F72747469746F722074696E636964756E74206C6F72656D2E204E756E6320646F6C6F72206F64696F2C20736167697474697320696E2C206C6F626F727469732076656C2C20766F6C7574706174207365642C206E6962682E0A0A5175697371756520626C616E646974206C656F2075742073617069656E2074656D70757320666163696C697369732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2041656E65616E20756C7472696369657320706F72747469746F72206A7573746F2E2046757363652072757472756D2065726F732075742075726E612E2050726F696E2071756973207175616D20656765742064756920616C697175616D20616363756D73616E2E20446F6E656320737573636970697420656C656966656E6420656C69742E2050656C6C656E746573717565206D61747469732C2066656C697320736F64616C657320696163756C697320696D706572646965742C206C616375732073656D20636F6E76616C6C69732061756775652C2073697420616D657420616C69717565742061726375207075727573206672696E67696C6C612072697375732E20496E206575206F64696F206964206D61676E61207068617265747261206F726E6172652E20416C697175616D20696E74657264756D2070756C76696E617220697073756D2E20536564206E657175652E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D2073697420616D6574206E6973692E2055742061742061756775652E204D617572697320766F6C757470617420626C616E646974206C6967756C612E204E756C6C61206575206D657475732E20566573746962756C756D206567657420656C69742E205072616573656E7420706F73756572652E20566573746962756C756D2069642073656D206E6F6E206C6563747573206D6F6C6C69732074696E636964756E742E20416C697175616D2069642066656C697320617420616E7465206F726E6172652074656D706F722E204E756C6C61206C61637573207475727069732C20666575676961742076697461652C2063757273757320717569732C20636F6E736563746574756572206E6F6E2C206D61757269732E204675736365206C61637573206D617373612C20706F72747469746F722075742C206D6F6C65737469652075742C2076656E656E6174697320612C206C6F72656D2E205072616573656E742073697420616D6574206F7263692E204D61757269732072686F6E6375732066656C69732076697461652066656C69732061646970697363696E6720696D706572646965742E204D616563656E6173206D6F6C6C6973206469616D206E6563206C656F2E0A0A467573636520656E696D20697073756D2C20756C7472696365732065752C206D6F6C65737469652069642C20656C656D656E74756D2069642C2073617069656E2E20496E746567657220612075726E612E204E616D2076656C6974206C696265726F2C2076656E656E6174697320656765742C2074656D706F722073697420616D65742C20666575676961742076697461652C20616E74652E204675736365206E756E632E205365642073656D706572206E69736C206E65632072697375732E20496E20736564206C696265726F2E2050726F696E20746F72746F72206E657175652C2074696E636964756E742061632C2074656D706F722061632C20706861726574726120717569732C2076656C69742E2044756973206C65637475732061756775652C20756C747269636965732076656C2C20636F6E7365717561742069642C20696163756C69732069642C20616E74652E20566976616D757320617563746F72206D65747573206120616E74652E204375726162697475722061726375206E6973692C20666163696C697369732061742C206C616F7265657420696E2C20636F6E736563746574756572207365642C206D61757269732E205175697371756520706C616365726174206469616D20736564206475692E20566976616D7573207072657469756D20636F6E64696D656E74756D206C6F72656D2E20437572616269747572206C616F726565742E2041656E65616E206F726369206C6967756C612C2063757273757320656765742C206C6163696E6961206E6F6E2C2066617563696275732076656C2C206C6F72656D2E0A0A416C697175616D206572617420766F6C75747061742E204375726162697475722065726F7320646F6C6F722C20636F6E67756520612C20636F6E64696D656E74756D207365642C206C75637475732075742C206E6962682E204D616563656E6173206E6F6E20746F72746F72206E65632074757270697320636F6D6D6F646F2070656C6C656E7465737175652E205072616573656E7420657569736D6F6420706C616365726174206D692E2053757370656E646973736520706F74656E74692E2050686173656C6C7573207574206E65717565207669746165206F726369206D617474697320696163756C69732E20496E746567657220656765742074656C6C75732E20446F6E656320617420616E74652E204E616D206C6163696E6961206C656F206567657420657261742E204D616563656E617320657569736D6F64206D61676E6120636F6E67756520746F72746F722E204D6F726269206E6563206D6173736120657520656E696D206D616C65737561646120736F6C6C696369747564696E2E2053656420616363756D73616E2E204E756C6C616D20697073756D2E205574206F64696F2E20416C697175616D206572617420766F6C75747061742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2050656C6C656E7465737175652069642076656C69742E204E616D206F64696F2073656D2C20616C69717565742075742C2074656D7075732073697420616D65742C20657569736D6F642065742C206E756E632E0A0A50656C6C656E746573717565206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205072616573656E74206D6175726973206E756E632C207661726975732075742C20636F6E76616C6C6973206D6F6C65737469652C206C75637475732073697420616D65742C206C656F2E205365642064696374756D206C6F72656D20657420617263752E204E756E632076656E656E617469732070656C6C656E746573717565206D617373612E204E756C6C6120666163696C6973692E2050686173656C6C757320696E20746F72746F722065676574207269737573207363656C657269737175652076756C7075746174652E20536564206E69626820656C69742C2073616769747469732061632C20636F6E64696D656E74756D206E65632C20636F6E76616C6C69732065742C206A7573746F2E20467573636520766F6C7574706174206D657475732E204E756E6320617563746F722E20566573746962756C756D206C656F2065726F732C2070656C6C656E7465737175652061632C206D6F6C6C697320756C7472696365732C2072686F6E637573206E6F6E2C20646F6C6F722E204D6175726973207665686963756C6120706C616365726174206E69736C2E20566573746962756C756D20626962656E64756D2C2061726375207175697320636F6E67756520656C656D656E74756D2C2076656C6974206E756E6320656C656966656E64207475727069732C206964206C7563747573207269737573206E69736C2073697420616D65742074656C6C75732E2050686173656C6C75732070656465206E657175652C20626C616E646974206E6F6E2C20636F6D6D6F646F2076697461652C20756C7472696369657320656765742C206D61676E612E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120666163696C6973692E20416C697175616D20616320616E74652E20437261732072697375732E204D6F726269206D6175726973206C616375732C20706F73756572652065752C20626C616E6469742065742C2070686172657472612061742C206D692E2050726F696E2061632070757275732E204475697320637572737573206E69736C2072757472756D207175616D2E20416C697175616D2061206F64696F206E6F6E206D61676E612070656C6C656E74657371756520756C747269636965732E204D616563656E6173206163206D6173736120717569732073617069656E20756C6C616D636F727065722074656D7075732E2043726173206375727375732076656C6974207365642073617069656E2E2050726F696E206E756C6C612E20566976616D757320736F64616C657320616C697175616D206E6962682E20457469616D206574206572617420757420616E7465206C6163696E696120657569736D6F642E204675736365206E6973692E2050726F696E2071756973206E756C6C612E0A0A517569737175652076656E656E617469732C2065726F7320736564206C616F7265657420736F6C6C696369747564696E2C206F72636920616E74652070656C6C656E746573717565206E69736C2C2073697420616D65742076697665727261207175616D2065726174206E6F6E2072697375732E20437261732065676574206C696265726F2E2053656420656C6974206D61676E612C2073656D7065722065752C206672696E67696C6C6120696E2C206469676E697373696D20736F64616C65732C20657261742E20566976616D757320666575676961742073656D2076656C206475692E20446F6E656320636F6E76616C6C697320736F6C6C696369747564696E206469616D2E2043726173207365642070757275732E20446F6E65632066656C69732065726F732C2073656D70657220656765742C2074656D706F7220636F6E7365637465747565722C20736167697474697320717569732C206E69736C2E204475697320696E20616E74652E2043726173206E6F6E207475727069732E204E756C6C612074656D706F722076656C697420616C697175657420747572706973206D6F6C657374696520706C6163657261742E2050726F696E20656C656D656E74756D206665726D656E74756D206D61757269732E20566976616D757320736564206F726369206C6163696E69612064756920706C6163657261742076656E656E617469732E20566573746962756C756D20666575676961742C2074656C6C757320696E20766F6C75747061742072757472756D2C206D61676E61206E69736920756C6C616D636F727065722065726F732C2069642070756C76696E6172206E657175652065726174207574206C616375732E20566976616D7573207365642061756775652E204E756C6C6120666163696C6973692E204D616563656E617320616E74652061756775652C20656C656D656E74756D2075742C20736F64616C65732076697461652C20636F6E64696D656E74756D206E65632C206C6F72656D2E20447569732070656465206F7263692C206672696E67696C6C612061742C20656C656966656E64206E65632C207072657469756D20696E2C20657261742E204E616D2073616769747469732C2074757270697320766974616520636F6E76616C6C69732070686172657472612C206F64696F2073656D207363656C65726973717565206C616375732C206E6563206C6F626F7274697320647569206469616D2076656C2065726F732E20496E2073656D7065722067726176696461206E657175652E0A0A496E7465676572206E756E632E205574207072657469756D20697073756D2073697420616D657420656C69742E20496E206E656320617263752E2053656420766573746962756C756D2076756C70757461746520697073756D2E2050656C6C656E7465737175652074696E636964756E742E204E756C6C61206772617669646120646F6C6F7220696E2074656C6C75732E2043726173207665686963756C612C20646F6C6F722075742070656C6C656E74657371756520616C697175616D2C206572617420656E696D20617563746F72206D617373612C207665686963756C61206C6F626F72746973206F64696F2065726F732071756973207175616D2E2050726F696E2064617069627573206E6571756520696E20656E696D2E2050726F696E20656C69742E20496E74656765722072686F6E6375732074696E636964756E7420656C69742E204675736365206C6F72656D206D657475732C2073656D7065722061632C20766F6C75747061742076697461652C20666163696C697369732075742C2074656C6C75732E20446F6E65632076656C20747572706973207669746165206E69736920706861726574726120706F72747469746F722E204D616563656E617320746F72746F722E204675736365206D692E204E756C6C616D206E6563207475727069732E2053656420736F64616C657320766573746962756C756D206E756E632E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A50656C6C656E74657371756520646F6C6F7220646F6C6F722C206C616F726565742065752C20616C697175657420717569732C207363656C657269737175652073697420616D65742C20617263752E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C616D206375727375732075726E61206567657420656C69742E205175697371756520626C616E6469742073617069656E20616320616E74652E2050726F696E206E756C6C612065726F732C206772617669646120766F6C75747061742C20736F64616C65732076656C2C206D6F6C6C69732065752C206D617373612E204E756C6C612074726973746971756520736F6C6C696369747564696E206E69736C2E20437572616269747572207669746165206C6F72656D2076697461652076656C69742065676573746173206F726E6172652E2041656E65616E20656765742065726F732E20416C697175616D206572617420766F6C75747061742E20467573636520612075726E61206964206F64696F20616C697175657420636F6E76616C6C69732E204375726162697475722073697420616D6574206E69736C20706F7375657265206C656F20706F737565726520646170696275732E2044756973206D6574757320657261742C206C75637475732076656C2C2072686F6E6375732061742C20636F6E76616C6C69732073697420616D65742C20656E696D2E20566976616D75732068656E6472657269742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D206567657420656C69742E0A0A4E756C6C616D2061206E756E632E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206D657475732075726E612C2074696E636964756E742065742C206C6163696E69612073697420616D65742C206C6F626F727469732076697461652C206C6967756C612E2050726F696E206574206D6175726973207669746165206D6920616363756D73616E2070656C6C656E7465737175652E20457469616D207175616D2070757275732C2068656E647265726974207365642C20666575676961742076697461652C20657569736D6F6420656765742C20746F72746F722E20557420616C697175616D206D61676E61207669746165206A7573746F2E2053757370656E6469737365206E6F6E206A7573746F2076656C2076656C697420636F6E64696D656E74756D2074656D7075732E20447569732074656D70757320697073756D2076697461652074656C6C75732E2050726F696E20696E206D617373612E20457469616D20756C6C616D636F727065722064696374756D2074656C6C75732E2050726F696E20616C69717565742066656C6973206174206C656F206C616F726565742070756C76696E61722E20566573746962756C756D20617263752070757275732C206D616C6573756164612073697420616D65742C206375727375732065752C20706C6163657261742073697420616D65742C206E756E632E204E616D206D61737361206F64696F2C20736F6C6C696369747564696E20696E2C2061646970697363696E6720612C20616C697175616D206E65632C2072697375732E20416C697175616D20626C616E6469742068656E647265726974206C696265726F2E204D617572697320677261766964612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204375726162697475722061206E6962682E20557420696E74657264756D206665726D656E74756D206E657175652E2050656C6C656E74657371756520736564206E756E632E204D6175726973207665686963756C61206E697369206574206E756E632E205072616573656E74206C6F72656D2E20446F6E65632073656D7065722E20496E7465676572206575206C6163757320696E2065737420616C697175616D2068656E6472657269742E20566573746962756C756D2065676574206E657175652E205365642073656D706572206C75637475732076656C69742E20437572616269747572206E6962682061756775652C20636F6E6775652065752C2068656E6472657269742069642C20636F6E6775652065742C20656E696D2E20496E746567657220706C61636572617420616C697175616D206C65637475732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20566976616D75732076697461652065726F732E20446F6E65632076656C206E69736C2E0A0A496E20766573746962756C756D20666163696C697369732075726E612E2055742072697375732E204D61757269732070686172657472612E2050656C6C656E746573717565206D61747469732E20496E746567657220737573636970697420616C697175616D20697073756D2E204475697320626C616E6469742C2073617069656E20657420756C7472696369657320636F6E64696D656E74756D2C2066656C6973206D6920656C656D656E74756D20706564652C206E6563207361676974746973206D65747573206D61757269732071756973207175616D2E205175697371756520616363756D73616E20617263752076656C206E756C6C612E20437261732073656D2073617069656E2C20706F72747469746F722069642C20756C747269636965732073616769747469732C206C75637475732065752C206E756C6C612E20496E746567657220717569732065726F732E204D6F726269207365642075726E6120612074656C6C7573207665686963756C612076756C7075746174652E20457469616D206E656320617567756520656765742066656C69732073656D706572207472697374697175652E205175697371756520757420646F6C6F722076656C2072697375732064696374756D20636F6E7365717561742E20536564206567657420646F6C6F7220736564206E756E63206C6163696E696120616C69717565742E2053757370656E646973736520616320746F72746F7220696E20697073756D20706F73756572652076656E656E617469732E20536564206567657420657261742E204E756C6C612066617563696275732E2044756973206C616F726565742C206D6173736120706F72747469746F7220616C697175657420656765737461732C20697073756D206C65637475732072686F6E637573207175616D2C20696E2061646970697363696E672065726F732073656D2075742074656C6C75732E2050656C6C656E74657371756520666575676961742074656D707573207175616D2E20566976616D757320696420646F6C6F7220656765742073617069656E20636F6E7365637465747565722074656D706F722E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120696163756C6973206665726D656E74756D206C696265726F2E204375726162697475722066617563696275732C206D61737361206D616C657375616461206375727375732074696E636964756E742C20657261742073656D20656C656966656E64206D61757269732C20736564206672696E67696C6C61206D6920616E74652061632070757275732E204475697320656C656D656E74756D206C65637475732E204E756E63206F726E617265206172637520657520746F72746F722E20566573746962756C756D2076656C20646F6C6F72206174207075727573206C6163696E6961206672696E67696C6C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E616D20696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204D616563656E61732074696E636964756E742C2065726F73206120656765737461732070656C6C656E7465737175652C2072697375732072697375732064696374756D206C696265726F2C20696420616C6971756574206D65747573206A7573746F20696E206D617373612E2050726F696E20612074656C6C75732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205365642070757275732E20536564206E6F6E20706564652E2041656E65616E206D617373612073617069656E2C20736F64616C65732073697420616D65742C20636F6E7365717561742064696374756D2C20656C656966656E642076697461652C20746F72746F722E20446F6E656320756C747269636573206C6163696E696120656C69742E0A0A4D6F7262692061646970697363696E6720736F64616C657320646F6C6F722E20557420756C6C616D636F7270657220756C74726963696573206573742E20496E2076656E656E617469732074656D7075732061756775652E2053757370656E646973736520746F72746F7220646F6C6F722C20616363756D73616E2065742C20737573636970697420612C2074696E636964756E742075742C206C696265726F2E20416C697175616D207363656C65726973717565206D61676E61207365642066656C69732E2051756973717565207574206E756E632061206D61676E612076756C70757461746520706C6163657261742E20416C697175616D2072686F6E637573207665686963756C61206475692E2053656420746F72746F722E204E756C6C616D2073697420616D6574206469616D2E204E756E63207365642065726F732E20536564206574206F64696F2074696E636964756E7420656C6974206772617669646120636F6E76616C6C69732E20437572616269747572207175697320746F72746F722061206C616375732073656D706572207661726975732E204D6175726973206174206175677565206E6F6E206D6920736F6C6C696369747564696E20616C697175616D2E20496E746567657220756C6C616D636F727065722E2050656C6C656E746573717565207375736369706974207175616D206E6F6E2070757275732E20416C697175616D2061632065726F73206174206172637520756C6C616D636F7270657220636F6E7365637465747565722E2053757370656E6469737365207072657469756D206D6174746973206C656F2E0A0A44756973206174206E756E632E2053656420646F6C6F72206573742C207661726975732061632C20706F7274612065742C2074696E636964756E742068656E6472657269742C2072697375732E20566976616D7573207574206D61676E612E205072616573656E74207574206D61757269732E20496E207075727573206C616375732C206D6174746973207365642C20766573746962756C756D206E65632C2074656D706F722061742C206E69736C2E204372617320756C6C616D636F727065722076656E656E617469732074656C6C75732E20557420646F6C6F722E204D616563656E6173206D616C6573756164612C207065646520612070756C76696E6172206D61747469732C2061726375206469616D207665686963756C612072697375732C207175697320706F72747469746F72206175677565206D6173736120696E2076656C69742E204E756E6320636F6E6775652E204D6F7262692076656C6974206D657475732C2072686F6E6375732065742C20616C697175616D20636F6E7365637465747565722C20756C74726963696573206D616C6573756164612C206C6967756C612E205365642076656C6974206E69736C2C2073616769747469732076697461652C20706861726574726120612C20706F7375657265207365642C206D617373612E204E756C6C6120666163696C6973692E20496E207661726975732C206C6967756C61206964206C6F626F7274697320736F64616C65732C206175677565206F726369206665726D656E74756D2074656C6C75732C2065752070756C76696E6172207269737573206C6967756C6120612073617069656E2E204D6F726269206C616F7265657420697073756D206E6F6E206D692E204E616D20637572737573206C6F72656D207574206D692E20566976616D7573206D61676E6120656E696D2C20706F7375657265206E6F6E2C2073656D70657220717569732C20736F64616C65732065752C20617263752E20457469616D206D692070757275732C207072657469756D20666575676961742C20766172697573207365642C2070656C6C656E74657371756520656765742C206C6967756C612E20496E206C656F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E6563207669746165206F726369206575206F72636920736F6C6C696369747564696E20666575676961742E0A0A5072616573656E74207075727573206D617373612C20657569736D6F642076697461652C2074656D707573206E65632C20636F6E7365717561742068656E6472657269742C206D657475732E2041656E65616E2066656C6973206573742C20656765737461732076697461652C20616363756D73616E20656765742C2070656C6C656E74657371756520696E2C2073617069656E2E204475697320646170696275732070656465206E6F6E2073617069656E2E204E756E632075726E612E20496E74656765722076656C206C696265726F2E204475697320617567756520617263752C2064617069627573206E6F6E2C20666163696C697369732076697461652C20706F73756572652075742C2065726F732E20446F6E6563207669746165206E756E632073697420616D6574206172637520696D706572646965742064696374756D2E204D6F72626920656C656966656E642C206C6F72656D20657520636F6E73656374657475657220766573746962756C756D2C206469616D206E756E63206F726E61726520617263752C2061632074656D706F722066656C697320646F6C6F7220656765742065726F732E2050686173656C6C7573206D617373612073656D2C20736F6C6C696369747564696E2061632C20736F64616C657320677261766964612C206C756374757320612C207175616D2E204E616D206E65717565207175616D2C20766976657272612061742C2076656E656E6174697320717569732C207361676974746973206E6F6E2C20656E696D2E0A0A4E756C6C6120666163696C6973692E2050656C6C656E7465737175652065676573746173206C6163696E6961206573742E205365642074696E636964756E742C2070656465207365642074696E636964756E7420766573746962756C756D2C2075726E6120646F6C6F722061646970697363696E672070757275732C207669746165206672696E67696C6C612066656C697320656C697420696E206E6962682E204E756C6C6120736564206E6973692E204D6175726973207375736369706974207363656C6572697371756520617263752E20457469616D206E6F6E20656E696D2076656C2065726F7320616363756D73616E206D616C6573756164612E204E756E632074696E636964756E7420636F6D6D6F646F206D61757269732E20496E2074696E636964756E7420726973757320717569732075726E612E204E756C6C61206469616D20746F72746F722C20616C69717565742065742C2074696E636964756E7420717569732C20736F6C6C696369747564696E2061632C20746F72746F722E2043726173206E69736C206E657175652C2076756C7075746174652073757363697069742C206D6F6C657374696520717569732C2070756C76696E61722061742C206E756C6C612E204E756C6C616D206163206D65747573206E6563206F64696F20706F7375657265207661726975732E2043726173207365642070656465206E65632064756920706F737565726520626962656E64756D2E204475697320657569736D6F6420756C6C616D636F72706572206C696265726F2E20416C697175616D2066617563696275732070756C76696E6172207475727069732E0A0A496E207574206E65717565206964206E756E63206665756769617420636F6D6D6F646F2E20437572616269747572206469676E697373696D2C2066656C697320617420736F6C6C696369747564696E206C6163696E69612C20656E696D20656C6974207375736369706974206E657175652C20736564206C7563747573206C6F72656D20697073756D20696E206C656F2E204475697320646170696275732C206F64696F207175697320617563746F7220636F6D6D6F646F2C206E69736C206F64696F206D61747469732074656C6C75732C206E65632074696E636964756E7420747572706973206469616D20696E20617263752E2043757261626974757220612073656D2E204E756C6C616D20766F6C7574706174206D61676E612E2050656C6C656E7465737175652073616769747469732C206E6571756520636F6E736571756174207072657469756D206375727375732C20646F6C6F72206C6163757320636F6E73656374657475657220617263752C20736564206C616F72656574206573742075726E61206574206D657475732E2053757370656E646973736520706C6163657261742C20647569206120706F7274612074656D706F722C206C6F72656D20647569206C6F626F72746973206E657175652C207365642076656E656E61746973206469616D20656E696D2069642065726F732E20457469616D206574206E69736C206E6F6E206C656374757320666175636962757320636F6E7365637465747565722E204D6F726269207363656C657269737175652C2073656D206E65632074656D70757320756C6C616D636F727065722C20697073756D206469616D2066657567696174206C6F72656D2C2061206672696E67696C6C612073617069656E20656C69742071756973206E6962682E204E756C6C616D206469616D2075726E612C2076697665727261207365642C2070686172657472612072686F6E6375732C2074696E636964756E742076656C2C206F7263692E20496E746567657220616363756D73616E206D617474697320657261742E204E616D2064696374756D2E204D6175726973206E6563206C656F2E204E756C6C6120696163756C69732E204E756C6C61206E69736C206D692C206461706962757320717569732C207665686963756C6120612C2063757273757320656765742C206F64696F2E0A0A50686173656C6C7573206461706962757320657569736D6F64206E6962682E20566976616D757320696D7065726469657420616E746520696E206C6967756C612E2050656C6C656E74657371756520616363756D73616E2E20496E20696D706572646965742C20647569206120617563746F72206672696E67696C6C612C206D65747573206E6973692063757273757320646F6C6F722C2076656C206C7563747573206C6967756C61206C6F72656D207669746165206D61757269732E205072616573656E74206D617474697320766573746962756C756D20656C69742E20416C697175616D20656E696D206C616375732C2070756C76696E6172206E6F6E2C206C6163696E69612073697420616D65742C20656C656966656E64206E6F6E2C2076656C69742E20566573746962756C756D206163206C656F2E204D617572697320696D70657264696574206A7573746F206163206C65637475732E20536564206D6F6C6573746965206C656374757320736564206475692E20536564206665726D656E74756D2074656D707573206D61757269732E204E616D206F726E617265206F7263692061632074656C6C75732E205574206D616C6573756164612C206C61637573206964206C6163696E696120616363756D73616E2C206469616D20656C69742061646970697363696E67206D657475732C20657420626962656E64756D2073617069656E206E69626820626C616E646974206F7263692E2053757370656E646973736520697073756D2074656C6C75732C20736167697474697320717569732C20766573746962756C756D206E6F6E2C2076756C7075746174652065752C2065726F732E205072616573656E74206174206E756C6C612069642070656465207363656C6572697371756520756C747269636965732E204372617320626C616E646974207072657469756D2074656C6C75732E204D616563656E6173206461706962757320636F6E64696D656E74756D2061756775652E2050686173656C6C75732074696E636964756E74207068617265747261206C6F72656D2E204D6F726269206E6F6E2065726F732E205365642074656D706F722C206E69736C20612074696E636964756E742074696E636964756E742C2065726F73206469616D2064696374756D2073656D2C2076656C206469676E697373696D20616E7465206469616D20736564206D61676E612E205072616573656E74206E6F6E206C6967756C61206964206D65747573206D6F6C657374696520636F6E7365637465747565722E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E64697373652076656C206D692E2043757261626974757220616E7465206E756C6C612C2072757472756D20612C20636F6E76616C6C69732076656C2C207665686963756C612061632C206E756E632E204E756E632073616769747469732C20656E696D2073697420616D657420617563746F722072757472756D2C206D617572697320617263752076756C707574617465206E657175652C20657420657569736D6F64206573742066656C6973207175697320616E74652E20566573746962756C756D207475727069732074656C6C75732C2068656E64726572697420696E2C206C6163696E696120636F6D6D6F646F2C20756C6C616D636F7270657220677261766964612C2072697375732E204D61757269732072686F6E637573206C6163696E69612072697375732E204D616563656E617320736F6C6C696369747564696E2065726174207669746165206E756E632E205072616573656E74207072657469756D2070656C6C656E7465737175652061756775652E20446F6E656320696E74657264756D2E205072616573656E742061632065726F732076697461652065726174206C6F626F72746973206672696E67696C6C612E2041656E65616E20636F6E7365717561742074656C6C75732E204E756C6C6120616363756D73616E20626962656E64756D2066656C69732E204D616563656E6173207072657469756D20616E7465206964206E6973692E2041656E65616E206D6920617263752C2073656D706572207365642C206D61747469732065752C2076656E656E617469732073697420616D65742C20617263752E20446F6E656320616C697175657420657569736D6F64206C656F2E2050726F696E206D61676E61206A7573746F2C2074726973746971756520612C2073656D7065722061632C20736F6C6C696369747564696E20612C206C6967756C612E204D6F7262692076656C69742E20416C697175616D2076656C206E6973692E0A0A496E2061206C6F72656D207574206E756E63206665756769617420636F6E6775652E20446F6E6563206665726D656E74756D20626962656E64756D206475692E2050726F696E207661726975732065737420717569732076656C69742E20446F6E656320616C69717565742073656D20616363756D73616E206D692E2053656420706C6163657261742E204E756C6C616D206163206E6973692061206D61737361206C6F626F727469732073757363697069742E204E756E63206964206C656F2E20416C697175616D206574206D617373612E204E756C6C616D20766573746962756C756D20656C656D656E74756D206D657475732E20496E20636F6E736563746574756572206E6973692076656C206A7573746F2E204D616563656E6173206567657420707572757320736564206D61737361207661726975732070656C6C656E7465737175652E2050686173656C6C75732066617563696275732066656C697320717569732066656C69732E2041656E65616E206F64696F20617263752C20626C616E64697420717569732C20666163696C6973697320696E2C20696D706572646965742065752C206C6F72656D2E204E616D20706F73756572652070756C76696E6172206D692E204675736365207472697374697175652C206D617572697320657420636F6E73656374657475657220756C747269636965732C206D6175726973206C65637475732074656D706F72206A7573746F2C206174206672696E67696C6C61206573742065737420736564206E6973692E20517569737175652066617563696275732E2053656420696E20746F72746F722074696E636964756E7420657374206C6163696E696120696163756C69732E204D616563656E61732061206D617373612E2050656C6C656E7465737175652061206E69626820617420707572757320706F7274612068656E6472657269742E0A0A4E756C6C616D207475727069732E2046757363652061632073656D20736564206F64696F2070656C6C656E74657371756520696D706572646965742E2043757261626974757220696E20617263752E205072616573656E74206C61637573206C616375732C20666575676961742069642C2070756C76696E617220696E2C2074696E636964756E74207365642C206E657175652E204D616563656E61732076697665727261206F64696F206567657420746F72746F722E20496E746567657220616C697175616D2C206C6F72656D2072757472756D2076656E656E61746973206469676E697373696D2C206C6967756C61206D61676E61206D616C65737561646120617263752C2076656C2066657567696174206C6F72656D20697073756D2071756973206D617373612E204D6F72626920616E74652E20566573746962756C756D206D6175726973206C696265726F2C20756C6C616D636F7270657220717569732C20756C74726963657320717569732C20666163696C69736973206E6F6E2C206D617373612E204D616563656E617320696D706572646965742E20416C697175616D206572617420766F6C75747061742E2050656C6C656E746573717565206469676E697373696D2067726176696461206C65637475732E20496E206E696268206F64696F2C20617563746F7220656765742C206461706962757320717569732C206469676E697373696D2076656E656E617469732C20617263752E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20447569732070656C6C656E746573717565206C6967756C612071756973206D617373612E2043757261626974757220636F6E64696D656E74756D2C206A7573746F2065676574206F726E617265206C75637475732C206C6F72656D206C6967756C6120736167697474697320706564652C206120706F727461206E756E63206E756E6320696E206E657175652E20517569737175652066656C6973206D61757269732C20636F6E64696D656E74756D2076697461652C20617563746F722076697461652C2074696E636964756E7420717569732C20706564652E204E756E63206C6163696E696120616E746520696E206C656F2E2050656C6C656E746573717565206C696265726F2E2041656E65616E2061206C6967756C61206574206E756E6320766573746962756C756D20636F6E7365637465747565722E0A0A4675736365206F726E6172652E205072616573656E742069642075726E612E20496E74656765722076656E656E617469732C207175616D206E6F6E20736167697474697320616363756D73616E2C20616E7465206E6962682073616769747469732061756775652C20736F6C6C696369747564696E2061646970697363696E6720646F6C6F722076656C697420657520657261742E2050726F696E207175697320656E696D206575207075727573207665686963756C6120616C697175616D2E204E756C6C612076656C20656E696D2076656C20656C697420736F6C6C696369747564696E206672696E67696C6C612E20416C697175616D206572617420766F6C75747061742E205365642073757363697069742066656C6973207574207475727069732E20457469616D2072757472756D20726973757320696D70657264696574206573742E20416C697175616D20612074656C6C75732061742074656C6C757320636F6D6D6F646F20646170696275732E204D61757269732072757472756D206D61676E61206574206F64696F2E20496E20617420646F6C6F722E20437572616269747572207665686963756C61206C656374757320696E20746F72746F722E204675736365206A7573746F2070757275732C206C75637475732076697461652C206D6F6C6C697320696E2C2070686172657472612061632C2070757275732E204E756C6C616D20706F737565726520696E74657264756D206A7573746F2E20437572616269747572207669746165206C616375732076656C206C656F20636F6E6775652070756C76696E61722E0A0A41656E65616E20656C656966656E64206E6962682076617269757320746F72746F722E2053757370656E64697373652076656C2065726F732E2050726F696E206E6563206469616D206120746F72746F7220756C747269636573206F726E6172652E20416C697175616D207363656C657269737175652066657567696174206A7573746F2E20566976616D757320616E74652075726E612C2061646970697363696E672076697461652C20706F72747469746F722065752C20736F64616C65732065742C2066656C69732E2053757370656E646973736520706F74656E74692E20437572616269747572206163206D6173736120696E206E69736C207361676974746973206D6F6C6C69732E204E616D207175616D206C6967756C612C20636F6E73656374657475657220656765742C20696163756C69732061742C207661726975732065752C206C656F2E204475697320646F6C6F72206C6967756C612C2074696E636964756E742061742C20756C6C616D636F72706572207365642C20616363756D73616E20616C697175616D2C206C6967756C612E2050686173656C6C75732076756C7075746174652C206C6F72656D2061742074696E636964756E742070686172657472612C207269737573206C6563747573206C6163696E6961206D61676E612C20717569732072757472756D20656E696D206D61676E612061742073656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E20447569732069642073656D2061206D617572697320736F6C6C696369747564696E2074696E636964756E742E20457469616D2065752070757275732065752061726375206672696E67696C6C612061646970697363696E672E20566976616D7573206F726E6172652074656D707573206469616D2E2050726F696E20747572706973207175616D2C206C6163696E6961206E6F6E2C20656765737461732061742C20636F6D6D6F646F20656765742C20706564652E205072616573656E742076756C70757461746520726973757320696E206573742E204E756C6C6120666163696C6973692E0A0A557420656C656D656E74756D206C6163696E69612070757275732E2050726F696E2076697461652061726375206163206E756C6C6120636F6E76616C6C697320616C697175616D2E204E756C6C6120636F6E6775652C206C696265726F2069642070656C6C656E746573717565206D61747469732C207175616D206C656374757320706F72747469746F72206469616D2C2061207363656C6572697371756520647569206C696265726F20696E2073617069656E2E204E756C6C616D2066656C6973206469616D2C207665686963756C612076656C2C206D6F6C65737469652075742C20766573746962756C756D20616C697175616D2C2073617069656E2E20446F6E656320636F6E76616C6C69732C2065737420757420656C656D656E74756D20766F6C75747061742C206D617572697320697073756D20677261766964612073656D2C20636F6D6D6F646F20666163696C697369732073617069656E206C65637475732073656D706572206C65637475732E205175697371756520706F72747469746F722065726F73207574206E6962682E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20457469616D206D617474697320726973757320736564206F64696F2E20566573746962756C756D206574206F64696F2E20496E206861632068616269746173736520706C617465612064696374756D73742E204E616D20747269737469717565206D61737361207574206C6967756C612E2051756973717565206E6962682074656C6C75732C207665686963756C612073697420616D65742C2061646970697363696E672061742C20636F6E76616C6C6973206E65632C206C6967756C612E20566573746962756C756D207072657469756D2C206D69206E6563206672696E67696C6C6120626962656E64756D2C20647569206E756E6320736F64616C657320706564652C20612073656D706572206D61676E61206E696268206E6F6E206469616D2E20446F6E6563206D61737361206E756E632C20766976657272612076656C2C20636F6E73656374657475657220706F7274612C2064617069627573206E6F6E2C20697073756D2E2044756973206E69736C206D61757269732C206375727375732076656C2C2073656D706572206E6F6E2C20736F6C6C696369747564696E20626962656E64756D2C2066656C69732E20566573746962756C756D206575206E657175652E0A0A43726173206E656320646F6C6F722E20446F6E6563206C616F726565742074656D707573206C65637475732E20437261732073656420746F72746F7220696E74657264756D206C6163757320656C656966656E64206469676E697373696D2E204D616563656E61732073697420616D657420656C69742E204E756C6C616D207175697320646F6C6F722076656C20647569207068617265747261206C75637475732E20496E2073697420616D6574207175616D2073697420616D6574207065646520756C74726963657320756C7472696365732E204D616563656E6173206469616D2E20496E74656765722075726E612E204375726162697475722064696374756D2C2076656C69742073656420706C6163657261742073757363697069742C206572617420747572706973206665726D656E74756D206A7573746F2C2073656420696E74657264756D206E657175652073656D206574206E6962682E20566976616D757320636F6E73657175617420636F6E76616C6C6973206D61676E612E204E616D20616C697175616D2C2065737420616320626962656E64756D20636F6D6D6F646F2C206D61676E61206573742064696374756D206D692C207669746165206D616C65737561646120656C6974206D61676E61207669746165206F64696F2E204D616563656E61732074656D706F722076756C7075746174652074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206475692E20457469616D20616363756D73616E207065646520636F6E67756520746F72746F722E0A0A4D6F7262692074656D706F72206C696265726F206163206C6F72656D2E20496E20616C697175657420766172697573206D61676E612E20496E20617263752E2050686173656C6C7573206F64696F2E2046757363652074696E636964756E7420616C69717565742066656C69732E20517569737175652076656C69742E20536564206C75637475732E20416C697175616D2066657567696174206672696E67696C6C61206D692E20416C697175616D206D6F6C657374696520766976657272612072697375732E2050726F696E20617263752E20566573746962756C756D206C6F626F727469732074656D707573206E6973692E205072616573656E742061206172637520696E2076656C697420766976657272612072757472756D2E0A0A496E20736564206C65637475732E20446F6E656320726973757320646F6C6F722C20626C616E6469742073697420616D65742C20656C656D656E74756D20636F6E76616C6C69732C20706861726574726120717569732C20706564652E20496E7465676572206F726E6172652E2041656E65616E20656765737461732064617069627573206A7573746F2E20536564207175616D206C656F2C20706F73756572652061742C20656C656D656E74756D2076697461652C20636F6D6D6F646F20656765742C206573742E20416C697175616D206D6F6C65737469652072686F6E63757320656E696D2E2043757261626974757220696163756C697320756C74726963657320706564652E204D6F72626920616C69717565742072757472756D206C616375732E20416C697175616D207175616D2E2053656420636F6D6D6F646F2C2074757270697320696E20706861726574726120706F73756572652C206D6920726973757320696D7065726469657420657261742C206120766573746962756C756D206D617373612074656C6C7573207665686963756C612073656D2E204D6175726973206672696E67696C6C6120756C747269636573206E756E632E204E616D206E69736920656E696D2C20656C656966656E642073697420616D65742C20756C747269636573207365642C206665726D656E74756D206E6F6E2C2061756775652E2050726F696E20636F6E677565206C6F626F72746973206E6973692E204D616563656E61732068656E6472657269742E204E616D20736564206E69736C2E204E756E6320656C656D656E74756D206F64696F2065752072697375732E20496E206D657475732E2050686173656C6C75732067726176696461207072657469756D206C6967756C612E204E756C6C61207669746165206E657175652E204E616D206E69736920746F72746F722C206F726E617265206E6F6E2C20626C616E6469742061742C206375727375732065752C20746F72746F722E0A0A4475697320626962656E64756D20697073756D20696E206E756E6320637572737573206D6F6C65737469652E204E756E63206F7263692E204E756C6C616D206E656320616E7465206E6F6E20657374206469676E697373696D20766976657272612E204D617572697320626C616E6469742C2076656C69742069642066657567696174207072657469756D2C20656C6974206D61676E612070656C6C656E74657371756520646F6C6F722C206174207361676974746973206C616375732076656C69742065676573746173206D61676E612E2050656C6C656E746573717565206375727375732C206469616D20636F6E736563746574756572207361676974746973206672696E67696C6C612C20746F72746F72206E6973692061646970697363696E67206E756E632C20657520766172697573206C6163757320726973757320616320656C69742E204D6175726973206964206E6973692071756973206C656F20657569736D6F642076656E656E617469732E2050656C6C656E74657371756520616320616E74652E204D617572697320617263752073617069656E2C2074656D706F722061742C20706F72747469746F722069642C20636F6E64696D656E74756D2075742C206475692E20457469616D206665726D656E74756D20756C747269636965732061756775652E20437261732075742065726F73206174206A7573746F20756C7472696369657320696163756C69732E2044756973206469676E697373696D2C206E69736C20657420666163696C69736973206665726D656E74756D2C2065726174207075727573206D6F6C65737469652074656C6C75732C20717569732074656D70757320697073756D206C656374757320617420656C69742E204E756C6C61207669746165206C6F72656D2E0A0A41656E65616E2076656C2073656D206574206469616D2073656D70657220636F6E6775652E20496E20626962656E64756D206469616D20717569732074656C6C75732E204E756E6320666163696C6973697320756C74726963696573206E6962682E2043726173206E756E6320656E696D2C2066657567696174207365642C20756C7472696365732076697461652C2073616769747469732076697461652C20697073756D2E204675736365207669746165206E756C6C612E20446F6E65632070656C6C656E7465737175652C2076656C697420696E20706F72747469746F7220656C656966656E642C20657374206E65717565206C6F626F727469732076656C69742C2073697420616D65742072757472756D20616E746520746F72746F72206E656320646F6C6F722E20446F6E6563207665686963756C612E204E756C6C6120666163696C6973692E20536564206567657374617320756C747269636573206E6962682E20446F6E656320656C6974206C65637475732C20636F6E76616C6C697320706F72747469746F722C20616C697175657420646170696275732C206665756769617420656765742C206C6967756C612E2053656420636F6E736563746574756572206A7573746F2E204D616563656E617320612073617069656E2073697420616D6574206E6973692064617069627573206C6F626F727469732E20566976616D7573206C7563747573206C6F72656D206E6F6E206E756C6C612E2053656420656765742065726174207669746165206C696265726F20696E74657264756D20706F73756572652E20437261732070756C76696E61722E204E756C6C616D20696D706572646965742C20646F6C6F722074656D706F72206469676E697373696D20626C616E6469742C206475692073617069656E2072686F6E637573206E657175652C206964206D616C657375616461206175677565206D61676E612073697420616D65742075726E612E204475697320736564206D61757269732E0A0A4D6F72626920616363756D73616E2E20536564206D61757269732061756775652C206672696E67696C6C61206E6F6E2C20617563746F722075742C20617563746F722065742C206F7263692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320757420706564652E20446F6E6563207669766572726120656E696D2076656C206C6F72656D2E2050656C6C656E746573717565206E65717565206D61757269732C20696E74657264756D2065752C2076656E656E617469732069642C20636F6E64696D656E74756D2065752C2073617069656E2E20446F6E656320697073756D20617263752C206C6163696E69612061646970697363696E672C206C616F726565742065742C206375727375732076656C2C2076656C69742E205574207361676974746973206D617572697320717569732072697375732E20496E7465676572206575206F64696F207669746165206C61637573207669766572726120616363756D73616E2E204D6F726269206C656F20616E74652C206469676E697373696D207365642C2076617269757320717569732C20766F6C75747061742076697461652C206E6973692E204E756C6C6120706C61636572617420696E74657264756D20656C69742E20446F6E6563206E65717565206475692C2073616769747469732076697461652C20736F6C6C696369747564696E20717569732C20636F6D6D6F646F2076697461652C206E657175652E204E756C6C612071756973206C6967756C61206F726E617265206C6967756C612064696374756D206F726E6172652E204D61757269732072757472756D2072757472756D206E657175652E2041656E65616E207665686963756C612074656D707573206573742E20446F6E656320766172697573207363656C6572697371756520706564652E20446F6E656320706C6163657261742076756C707574617465206C656F2E204E756C6C616D206E756E63206E69736C2C20706F7375657265206E6F6E2C20666575676961742076697461652C2070656C6C656E74657371756520717569732C206D61757269732E20496E20647569206E657175652C2063757273757320656765742C20736167697474697320656765742C20646170696275732076697461652C206D692E2050726F696E2065676574206573742E0A0A467573636520706F727461206573742E204D6175726973206D61676E612E20416C697175616D20697073756D206C616375732C20756C747269636965732069642C20766573746962756C756D206C75637475732C20616363756D73616E2075742C20616E74652E20536564206D61757269732E205365642061646970697363696E67206C656F2073697420616D6574206D61676E612E2053757370656E646973736520706F74656E74692E204E756E63206D6173736120656C69742C206672696E67696C6C6120656765742C20656765737461732076697461652C206C75637475732076697461652C20646F6C6F722E2050686173656C6C75732071756973206E756C6C61206575206E69736920696E74657264756D20736F6C6C696369747564696E2E204E756C6C616D2069642074656C6C75732E20496E746567657220696163756C697320646F6C6F722061632070757275732E205365642076656C206D692E20437572616269747572206E6F6E206D61676E612073697420616D6574206A7573746F20636F6E64696D656E74756D2076756C7075746174652E20517569737175652074696E636964756E742070656465206575206E69736C2E20566976616D7573206C6F626F727469732E204E756E63206D65747573206D657475732C20636F6E677565207365642C2074696E636964756E74207365642C207072657469756D2061742C206F64696F2E20446F6E6563206120617263752E20496E2073656D206A7573746F2C207665686963756C61207365642C207661726975732069642C20766F6C75747061742061742C2072697375732E205072616573656E7420696163756C6973206D617373612E20496E206172637520656C69742C2068656E64726572697420656765742C20756C6C616D636F7270657220696E2C20706F7274612069642C2074656C6C75732E20446F6E65632073616769747469732068656E647265726974206469616D2E0A0A53757370656E646973736520706F74656E74692E20536564206574206469616D206574206175677565207361676974746973206C6F626F727469732E2050686173656C6C757320646F6C6F722E2055742065742061726375206567657420616E74652074656D706F7220706F73756572652E20416C697175616D206665726D656E74756D207363656C65726973717565206475692E204D61757269732061742070757275732E20446F6E656320657261742073656D2C20766573746962756C756D206E65632C2066617563696275732061632C206D617474697320612C206C656F2E2053757370656E64697373652061646970697363696E67206C6163696E69612073656D2E204E756C6C616D206F72636920617263752C2064696374756D2065742C20666175636962757320766976657272612C20646170696275732065742C206E657175652E2043726173206E756E63206469616D2C2061646970697363696E67206E6F6E2C20736F6C6C696369747564696E20696E2C20696E74657264756D2076656C2C206D617373612E204D61757269732073616769747469732C206A7573746F206174207472697374697175652074656D7075732C206D6175726973206D617572697320616C697175616D20616E74652C2073697420616D657420706F7375657265206469616D206475692065676574206C6967756C612E20496E206469676E697373696D2C206E69736C207574206C6163696E696120636F6E64696D656E74756D2C2065726174206A7573746F20706F72747469746F72206E756C6C612C206E6F6E2067726176696461206C6967756C61206D61676E612065676574206D617373612E20566573746962756C756D207669746165206C6967756C61206174206D6920766573746962756C756D2073757363697069742E2044756973206C616F726565742E204E756C6C6120636F6D6D6F646F206C696265726F2073697420616D6574206C6F72656D2E20557420656C656D656E74756D2073656D2E20496E74656765722076656C20646F6C6F722E204E616D20666163696C69736973206D6920717569732073656D20756C7472696365732073616769747469732E205365642071756973207175616D206174206D65747573206D6F6C657374696520626962656E64756D2E0A0A50726F696E2064756920656E696D2C206C6163696E696120612C20666575676961742061632C20706C6163657261742076697461652C20706564652E205175697371756520656765737461732C206C656F206567657420616C697175616D207072657469756D2C206C696265726F206A7573746F2074696E636964756E742065726F732C2075742065676573746173206175677565207065646520656C656D656E74756D206E6962682E20437572616269747572206D6F6C6C697320736F64616C657320656E696D2E20446F6E65632061756775652E2050686173656C6C757320696420697073756D20706F737565726520647569207072657469756D2066617563696275732E204D6175726973206C756374757320616E74652073656D706572206E69736920696E74657264756D2061646970697363696E672E204475697320646170696275732C206F64696F207175697320766976657272612072686F6E6375732C206A7573746F207175616D20626962656E64756D20646F6C6F722C20696420646170696275732076656C697420657261742076656C20657261742E2046757363652073697420616D6574206E69736C2076656E656E61746973207175616D20756C74726963657320636F6E64696D656E74756D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632072686F6E637573207363656C65726973717565206C6967756C612E20566573746962756C756D206D69206F64696F2C20616363756D73616E2065742C2061646970697363696E6720656765742C206F726E6172652075742C207175616D2E204E756C6C616D20626C616E646974206D6F6C6573746965206D61757269732E20437572616269747572206469676E697373696D206D6175726973206574206C6F72656D2E2053757370656E64697373652061206A7573746F2E204E616D206D617474697320666175636962757320617263752E204475697320626C616E64697420656E696D206E6F6E206D617373612E0A0A4E756C6C616D206C6F72656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E204D617572697320636F6E73656374657475657220706F7375657265206D61757269732E204D616563656E61732074696E636964756E74206D617572697320696E2065726F732E204E756C6C61206575206D65747573206575206F72636920736F6C6C696369747564696E2066617563696275732E2053757370656E646973736520616C697175616D206D6175726973206964206573742E204372617320626C616E646974206475692065742075726E612E204E756C6C6120617263752E2053656420612075726E612E204E756C6C612064617069627573207665686963756C6120746F72746F722E20446F6E65632072697375732E20536564207175616D206D657475732C20656765737461732065752C206375727375732075742C2076697665727261206E6F6E2C206F64696F2E205574206A7573746F206A7573746F2C206D616C6573756164612073697420616D65742C20626C616E6469742073757363697069742C206D6F6C657374696520696E2C206A7573746F2E20566573746962756C756D20636F6E7365717561742C207175616D20616320666575676961742074696E636964756E742C20697073756D206C696265726F20656C656966656E64206F64696F2C206E6F6E20656C656966656E64207065646520697073756D206E6F6E20616E74652E204E756C6C616D2061206D657475732E0A0A4E616D206163206E6973692061742066656C697320637572737573206D61747469732E2050656C6C656E74657371756520636F6E7365717561742073656D2071756973206F7263692E20517569737175652074656D7075732E2041656E65616E20696D70657264696574206D6F6C657374696520706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652065752074656C6C75732E204E756C6C61206469616D2065726F732C20736F64616C65732075742C20736F64616C6573206E65632C2074696E636964756E742061632C206E756E632E204E756E63206C6163696E696120666175636962757320697073756D2E20566976616D75732076656C206E6571756520696E2065726174206665726D656E74756D206C75637475732E204E756C6C612065676574206D65747573206E656320617567756520626962656E64756D20706C6163657261742E20566976616D75732074656D7075732E205072616573656E7420636F6E677565206F726E61726520697073756D2E20457469616D206D61747469732066657567696174206A7573746F2E0A0A416C697175616D206475692E2041656E65616E20636F6D6D6F646F20746F72746F72207669746165206E756C6C612E204D6F72626920657420697073756D2E204D617572697320616320697073756D2E204E616D2076656C207269737573207574206C6563747573206D6F6C6C697320766976657272612E2043757261626974757220656C656D656E74756D206D6F6C6C6973206573742E204E756C6C616D20656C69742E20566573746962756C756D207375736369706974207072657469756D20656E696D2E20566573746962756C756D207574206D617373612E2050726F696E206E65632066656C69732E204D616563656E617320677261766964612C2061726375206E656320636F6E7365717561742073616769747469732C2065726F732074656C6C7573207363656C65726973717565206D61757269732C20766974616520616363756D73616E207175616D207175616D207574206E756E632E20496E7465676572206567657420616E74652065752076656C6974206C616F72656574206D616C6573756164612E204E756E632073616769747469732C206D617572697320766974616520706861726574726120766F6C75747061742C2074656C6C75732074656C6C757320656C656966656E642065726F732C2073697420616D65742072757472756D20697073756D206E69736920612076656C69742E205072616573656E7420766172697573206C656F20657520657261742E20566976616D757320636F6E73657175617420706C6163657261742070757275732E20446F6E6563207072657469756D20656C656D656E74756D206E6962682E2050726F696E20617420656C6974206E6F6E2073656D20616C6971756574206D61747469732E2053656420756C6C616D636F7270657220697073756D2073697420616D657420656C69742E0A0A4D617572697320696E206D657475732E2053757370656E6469737365206D61676E61206C6F72656D2C2066617563696275732076656C2C2074696E636964756E7420717569732C207363656C65726973717565206E6F6E2C2074656C6C75732E2046757363652071756973206C6F72656D2E2050726F696E2061206C616375732073697420616D6574206D617572697320696163756C69732070756C76696E61722E2053757370656E64697373652072686F6E6375732065726F73206E6563206D692E205072616573656E7420657569736D6F642C207475727069732076697461652072757472756D207072657469756D2C206F64696F206D6574757320766F6C7574706174206E657175652C20656765742074656D7075732073617069656E206E657175652073656420657261742E20446F6E6563206665726D656E74756D207075727573206174206C65637475732E204E756C6C616D2073656D2E2046757363652076656C206D6920717569732065726174206C6F626F7274697320706F73756572652E2041656E65616E20656765742075726E612E2053757370656E6469737365206C6967756C612E204475697320696E206E6973692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A4375726162697475722076756C707574617465206C656374757320696420706564652E2050686173656C6C75732065752076656C69742E20457469616D2076656E656E617469732061646970697363696E67206E6962682E20416C697175616D206375727375732070756C76696E61722074656C6C75732E20566573746962756C756D206E657175652E204D6175726973206E6563206A7573746F20657420657261742073656D7065722070656C6C656E7465737175652E204675736365206D61747469732064696374756D20646F6C6F722E20457469616D2065676574207075727573206575206D617373612076617269757320656C656D656E74756D2E2050656C6C656E746573717565206D617373612E20557420756C74726963696573206469616D2073656420697073756D2E204E756C6C616D206469616D2E2050656C6C656E746573717565206964206D61676E61206964206C696265726F2074726973746971756520616C697175616D2E0A0A557420656C656966656E642C20707572757320696420706C6163657261742076656E656E617469732C2075726E6120617567756520616C6971756574206C6967756C612C20696E20756C74726963696573206C656F2072697375732065742074656C6C75732E204D6175726973206574206E756C6C612069642075726E61207472697374697175652074656D7075732E20557420666163696C697369732C2075726E6120657520766573746962756C756D2072686F6E6375732C206C616375732065726F7320636F6E736563746574756572206D657475732C2065742072757472756D20647569206C656374757320696E2070757275732E204E756E632076656C206E69736C206E6F6E20697073756D2074696E636964756E74206D6F6C6C69732E204E616D207175616D206C616375732C206F726E6172652076697461652C2072686F6E637573206E6F6E2C20636F6E677565207365642C206F64696F2E2050726F696E206E696268206475692C20706F7274612076656C2C2076656E656E61746973206E6F6E2C2070656C6C656E7465737175652075742C206E6973692E20536564207472697374697175652066656C69732061206D61676E612E2053757370656E646973736520656765742074656C6C75732E2043726173206772617669646120696D706572646965742076656C69742E20496E74656765722068656E6472657269742072697375732E2050726F696E206F7263692E20416C697175616D20756C6C616D636F72706572206D61757269732071756973206D61757269732E204E756E63206C6163696E696120766573746962756C756D206D657475732E20447569732074656C6C75732E204E756C6C616D2066617563696275732C206C656F2061632076756C70757461746520736F6C6C696369747564696E2C206C656F20646F6C6F7220666175636962757320657261742C207175697320626962656E64756D206F726369206F64696F206E6F6E20617263752E0A0A4E756C6C616D20616363756D73616E206D617474697320646F6C6F722E20446F6E6563206574206475692E205072616573656E7420612066656C6973206D6F6C6C6973206C616375732073656D706572206C6163696E69612E204375726162697475722070656C6C656E746573717565206C7563747573206573742E2050726F696E206E756C6C61206475692C20636F6E64696D656E74756D2076656C2C206661756369627573206E6F6E2C20696E74657264756D2061632C20657261742E204D616563656E6173207363656C657269737175652C206C656374757320696420766F6C757470617420616363756D73616E2C2073617069656E20746F72746F722070656C6C656E746573717565206475692C207365642073656D706572206D61676E612073656D207574206C656F2E2050726F696E206E756C6C612E204E756C6C616D206461706962757320756C6C616D636F727065722073656D2E2053757370656E6469737365207665686963756C61206D6574757320696E206E756E632E2050656C6C656E746573717565206E6F6E207175616D2076656C206172637520756C74726963657320756C6C616D636F727065722E2050686173656C6C757320717569732066656C69732073697420616D65742074656C6C757320756C6C616D636F72706572206665726D656E74756D2E20536564207665686963756C6120736F6C6C696369747564696E2075726E612E20437572616269747572207068617265747261207363656C657269737175652072697375732E2050656C6C656E746573717565206964206D617373612071756973206D6574757320616C697175616D20696D706572646965742E20496E206E756E63206C616375732C206665756769617420696E2C206772617669646120656765742C2076656E656E617469732075742C2074656C6C75732E2053757370656E646973736520706F74656E74692E204E616D20636F6E7365717561742061646970697363696E67206475692E20496E206E756C6C61206E6973692C20666575676961742075742C206665726D656E74756D2076656C2C2067726176696461206E65632C20746F72746F722E20496E207365642061756775652E0A0A457469616D20756C6C616D636F7270657220617567756520617420656E696D2E20496E7465676572206469676E697373696D2E20416C697175616D2070756C76696E617220636F6E677565206E756C6C612E204D6F72626920656E696D206D617373612C206672696E67696C6C6120612C20616363756D73616E20656765742C20636F6E64696D656E74756D206E65632C20657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2041656E65616E2070686172657472612E20457469616D20706F72747469746F722070757275732061206D657475732E20416C697175616D20696E74657264756D2073656D2065676574206A7573746F2E205175697371756520766F6C7574706174206C7563747573206573742E2041656E65616E2061756775652E2050686173656C6C757320647569206C65637475732C20756C747269636573206E65632C20636F6D6D6F646F2076656C2C20617563746F722076656C2C206E6973692E20557420756C7472696365732070656C6C656E746573717565206E6973692E20496E74656765722061632076656C69742065742073656D20696D70657264696574206C75637475732E20467573636520766974616520747572706973206964206175677565206D6F6C6C697320636F6E7365637465747565722E0A0A4D616563656E6173206E6563206C616375732E204D616563656E617320636F6E64696D656E74756D206F64696F2065752066656C69732E204D6175726973207574206E69736C207669766572726120657261742066617563696275732061646970697363696E672E20457469616D20656765737461732E204E756E6320657420646F6C6F72207669746165207269737573206469676E697373696D20636F6D6D6F646F2E204D6F726269206C65637475732076656C69742C2074696E636964756E74206E65632C20616C69717565742076656C2C206D61747469732076697461652C206C6967756C612E204D616563656E617320756C747269636965732073656D70657220646F6C6F722E2053757370656E6469737365206D616C6573756164612E20496E7465676572206D617474697320656C69742E20446F6E656320616363756D73616E2C206C6163757320666163696C69736973207661726975732074656D7075732C206E756C6C6120656C697420706F72746120657261742C2065742072757472756D20656C69742073656D2073697420616D6574206475692E0A0A4D616563656E6173206D6F6C6C6973206D69206E6F6E206E756C6C612E20566976616D7573207475727069732E2053757370656E64697373652061206D657475732E20496E2071756973206D6920696E2074757270697320636F6E67756520617563746F722E204D616563656E6173206C616375732E2053757370656E646973736520736F6C6C696369747564696E2E2050686173656C6C757320706F727461206E756E63206E6F6E206E69736C2070756C76696E617220656765737461732E20536564206E756C6C612E20566573746962756C756D206163206D692E204D617572697320756C7472696369657320636F6E64696D656E74756D206E657175652E204E756C6C612074656D707573206A7573746F2076656C206D617373612E204E756C6C6120737573636970697420636F6E67756520617263752E205072616573656E74206964207475727069732E204D6175726973206E69626820706564652C20657569736D6F642073656D7065722C206D6F6C65737469652061632C2072686F6E6375732076697461652C20616E74652E204D616563656E617320657261742066656C69732C207669766572726120736F6C6C696369747564696E2C20736167697474697320656765742C2070656C6C656E746573717565206E65632C206F7263692E20467573636520756C74726963657320636F6E736571756174206C616375732E20416C697175616D2065726174206D61676E612C20666575676961742061742C207669766572726120612C206D6F6C6C6973206E6F6E2C207475727069732E0A0A446F6E6563206D692E204E616D2064696374756D2070656C6C656E7465737175652073656D2E20446F6E6563206D6F6C6C69732072686F6E63757320656C69742E2050686173656C6C75732072686F6E63757320706564652073697420616D65742072697375732E20446F6E656320656765742061756775652E204D616563656E6173206E6F6E206C65637475732E2050686173656C6C757320736F6C6C696369747564696E206E697369206E65632066656C69732E20416C697175616D207072657469756D2C2065737420656765742073656D70657220636F6E76616C6C69732C206E696268206E756E6320736F6C6C696369747564696E2070757275732C2069642074656D706F722070656465206475692076656C206D61676E612E20566976616D7573206163206C6F72656D2E20457469616D206E69736C20746F72746F722C2061646970697363696E672064696374756D2C20656C656D656E74756D20696E2C20666163696C69736973207365642C206E6962682E2050726F696E206D61757269732E2050726F696E2072757472756D206D6173736120656765742073656D2E204375726162697475722074656D706F722061646970697363696E6720656C69742E204375726162697475722070757275732074656C6C75732C206665726D656E74756D20656765742C20616C69717565742076697461652C20636F6E76616C6C69732061632C206D61757269732E0A0A496E746567657220636F6E7365717561742076656C69742065752065726F732074696E636964756E74207665686963756C612E204E756C6C616D206C6F72656D2073617069656E2C2072686F6E637573206E6F6E2C206D617474697320717569732C20756C747269636965732073697420616D65742C20656E696D2E2043757261626974757220636F6D6D6F646F2C206C696265726F20696E20657569736D6F642073757363697069742C2073656D207075727573206672696E67696C6C6120656E696D2C206163206D6F6C657374696520746F72746F72206F7263692065742076656C69742E20446F6E656320706564652E20457469616D20706C61636572617420636F6E64696D656E74756D207475727069732E2050686173656C6C7573206567657374617320656E696D206E6563206D61676E612E20566976616D757320636F6E64696D656E74756D2C206E756C6C612076656C206C7563747573207472697374697175652C2065726F7320726973757320766573746962756C756D206E756C6C612C20696E207665686963756C61206172637520697073756D2061742066656C69732E20446F6E656320616C697175616D20656C69742061742061756775652E205175697371756520612065726F73206575206C6967756C6120616363756D73616E2064696374756D2E20457469616D207665686963756C61207475727069732071756973206C696265726F2E20416C697175616D206E6F6E206D692E20446F6E6563206574206C656F2E2050726F696E206C656F206C696265726F2C20616C697175616D2074696E636964756E742C20636F6E677565206E65632C2061646970697363696E6720706F7274612C20656E696D2E204E756C6C61206C6F626F727469732C20746F72746F722073697420616D657420696D7065726469657420756C6C616D636F727065722C20646F6C6F72206F726369206D616C65737561646120706564652C207365642067726176696461206E6962682075726E612076656C206C6F72656D2E20536564207068617265747261206D616C6573756164612065726F732E205175697371756520657569736D6F6420616C697175657420657261742E2053757370656E646973736520616C6971756574206D61747469732070757275732E0A0A4E756E63206964206E756C6C612071756973206A7573746F20636F6E67756520736F6C6C696369747564696E2E205072616573656E742065726174207475727069732C2072686F6E6375732065752C207072657469756D2065752C2070656C6C656E74657371756520612C206E6962682E20566976616D75732074656D7075732E2043726173206E65632072697375732061742074757270697320696D70657264696574206C6F626F727469732E205574206D61747469732E204D616563656E6173206573742066656C69732C2070656C6C656E746573717565206E6F6E2C20696D70657264696574207365642C20656C656966656E642074696E636964756E742C206C6F72656D2E20496E2074696E636964756E742E205365642076656C206C656F2E20446F6E65632065742075726E6120696E207475727069732068656E64726572697420626C616E6469742E20446F6E656320636F6E64696D656E74756D20616363756D73616E206573742E2055742070686172657472612C206D65747573207669746165206D617474697320636F6E7365637465747565722C206C656F207175616D2076756C707574617465206F64696F2C206E6563206C616F72656574206E6973692076656C697420657520657261742E20496E7465676572206C65637475732061756775652C206567657374617320696E2C20696E74657264756D2065752C2076656E656E617469732076656C2C2073617069656E2E2051756973717565206574206573742076697461652065726F73206C616F72656574206C6F626F727469732E204E756C6C616D207574207269737573206E6F6E206E756C6C6120706C6163657261742061646970697363696E672E205072616573656E7420646170696275732E20457469616D20612066656C69732E20557420736F64616C657320636F6E736571756174206D61757269732E2044756973206C6F72656D2066656C69732C206C756374757320612C2074726973746971756520696E2C206D6F6C65737469652061742C2072697375732E20536564207665686963756C6120626962656E64756D2074656C6C75732E204E616D20636F6E73657175617420657569736D6F64206C616375732E0A0A41656E65616E20746F72746F7220656C69742C2067726176696461206E65632C206665726D656E74756D2065752C206C6F626F727469732069642C20697073756D2E204D616563656E61732065752070757275732E204372617320616320747572706973207574206E69736920696163756C69732072686F6E6375732E204E756C6C61207075727573206D657475732C206469676E697373696D206E65632C2074696E636964756E742076697461652C20646170696275732065752C206E6962682E204675736365206C6F626F727469732C206E756E63206174207669766572726120656C656966656E642C206A7573746F20747572706973207363656C657269737175652065726F732C2061632070656C6C656E746573717565206D65747573206E69736C2061742070757275732E2053656420656C656D656E74756D2074656C6C75732073656420656E696D20696E74657264756D20626C616E6469742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E746567657220756C7472696369657320616C6971756574206F64696F2E204D61757269732065676574206E756E63206120697073756D20756C74726963657320736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2041656E65616E20616363756D73616E2E20446F6E65632073617069656E206C65637475732C20636F6E6775652061742C20706F7274612069642C2068656E6472657269742076697461652C206E69736C2E204375726162697475722076656C207175616D2076656C206E6571756520616363756D73616E206C616F726565742E204D6F7262692073617069656E206573742C207072657469756D20696E2C20636F6E7365637465747565722061632C206D6F6C6C69732075742C206C696265726F2E20446F6E65632074696E636964756E742061646970697363696E67206D657475732E204E756E6320766573746962756C756D20656765737461732061756775652E20446F6E6563207363656C65726973717565206475692075742073656D2E2053757370656E64697373652076656C206D6574757320696420657374206D6F6C657374696520696163756C69732E0A0A566976616D75732070686172657472612C20656C6974206575206D616C65737561646120626C616E6469742C206469616D20746F72746F72206D6F6C6C6973206475692C207365642070756C76696E6172206D61737361206E756E63206574206D61676E612E2053656420706C61636572617420656C697420617563746F7220746F72746F722E204E756C6C6120616320657261742E2050656C6C656E74657371756520636F6E7365637465747565722C2064756920636F6E76616C6C69732074696E636964756E7420636F6E64696D656E74756D2C2073656D206F64696F20766F6C7574706174206C696265726F2C206E6F6E20656C656D656E74756D2066656C6973206E65717565206E6563206F64696F2E204D616563656E61732068656E6472657269742065726F73206964206469616D2E204D61757269732076656C207075727573206163206F72636920636F6E76616C6C697320636F6E76616C6C69732E205365642073697420616D6574206C616375732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652064696374756D20766172697573206C616375732E204D61757269732065676574206E69736C2E2053757370656E646973736520706C6163657261742C206E756C6C61206E6F6E206F726E617265206469676E697373696D2C206E69736C206469616D2073616769747469732074656C6C75732C20696E2073656D706572206E69736920646F6C6F72206174206E6962682E204475697320756C6C616D636F7270657220766976657272612066656C69732E20496E746567657220612074656C6C75732E2053757370656E64697373652065676574206E756E632E2041656E65616E206469616D206573742C20616363756D73616E2069642C20737573636970697420696E74657264756D2C206672696E67696C6C612076697461652C206A7573746F2E2050726F696E20706564652E204D616563656E6173206174206E6571756520696E206E6571756520766573746962756C756D20656C656966656E642E0A0A566573746962756C756D206E756C6C61206C6F72656D2C20706F72747469746F7220656765742C20657569736D6F642061632C20616C697175616D2061742C206E69736C2E204D616563656E6173206574206573742065676574206D6173736120766172697573206C6F626F727469732E20496E206D692E204475697320706F72747469746F72206665726D656E74756D2070757275732E20446F6E65632063757273757320696D70657264696574206C6967756C612E204D6F726269206574206C6967756C6120657420616E7465206D6F6C6573746965207665686963756C612E204D61757269732073656420646F6C6F722E2053656420696D706572646965742066656C69732075742073656D2E20536564207669746165206E6571756520656C656D656E74756D206C656F20617563746F72206665726D656E74756D2E2044756973206665756769617420756C6C616D636F7270657220657261742E2041656E65616E2070757275732E204D6F726269206665726D656E74756D20766573746962756C756D206573742E2050656C6C656E7465737175652076656E656E61746973206D61757269732E2050686173656C6C75732070756C76696E61722E20496E746567657220697073756D206C65637475732C20696163756C697320612C206C6163696E69612069642C20616363756D73616E2069642C20617263752E2050686173656C6C7573206174206573742E204675736365206E65717565207175616D2C20756C747269636965732069642C20696163756C69732076656C2C20646170696275732076697461652C206C616375732E20496E206C6F626F7274697320636F6E76616C6C697320616E74652E204E756C6C61206E756E632070757275732C2076756C70757461746520696E2C2068656E6472657269742065742C20626C616E6469742065742C206C6967756C612E0A0A50656C6C656E746573717565206C656F206D657475732C20736167697474697320696E2C206D6F6C65737469652076697461652C2064696374756D20696E2C20706564652E204D6F726269207072657469756D2066656C6973206E6563207175616D2E2050656C6C656E746573717565206D617474697320616E746520736564207175616D20736167697474697320646170696275732E2053757370656E64697373652073617069656E2E205072616573656E7420626962656E64756D20696163756C697320746F72746F722E20447569732061206E69736C2E2041656E65616E206D692E20446F6E65632064696374756D206172637520696E206573742E204D6F72626920696E74657264756D2076756C70757461746520697073756D2E2041656E65616E2073697420616D6574206D61676E61206E6F6E206E69736C2074726973746971756520706F73756572652E2050686173656C6C75732076656C6974206D657475732C2074656D706F722061632C206665726D656E74756D20656765742C20636F6E64696D656E74756D206E6F6E2C2076656C69742E20566573746962756C756D2073697420706F73756572652E0A0A4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204372617320616C6971756574206D61737361206E6563206475692E20437261732061726375206E756E632C2068656E6472657269742061632C20656C656966656E642065752C20756C6C616D636F72706572206E65632C2074656C6C75732E205365642070686172657472612070757275732073697420616D6574207175616D2E20437572616269747572206D6F6C6C69732E204E616D20766974616520706564652E20457469616D207269737573206D617373612C207665686963756C612073697420616D65742C207068617265747261206E65632C20736F6C6C696369747564696E2075742C206475692E20446F6E65632065676573746173206A7573746F206174207175616D2E2050726F696E206E69736C2072697375732C20766573746962756C756D206E65632C207072657469756D2076697461652C207472697374697175652061632C206C6F72656D2E20416C697175616D206572617420766F6C75747061742E204372617320736564206E6962682E2050656C6C656E74657371756520736F6C6C696369747564696E20657569736D6F642061756775652E0A0A457469616D206672696E67696C6C6120736F6C6C696369747564696E206F7263692E204D61757269732063757273757320656C69742071756973206C616375732E204372617320746F72746F722E20496E2061646970697363696E672C206C656374757320696420617563746F7220766573746962756C756D2C206E65717565207065646520616363756D73616E20646F6C6F722C206E6F6E20696D70657264696574206D61676E61206469616D20616363756D73616E2076656C69742E2053757370656E6469737365206174206C696265726F207574206E69736920626C616E6469742073616769747469732E2050686173656C6C7573206E6F6E206D61757269732E20467573636520656C656D656E74756D2073616769747469732073656D2E2053757370656E646973736520616C697175616D20656C656966656E642074656C6C75732E2050726F696E206C6967756C61206C6F72656D2C20696D7065726469657420717569732C2076656E656E617469732069642C20696163756C6973206D6F6C6C69732C206E69736C2E20457469616D20636F6E76616C6C69732070656465206174206D617373612E204D6F72626920616363756D73616E20647569206574206D61757269732E0A0A53656420736564206F7263692E204E756E632070757275732E2053757370656E646973736520706F74656E74692E205574206C7563747573206672696E67696C6C61206D61757269732E20446F6E6563206E6962682E2050686173656C6C757320706F7274612E2050686173656C6C75732073697420616D6574206F64696F20736564206D61676E6120736F64616C65732070686172657472612E2043726173206C65637475732E2053757370656E6469737365206C696265726F20697073756D2C20636F6D6D6F646F206E65632C20666163696C6973697320696E2C207375736369706974206C6F626F727469732C206C6967756C612E2044756973206D61737361206E756C6C612C2073656D7065722065742C20636F6E736571756174206E65632C2070686172657472612065752C20656C69742E20566976616D757320756C7472696369657320616C697175616D206F64696F2E20566573746962756C756D2073697420616D6574206D617373612E2053656420636F6E736571756174206C61637573207365642075726E612E20457469616D2066617563696275732066656C69732076656C206F7263692E2050686173656C6C757320756C6C616D636F727065722E2041656E65616E20636F6E736563746574756572206C61637573206174206C696265726F2E0A0A436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204475697320666163696C697369732C206C6967756C6120766974616520636F6E64696D656E74756D207363656C657269737175652C2076656C6974206F72636920677261766964612066656C69732C2076656C20756C74726963696573207175616D206D69206E6F6E206469616D2E20566976616D757320617563746F72206D65747573206E6F6E206C696265726F2E205072616573656E74206C6967756C61206E6973692C20636F6D6D6F646F20636F6E64696D656E74756D2C206D6F6C65737469652065742C20766976657272612065742C206A7573746F2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320736F6C6C696369747564696E2E204E756E6320626C616E6469742063757273757320697073756D2E2041656E65616E206E6563206C6967756C612075742074656C6C757320736F64616C6573206D61747469732E20496E74656765722073656D2E20416C697175616D206964206C6967756C612E2053656420746F72746F72206D61757269732C20626C616E6469742076697461652C206375727375732076656C2C20656C656D656E74756D2065742C206E756C6C612E20416C697175616D207363656C65726973717565206D65747573206574206E69736C2E20447569732061646970697363696E67206D61676E61206174206E657175652E20517569737175652076756C70757461746520656C656966656E64206E756E632E20416C697175616D206567657420656C69742E2050686173656C6C757320647569206F64696F2C20626962656E64756D2073616769747469732C20766573746962756C756D2069642C206469676E697373696D20696D706572646965742C206F7263692E204E756C6C616D2065752066656C6973206E6F6E206E756E63206C6163696E696120736F64616C65732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A53757370656E64697373652070656C6C656E7465737175652C206C696265726F206D617474697320756C7472696369657320616363756D73616E2C20746F72746F7220746F72746F72206D616C6573756164612073656D2C20657420736F64616C6573206C696265726F206F64696F20616320697073756D2E20566976616D75732071756973206D61676E61206E656320657374207375736369706974206C6F626F727469732E20437261732074656D70757320706F7375657265206E756E632E205175697371756520757420656E696D20612066656C697320656765737461732073656D7065722E20536564207068617265747261206D6174746973206E657175652E20467573636520747572706973206E756E632C20636F6E677565207365642C20636F6E736571756174206E6F6E2C20636F6E677565207365642C206E756C6C612E2053757370656E646973736520766172697573206C6F72656D20696420726973757320706F72746120766573746962756C756D2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204675736365207365642070757275732E20496E20612066656C69732E20496E7465676572206567657374617320617563746F72206F7263692E204D617572697320756C747269636573207375736369706974206E69736C2E204E756C6C616D2070757275732E0A0A437261732074656D706F722061646970697363696E6720697073756D2E2055742071756973206D692E204D616563656E617320696E206A7573746F207574206E756C6C6120636F6E6775652070686172657472612E2050656C6C656E746573717565207574206C696265726F20657520646F6C6F722076656E656E617469732073757363697069742E205072616573656E74206665756769617420636F6E736563746574756572206E6962682E204D6F7262692066617563696275732073656D206E6F6E2066656C69732E20496E2068656E6472657269742061726375206163206D617373612E20496E20616363756D73616E20756C747269636573206D692E2050726F696E206D616C65737561646120617563746F722066656C69732E2043757261626974757220696E74657264756D2E20536564206469616D20697073756D2C20756C7472696369657320696E2C2074656D706F722073697420616D65742C207669766572726120696D706572646965742C20656C69742E204D6F726269206D6F6C6573746965206E6973692E204D617572697320697073756D2E2046757363652064696374756D206D6F6C6C6973206D61676E612E204475697320636F6D6D6F646F206469676E697373696D206E756C6C612E20566573746962756C756D20617567756520656E696D2C20756C7472696369657320717569732C20696163756C6973206E65632C2074696E636964756E742076697461652C206469616D2E204D6175726973206C6163696E69612074656D70757320697073756D2E20536564206174206D61757269732E205574206C6F72656D2E20446F6E6563206C696265726F2E0A0A4475697320696163756C6973206C6163696E6961206C65637475732E2041656E65616E20636F6E76616C6C69732065726F7320616320616E74652E205365642071756973206F726369206E656320726973757320617563746F72206672696E67696C6C612E2050686173656C6C757320666163696C6973697320656C656D656E74756D206E6973692E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E6320706F727461206C61637573206E656320616E74652E204D6F726269206D617572697320657261742C2061646970697363696E6720696E2C2070756C76696E6172206E65632C206C6F626F72746973206E65632C206F64696F2E20557420656C656966656E64206C656374757320736564207175616D2E204E756C6C616D206D6F6C6C69732E20496E206E6F6E20747572706973206574206E69736C2068656E64726572697420626C616E6469742E204475697320656C656D656E74756D2E204E756E63206E6563206C696265726F2E2053757370656E646973736520766573746962756C756D207269737573206E6F6E20706564652E204D6F72626920696D70657264696574206F64696F2073697420616D6574206C696265726F2E2053656420736564206D6173736120766974616520697073756D206D61747469732074696E636964756E742E204E756C6C61206E656320746F72746F72207669746165206C696265726F20766F6C75747061742074656D7075732E20446F6E656320616C697175616D2E0A0A4475697320736564206E756E632E2043757261626974757220747572706973206E756C6C612C207665686963756C61207365642C206C756374757320717569732C20656C656D656E74756D20656765742C2066656C69732E204D616563656E61732065742070757275732E204D616563656E6173206C656F2074656C6C75732C2074696E636964756E7420612C20666163696C697369732076697461652C206C6F626F727469732073697420616D65742C2076656C69742E20446F6E656320636F6E76616C6C69732073617069656E2E204D616563656E6173206D6F6C6C6973206F64696F206575206E6962682E20457469616D20677261766964612E20496E7465676572206D6F6C65737469652C2073617069656E206575206D6F6C6573746965206C6163696E69612C206E756E63206E69626820616C697175616D206C6967756C612C2065752073616769747469732074656C6C7573206572617420736F6C6C696369747564696E206F64696F2E20447569732065742072697375732E2050686173656C6C7573206E697369206E657175652C20706C616365726174206E65632C20636F6E64696D656E74756D206E6F6E2C20756C7472696365732065752C2073656D2E20557420706564652E20457469616D206E756C6C61206D657475732C20766F6C75747061742069642C20636F6E76616C6C6973207365642C2073757363697069742076656C2C2075726E612E20446F6E65632076656C20656C69742E205574206C656F206E657175652C2076656E656E617469732066617563696275732C206C6163696E6961206E65632C2074696E636964756E742065752C20656E696D2E2043726173206964206475692061206C696265726F207068617265747261206469676E697373696D2E20446F6E65632065726F73206C656F2C20706F72746120717569732C206C616F726565742075742C2070656C6C656E74657371756520766F6C75747061742C206C65637475732E0A0A4E756C6C616D20626C616E6469742E20416C697175616D206572617420766F6C75747061742E2046757363652061646970697363696E6720656E696D2E2053757370656E6469737365206E6F6E206475692071756973206C6967756C6120706F72746120766573746962756C756D2E20446F6E65632065752074656C6C75732076656C206C6F72656D207072657469756D20706F72747469746F722E205072616573656E74206C75637475732E20416C697175616D2061632065726F7320696E206D6173736120646170696275732074696E636964756E742E20446F6E6563207574206D61676E612E20457469616D20617563746F72206C616375732073697420616D6574206C616375732E2053656420756C7472696369657320697073756D206E656320656C69742E205175697371756520612065737420696E207075727573207375736369706974207472697374697175652E0A0A41656E65616E20736564206475692076656C20646F6C6F722070756C76696E6172206C616F726565742E20566976616D7573207665686963756C61206C6F72656D20696E20706564652E20566976616D7573206574206469616D2E20496E7465676572206163206F64696F2076656C206469616D2068656E64726572697420626962656E64756D2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E756C6C612061206E6973692E2050686173656C6C75732074696E636964756E74206475692076697461652061756775652E20447569732066617563696275732C2064756920696E74657264756D206672696E67696C6C612074696E636964756E742C206F64696F20656C697420766573746962756C756D206C696265726F2C206163206D6F6C6573746965206D61676E61206C6563747573206964206C616375732E2041656E65616E206C6967756C612E204E756C6C6120666163696C6973692E0A0A46757363652076656C2073656D2065752076656C6974206672696E67696C6C61206F726E6172652E2053656420666575676961742074696E636964756E742066656C69732E204E756C6C616D2066656C6973206D692C20657569736D6F642073697420616D65742C206D6F6C6C69732061742C20736F64616C657320656765742C2061756775652E204E616D20696D70657264696574206E6962682061742076656C69742E2053656420757420657261742E20496E206475692E204E756C6C6120666163696C6973692E204E756C6C616D206175677565206C696265726F2C2074696E636964756E74206E65632C207072657469756D2065752C2070756C76696E617220696E2C206475692E204D6F7262692076697461652066656C69732E2050656C6C656E7465737175652076656C206A7573746F2076656C2076656C6974207361676974746973206D616C6573756164612E2050726F696E207665686963756C6120626C616E646974206D617373612E20457469616D2074696E636964756E742070686172657472612075726E612E20496E206D65747573206573742C20617563746F72206E65632C20626C616E64697420612C20637572737573206E65632C207175616D2E204D6175726973206163206D657475732061206C696265726F20636F6E6775652066617563696275732E204D6175726973206D617572697320646F6C6F722C20736F64616C657320696E2C206375727375732075742C20736F64616C65732072757472756D2C2065726F732E2051756973717565206D61757269732065726F732C2073616769747469732076697461652C206C6F626F727469732075742C20656C656966656E642069642C206E6973692E0A0A41656E65616E206E657175652E20566573746962756C756D20656765737461732070656C6C656E746573717565206C6967756C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2050686173656C6C7573207361676974746973206A7573746F2076656C2072697375732E20536564207072657469756D206E657175652076697461652075726E612E2050656C6C656E74657371756520636F6E677565206C696265726F206964206C6F72656D2E204D6175726973206C656F206C6F72656D2C20626C616E6469742073697420616D65742C20636F6E76616C6C697320717569732C20636F6E736563746574756572207365642C2065726F732E204D61757269732074696E636964756E742C20656E696D2061206772617669646120657569736D6F642C206D61676E61206E756C6C61206665726D656E74756D206C696265726F2C207669766572726120656765737461732076656C6974207175616D20657420746F72746F722E20566976616D757320616C6971756574206D61737361207669746165206A7573746F2E204E756C6C6120636F6E677565206C6163757320616320656C69742E0A0A50686173656C6C757320636F6D6D6F646F207175616D2076656C206C6967756C612E2050726F696E206E6F6E206D657475732061742065726F732070756C76696E6172206C75637475732E204D6175726973206469616D206C6F72656D2C20706F737565726520717569732C20677261766964612065742C2074696E636964756E74206E65632C206C6967756C612E20536564206469616D2E20416C697175616D20656C6974206C65637475732C2068656E6472657269742075742C20696D706572646965742073697420616D65742C207072657469756D2073697420616D65742C20697073756D2E204D6175726973207665686963756C61206E69736C20696E206475692E204375726162697475722065676574207175616D207574206D61676E6120656C656D656E74756D206665726D656E74756D2E204D6175726973207363656C657269737175652E2051756973717565206C616F726565742E20457469616D2074656D707573207475727069732E2050656C6C656E746573717565206175677565207175616D2C2068656E647265726974207365642C2074696E636964756E742061742C2070686172657472612061742C206E69736C2E20416C697175616D206C616375732E2053757370656E646973736520706F74656E74692E2041656E65616E2076656C6974206C696265726F2C20756C74726963657320696E2C206C6163696E69612065752C206C75637475732076656C2C20616E74652E20457469616D2064696374756D206D6920696E2066656C69732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20467573636520677261766964612064617069627573206E69736C2E2043726173207669746165206E69736C2E0A0A4D616563656E6173206469676E697373696D2C206C6967756C61206E6F6E20706F727461206375727375732C20656E696D206E756E63206D616C6573756164612073656D2C20657520706F72747469746F72206E756C6C612075726E61206575207175616D2E2046757363652065726F732E20416C697175616D2065726F732E204E616D20617563746F722E204E756C6C61206D6F6C657374696520706F727461206573742E2053757370656E646973736520706F74656E74692E20566976616D7573206D6F6C6573746965206C6F72656D2073656420657261742E20536564206567657420697073756D2E20496E746567657220616C697175616D2070756C76696E6172206E756C6C612E204372617320616C69717565742073656D207574206E756E632E2046757363652066617563696275732074656D707573206C65637475732E204372617320736F64616C65732C206E69736920616320666163696C6973697320756C7472696365732C2065726F73206172637520646170696275732073617069656E2C20657420756C747269636573206D61757269732074656C6C7573206E6F6E20646F6C6F722E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20437261732063757273757320766172697573206D657475732E205574207475727069732E20566976616D7573206567657420746F72746F722E0A0A536564206C616F726565742C2076656C6974206E6F6E20616363756D73616E206375727375732C206E756E632075726E6120706F7375657265206A7573746F2C20696E2064696374756D206C6563747573207065646520696420616E74652E20437261732076756C7075746174652E204372617320636F6E677565206475692073656420656C69742E2050726F696E206C616375732073656D2C20756C7472696365732061742C20636F6E73657175617420696E2C2074656D706F7220717569732C206D657475732E2050726F696E2076656C20617263752E204E616D20657569736D6F642068656E64726572697420656C69742E20557420657261742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2053656420706F73756572652E204D6F7262692065726F732075726E612C2073656D7065722061742C2073656D706572206E6F6E2C20636F6E76616C6C697320717569732C2076656C69742E204D616563656E6173206F7263692E20566573746962756C756D206C6F626F7274697320747269737469717565206D657475732E20566573746962756C756D206C6F72656D206E756C6C612C20736F6C6C696369747564696E2076697461652C20636F6E64696D656E74756D20717569732C20617563746F722075742C206475692E20566976616D757320766573746962756C756D206D61676E61207574206E6973692E2043757261626974757220656C656966656E64206475692076656C206E756E632E20437572616269747572206D6175726973206C616375732C206D616C6573756164612073697420616D65742C207375736369706974207365642C2072757472756D206C75637475732C2074656C6C75732E20496E746567657220666163696C697369732075726E61207669746165206C65637475732E0A0A41656E65616E207175616D206C656F2C206C6F626F7274697320717569732C206D616C6573756164612065752C2076756C7075746174652076697461652C206E69736C2E205072616573656E7420656765742065726F732E205574206665726D656E74756D20747572706973206964207175616D2E204E616D20746F72746F722E205072616573656E74206E6563206F7263692E204E756C6C6120626962656E64756D2061646970697363696E672061756775652E20557420636F6D6D6F646F2C206D61676E61206964206D616C65737561646120677261766964612C206175677565206F64696F206D616C657375616461206D692C20706F727461206D616C65737561646120656C697420657374207669746165206469616D2E204D6175726973206E6F6E206E756C6C612E2053757370656E64697373652074696E636964756E742C206E756E6320756C7472696369657320706F7274612076656E656E617469732C206D6920706564652074696E636964756E74206C696265726F2C20656765742076617269757320616E7465206C696265726F207574206C6967756C612E20437572616269747572207072657469756D20706F72747469746F7220746F72746F722E0A0A4D616563656E617320766974616520656C69742065676574206E69736920646170696275732064696374756D2E204E756E6320696E206C696265726F2E204E756C6C612064696374756D206F726369206575206572617420617563746F72206C6F626F727469732E2050686173656C6C75732072697375732E2053757370656E646973736520706F74656E74692E2053757370656E646973736520706F74656E74692E205072616573656E742061646970697363696E6720636F6E73657175617420656C69742E20496E74656765722069642061756775652E205072616573656E7420696E206A7573746F206E6563206D61676E6120646170696275732070756C76696E61722E2044756973206E69736C2E2053757370656E6469737365206163206F64696F2E20566976616D757320696D706572646965742E20446F6E6563206E6F6E2076656C69742073697420616D6574207269737573206469676E697373696D20636F6E6775652E204E616D20616C697175657420706F73756572652076656C69742E2043726173207475727069732E204D6F726269206D616C657375616461206469676E697373696D206D692E0A0A536564206C656F206E657175652C2076617269757320717569732C2076656E656E61746973207365642C207068617265747261207365642C206573742E204D6F72626920626C616E6469742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D2073656D7065722070656C6C656E746573717565206D692E2055742076656C206C6F72656D2E204E756E63206D6920746F72746F722C206C616F726565742061742C2066617563696275732065752C2074696E636964756E742073697420616D65742C20657261742E20447569732074656D706F72206D616C65737561646120697073756D2E2050686173656C6C757320616C69717565742E20446F6E656320657420656C69742E2050656C6C656E7465737175652070757275732E20566573746962756C756D2072757472756D2073656D706572206E6962682E204E756C6C6120666163696C6973692E2050686173656C6C757320657420656E696D2073697420616D657420616E746520766573746962756C756D207665686963756C612E2050686173656C6C7573206964206E69736C2E20446F6E6563206D6F6C6C6973206C656F2061742065726F732E204D61757269732070656C6C656E746573717565206E657175652061742070757275732E204D6F726269207175697320646F6C6F7220617420697073756D207363656C6572697371756520736F64616C65732E20457469616D20766F6C7574706174207475727069732061206D657475732E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206C6F72656D206C6F72656D2C20766573746962756C756D2061632C20657569736D6F6420656765742C20756C6C616D636F72706572206469676E697373696D2C2076656C69742E0A0A43756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204372617320756C7472696365732C206E6962682076656C20616C697175616D20766573746962756C756D2C2065726F7320656E696D2076656E656E61746973206475692C20696420696163756C697320656E696D206E756E632076656C206D617373612E204D6F72626920656C656966656E64206F726369206574206D617373612E20416C697175616D206572617420766F6C75747061742E204E756C6C61206D6F6C6C69732065676573746173207475727069732E20496E20736F64616C6573206E756E63206567657420746F72746F722E2053656420697073756D2065726F732C2074656D706F7220717569732C20616C69717565742076697461652C20696D70657264696574206E6F6E2C206C6F72656D2E2050656C6C656E746573717565207175697320656C6974206964206D69206C756374757320646170696275732E20536564206E756E6320617263752C2072686F6E637573206E65632C20636F6E76616C6C697320717569732C206375727375732061742C206E657175652E204D617572697320636F6E76616C6C697320707572757320617420657261742E2050656C6C656E74657371756520766573746962756C756D2E20566976616D7573206672696E67696C6C6120656C697420617420617263752E204E756C6C616D20616C697175657420656E696D206E656320617263752E204E616D20696420746F72746F722E204E756C6C612071756973206E756E632E20557420617263752E2053757370656E646973736520706F74656E74692E2050656C6C656E74657371756520756C6C616D636F72706572206C6967756C6120696420617263752E0A0A4E616D206E6F6E206C696265726F207669746165206E69736C207363656C65726973717565206672696E67696C6C612E20517569737175652076617269757320616E7465206964206D657475732072686F6E637573206672696E67696C6C612E204E756C6C6120666163696C6973692E205072616573656E7420656C656966656E6420706F72747469746F72206C6967756C612E20457469616D207175697320646F6C6F72206E6F6E20617567756520636F6D6D6F646F20617563746F722E20446F6E65632061206D692E20566573746962756C756D2074656D706F722E20446F6E65632066656C69732075726E612C20617563746F722061742C206375727375732064696374756D2C20677261766964612069642C20617263752E2041656E65616E2064696374756D206D616C65737561646120646F6C6F722E20566976616D7573206D61747469732E2050686173656C6C757320657520706564652E2046757363652061646970697363696E67206A7573746F206672696E67696C6C61206D657475732E20457469616D20616E74652E20496E7465676572206D6F6C6C6973206D617373612071756973206E756E632E20496E74656765722064696374756D206E65717565206C756374757320656E696D2E0A0A536564206575206C696265726F2E20496E74656765722074656D706F72206C6967756C6120696E2076656C69742E2055742074696E636964756E74206C6163696E69612073656D2E204E756C6C616D2076656C2072697375732E2053656420736F64616C657320616E7465206120646F6C6F722E204375726162697475722065726F732E2053656420736F64616C65732E20536564206E6F6E206D657475732E20566573746962756C756D20656C656D656E74756D20666175636962757320616E74652E204E756C6C612076656C206E6962682E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206E6563206C6F72656D20757420697073756D206C6163696E696120696163756C69732E204475697320657261742E20416C697175616D20657261742E204372617320696163756C69732E20496E206861632068616269746173736520706C617465612064696374756D73742E0A0A4E756C6C616D20616E74652E2043726173207669746165206573742E2050656C6C656E7465737175652076656C206D657475732061206C6967756C612064617069627573206D61747469732E2044756973206665756769617420616C69717565742066656C69732E20457469616D206964206E69736C207175697320657374206469676E697373696D20636F6E64696D656E74756D2E2053757370656E646973736520706F74656E74692E204D6F7262692076656C6974206C6F72656D2C206F726E61726520717569732C2070656C6C656E7465737175652076656C2C20706C61636572617420656765742C20746F72746F722E20566573746962756C756D2074696E636964756E74206D6F6C6573746965206C696265726F2E204E756C6C61206E756C6C6120656E696D2C206D616C6573756164612069642C20756C6C616D636F727065722076697461652C2064696374756D2061742C2070757275732E20446F6E6563206469676E697373696D206F64696F20757420656E696D2E2053757370656E6469737365206174206C65637475732E0A0A5072616573656E74206C6F626F727469732061756775652076656C206C65637475732E20557420696E206C6967756C612075742066656C697320636F6E6775652073757363697069742E2051756973717565206469676E697373696D20746F72746F72207574206D692E204675736365206D61676E61206E6973692C20656C656966656E642061632C206F726E6172652076656C2C20706F72747469746F722076697461652C207175616D2E20566573746962756C756D20736F64616C6573206A7573746F2071756973207475727069732E2046757363652075726E61206E6973692C2072686F6E63757320717569732C20636F6E64696D656E74756D2076656C2C2064696374756D2065752C206E756E632E20467573636520736564206E696268207669746165206F64696F20706F73756572652061646970697363696E672E2053656420706F72746120656C6974207175697320646F6C6F722E204E616D206C696265726F206E756C6C612C20617563746F72207365642C2074696E636964756E7420717569732C2066617563696275732073697420616D65742C206D692E2051756973717565206F7263692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E756C6C616D2069642073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632076656C2065726F732E0A0A566976616D7573206C7563747573206C6F626F72746973206C656F2E2053757370656E64697373652076656C20656C6974206120656E696D20756C6C616D636F7270657220706F73756572652E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20446F6E656320717569732070656465206D6174746973206C6563747573206D6F6C6C69732061646970697363696E672E2053656420616363756D73616E20706F737565726520657261742E205072616573656E7420657569736D6F642074696E636964756E742066656C69732E20446F6E6563206D692E20557420636F6D6D6F646F2061726375206C6163696E69612074656C6C75732E20416C697175616D2061206C696265726F2071756973206C65637475732073656D70657220766976657272612E20437572616269747572206C6163696E6961206D61757269732061742074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E756E632073697420616D6574206D61676E61206D6F6C6573746965206F726369207375736369706974206672696E67696C6C612E204675736365207072657469756D206D65747573206E6F6E2073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642068656E6472657269742E204E756C6C612066656C69732E2053757370656E646973736520706F74656E74692E20416C697175616D20626C616E64697420747269737469717565206E657175652E20437572616269747572207175697320657261742076656C206E756E6320616363756D73616E206D6F6C6C69732E0A0A447569732073616769747469732C2074656C6C757320757420616C697175616D206672696E67696C6C612C20646F6C6F72206D6920756C6C616D636F72706572206E69736C2C20757420747269737469717565207065646520656C697420736564206D61757269732E204375726162697475722069642066656C69732E20446F6E65632070756C76696E6172206C61637573206574206C65637475732E20416C697175616D2076756C7075746174652076756C707574617465206D657475732E20437572616269747572206D61676E612066656C69732C2061646970697363696E672061632C20616363756D73616E2076656C2C206D6F6C657374696520717569732C207175616D2E204D617572697320656C697420617263752C207072657469756D2076697461652C206D6F6C6C69732073697420616D65742C20736F6C6C696369747564696E2075742C206D692E20446F6E656320696D70657264696574206469676E697373696D206D692E204E756C6C616D2073697420616D657420746F72746F722E20416C697175616D206E65717565206E756C6C612C2076656E656E6174697320612C20706F72746120696E2C20706C6163657261742074656D7075732C206C616375732E205175697371756520766573746962756C756D20647569206574206C616375732E2050726F696E206469676E697373696D20636F6E7365637465747565722070757275732E20457469616D206772617669646120746F72746F7220696E206E756E632E2055742074656D706F722074726973746971756520746F72746F722E20536564206C616F726565742074696E636964756E74207175616D2E20566573746962756C756D20706F7274612074757270697320757420656C69742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20446F6E6563206E696268206475692C2066657567696174206E65632C206C616F726565742069642C206D616C65737561646120656765742C206E6973692E205574206E65717565206D617373612C207665686963756C612065752C20636F6D6D6F646F206E6F6E2C20756C747269636965732076697461652C2070757275732E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204D617572697320657569736D6F642C2066656C69732076656C2074656D706F7220616C69717565742C20746F72746F72206D6175726973206D616C657375616461206E756E632C2076656C206665726D656E74756D2073656D206469616D206964206475692E204E616D2072757472756D2073617069656E2065676574206F64696F2E20416C697175616D20736564206C696265726F206E6F6E206D692066617563696275732074656D7075732E2046757363652068656E6472657269742C206469616D206E6F6E20766F6C75747061742072757472756D2C2065726174206D657475732076656E656E61746973206C6967756C612C206E6F6E207363656C657269737175652070656465206C6967756C612076656C207175616D2E204D6F7262692072686F6E6375732065726F7320616320647569206665756769617420656C656D656E74756D2E2044756973206575206C696265726F2065742074656C6C757320636F6E67756520766976657272612E204D6F726269207175616D207175616D2C20656C656D656E74756D207365642C20756C6C616D636F7270657220696D706572646965742C20636F6D6D6F646F206E6F6E2C206F64696F2E204E616D20616C697175657420656765737461732075726E612E204D6175726973206F64696F2066656C69732C207661726975732065752C206C6163696E69612065752C20636F6E64696D656E74756D20612C206C65637475732E20536564206A7573746F206D617373612C2070756C76696E61722069642C2076617269757320612C20706F72747469746F72206E65632C206C696265726F2E20457469616D207661726975732E2043757261626974757220736F64616C65732C206F64696F20617420706F73756572652073656D7065722C2065726F73206E6962682074696E636964756E74206C65637475732C2076656C2072757472756D2073617069656E206E69736920696E206C6967756C612E2053757370656E6469737365206567657420617263752E2050686173656C6C757320696D70657264696574206573742061632073617069656E2E20446F6E6563206E756C6C6120746F72746F722C20706C6163657261742076656C2C2074656D70757320612C206C6F626F727469732076656C2C206E6962682E20416C697175616D20766172697573206E6973692E204E756C6C6120657420656E696D2E20467573636520636F6E76616C6C6973206C616F72656574206C616375732E0A0A50686173656C6C757320697073756D20646F6C6F722C206D6F6C657374696520717569732C20636F6E64696D656E74756D20696E2C20636F6D6D6F646F2065752C206469616D2E205175697371756520626962656E64756D206C6163696E6961206475692E204E756C6C616D20626C616E6469742076756C707574617465206F7263692E205574206C6163696E6961206D617373612076656C2061756775652E20416C697175616D20677261766964612C207175616D207175697320696D7065726469657420696D706572646965742C2074656C6C7573206469616D20706861726574726120657261742C206174207068617265747261206C61637573206E6962682065676573746173206D61676E612E204E756C6C61207361676974746973206C6F72656D207574206C6F72656D2E204475697320636F6E64696D656E74756D2C2064756920766974616520616C697175616D20706F73756572652C206469616D207175616D20636F6E76616C6C69732076656C69742C2075742067726176696461206C656F20697073756D206E6F6E2072697375732E205574206665726D656E74756D20736F6C6C696369747564696E20657261742E20446F6E6563207361676974746973207363656C657269737175652066656C69732E204E756E6320617263752E20457469616D2074656D7075732C206D61676E612073697420616D657420737573636970697420657569736D6F642C2065726F732073656D2072757472756D206475692C207669746165207361676974746973206E696268207075727573206E6F6E206C616375732E20536564206D6F6C6C69732061726375206567657420646F6C6F722E20446F6E6563206F726E6172652C20617263752073697420616D6574206665726D656E74756D2076756C7075746174652C20726973757320656E696D206665726D656E74756D206C696265726F2C2061206C6163696E696120646F6C6F72206D69206E6F6E2076656C69742E20457469616D206C6F626F72746973207075727573206120656C69742E204E756E63206E756C6C61206475692C206D617474697320717569732C20626962656E64756D20612C20756C7472696365732061632C2061756775652E20496E20616C697175616D207665686963756C61207475727069732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A496E7465676572206964206E69736C2E20517569737175652064696374756D20656C656D656E74756D206F64696F2E2041656E65616E206C75637475732E205365642065752073656D206120706564652076756C70757461746520636F6E64696D656E74756D2E2051756973717565206D61676E612E20446F6E656320616C697175616D206D617474697320697073756D2E204375726162697475722064696374756D20736F6C6C696369747564696E2073656D2E20416C697175616D2070756C76696E61722E204E756E6320736F6C6C696369747564696E207269737573206120657261742E20566976616D757320717569732074656C6C75732073697420616D6574206E69626820766573746962756C756D20636F6E7365717561742E204E756C6C61207072657469756D20736F6C6C696369747564696E20646F6C6F722E20416C697175616D20696163756C69732074696E636964756E74207475727069732E2050686173656C6C757320697073756D206C656F2C2076656E656E6174697320696E2C20736167697474697320696E2C206F726E6172652061742C206E756E632E0A0A50656C6C656E74657371756520756C7472696365732C2064756920657520696163756C6973206C75637475732C2074656C6C757320617567756520766F6C75747061742073617069656E2C20696E206469676E697373696D2075726E612066656C6973207574206D692E205365642061726375206475692C206469676E697373696D2069642C20706F72747469746F722075742C20696D706572646965742076697461652C20616E74652E204E756C6C61206475692073656D2C20636F6D6D6F646F206E65632C2073616769747469732065742C206C6163696E69612065742C20706564652E20457469616D20656C656966656E6420647569207574206E69736C2E20446F6E656320616E7465206D61757269732C2074656D7075732073697420616D65742C207661726975732076697461652C206772617669646120717569732C206D692E20496E207363656C657269737175652C2066656C697320766974616520766976657272612073616769747469732C2076656C6974206D6574757320756C74726963696573206E657175652C207175697320696D706572646965742076656C697420656C6974206574206D61676E612E2053757370656E646973736520706F74656E74692E205365642076656C69742065726F732C20657569736D6F64207365642C20636F6E64696D656E74756D206E65632C206661756369627573207365642C2073617069656E2E204E616D20616363756D73616E206C6967756C612073697420616D6574206E657175652E20416C697175616D206572617420766F6C75747061742E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E616D20657520706564652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642065752066656C69732073656420746F72746F722074656D706F72206665726D656E74756D2E2050686173656C6C757320636F6D6D6F646F2073656D2076656C206E69736C2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050726F696E206C656374757320656C69742C2070686172657472612073697420616D65742C20616363756D73616E207365642C2074696E636964756E742065742C206D61757269732E204475697320646170696275732070686172657472612073656D2E20496E746567657220696E206A7573746F2E205072616573656E742065726F732E20566573746962756C756D20616320616E74652E20416C697175616D207363656C657269737175652073656D2070656C6C656E746573717565206E69626820636F6E73656374657475657220736F64616C65732E20416C697175616D20636F6E736563746574756572206F64696F2E2044756973206C6563747573206F64696F2C206C75637475732065752C20636F6D6D6F646F20717569732C206D6F6C6C69732076697461652C2076656C69742E2043726173206E6563206E756E63206E6F6E20656C697420696163756C6973206D61747469732E2041656E65616E206A7573746F206E657175652C20736F6C6C696369747564696E20656765742C20756C6C616D636F7270657220656765742C20656765737461732069642C2073656D2E20496E2065752072697375732E2053656420656765737461732E0A0A496E7465676572206174206E657175652E20536564207072657469756D207363656C65726973717565206E756C6C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20467573636520757420706564652E20457469616D207669746165207175616D20612075726E612076617269757320696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2044756973207665686963756C612E20467573636520756C6C616D636F72706572206E696268206E6F6E20657261742E205175697371756520696E206E657175652E205072616573656E74206573742E2050656C6C656E74657371756520617263752E0A0A50726F696E20706F73756572652E2053757370656E646973736520706F74656E74692E20496E74656765722066656C6973206C616375732C20616C697175616D207365642C2076756C70757461746520696E2C206D6F6C6C69732076656C2C2074656C6C75732E20496E7465676572207665686963756C6120626962656E64756D206573742E204E756E63206E6F6E20646F6C6F7220696E2074656C6C7573206D617474697320666163696C697369732E20496E746567657220766573746962756C756D2C20617567756520617420636F6D6D6F646F20616C697175616D2C2064756920657374206D6174746973206C6967756C612C2073697420616D65742061646970697363696E67206F7263692073656D207669746165206D61676E612E205072616573656E7420656E696D2076656C69742C206D616C6573756164612061742C20636F6E677565206E65632C206C756374757320696E2C206A7573746F2E20536564207661726975732E204D6F7262692070686172657472612E20446F6E6563206575206D61737361206E65632074656C6C75732076756C7075746174652070756C76696E61722E20557420636F6D6D6F646F20747572706973206E6F6E2073656D2E20557420636F6E76616C6C697320756C6C616D636F727065722072697375732E20457469616D20696E74657264756D2070656465206964206E6973692E2043726173206D61676E612073617069656E2C20737573636970697420612C206C616F72656574206E6F6E2C2072686F6E6375732065742C2066656C69732E20496E7465676572206F726369206C6F72656D2C20766573746962756C756D2064696374756D2C20756C6C616D636F7270657220612C20706F72747469746F722065742C206475692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A4E756E63206574206D61676E612E2053656420626962656E64756D2074656C6C757320696E206469616D2E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E616D20766974616520746F72746F722E20496E7465676572206D61676E612E20447569732076656E656E617469732C206C656F2061632074656D706F72206C616F726565742C20656C6974206E756C6C6120706861726574726120706564652C206E6F6E206665726D656E74756D206E756E63206F64696F2061206F64696F2E2050726F696E206E6F6E2076656C69742E2053656420696D706572646965742061756775652071756973206E69736C2E20496E746567657220636F6E64696D656E74756D206E69736C206E6563206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20566976616D757320706C616365726174206C696265726F2E204475697320636F6E6775652064696374756D206D61676E612E20416C697175616D206461706962757320626962656E64756D20656E696D2E204E756E6320656C656966656E6420706564652076656C20697073756D2E0A0A457469616D2076697461652076656C69742E204D61757269732065726174206E756E632C206D616C6573756164612075742C20666575676961742061632C20706C61636572617420636F6E64696D656E74756D2C2061756775652E204E616D20766F6C75747061742E20416C697175616D207665686963756C6120697073756D206964206F64696F2E20566976616D757320736F6C6C696369747564696E207475727069732069642073617069656E2E20467573636520612066656C6973207669746165206F64696F20636F6E76616C6C697320626C616E6469742E204375726162697475722076697461652065726F732069642065726F7320706F727461207072657469756D2E204E756C6C6120696E206D61676E6120656765742075726E61206C6163696E696120636F6E76616C6C69732E20416C697175616D206D61747469732076656E656E617469732070757275732E2053656420736564206D69206567657420657261742074726973746971756520706F7274612E20446F6E656320617563746F7220646F6C6F72206120657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20496E206E6563206C6967756C612E204E756E6320656C656966656E642E20566573746962756C756D2071756973206E697369206567657420656C697420706F72747469746F7220636F6E6775652E204D616563656E61732066617563696275732C206D61676E6120656765742061646970697363696E672074696E636964756E742C20646F6C6F7220616E7465206D616C65737561646120656C69742C206E6F6E20656C656D656E74756D206C616375732074757270697320696E20706564652E0A0A5574206D616C657375616461206D69206E6563206D657475732E205072616573656E7420617563746F72206175677565206163206E69736C20756C7472696369657320666163696C697369732E204E616D2070757275732073617069656E2C2070656C6C656E746573717565206469676E697373696D2C20706F73756572652065752C206375727375732069642C206469616D2E205175697371756520736F6C6C696369747564696E2C20656C697420612070656C6C656E746573717565207363656C657269737175652C206C6F72656D20726973757320617563746F72207175616D2C207175697320636F6E7365717561742074656C6C7573206E657175652069642075726E612E2053757370656E6469737365206469616D20746F72746F722C20656C656966656E64206469676E697373696D2C20656765737461732075742C206C756374757320696E2C20616E74652E204475697320616E74652E204D616563656E6173206C75637475732E20437572616269747572206375727375732070686172657472612075726E612E204D616563656E617320696D706572646965742C2065726174206E6F6E20656C656D656E74756D20657569736D6F642C20746F72746F72206F64696F20657569736D6F64206C65637475732C20616320666163696C697369732073656D206E696268207669746165206E756C6C612E204E756E6320677261766964612E204D6F72626920736F6C6C696369747564696E206F64696F2071756973206C616375732E20416C697175616D2061206E696268206E6F6E2075726E6120706F72746120696D706572646965742E20416C697175616D206572617420766F6C75747061742E20496E20696163756C6973206C6163696E69612076656C69742E20536564206C696265726F206C616375732C207472697374697175652065752C206C6163696E69612061632C20616C697175657420656765742C2075726E612E0A0A457469616D206174206E69736C2E2050686173656C6C7573206661756369627573206C7563747573206C65637475732E20557420706C6163657261742076756C70757461746520646F6C6F722E2050686173656C6C75732076656C2076656C69742E204D6F72626920766976657272612E2050686173656C6C7573206F7263692E20496E7465676572206469676E697373696D206D6174746973206D61757269732E2050656C6C656E74657371756520706F7375657265206C656F20706F7375657265207175616D2E2051756973717565206E6563206D61676E61206174206469616D20766976657272612070656C6C656E7465737175652E2053757370656E64697373652076656C697420617263752C20756C7472696369657320717569732C20636F6E67756520612C2076656E656E6174697320656765742C206C616375732E20496E74656765722073616769747469732068656E64726572697420646F6C6F722E2046757363652074696E636964756E7420616E746520612073656D2E0A0A4D616563656E617320636F6E7365637465747565722C206A7573746F207365642072686F6E6375732076656E656E617469732C206E69626820617263752072757472756D20646F6C6F722C2073656420636F6E64696D656E74756D206C696265726F206C696265726F20657420697073756D2E20566976616D7573206D6174746973206A7573746F207574206C6F72656D2074696E636964756E74206C6F626F727469732E205574206E6F6E2076656C6974206964206E6571756520616C697175657420616363756D73616E2E205365642074656D7075732076697665727261206E756C6C612E2043757261626974757220756C6C616D636F727065722C206E6571756520717569732064617069627573207363656C657269737175652C2066656C6973206469616D2067726176696461206F7263692C206E6F6E20637572737573207175616D206E6571756520766974616520656C69742E20457469616D2070686172657472612074696E636964756E74206C616375732E204475697320657569736D6F64206672696E67696C6C61206573742E20457469616D206F726E6172652074696E636964756E74206C65637475732E2050726F696E20696E207475727069732E204E756E6320626C616E64697420626C616E646974207475727069732E2041656E65616E2075742061756775652E2044756973206F726369206A7573746F2C2074696E636964756E742065752C2072757472756D207365642C2072757472756D2065742C207475727069732E2043757261626974757220666163696C69736973206F64696F20696E20616E74652E20496E206861632068616269746173736520706C617465612064696374756D73742E205365642065726F73206573742C2070656C6C656E7465737175652061742C2074696E636964756E742065752C20756C74726963657320717569732C206D657475732E204D6F7262692073697420616D6574206A7573746F2E204D616563656E617320616320617263752E204D6175726973206469676E697373696D2E0A0A50656C6C656E74657371756520756C747269636965732072757472756D206F7263692E2041656E65616E206F726E6172652E20566976616D75732065752072697375732076656C206D6175726973206C6F626F727469732064696374756D2E205365642065742074757270697320617563746F72206D692072686F6E6375732070756C76696E61722E20536564206E6563206E756E6320612070757275732074656D706F7220766976657272612E2050656C6C656E7465737175652073757363697069742E20446F6E656320747269737469717565207269737573206E6F6E206E6962682E20457469616D206E69736C206D61676E612C20736F6C6C696369747564696E2075742C20756C7472696365732073697420616D65742C20656765737461732065752C206E756C6C612E20416C697175616D206572617420766F6C75747061742E20566573746962756C756D2070686172657472612E2053656420656765737461732C206D657475732073697420616D6574206C6F626F7274697320636F6E7365717561742C206572617420656C697420696D70657264696574206C696265726F2C20657520696E74657264756D207175616D206D61737361206567657420646F6C6F722E2053757370656E6469737365207669746165206F64696F2E2050726F696E20626C616E646974206D617572697320696163756C6973206D657475732E0A0A566976616D757320766573746962756C756D2E20457469616D206574206E69736C2E20416C697175616D20696E206469616D2076656C20656C697420706C6163657261742073757363697069742E204475697320736F64616C6573207075727573206163206E6962682E204E756C6C6120696E206F64696F206567657420656E696D206C756374757320626C616E6469742E2043757261626974757220756C74726963657320697073756D206E6F6E206E65717565206567657374617320656C656966656E642E20536564207475727069732E2050726F696E20636F6E7365637465747565722E20566976616D7573206D61747469732E20496E20616C69717565742E0A0A4E756E632069642065726F732E20446F6E65632076656E656E617469732C206E756C6C61206574206D6174746973206C75637475732C20616E7465206C656F2073656D706572206A7573746F2C206E6F6E2061646970697363696E67206F64696F20726973757320736564206C616375732E205072616573656E7420766974616520726973757320636F6E677565206C696265726F20636F6E6775652074656D7075732E2050686173656C6C75732061632065726F732E204E756C6C61207665686963756C612C206C6F72656D20696E20616C69717565742073757363697069742C2061726375206572617420656765737461732073656D2C2071756973206C6F626F72746973207175616D20616E7465206575206D617373612E20437572616269747572206E6F6E206D617373612E2053656420626962656E64756D206C6163696E6961206F64696F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20566976616D757320766F6C757470617420626C616E646974206C616375732E2050726F696E20706F7274612C2074656C6C757320757420617563746F72206C616F726565742C206C65637475732065726F73206665726D656E74756D206C65637475732C2069642073616769747469732061726375206A7573746F20696E207475727069732E2050686173656C6C757320636F6E7365717561742E204E616D2070656C6C656E7465737175652C206D69206964207669766572726120636F6E76616C6C69732C206E756E63206C696265726F20706C616365726174206C656F2C20656C656966656E6420706F7274612073656D206E69736C2076697461652073617069656E2E2050656C6C656E746573717565206C6967756C61206C696265726F2C20747269737469717565206E6F6E2C20706F72747469746F722072757472756D2C20706F72747469746F72206E6F6E2C20657261742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E74656765722064696374756D2074656C6C7573206120746F72746F722E20566976616D75732066656C6973206E756E632C206D6F6C6573746965206E6F6E2C2072686F6E63757320717569732C2070686172657472612069642C206475692E20446F6E6563207269737573206D657475732C206672696E67696C6C612076656C2C20616C69717565742065752C20706C6163657261742069642C206E657175652E0A0A53757370656E646973736520697073756D2E20566976616D7573206C65637475732E2053656420766976657272612C206D61737361206567657420636F6E76616C6C6973206D61747469732C207175616D2074757270697320636F6E736563746574756572206E756E632C206567657420706F7375657265206D61676E612073656D2069642076656C69742E20496E206E6563206D61757269732E2041656E65616E206120707572757320736564207175616D206C6F626F72746973206672696E67696C6C612E2050726F696E20756C74726963696573206C6163696E696120616E74652E205365642061646970697363696E67206572617420717569732076656C69742E204E756C6C616D207669746165206E69736C206964206A7573746F20736F6C6C696369747564696E206D6F6C65737469652E204E756C6C6120666163696C6973692E20536564206E65632075726E6120736564206E69736C206672696E67696C6C6120646170696275732E204E756C6C61206174206469616D2E20416C697175616D2065676574206E6962682E204E756E63206163206E6973692073697420616D65742074656C6C757320656765737461732074656D7075732E204E616D207363656C657269737175652075726E61206574206E657175652E20446F6E656320657374206F7263692C207361676974746973206E6F6E2C2076756C70757461746520612C20636F6D6D6F646F2065742C2061756775652E205574206461706962757320746F72746F722E205574206E756E632E20446F6E65632064696374756D2064617069627573206F64696F2E204E616D20756C7472696369657320756C6C616D636F72706572206C6967756C612E2050656C6C656E74657371756520616363756D73616E20766172697573206C656F2E0A0A4D6F72626920657569736D6F64206C616F7265657420657261742E20566976616D7573207175697320697073756D2E204D6F72626920657569736D6F642E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2053757370656E64697373652076656C2070757275732E204E756C6C616D206174206D61676E612E20437572616269747572206C61637573206C6F72656D2C20696163756C697320717569732C2064617069627573206E6F6E2C20766F6C75747061742076656C2C206E756C6C612E20446F6E656320757420617263752072686F6E63757320646F6C6F72207072657469756D2064696374756D2E204E756C6C616D2076656C206D657475732E20557420617263752E2050656C6C656E746573717565206E697369206E756E632C20706C61636572617420656765742C2074696E636964756E742076656C2C207068617265747261206E6F6E2C206E756E632E20496E74656765722074696E636964756E7420756C74726963696573206C65637475732E20496E74656765722073656D7065722C2070757275732073656420756C74726963657320666575676961742C206E756C6C61207065646520736F6C6C696369747564696E20657261742C2076656C20617563746F72206E756C6C6120697073756D2076656C206C65637475732E2041656E65616E206D692E0A0A4E756C6C616D20736564206E697369206574206172637520696D70657264696574206665726D656E74756D2E204D6175726973206E6563206D657475732E20496E20616320646F6C6F722E20496E206D6920617263752C20636F6E6775652061632C207068617265747261206E65632C207363656C657269737175652073697420616D65742C206D61676E612E20437572616269747572206C616375732E2043757261626974757220657420656C69742E20416C697175616D20756C6C616D636F72706572206E756E6320657520656C69742E2053656420636F6E76616C6C697320646F6C6F722061742076656C69742E20566573746962756C756D20646170696275732C20617567756520696420636F6E73656374657475657220706C6163657261742C206E756E63206D6173736120626C616E6469742073617069656E2C20696420616C697175616D20656C6974206E697369206964206D692E2050686173656C6C75732073617069656E206573742C20677261766964612065752C20626962656E64756D2075742C2061646970697363696E6720717569732C206573742E205574206D6F6C6573746965207175616D207669746165206F64696F2E20446F6E65632071756973207269737573206964206572617420666175636962757320736F6C6C696369747564696E2E204E616D2069642066656C69732E204D61757269732073656420656E696D207669746165206C656F20616363756D73616E207072657469756D2E0A0A4E616D206A7573746F2E20446F6E656320747572706973206E69736C2C20636F6D6D6F646F2065742C20696E74657264756D2061632C20636F6E736563746574756572206E6F6E2C206D617373612E2046757363652073656D206D657475732C206C616F72656574206E65632C20706F73756572652069642C20696D7065726469657420696E2C2076656C69742E20446F6E65632076756C707574617465206A7573746F2065676574207475727069732E204E756C6C6120706564652E204D6F7262692074696E636964756E742E20467573636520616C69717565742C207175616D20657420616C697175616D206672696E67696C6C612C20616E746520616E746520696163756C6973206475692C206E656320616C697175616D20617263752070757275732073656420657261742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050686173656C6C7573207375736369706974207175616D206574206573742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B0A0A496E7465676572207365642074656C6C75732E20536564207365642076656C697420756C74726963696573206C656F2072757472756D206C616F726565742E20536564206E6F6E2065726F7320616320707572757320736167697474697320666575676961742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E205365642068656E647265726974206C6967756C612073697420616D6574206E6962682E204D616563656E6173207475727069732E204D6F72626920636F6E7365637465747565722C20646F6C6F722065742061646970697363696E6720696D706572646965742C20616E7465206E65717565206665756769617420646F6C6F722C20617420706F727461207175616D206E657175652071756973206C6967756C612E204D61757269732073656D7065722076656C69742073697420616D657420697073756D2E2050656C6C656E7465737175652074656D7075732C20707572757320696E2072757472756D20636F6E7365717561742C20656E696D2065726174207665686963756C61206D617373612C20696420616363756D73616E206C656F2073617069656E206E65632070757275732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E20646F6C6F722E20496E746567657220666163696C69736973206C696265726F2073697420616D657420706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2055742076617269757320616C697175657420656E696D2E204E756C6C6120666163696C6973692E2043757261626974757220636F6E7365637465747565722C206F64696F206575207072657469756D2074696E636964756E742C206E756E63206E69736920616C6971756574206E657175652C2076656C20696D7065726469657420656C6974206D617373612073697420616D6574207475727069732E2050656C6C656E7465737175652074656D7075732C206F72636920766F6C757470617420626C616E646974206672696E67696C6C612C206F64696F2073656D20706F737565726520616E74652C20766974616520626962656E64756D2075726E61206C6F72656D2076697461652065726F732E205072616573656E7420766976657272612072686F6E63757320617263752E2053656420617563746F722C206573742073697420616D6574206D6F6C6C6973206D6F6C6C69732C207175616D207175616D20677261766964612073617069656E2C20696E20636F6D6D6F646F206D65747573206E756C6C6120617563746F7220656E696D2E20446F6E656320666163696C697369732E0A0A50726F696E2074696E636964756E742C2073617069656E206567657420756C747269636965732061646970697363696E672C20657374206F64696F2064696374756D20617263752C207574206D6F6C6C69732065726174206475692073697420616D65742076656C69742E204D6F726269206573742073656D2C20696E74657264756D2061742C20636F6E67756520612C20656C656D656E74756D2076697461652C206D657475732E2053757370656E64697373652069642061756775652E204D617572697320656E696D2073656D2C2070756C76696E617220656765742C2074656D70757320612C2074656D7075732073697420616D65742C2073617069656E2E20467573636520766573746962756C756D20636F6E736563746574756572206475692E2050656C6C656E74657371756520657261742E20536564206469676E697373696D20706C616365726174206F64696F2E204D616563656E61732073656D7065722072686F6E637573206C65637475732E2050686173656C6C7573207072657469756D2E2044756973206C696265726F20656C69742C20656C656966656E64206E65632C20656765737461732075742C20637572737573207365642C2066656C69732E204E616D206E69736C20617263752C20616C69717565742065742C20666163696C697369732065752C206C75637475732075742C2072697375732E20457469616D20756C7472696365732C20646F6C6F722073656420766F6C7574706174206D616C6573756164612C20747572706973206172637520696D7065726469657420746F72746F722C20657569736D6F6420636F6D6D6F646F206C696265726F206D61737361207574207175616D2E20496E7465676572206D6F6C6573746965207075727573206E6F6E20656C69742E2055742076656E656E617469732073656D70657220746F72746F722E20457469616D20626962656E64756D206567657374617320697073756D2E204D617572697320736F6C6C696369747564696E2073656D206E6563206E6962682E204E756C6C61207072657469756D206D65747573206575206D657475732E2050656C6C656E7465737175652073697420616D65742073656D2E0A0A53757370656E6469737365206163206E6973692E205574206C656F2E20566573746962756C756D2068656E647265726974207072657469756D20646F6C6F722E204E756E632066657567696174206D616C6573756164612070757275732E2043726173206574206E6962682E20437572616269747572206E756E6320657261742C206D616C6573756164612076697461652C206C616F726565742061632C20756C7472696369657320696E2C2070757275732E20566976616D75732074656C6C757320617263752C20736F64616C65732065752C20666163696C6973697320612C206C6163696E6961206E65632C206E756E632E2050656C6C656E7465737175652069642076656C69742E20496E206575206E6962682E204E756E63206E656320657261742E205365642064696374756D206E65717565207574206E69736C2E0A0A4D6F726269206C65637475732074656C6C75732C2074696E636964756E742061632C20706F72747469746F722061632C2074726973746971756520696E2C2065726F732E20446F6E6563206C7563747573206C7563747573206C656F2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2046757363652075742065737420657420656E696D207363656C6572697371756520616363756D73616E2E20446F6E6563206C6967756C612066656C69732C206C6163696E696120717569732C2070656C6C656E74657371756520696E2C2073656D70657220766573746962756C756D2C20656C69742E204D61757269732065676574206F72636920612066656C697320636F6E677565207665686963756C612E20557420736F6C6C696369747564696E2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204E756C6C616D20696420646F6C6F72207574206C6F72656D206469676E697373696D2076656E656E617469732E2053757370656E64697373652076697461652073617069656E2E2050726F696E206E6F6E206D61676E612075742065726F7320766976657272612070756C76696E61722E20446F6E65632071756973206F64696F2E204E756C6C616D206E6F6E20617263752076656C206C6F72656D20737573636970697420616C697175616D2E20416C697175616D2072757472756D2074757270697320696E206C656F2E0A0A5574206C7563747573206E6962682074726973746971756520657261742E2053757370656E646973736520626962656E64756D206F64696F20766974616520746F72746F722E20446F6E6563206C6163696E69612E204372617320736F64616C65732066656C6973206C7563747573206E756C6C612E204E616D20656C656966656E64207361676974746973206C6967756C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E64697373652076656C206E657175652E204D6F72626920616C6971756574207665686963756C61206D61676E612E2041656E65616E206174206F64696F2E20447569732070656C6C656E746573717565206D61676E612E204E756C6C6120617420746F72746F72207574206469616D2064696374756D2066617563696275732E204D617572697320717569732076656C69742E20446F6E6563206E6F6E2074656C6C7573207669746165206C6F72656D206672696E67696C6C6120706F72747469746F722E2046757363652075742073617069656E207175697320746F72746F7220666575676961742073616769747469732E20446F6E656320766976657272612073656D2076697461652073617069656E2E205072616573656E7420736F64616C65732C206C6163757320696E206672696E67696C6C6120766976657272612C206F64696F2061756775652061646970697363696E672075726E612C20766974616520696E74657264756D20616E74652073656D206E6F6E206E6973692E204E756C6C616D20746F72746F72206C6F72656D2C20656C656966656E642061632C206D6F6C6C6973206E6F6E2C206C616F726565742061632C2072697375732E20496E7465676572206F726E617265206C656F20736564206A7573746F2E2051756973717565206375727375732C2073656D206E6F6E20666163696C6973697320626962656E64756D2C206E697369206D69207661726975732066656C69732C206665726D656E74756D2066657567696174206C6F72656D2065726F73206C616F726565742072697375732E0A0A517569737175652073697420616D657420657374206574206C6F72656D207665686963756C61206C6163696E69612E20446F6E6563206E656320746F72746F722E2043726173206F64696F2E204E616D207363656C657269737175652076756C7075746174652075726E612E205072616573656E74206475692E20457469616D206E6563206E69736C206C6F626F7274697320697073756D20616C69717565742074656D7075732E204D616563656E6173207072657469756D20736F6C6C696369747564696E206D61757269732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206175677565206D617373612C20636F6E67756520656765742C20636F6E76616C6C697320656765742C207472697374697175652073697420616D65742C2065726F732E2053656420636F6E736571756174206E6973692065752066656C69732E2050656C6C656E746573717565206A7573746F2E2053757370656E6469737365206E6F6E2061756775652E20496E206469676E697373696D206C6F626F72746973206D61757269732E204D61757269732073616769747469732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E0A0A5365642061646970697363696E672E20446F6E656320612074656C6C75732076697461652065737420637572737573207665686963756C612E204E616D20616E74652073656D2C20736F64616C65732069642C206672696E67696C6C612076656C2C20636F6E64696D656E74756D2076656C2C206E756C6C612E205175697371756520736F64616C65732E20457469616D20696D7065726469657420656C6974206964206F64696F2E20416C697175616D206572617420766F6C75747061742E204D616563656E617320706F7274612074656D706F7220617263752E204E756C6C612073656D2061756775652C2070656C6C656E7465737175652061632C20636F6E7365717561742075742C20636F6E64696D656E74756D20657569736D6F642C2072697375732E2053656420616C697175616D2074696E636964756E74206D692E20496E20696E74657264756D206C6F626F72746973206F7263692E0A0A536564207665686963756C612068656E6472657269742070757275732E20457469616D2061206469616D2E2043757261626974757220636F6E76616C6C69732E2053757370656E64697373652061206E6973692E20446F6E6563206964206D61676E6120696E207175616D20736F6C6C696369747564696E20756C747269636965732E20446F6E656320766976657272612E205175697371756520766F6C757470617420657374207365642073656D2E20416C697175616D206A7573746F2E20566573746962756C756D20746F72746F72206D617373612C20706F72747469746F72207365642C2076617269757320717569732C20696163756C697320717569732C206F64696F2E20416C697175616D2065676574206E657175652E0A0A4D6175726973206E756C6C612E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566573746962756C756D206575207175616D20696E206E6571756520756C7472696365732070656C6C656E7465737175652E204372617320696E20646F6C6F722071756973207175616D207661726975732068656E6472657269742E20416C697175616D206E697369206C616375732C206C6F626F727469732065752C20636F6E76616C6C69732073697420616D65742C20666163696C697369732075742C206D692E20416C697175616D206174206E657175652E204372617320736167697474697320656C656D656E74756D206A7573746F2E20566573746962756C756D207574206C656374757320616C6971756574207075727573206D616C65737561646120766F6C75747061742E2044756973206174206C616375732061646970697363696E67206C696265726F2074696E636964756E7420766573746962756C756D2E204D6F7262692061206C696265726F2E20437261732070757275732E204D6F72626920757420617567756520657420707572757320696E74657264756D207363656C657269737175652E20496E74656765722061206475692E20496E206861632068616269746173736520706C617465612064696374756D73742E2044756973207068617265747261206D657475732065676574206D61757269732E20416C697175616D20696E74657264756D20756C6C616D636F72706572206D617373612E0A0A457469616D206F726E6172652E204E756C6C616D20657569736D6F642E2041656E65616E20636F6E7365717561742067726176696461206C6967756C612E20416C697175616D206573742E2050726F696E207669746165206C616375732E205072616573656E7420612065726F732073697420616D657420647569206C756374757320636F6D6D6F646F2E2050686173656C6C7573207665686963756C612061726375206567657420646F6C6F722E205072616573656E74206665726D656E74756D20636F6E677565206C656F2E20416C697175616D20766F6C7574706174207075727573207574206C6F72656D2E2046757363652068656E64726572697420656E696D206174206C656F2E20416C697175616D2072686F6E637573206E69736C2E20566976616D75732064696374756D2065676573746173206D692E2053757370656E64697373652070656C6C656E74657371756520626962656E64756D20646F6C6F722E2050656C6C656E7465737175652074696E636964756E742C207475727069732073656D7065722070656C6C656E74657371756520636F6E64696D656E74756D2C20697073756D206D6574757320736F64616C6573206C6967756C612C20696420766F6C7574706174206469616D2074757270697320757420656C69742E0A0A5072616573656E7420736564206C616375732E204E616D20656C656966656E64206D6F6C6573746965206D61757269732E20446F6E65632064617069627573206665726D656E74756D206D617373612E20446F6E656320766976657272612066617563696275732070757275732E2043757261626974757220636F6E6775652C206C696265726F20766974616520766976657272612070656C6C656E7465737175652C206469616D2076656C697420736F64616C657320656E696D2C20736564207375736369706974206C6563747573206E697369206E6563206E657175652E20566573746962756C756D206D616C6573756164612C206C616375732061742063757273757320636F6E6775652C2076656C6974206C65637475732074726973746971756520646F6C6F722C2073697420616D657420736F64616C6573206E6571756520697073756D2061206C696265726F2E20566573746962756C756D206574207175616D2E2043757261626974757220706C6163657261742E20437572616269747572206E756E6320617263752C20657569736D6F64206E65632C2076756C7075746174652068656E6472657269742C20616C697175657420656765742C207175616D2E204375726162697475722076656C20656E696D2E2053757370656E646973736520706F74656E74692E0A0A4E756E6320636F6E736571756174206F726369207574206C616375732E2046757363652076656C697420646F6C6F722C2064617069627573207365642C20626C616E6469742073697420616D65742C2072686F6E6375732069642C2072697375732E20447569732075726E61206E6962682C207363656C6572697371756520717569732C206461706962757320612C207363656C65726973717565207365642C206E6962682E20446F6E6563206C75637475732E205574206575206D617572697320637572737573206469616D206C6163696E69612072686F6E6375732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20416C697175616D207665686963756C61206D6F6C6573746965206A7573746F2E204D616563656E617320696D70657264696574207065646520736564206D692E2053757370656E6469737365206E756C6C6120646F6C6F722C2068656E64726572697420656765742C2068656E6472657269742069642C2064696374756D2076656C2C206C656F2E204475697320616363756D73616E2E2043757261626974757220696E2066656C69732E204E756E63206C6F72656D2E205574206C656F20646F6C6F722C206C616F72656574206E65632C2076756C7075746174652061742C20656C656966656E6420696E2C206E756C6C612E2051756973717565206E756E632070757275732C2076617269757320656765742C20616363756D73616E206E65632C20616C69717565742065742C206E6962682E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20437261732061646970697363696E67207669766572726120646F6C6F722E204D617572697320706F72747469746F7220756C7472696365732070757275732E204E756C6C6120666163696C6973692E205072616573656E7420666175636962757320616E7465207669746165206D61757269732E0A0A5072616573656E74206C6163696E6961206C656374757320736564206E69736C2E20496E2074656D70757320636F6E677565206D61757269732E20496E746567657220666163696C69736973206F726E61726520656E696D2E204E756C6C61206964206D617373612E20446F6E656320636F6D6D6F646F206469616D2061742074656C6C75732E204E616D20646170696275732076697665727261206573742E204E616D2074656C6C75732E205072616573656E742061206C696265726F2E20496E206661756369627573206573742065676574206E6962682E204E756C6C612065726F73206F7263692C20696D70657264696574206E6F6E2C20626C616E646974206E6F6E2C2074656D706F7220656765742C206D692E2050656C6C656E74657371756520636F6E76616C6C69732E0A0A517569737175652065676574206D69206163206C656F20657569736D6F642066617563696275732E2050686173656C6C75732072686F6E637573207075727573206964206475692E20566573746962756C756D206D616C65737561646120656C656966656E6420616E74652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050656C6C656E74657371756520626C616E646974206D6174746973206F64696F2E2053757370656E646973736520636F6E7365717561742C206C65637475732061632073656D70657220736F6C6C696369747564696E2C206D692076656C69742064696374756D2061756775652C2061632074656D70757320646F6C6F7220657261742073697420616D6574206475692E2050726F696E2068656E6472657269742C2066656C6973207175697320766F6C757470617420706F73756572652C206469616D206F64696F206D616C657375616461206F64696F2C206120696E74657264756D206F726369206469616D20717569732073617069656E2E2050656C6C656E746573717565206F64696F206F64696F2C20766976657272612076656C2C20677261766964612065752C206D6F6C6573746965207365642C206E756C6C612E2050686173656C6C7573206D617572697320706564652C20636F6D6D6F646F2075742C20657569736D6F642065752C2068656E6472657269742065752C206573742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C6120656C656D656E74756D206C616375732065752061756775652E2053656420657261742E2050726F696E20706F7274612E204D616563656E61732071756973206D692E2050686173656C6C757320617420656E696D206163206A7573746F206772617669646120756C7472696365732E2043726173206C656F2E0A0A496E746567657220757420617263752E20446F6E656320736564206D61676E612E2050726F696E2066656C69732E20496E20696163756C69732C206C6967756C61206964206672696E67696C6C61207072657469756D2C206E696268206469616D20616363756D73616E2074656C6C75732C206567657420616363756D73616E206D657475732064756920766172697573207475727069732E2050686173656C6C7573206F726369206D657475732C20656C656966656E64207365642C2074656D706F722061632C207363656C657269737175652061632C2075726E612E20496E74656765722076697665727261206E657175652061206D61757269732E204D617572697320706F72747469746F7220646F6C6F722065752076656C69742E20496E7465676572206F64696F20656C69742C20766573746962756C756D2075742C20766F6C75747061742069642C2072686F6E63757320636F6D6D6F646F2C2075726E612E20457469616D20706C61636572617420706861726574726120657261742E2055742074656D706F72206573742E20496E7465676572206469676E697373696D20626C616E6469742074656C6C75732E204D6F726269206E69626820646F6C6F722C207363656C657269737175652069642C20636F6D6D6F646F206D616C6573756164612C206D61747469732061742C206D692E20437261732074696E636964756E7420636F6D6D6F646F2070757275732E20496E2074696E636964756E742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D20756C6C616D636F727065722E2055742068656E6472657269742E204D6F72626920756C7472696365732E0A0A5072616573656E7420696163756C69732C2065726F73206163206567657374617320736F64616C65732C2075726E61206C656F206665726D656E74756D206C6967756C612C2073697420616D657420616C697175616D2076656C69742073656D206E6F6E2070757275732E20446F6E65632072757472756D206172637520717569732070757275732E204E616D20706F73756572652C206C6163757320617420636F6E73657175617420706C6163657261742C206E756C6C61207065646520706F7375657265206F7263692C206E6F6E20657569736D6F6420747572706973206475692071756973206E69736C2E2050726F696E20706F7274612061646970697363696E67206E6962682E20446F6E65632074726973746971756520646F6C6F722061742074656C6C75732E20446F6E6563206E65717565206D617373612C20617563746F722069642C2066617563696275732076697461652C20756C6C616D636F727065722076656C2C206E6973692E2050726F696E206D6F6C6573746965206E6571756520736564206D617373612E204E616D2074656D706F722E204D6F72626920616C697175616D2073617069656E2061742074656C6C75732E2046757363652071756973207269737573206574206D69207072657469756D2070756C76696E61722E2046757363652073697420616D6574206C6967756C612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E646973736520657520656E696D2065742066656C6973207363656C65726973717565206C6F626F727469732E205072616573656E7420626962656E64756D2E20566976616D7573207665686963756C612E20496E7465676572206174206E696268207365642076656C69742072686F6E637573206D6F6C65737469652E2043726173206C616375732E2053656420756C6C616D636F727065722065726F732076656C20657261742E20467573636520657520746F72746F722073697420616D6574206469616D20657569736D6F642073616769747469732E204E756E632071756973206C61637573206964206E69626820636F6E76616C6C6973207661726975732E2053757370656E6469737365207669746165206D692E20566573746962756C756D207472697374697175652E20446F6E6563206D616C65737561646120697073756D206964206E657175652E204E756C6C616D20736564206C616375732E204475697320656765737461732C206A7573746F20757420636F6E677565206F726E6172652C2061756775652073617069656E206C7563747573206469616D2C20617420616363756D73616E20657261742073617069656E207574206C696265726F2E2050686173656C6C75732076656C206E756C6C612E2053757370656E646973736520617263752074656C6C75732C20706F72747469746F7220612C2070686172657472612066617563696275732C20616C697175616D2073697420616D65742C206D617373612E204E756C6C6120706F72747469746F722074696E636964756E74206C6F72656D2E204E756E6320646F6C6F72206F64696F2C20736167697474697320696E2C206C6F626F727469732076656C2C20766F6C7574706174207365642C206E6962682E0A0A5175697371756520626C616E646974206C656F2075742073617069656E2074656D70757320666163696C697369732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2041656E65616E20756C7472696369657320706F72747469746F72206A7573746F2E2046757363652072757472756D2065726F732075742075726E612E2050726F696E2071756973207175616D20656765742064756920616C697175616D20616363756D73616E2E20446F6E656320737573636970697420656C656966656E6420656C69742E2050656C6C656E746573717565206D61747469732C2066656C697320736F64616C657320696163756C697320696D706572646965742C206C616375732073656D20636F6E76616C6C69732061756775652C2073697420616D657420616C69717565742061726375207075727573206672696E67696C6C612072697375732E20496E206575206F64696F206964206D61676E61207068617265747261206F726E6172652E20416C697175616D20696E74657264756D2070756C76696E617220697073756D2E20536564206E657175652E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D2073697420616D6574206E6973692E2055742061742061756775652E204D617572697320766F6C757470617420626C616E646974206C6967756C612E204E756C6C61206575206D657475732E20566573746962756C756D206567657420656C69742E205072616573656E7420706F73756572652E20566573746962756C756D2069642073656D206E6F6E206C6563747573206D6F6C6C69732074696E636964756E742E20416C697175616D2069642066656C697320617420616E7465206F726E6172652074656D706F722E204E756C6C61206C61637573207475727069732C20666575676961742076697461652C2063757273757320717569732C20636F6E736563746574756572206E6F6E2C206D61757269732E204675736365206C61637573206D617373612C20706F72747469746F722075742C206D6F6C65737469652075742C2076656E656E6174697320612C206C6F72656D2E205072616573656E742073697420616D6574206F7263692E204D61757269732072686F6E6375732066656C69732076697461652066656C69732061646970697363696E6720696D706572646965742E204D616563656E6173206D6F6C6C6973206469616D206E6563206C656F2E0A0A467573636520656E696D20697073756D2C20756C7472696365732065752C206D6F6C65737469652069642C20656C656D656E74756D2069642C2073617069656E2E20496E746567657220612075726E612E204E616D2076656C6974206C696265726F2C2076656E656E6174697320656765742C2074656D706F722073697420616D65742C20666575676961742076697461652C20616E74652E204675736365206E756E632E205365642073656D706572206E69736C206E65632072697375732E20496E20736564206C696265726F2E2050726F696E20746F72746F72206E657175652C2074696E636964756E742061632C2074656D706F722061632C20706861726574726120717569732C2076656C69742E2044756973206C65637475732061756775652C20756C747269636965732076656C2C20636F6E7365717561742069642C20696163756C69732069642C20616E74652E20566976616D757320617563746F72206D65747573206120616E74652E204375726162697475722061726375206E6973692C20666163696C697369732061742C206C616F7265657420696E2C20636F6E736563746574756572207365642C206D61757269732E205175697371756520706C616365726174206469616D20736564206475692E20566976616D7573207072657469756D20636F6E64696D656E74756D206C6F72656D2E20437572616269747572206C616F726565742E2041656E65616E206F726369206C6967756C612C2063757273757320656765742C206C6163696E6961206E6F6E2C2066617563696275732076656C2C206C6F72656D2E0A0A416C697175616D206572617420766F6C75747061742E204375726162697475722065726F7320646F6C6F722C20636F6E67756520612C20636F6E64696D656E74756D207365642C206C75637475732075742C206E6962682E204D616563656E6173206E6F6E20746F72746F72206E65632074757270697320636F6D6D6F646F2070656C6C656E7465737175652E205072616573656E7420657569736D6F6420706C616365726174206D692E2053757370656E646973736520706F74656E74692E2050686173656C6C7573207574206E65717565207669746165206F726369206D617474697320696163756C69732E20496E746567657220656765742074656C6C75732E20446F6E656320617420616E74652E204E616D206C6163696E6961206C656F206567657420657261742E204D616563656E617320657569736D6F64206D61676E6120636F6E67756520746F72746F722E204D6F726269206E6563206D6173736120657520656E696D206D616C65737561646120736F6C6C696369747564696E2E2053656420616363756D73616E2E204E756C6C616D20697073756D2E205574206F64696F2E20416C697175616D206572617420766F6C75747061742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2050656C6C656E7465737175652069642076656C69742E204E616D206F64696F2073656D2C20616C69717565742075742C2074656D7075732073697420616D65742C20657569736D6F642065742C206E756E632E0A0A50656C6C656E746573717565206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205072616573656E74206D6175726973206E756E632C207661726975732075742C20636F6E76616C6C6973206D6F6C65737469652C206C75637475732073697420616D65742C206C656F2E205365642064696374756D206C6F72656D20657420617263752E204E756E632076656E656E617469732070656C6C656E746573717565206D617373612E204E756C6C6120666163696C6973692E2050686173656C6C757320696E20746F72746F722065676574207269737573207363656C657269737175652076756C7075746174652E20536564206E69626820656C69742C2073616769747469732061632C20636F6E64696D656E74756D206E65632C20636F6E76616C6C69732065742C206A7573746F2E20467573636520766F6C7574706174206D657475732E204E756E6320617563746F722E20566573746962756C756D206C656F2065726F732C2070656C6C656E7465737175652061632C206D6F6C6C697320756C7472696365732C2072686F6E637573206E6F6E2C20646F6C6F722E204D6175726973207665686963756C6120706C616365726174206E69736C2E20566573746962756C756D20626962656E64756D2C2061726375207175697320636F6E67756520656C656D656E74756D2C2076656C6974206E756E6320656C656966656E64207475727069732C206964206C7563747573207269737573206E69736C2073697420616D65742074656C6C75732E2050686173656C6C75732070656465206E657175652C20626C616E646974206E6F6E2C20636F6D6D6F646F2076697461652C20756C7472696369657320656765742C206D61676E612E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120666163696C6973692E20416C697175616D20616320616E74652E20437261732072697375732E204D6F726269206D6175726973206C616375732C20706F73756572652065752C20626C616E6469742065742C2070686172657472612061742C206D692E2050726F696E2061632070757275732E204475697320637572737573206E69736C2072757472756D207175616D2E20416C697175616D2061206F64696F206E6F6E206D61676E612070656C6C656E74657371756520756C747269636965732E204D616563656E6173206163206D6173736120717569732073617069656E20756C6C616D636F727065722074656D7075732E2043726173206375727375732076656C6974207365642073617069656E2E2050726F696E206E756C6C612E20566976616D757320736F64616C657320616C697175616D206E6962682E20457469616D206574206572617420757420616E7465206C6163696E696120657569736D6F642E204675736365206E6973692E2050726F696E2071756973206E756C6C612E0A0A517569737175652076656E656E617469732C2065726F7320736564206C616F7265657420736F6C6C696369747564696E2C206F72636920616E74652070656C6C656E746573717565206E69736C2C2073697420616D65742076697665727261207175616D2065726174206E6F6E2072697375732E20437261732065676574206C696265726F2E2053656420656C6974206D61676E612C2073656D7065722065752C206672696E67696C6C6120696E2C206469676E697373696D20736F64616C65732C20657261742E20566976616D757320666575676961742073656D2076656C206475692E20446F6E656320636F6E76616C6C697320736F6C6C696369747564696E206469616D2E2043726173207365642070757275732E20446F6E65632066656C69732065726F732C2073656D70657220656765742C2074656D706F7220636F6E7365637465747565722C20736167697474697320717569732C206E69736C2E204475697320696E20616E74652E2043726173206E6F6E207475727069732E204E756C6C612074656D706F722076656C697420616C697175657420747572706973206D6F6C657374696520706C6163657261742E2050726F696E20656C656D656E74756D206665726D656E74756D206D61757269732E20566976616D757320736564206F726369206C6163696E69612064756920706C6163657261742076656E656E617469732E20566573746962756C756D20666575676961742C2074656C6C757320696E20766F6C75747061742072757472756D2C206D61676E61206E69736920756C6C616D636F727065722065726F732C2069642070756C76696E6172206E657175652065726174207574206C616375732E20566976616D7573207365642061756775652E204E756C6C6120666163696C6973692E204D616563656E617320616E74652061756775652C20656C656D656E74756D2075742C20736F64616C65732076697461652C20636F6E64696D656E74756D206E65632C206C6F72656D2E20447569732070656465206F7263692C206672696E67696C6C612061742C20656C656966656E64206E65632C207072657469756D20696E2C20657261742E204E616D2073616769747469732C2074757270697320766974616520636F6E76616C6C69732070686172657472612C206F64696F2073656D207363656C65726973717565206C616375732C206E6563206C6F626F7274697320647569206469616D2076656C2065726F732E20496E2073656D7065722067726176696461206E657175652E0A0A496E7465676572206E756E632E205574207072657469756D20697073756D2073697420616D657420656C69742E20496E206E656320617263752E2053656420766573746962756C756D2076756C70757461746520697073756D2E2050656C6C656E7465737175652074696E636964756E742E204E756C6C61206772617669646120646F6C6F7220696E2074656C6C75732E2043726173207665686963756C612C20646F6C6F722075742070656C6C656E74657371756520616C697175616D2C206572617420656E696D20617563746F72206D617373612C207665686963756C61206C6F626F72746973206F64696F2065726F732071756973207175616D2E2050726F696E2064617069627573206E6571756520696E20656E696D2E2050726F696E20656C69742E20496E74656765722072686F6E6375732074696E636964756E7420656C69742E204675736365206C6F72656D206D657475732C2073656D7065722061632C20766F6C75747061742076697461652C20666163696C697369732075742C2074656C6C75732E20446F6E65632076656C20747572706973207669746165206E69736920706861726574726120706F72747469746F722E204D616563656E617320746F72746F722E204675736365206D692E204E756C6C616D206E6563207475727069732E2053656420736F64616C657320766573746962756C756D206E756E632E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A50656C6C656E74657371756520646F6C6F7220646F6C6F722C206C616F726565742065752C20616C697175657420717569732C207363656C657269737175652073697420616D65742C20617263752E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C616D206375727375732075726E61206567657420656C69742E205175697371756520626C616E6469742073617069656E20616320616E74652E2050726F696E206E756C6C612065726F732C206772617669646120766F6C75747061742C20736F64616C65732076656C2C206D6F6C6C69732065752C206D617373612E204E756C6C612074726973746971756520736F6C6C696369747564696E206E69736C2E20437572616269747572207669746165206C6F72656D2076697461652076656C69742065676573746173206F726E6172652E2041656E65616E20656765742065726F732E20416C697175616D206572617420766F6C75747061742E20467573636520612075726E61206964206F64696F20616C697175657420636F6E76616C6C69732E204375726162697475722073697420616D6574206E69736C20706F7375657265206C656F20706F737565726520646170696275732E2044756973206D6574757320657261742C206C75637475732076656C2C2072686F6E6375732061742C20636F6E76616C6C69732073697420616D65742C20656E696D2E20566976616D75732068656E6472657269742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D206567657420656C69742E0A0A4E756C6C616D2061206E756E632E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206D657475732075726E612C2074696E636964756E742065742C206C6163696E69612073697420616D65742C206C6F626F727469732076697461652C206C6967756C612E2050726F696E206574206D6175726973207669746165206D6920616363756D73616E2070656C6C656E7465737175652E20457469616D207175616D2070757275732C2068656E647265726974207365642C20666575676961742076697461652C20657569736D6F6420656765742C20746F72746F722E20557420616C697175616D206D61676E61207669746165206A7573746F2E2053757370656E6469737365206E6F6E206A7573746F2076656C2076656C697420636F6E64696D656E74756D2074656D7075732E20447569732074656D70757320697073756D2076697461652074656C6C75732E2050726F696E20696E206D617373612E20457469616D20756C6C616D636F727065722064696374756D2074656C6C75732E2050726F696E20616C69717565742066656C6973206174206C656F206C616F726565742070756C76696E61722E20566573746962756C756D20617263752070757275732C206D616C6573756164612073697420616D65742C206375727375732065752C20706C6163657261742073697420616D65742C206E756E632E204E616D206D61737361206F64696F2C20736F6C6C696369747564696E20696E2C2061646970697363696E6720612C20616C697175616D206E65632C2072697375732E20416C697175616D20626C616E6469742068656E647265726974206C696265726F2E204D617572697320677261766964612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204375726162697475722061206E6962682E20557420696E74657264756D206665726D656E74756D206E657175652E2050656C6C656E74657371756520736564206E756E632E204D6175726973207665686963756C61206E697369206574206E756E632E205072616573656E74206C6F72656D2E20446F6E65632073656D7065722E20496E7465676572206575206C6163757320696E2065737420616C697175616D2068656E6472657269742E20566573746962756C756D2065676574206E657175652E205365642073656D706572206C75637475732076656C69742E20437572616269747572206E6962682061756775652C20636F6E6775652065752C2068656E6472657269742069642C20636F6E6775652065742C20656E696D2E20496E746567657220706C61636572617420616C697175616D206C65637475732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20566976616D75732076697461652065726F732E20446F6E65632076656C206E69736C2E0A0A496E20766573746962756C756D20666163696C697369732075726E612E2055742072697375732E204D61757269732070686172657472612E2050656C6C656E746573717565206D61747469732E20496E746567657220737573636970697420616C697175616D20697073756D2E204475697320626C616E6469742C2073617069656E20657420756C7472696369657320636F6E64696D656E74756D2C2066656C6973206D6920656C656D656E74756D20706564652C206E6563207361676974746973206D65747573206D61757269732071756973207175616D2E205175697371756520616363756D73616E20617263752076656C206E756C6C612E20437261732073656D2073617069656E2C20706F72747469746F722069642C20756C747269636965732073616769747469732C206C75637475732065752C206E756C6C612E20496E746567657220717569732065726F732E204D6F726269207365642075726E6120612074656C6C7573207665686963756C612076756C7075746174652E20457469616D206E656320617567756520656765742066656C69732073656D706572207472697374697175652E205175697371756520757420646F6C6F722076656C2072697375732064696374756D20636F6E7365717561742E20536564206567657420646F6C6F7220736564206E756E63206C6163696E696120616C69717565742E2053757370656E646973736520616320746F72746F7220696E20697073756D20706F73756572652076656E656E617469732E20536564206567657420657261742E204E756C6C612066617563696275732E2044756973206C616F726565742C206D6173736120706F72747469746F7220616C697175657420656765737461732C20697073756D206C65637475732072686F6E637573207175616D2C20696E2061646970697363696E672065726F732073656D2075742074656C6C75732E2050656C6C656E74657371756520666575676961742074656D707573207175616D2E20566976616D757320696420646F6C6F7220656765742073617069656E20636F6E7365637465747565722074656D706F722E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120696163756C6973206665726D656E74756D206C696265726F2E204375726162697475722066617563696275732C206D61737361206D616C657375616461206375727375732074696E636964756E742C20657261742073656D20656C656966656E64206D61757269732C20736564206672696E67696C6C61206D6920616E74652061632070757275732E204475697320656C656D656E74756D206C65637475732E204E756E63206F726E617265206172637520657520746F72746F722E20566573746962756C756D2076656C20646F6C6F72206174207075727573206C6163696E6961206672696E67696C6C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E616D20696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204D616563656E61732074696E636964756E742C2065726F73206120656765737461732070656C6C656E7465737175652C2072697375732072697375732064696374756D206C696265726F2C20696420616C6971756574206D65747573206A7573746F20696E206D617373612E2050726F696E20612074656C6C75732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205365642070757275732E20536564206E6F6E20706564652E2041656E65616E206D617373612073617069656E2C20736F64616C65732073697420616D65742C20636F6E7365717561742064696374756D2C20656C656966656E642076697461652C20746F72746F722E20446F6E656320756C747269636573206C6163696E696120656C69742E0A0A4D6F7262692061646970697363696E6720736F64616C657320646F6C6F722E20557420756C6C616D636F7270657220756C74726963696573206573742E20496E2076656E656E617469732074656D7075732061756775652E2053757370656E646973736520746F72746F7220646F6C6F722C20616363756D73616E2065742C20737573636970697420612C2074696E636964756E742075742C206C696265726F2E20416C697175616D207363656C65726973717565206D61676E61207365642066656C69732E2051756973717565207574206E756E632061206D61676E612076756C70757461746520706C6163657261742E20416C697175616D2072686F6E637573207665686963756C61206475692E2053656420746F72746F722E204E756C6C616D2073697420616D6574206469616D2E204E756E63207365642065726F732E20536564206574206F64696F2074696E636964756E7420656C6974206772617669646120636F6E76616C6C69732E20437572616269747572207175697320746F72746F722061206C616375732073656D706572207661726975732E204D6175726973206174206175677565206E6F6E206D6920736F6C6C696369747564696E20616C697175616D2E20496E746567657220756C6C616D636F727065722E2050656C6C656E746573717565207375736369706974207175616D206E6F6E2070757275732E20416C697175616D2061632065726F73206174206172637520756C6C616D636F7270657220636F6E7365637465747565722E2053757370656E6469737365207072657469756D206D6174746973206C656F2E0A0A44756973206174206E756E632E2053656420646F6C6F72206573742C207661726975732061632C20706F7274612065742C2074696E636964756E742068656E6472657269742C2072697375732E20566976616D7573207574206D61676E612E205072616573656E74207574206D61757269732E20496E207075727573206C616375732C206D6174746973207365642C20766573746962756C756D206E65632C2074656D706F722061742C206E69736C2E204372617320756C6C616D636F727065722076656E656E617469732074656C6C75732E20557420646F6C6F722E204D616563656E6173206D616C6573756164612C207065646520612070756C76696E6172206D61747469732C2061726375206469616D207665686963756C612072697375732C207175697320706F72747469746F72206175677565206D6173736120696E2076656C69742E204E756E6320636F6E6775652E204D6F7262692076656C6974206D657475732C2072686F6E6375732065742C20616C697175616D20636F6E7365637465747565722C20756C74726963696573206D616C6573756164612C206C6967756C612E205365642076656C6974206E69736C2C2073616769747469732076697461652C20706861726574726120612C20706F7375657265207365642C206D617373612E204E756C6C6120666163696C6973692E20496E207661726975732C206C6967756C61206964206C6F626F7274697320736F64616C65732C206175677565206F726369206665726D656E74756D2074656C6C75732C2065752070756C76696E6172207269737573206C6967756C6120612073617069656E2E204D6F726269206C616F7265657420697073756D206E6F6E206D692E204E616D20637572737573206C6F72656D207574206D692E20566976616D7573206D61676E6120656E696D2C20706F7375657265206E6F6E2C2073656D70657220717569732C20736F64616C65732065752C20617263752E20457469616D206D692070757275732C207072657469756D20666575676961742C20766172697573207365642C2070656C6C656E74657371756520656765742C206C6967756C612E20496E206C656F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E6563207669746165206F726369206575206F72636920736F6C6C696369747564696E20666575676961742E0A0A5072616573656E74207075727573206D617373612C20657569736D6F642076697461652C2074656D707573206E65632C20636F6E7365717561742068656E6472657269742C206D657475732E2041656E65616E2066656C6973206573742C20656765737461732076697461652C20616363756D73616E20656765742C2070656C6C656E74657371756520696E2C2073617069656E2E204475697320646170696275732070656465206E6F6E2073617069656E2E204E756E632075726E612E20496E74656765722076656C206C696265726F2E204475697320617567756520617263752C2064617069627573206E6F6E2C20666163696C697369732076697461652C20706F73756572652075742C2065726F732E20446F6E6563207669746165206E756E632073697420616D6574206172637520696D706572646965742064696374756D2E204D6F72626920656C656966656E642C206C6F72656D20657520636F6E73656374657475657220766573746962756C756D2C206469616D206E756E63206F726E61726520617263752C2061632074656D706F722066656C697320646F6C6F7220656765742065726F732E2050686173656C6C7573206D617373612073656D2C20736F6C6C696369747564696E2061632C20736F64616C657320677261766964612C206C756374757320612C207175616D2E204E616D206E65717565207175616D2C20766976657272612061742C2076656E656E6174697320717569732C207361676974746973206E6F6E2C20656E696D2E0A0A4E756C6C6120666163696C6973692E2050656C6C656E7465737175652065676573746173206C6163696E6961206573742E205365642074696E636964756E742C2070656465207365642074696E636964756E7420766573746962756C756D2C2075726E6120646F6C6F722061646970697363696E672070757275732C207669746165206672696E67696C6C612066656C697320656C697420696E206E6962682E204E756C6C6120736564206E6973692E204D6175726973207375736369706974207363656C6572697371756520617263752E20457469616D206E6F6E20656E696D2076656C2065726F7320616363756D73616E206D616C6573756164612E204E756E632074696E636964756E7420636F6D6D6F646F206D61757269732E20496E2074696E636964756E7420726973757320717569732075726E612E204E756C6C61206469616D20746F72746F722C20616C69717565742065742C2074696E636964756E7420717569732C20736F6C6C696369747564696E2061632C20746F72746F722E2043726173206E69736C206E657175652C2076756C7075746174652073757363697069742C206D6F6C657374696520717569732C2070756C76696E61722061742C206E756C6C612E204E756C6C616D206163206D65747573206E6563206F64696F20706F7375657265207661726975732E2043726173207365642070656465206E65632064756920706F737565726520626962656E64756D2E204475697320657569736D6F6420756C6C616D636F72706572206C696265726F2E20416C697175616D2066617563696275732070756C76696E6172207475727069732E0A0A496E207574206E65717565206964206E756E63206665756769617420636F6D6D6F646F2E20437572616269747572206469676E697373696D2C2066656C697320617420736F6C6C696369747564696E206C6163696E69612C20656E696D20656C6974207375736369706974206E657175652C20736564206C7563747573206C6F72656D20697073756D20696E206C656F2E204475697320646170696275732C206F64696F207175697320617563746F7220636F6D6D6F646F2C206E69736C206F64696F206D61747469732074656C6C75732C206E65632074696E636964756E7420747572706973206469616D20696E20617263752E2043757261626974757220612073656D2E204E756C6C616D20766F6C7574706174206D61676E612E2050656C6C656E7465737175652073616769747469732C206E6571756520636F6E736571756174207072657469756D206375727375732C20646F6C6F72206C6163757320636F6E73656374657475657220617263752C20736564206C616F72656574206573742075726E61206574206D657475732E2053757370656E646973736520706C6163657261742C20647569206120706F7274612074656D706F722C206C6F72656D20647569206C6F626F72746973206E657175652C207365642076656E656E61746973206469616D20656E696D2069642065726F732E20457469616D206574206E69736C206E6F6E206C656374757320666175636962757320636F6E7365637465747565722E204D6F726269207363656C657269737175652C2073656D206E65632074656D70757320756C6C616D636F727065722C20697073756D206469616D2066657567696174206C6F72656D2C2061206672696E67696C6C612073617069656E20656C69742071756973206E6962682E204E756C6C616D206469616D2075726E612C2076697665727261207365642C2070686172657472612072686F6E6375732C2074696E636964756E742076656C2C206F7263692E20496E746567657220616363756D73616E206D617474697320657261742E204E616D2064696374756D2E204D6175726973206E6563206C656F2E204E756C6C6120696163756C69732E204E756C6C61206E69736C206D692C206461706962757320717569732C207665686963756C6120612C2063757273757320656765742C206F64696F2E0A0A50686173656C6C7573206461706962757320657569736D6F64206E6962682E20566976616D757320696D7065726469657420616E746520696E206C6967756C612E2050656C6C656E74657371756520616363756D73616E2E20496E20696D706572646965742C20647569206120617563746F72206672696E67696C6C612C206D65747573206E6973692063757273757320646F6C6F722C2076656C206C7563747573206C6967756C61206C6F72656D207669746165206D61757269732E205072616573656E74206D617474697320766573746962756C756D20656C69742E20416C697175616D20656E696D206C616375732C2070756C76696E6172206E6F6E2C206C6163696E69612073697420616D65742C20656C656966656E64206E6F6E2C2076656C69742E20566573746962756C756D206163206C656F2E204D617572697320696D70657264696574206A7573746F206163206C65637475732E20536564206D6F6C6573746965206C656374757320736564206475692E20536564206665726D656E74756D2074656D707573206D61757269732E204E616D206F726E617265206F7263692061632074656C6C75732E205574206D616C6573756164612C206C61637573206964206C6163696E696120616363756D73616E2C206469616D20656C69742061646970697363696E67206D657475732C20657420626962656E64756D2073617069656E206E69626820626C616E646974206F7263692E2053757370656E646973736520697073756D2074656C6C75732C20736167697474697320717569732C20766573746962756C756D206E6F6E2C2076756C7075746174652065752C2065726F732E205072616573656E74206174206E756C6C612069642070656465207363656C6572697371756520756C747269636965732E204372617320626C616E646974207072657469756D2074656C6C75732E204D616563656E6173206461706962757320636F6E64696D656E74756D2061756775652E2050686173656C6C75732074696E636964756E74207068617265747261206C6F72656D2E204D6F726269206E6F6E2065726F732E205365642074656D706F722C206E69736C20612074696E636964756E742074696E636964756E742C2065726F73206469616D2064696374756D2073656D2C2076656C206469676E697373696D20616E7465206469616D20736564206D61676E612E205072616573656E74206E6F6E206C6967756C61206964206D65747573206D6F6C657374696520636F6E7365637465747565722E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E64697373652076656C206D692E2043757261626974757220616E7465206E756C6C612C2072757472756D20612C20636F6E76616C6C69732076656C2C207665686963756C612061632C206E756E632E204E756E632073616769747469732C20656E696D2073697420616D657420617563746F722072757472756D2C206D617572697320617263752076756C707574617465206E657175652C20657420657569736D6F64206573742066656C6973207175697320616E74652E20566573746962756C756D207475727069732074656C6C75732C2068656E64726572697420696E2C206C6163696E696120636F6D6D6F646F2C20756C6C616D636F7270657220677261766964612C2072697375732E204D61757269732072686F6E637573206C6163696E69612072697375732E204D616563656E617320736F6C6C696369747564696E2065726174207669746165206E756E632E205072616573656E74207072657469756D2070656C6C656E7465737175652061756775652E20446F6E656320696E74657264756D2E205072616573656E742061632065726F732076697461652065726174206C6F626F72746973206672696E67696C6C612E2041656E65616E20636F6E7365717561742074656C6C75732E204E756C6C6120616363756D73616E20626962656E64756D2066656C69732E204D616563656E6173207072657469756D20616E7465206964206E6973692E2041656E65616E206D6920617263752C2073656D706572207365642C206D61747469732065752C2076656E656E617469732073697420616D65742C20617263752E20446F6E656320616C697175657420657569736D6F64206C656F2E2050726F696E206D61676E61206A7573746F2C2074726973746971756520612C2073656D7065722061632C20736F6C6C696369747564696E20612C206C6967756C612E204D6F7262692076656C69742E20416C697175616D2076656C206E6973692E0A0A496E2061206C6F72656D207574206E756E63206665756769617420636F6E6775652E20446F6E6563206665726D656E74756D20626962656E64756D206475692E2050726F696E207661726975732065737420717569732076656C69742E20446F6E656320616C69717565742073656D20616363756D73616E206D692E2053656420706C6163657261742E204E756C6C616D206163206E6973692061206D61737361206C6F626F727469732073757363697069742E204E756E63206964206C656F2E20416C697175616D206574206D617373612E204E756C6C616D20766573746962756C756D20656C656D656E74756D206D657475732E20496E20636F6E736563746574756572206E6973692076656C206A7573746F2E204D616563656E6173206567657420707572757320736564206D61737361207661726975732070656C6C656E7465737175652E2050686173656C6C75732066617563696275732066656C697320717569732066656C69732E2041656E65616E206F64696F20617263752C20626C616E64697420717569732C20666163696C6973697320696E2C20696D706572646965742065752C206C6F72656D2E204E616D20706F73756572652070756C76696E6172206D692E204675736365207472697374697175652C206D617572697320657420636F6E73656374657475657220756C747269636965732C206D6175726973206C65637475732074656D706F72206A7573746F2C206174206672696E67696C6C61206573742065737420736564206E6973692E20517569737175652066617563696275732E2053656420696E20746F72746F722074696E636964756E7420657374206C6163696E696120696163756C69732E204D616563656E61732061206D617373612E2050656C6C656E7465737175652061206E69626820617420707572757320706F7274612068656E6472657269742E0A0A4E756C6C616D207475727069732E2046757363652061632073656D20736564206F64696F2070656C6C656E74657371756520696D706572646965742E2043757261626974757220696E20617263752E205072616573656E74206C61637573206C616375732C20666575676961742069642C2070756C76696E617220696E2C2074696E636964756E74207365642C206E657175652E204D616563656E61732076697665727261206F64696F206567657420746F72746F722E20496E746567657220616C697175616D2C206C6F72656D2072757472756D2076656E656E61746973206469676E697373696D2C206C6967756C61206D61676E61206D616C65737561646120617263752C2076656C2066657567696174206C6F72656D20697073756D2071756973206D617373612E204D6F72626920616E74652E20566573746962756C756D206D6175726973206C696265726F2C20756C6C616D636F7270657220717569732C20756C74726963657320717569732C20666163696C69736973206E6F6E2C206D617373612E204D616563656E617320696D706572646965742E20416C697175616D206572617420766F6C75747061742E2050656C6C656E746573717565206469676E697373696D2067726176696461206C65637475732E20496E206E696268206F64696F2C20617563746F7220656765742C206461706962757320717569732C206469676E697373696D2076656E656E617469732C20617263752E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20447569732070656C6C656E746573717565206C6967756C612071756973206D617373612E2043757261626974757220636F6E64696D656E74756D2C206A7573746F2065676574206F726E617265206C75637475732C206C6F72656D206C6967756C6120736167697474697320706564652C206120706F727461206E756E63206E756E6320696E206E657175652E20517569737175652066656C6973206D61757269732C20636F6E64696D656E74756D2076697461652C20617563746F722076697461652C2074696E636964756E7420717569732C20706564652E204E756E63206C6163696E696120616E746520696E206C656F2E2050656C6C656E746573717565206C696265726F2E2041656E65616E2061206C6967756C61206574206E756E6320766573746962756C756D20636F6E7365637465747565722E0A0A4675736365206F726E6172652E205072616573656E742069642075726E612E20496E74656765722076656E656E617469732C207175616D206E6F6E20736167697474697320616363756D73616E2C20616E7465206E6962682073616769747469732061756775652C20736F6C6C696369747564696E2061646970697363696E6720646F6C6F722076656C697420657520657261742E2050726F696E207175697320656E696D206575207075727573207665686963756C6120616C697175616D2E204E756C6C612076656C20656E696D2076656C20656C697420736F6C6C696369747564696E206672696E67696C6C612E20416C697175616D206572617420766F6C75747061742E205365642073757363697069742066656C6973207574207475727069732E20457469616D2072757472756D20726973757320696D70657264696574206573742E20416C697175616D20612074656C6C75732061742074656C6C757320636F6D6D6F646F20646170696275732E204D61757269732072757472756D206D61676E61206574206F64696F2E20496E20617420646F6C6F722E20437572616269747572207665686963756C61206C656374757320696E20746F72746F722E204675736365206A7573746F2070757275732C206C75637475732076697461652C206D6F6C6C697320696E2C2070686172657472612061632C2070757275732E204E756C6C616D20706F737565726520696E74657264756D206A7573746F2E20437572616269747572207669746165206C616375732076656C206C656F20636F6E6775652070756C76696E61722E0A0A41656E65616E20656C656966656E64206E6962682076617269757320746F72746F722E2053757370656E64697373652076656C2065726F732E2050726F696E206E6563206469616D206120746F72746F7220756C747269636573206F726E6172652E20416C697175616D207363656C657269737175652066657567696174206A7573746F2E20566976616D757320616E74652075726E612C2061646970697363696E672076697461652C20706F72747469746F722065752C20736F64616C65732065742C2066656C69732E2053757370656E646973736520706F74656E74692E20437572616269747572206163206D6173736120696E206E69736C207361676974746973206D6F6C6C69732E204E616D207175616D206C6967756C612C20636F6E73656374657475657220656765742C20696163756C69732061742C207661726975732065752C206C656F2E204475697320646F6C6F72206C6967756C612C2074696E636964756E742061742C20756C6C616D636F72706572207365642C20616363756D73616E20616C697175616D2C206C6967756C612E2050686173656C6C75732076756C7075746174652C206C6F72656D2061742074696E636964756E742070686172657472612C207269737573206C6563747573206C6163696E6961206D61676E612C20717569732072757472756D20656E696D206D61676E612061742073656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E20447569732069642073656D2061206D617572697320736F6C6C696369747564696E2074696E636964756E742E20457469616D2065752070757275732065752061726375206672696E67696C6C612061646970697363696E672E20566976616D7573206F726E6172652074656D707573206469616D2E2050726F696E20747572706973207175616D2C206C6163696E6961206E6F6E2C20656765737461732061742C20636F6D6D6F646F20656765742C20706564652E205072616573656E742076756C70757461746520726973757320696E206573742E204E756C6C6120666163696C6973692E0A0A557420656C656D656E74756D206C6163696E69612070757275732E2050726F696E2076697461652061726375206163206E756C6C6120636F6E76616C6C697320616C697175616D2E204E756C6C6120636F6E6775652C206C696265726F2069642070656C6C656E746573717565206D61747469732C207175616D206C656374757320706F72747469746F72206469616D2C2061207363656C6572697371756520647569206C696265726F20696E2073617069656E2E204E756C6C616D2066656C6973206469616D2C207665686963756C612076656C2C206D6F6C65737469652075742C20766573746962756C756D20616C697175616D2C2073617069656E2E20446F6E656320636F6E76616C6C69732C2065737420757420656C656D656E74756D20766F6C75747061742C206D617572697320697073756D20677261766964612073656D2C20636F6D6D6F646F20666163696C697369732073617069656E206C65637475732073656D706572206C65637475732E205175697371756520706F72747469746F722065726F73207574206E6962682E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20457469616D206D617474697320726973757320736564206F64696F2E20566573746962756C756D206574206F64696F2E20496E206861632068616269746173736520706C617465612064696374756D73742E204E616D20747269737469717565206D61737361207574206C6967756C612E2051756973717565206E6962682074656C6C75732C207665686963756C612073697420616D65742C2061646970697363696E672061742C20636F6E76616C6C6973206E65632C206C6967756C612E20566573746962756C756D207072657469756D2C206D69206E6563206672696E67696C6C6120626962656E64756D2C20647569206E756E6320736F64616C657320706564652C20612073656D706572206D61676E61206E696268206E6F6E206469616D2E20446F6E6563206D61737361206E756E632C20766976657272612076656C2C20636F6E73656374657475657220706F7274612C2064617069627573206E6F6E2C20697073756D2E2044756973206E69736C206D61757269732C206375727375732076656C2C2073656D706572206E6F6E2C20736F6C6C696369747564696E20626962656E64756D2C2066656C69732E20566573746962756C756D206575206E657175652E0A0A43726173206E656320646F6C6F722E20446F6E6563206C616F726565742074656D707573206C65637475732E20437261732073656420746F72746F7220696E74657264756D206C6163757320656C656966656E64206469676E697373696D2E204D616563656E61732073697420616D657420656C69742E204E756C6C616D207175697320646F6C6F722076656C20647569207068617265747261206C75637475732E20496E2073697420616D6574207175616D2073697420616D6574207065646520756C74726963657320756C7472696365732E204D616563656E6173206469616D2E20496E74656765722075726E612E204375726162697475722064696374756D2C2076656C69742073656420706C6163657261742073757363697069742C206572617420747572706973206665726D656E74756D206A7573746F2C2073656420696E74657264756D206E657175652073656D206574206E6962682E20566976616D757320636F6E73657175617420636F6E76616C6C6973206D61676E612E204E616D20616C697175616D2C2065737420616320626962656E64756D20636F6D6D6F646F2C206D61676E61206573742064696374756D206D692C207669746165206D616C65737561646120656C6974206D61676E61207669746165206F64696F2E204D616563656E61732074656D706F722076756C7075746174652074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206475692E20457469616D20616363756D73616E207065646520636F6E67756520746F72746F722E0A0A4D6F7262692074656D706F72206C696265726F206163206C6F72656D2E20496E20616C697175657420766172697573206D61676E612E20496E20617263752E2050686173656C6C7573206F64696F2E2046757363652074696E636964756E7420616C69717565742066656C69732E20517569737175652076656C69742E20536564206C75637475732E20416C697175616D2066657567696174206672696E67696C6C61206D692E20416C697175616D206D6F6C657374696520766976657272612072697375732E2050726F696E20617263752E20566573746962756C756D206C6F626F727469732074656D707573206E6973692E205072616573656E742061206172637520696E2076656C697420766976657272612072757472756D2E0A0A496E20736564206C65637475732E20446F6E656320726973757320646F6C6F722C20626C616E6469742073697420616D65742C20656C656D656E74756D20636F6E76616C6C69732C20706861726574726120717569732C20706564652E20496E7465676572206F726E6172652E2041656E65616E20656765737461732064617069627573206A7573746F2E20536564207175616D206C656F2C20706F73756572652061742C20656C656D656E74756D2076697461652C20636F6D6D6F646F20656765742C206573742E20416C697175616D206D6F6C65737469652072686F6E63757320656E696D2E2043757261626974757220696163756C697320756C74726963657320706564652E204D6F72626920616C69717565742072757472756D206C616375732E20416C697175616D207175616D2E2053656420636F6D6D6F646F2C2074757270697320696E20706861726574726120706F73756572652C206D6920726973757320696D7065726469657420657261742C206120766573746962756C756D206D617373612074656C6C7573207665686963756C612073656D2E204D6175726973206672696E67696C6C6120756C747269636573206E756E632E204E616D206E69736920656E696D2C20656C656966656E642073697420616D65742C20756C747269636573207365642C206665726D656E74756D206E6F6E2C2061756775652E2050726F696E20636F6E677565206C6F626F72746973206E6973692E204D616563656E61732068656E6472657269742E204E616D20736564206E69736C2E204E756E6320656C656D656E74756D206F64696F2065752072697375732E20496E206D657475732E2050686173656C6C75732067726176696461207072657469756D206C6967756C612E204E756C6C61207669746165206E657175652E204E616D206E69736920746F72746F722C206F726E617265206E6F6E2C20626C616E6469742061742C206375727375732065752C20746F72746F722E0A0A4475697320626962656E64756D20697073756D20696E206E756E6320637572737573206D6F6C65737469652E204E756E63206F7263692E204E756C6C616D206E656320616E7465206E6F6E20657374206469676E697373696D20766976657272612E204D617572697320626C616E6469742C2076656C69742069642066657567696174207072657469756D2C20656C6974206D61676E612070656C6C656E74657371756520646F6C6F722C206174207361676974746973206C616375732076656C69742065676573746173206D61676E612E2050656C6C656E746573717565206375727375732C206469616D20636F6E736563746574756572207361676974746973206672696E67696C6C612C20746F72746F72206E6973692061646970697363696E67206E756E632C20657520766172697573206C6163757320726973757320616320656C69742E204D6175726973206964206E6973692071756973206C656F20657569736D6F642076656E656E617469732E2050656C6C656E74657371756520616320616E74652E204D617572697320617263752073617069656E2C2074656D706F722061742C20706F72747469746F722069642C20636F6E64696D656E74756D2075742C206475692E20457469616D206665726D656E74756D20756C747269636965732061756775652E20437261732075742065726F73206174206A7573746F20756C7472696369657320696163756C69732E2044756973206469676E697373696D2C206E69736C20657420666163696C69736973206665726D656E74756D2C2065726174207075727573206D6F6C65737469652074656C6C75732C20717569732074656D70757320697073756D206C656374757320617420656C69742E204E756C6C61207669746165206C6F72656D2E0A0A41656E65616E2076656C2073656D206574206469616D2073656D70657220636F6E6775652E20496E20626962656E64756D206469616D20717569732074656C6C75732E204E756E6320666163696C6973697320756C74726963696573206E6962682E2043726173206E756E6320656E696D2C2066657567696174207365642C20756C7472696365732076697461652C2073616769747469732076697461652C20697073756D2E204675736365207669746165206E756C6C612E20446F6E65632070656C6C656E7465737175652C2076656C697420696E20706F72747469746F7220656C656966656E642C20657374206E65717565206C6F626F727469732076656C69742C2073697420616D65742072757472756D20616E746520746F72746F72206E656320646F6C6F722E20446F6E6563207665686963756C612E204E756C6C6120666163696C6973692E20536564206567657374617320756C747269636573206E6962682E20446F6E656320656C6974206C65637475732C20636F6E76616C6C697320706F72747469746F722C20616C697175657420646170696275732C206665756769617420656765742C206C6967756C612E2053656420636F6E736563746574756572206A7573746F2E204D616563656E617320612073617069656E2073697420616D6574206E6973692064617069627573206C6F626F727469732E20566976616D7573206C7563747573206C6F72656D206E6F6E206E756C6C612E2053656420656765742065726174207669746165206C696265726F20696E74657264756D20706F73756572652E20437261732070756C76696E61722E204E756C6C616D20696D706572646965742C20646F6C6F722074656D706F72206469676E697373696D20626C616E6469742C206475692073617069656E2072686F6E637573206E657175652C206964206D616C657375616461206175677565206D61676E612073697420616D65742075726E612E204475697320736564206D61757269732E0A0A4D6F72626920616363756D73616E2E20536564206D61757269732061756775652C206672696E67696C6C61206E6F6E2C20617563746F722075742C20617563746F722065742C206F7263692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320757420706564652E20446F6E6563207669766572726120656E696D2076656C206C6F72656D2E2050656C6C656E746573717565206E65717565206D61757269732C20696E74657264756D2065752C2076656E656E617469732069642C20636F6E64696D656E74756D2065752C2073617069656E2E20446F6E656320697073756D20617263752C206C6163696E69612061646970697363696E672C206C616F726565742065742C206375727375732076656C2C2076656C69742E205574207361676974746973206D617572697320717569732072697375732E20496E7465676572206575206F64696F207669746165206C61637573207669766572726120616363756D73616E2E204D6F726269206C656F20616E74652C206469676E697373696D207365642C2076617269757320717569732C20766F6C75747061742076697461652C206E6973692E204E756C6C6120706C61636572617420696E74657264756D20656C69742E20446F6E6563206E65717565206475692C2073616769747469732076697461652C20736F6C6C696369747564696E20717569732C20636F6D6D6F646F2076697461652C206E657175652E204E756C6C612071756973206C6967756C61206F726E617265206C6967756C612064696374756D206F726E6172652E204D61757269732072757472756D2072757472756D206E657175652E2041656E65616E207665686963756C612074656D707573206573742E20446F6E656320766172697573207363656C6572697371756520706564652E20446F6E656320706C6163657261742076756C707574617465206C656F2E204E756C6C616D206E756E63206E69736C2C20706F7375657265206E6F6E2C20666575676961742076697461652C2070656C6C656E74657371756520717569732C206D61757269732E20496E20647569206E657175652C2063757273757320656765742C20736167697474697320656765742C20646170696275732076697461652C206D692E2050726F696E2065676574206573742E0A0A467573636520706F727461206573742E204D6175726973206D61676E612E20416C697175616D20697073756D206C616375732C20756C747269636965732069642C20766573746962756C756D206C75637475732C20616363756D73616E2075742C20616E74652E20536564206D61757269732E205365642061646970697363696E67206C656F2073697420616D6574206D61676E612E2053757370656E646973736520706F74656E74692E204E756E63206D6173736120656C69742C206672696E67696C6C6120656765742C20656765737461732076697461652C206C75637475732076697461652C20646F6C6F722E2050686173656C6C75732071756973206E756C6C61206575206E69736920696E74657264756D20736F6C6C696369747564696E2E204E756C6C616D2069642074656C6C75732E20496E746567657220696163756C697320646F6C6F722061632070757275732E205365642076656C206D692E20437572616269747572206E6F6E206D61676E612073697420616D6574206A7573746F20636F6E64696D656E74756D2076756C7075746174652E20517569737175652074696E636964756E742070656465206575206E69736C2E20566976616D7573206C6F626F727469732E204E756E63206D65747573206D657475732C20636F6E677565207365642C2074696E636964756E74207365642C207072657469756D2061742C206F64696F2E20446F6E6563206120617263752E20496E2073656D206A7573746F2C207665686963756C61207365642C207661726975732069642C20766F6C75747061742061742C2072697375732E205072616573656E7420696163756C6973206D617373612E20496E206172637520656C69742C2068656E64726572697420656765742C20756C6C616D636F7270657220696E2C20706F7274612069642C2074656C6C75732E20446F6E65632073616769747469732068656E647265726974206469616D2E0A0A53757370656E646973736520706F74656E74692E20536564206574206469616D206574206175677565207361676974746973206C6F626F727469732E2050686173656C6C757320646F6C6F722E2055742065742061726375206567657420616E74652074656D706F7220706F73756572652E20416C697175616D206665726D656E74756D207363656C65726973717565206475692E204D61757269732061742070757275732E20446F6E656320657261742073656D2C20766573746962756C756D206E65632C2066617563696275732061632C206D617474697320612C206C656F2E2053757370656E64697373652061646970697363696E67206C6163696E69612073656D2E204E756C6C616D206F72636920617263752C2064696374756D2065742C20666175636962757320766976657272612C20646170696275732065742C206E657175652E2043726173206E756E63206469616D2C2061646970697363696E67206E6F6E2C20736F6C6C696369747564696E20696E2C20696E74657264756D2076656C2C206D617373612E204D61757269732073616769747469732C206A7573746F206174207472697374697175652074656D7075732C206D6175726973206D617572697320616C697175616D20616E74652C2073697420616D657420706F7375657265206469616D206475692065676574206C6967756C612E20496E206469676E697373696D2C206E69736C207574206C6163696E696120636F6E64696D656E74756D2C2065726174206A7573746F20706F72747469746F72206E756C6C612C206E6F6E2067726176696461206C6967756C61206D61676E612065676574206D617373612E20566573746962756C756D207669746165206C6967756C61206174206D6920766573746962756C756D2073757363697069742E2044756973206C616F726565742E204E756C6C6120636F6D6D6F646F206C696265726F2073697420616D6574206C6F72656D2E20557420656C656D656E74756D2073656D2E20496E74656765722076656C20646F6C6F722E204E616D20666163696C69736973206D6920717569732073656D20756C7472696365732073616769747469732E205365642071756973207175616D206174206D65747573206D6F6C657374696520626962656E64756D2E0A0A50726F696E2064756920656E696D2C206C6163696E696120612C20666575676961742061632C20706C6163657261742076697461652C20706564652E205175697371756520656765737461732C206C656F206567657420616C697175616D207072657469756D2C206C696265726F206A7573746F2074696E636964756E742065726F732C2075742065676573746173206175677565207065646520656C656D656E74756D206E6962682E20437572616269747572206D6F6C6C697320736F64616C657320656E696D2E20446F6E65632061756775652E2050686173656C6C757320696420697073756D20706F737565726520647569207072657469756D2066617563696275732E204D6175726973206C756374757320616E74652073656D706572206E69736920696E74657264756D2061646970697363696E672E204475697320646170696275732C206F64696F207175697320766976657272612072686F6E6375732C206A7573746F207175616D20626962656E64756D20646F6C6F722C20696420646170696275732076656C697420657261742076656C20657261742E2046757363652073697420616D6574206E69736C2076656E656E61746973207175616D20756C74726963657320636F6E64696D656E74756D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632072686F6E637573207363656C65726973717565206C6967756C612E20566573746962756C756D206D69206F64696F2C20616363756D73616E2065742C2061646970697363696E6720656765742C206F726E6172652075742C207175616D2E204E756C6C616D20626C616E646974206D6F6C6573746965206D61757269732E20437572616269747572206469676E697373696D206D6175726973206574206C6F72656D2E2053757370656E64697373652061206A7573746F2E204E616D206D617474697320666175636962757320617263752E204475697320626C616E64697420656E696D206E6F6E206D617373612E0A0A4E756C6C616D206C6F72656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E204D617572697320636F6E73656374657475657220706F7375657265206D61757269732E204D616563656E61732074696E636964756E74206D617572697320696E2065726F732E204E756C6C61206575206D65747573206575206F72636920736F6C6C696369747564696E2066617563696275732E2053757370656E646973736520616C697175616D206D6175726973206964206573742E204372617320626C616E646974206475692065742075726E612E204E756C6C6120617263752E2053656420612075726E612E204E756C6C612064617069627573207665686963756C6120746F72746F722E20446F6E65632072697375732E20536564207175616D206D657475732C20656765737461732065752C206375727375732075742C2076697665727261206E6F6E2C206F64696F2E205574206A7573746F206A7573746F2C206D616C6573756164612073697420616D65742C20626C616E6469742073757363697069742C206D6F6C657374696520696E2C206A7573746F2E20566573746962756C756D20636F6E7365717561742C207175616D20616320666575676961742074696E636964756E742C20697073756D206C696265726F20656C656966656E64206F64696F2C206E6F6E20656C656966656E64207065646520697073756D206E6F6E20616E74652E204E756C6C616D2061206D657475732E0A0A4E616D206163206E6973692061742066656C697320637572737573206D61747469732E2050656C6C656E74657371756520636F6E7365717561742073656D2071756973206F7263692E20517569737175652074656D7075732E2041656E65616E20696D70657264696574206D6F6C657374696520706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652065752074656C6C75732E204E756C6C61206469616D2065726F732C20736F64616C65732075742C20736F64616C6573206E65632C2074696E636964756E742061632C206E756E632E204E756E63206C6163696E696120666175636962757320697073756D2E20566976616D75732076656C206E6571756520696E2065726174206665726D656E74756D206C75637475732E204E756C6C612065676574206D65747573206E656320617567756520626962656E64756D20706C6163657261742E20566976616D75732074656D7075732E205072616573656E7420636F6E677565206F726E61726520697073756D2E20457469616D206D61747469732066657567696174206A7573746F2E0A0A416C697175616D206475692E2041656E65616E20636F6D6D6F646F20746F72746F72207669746165206E756C6C612E204D6F72626920657420697073756D2E204D617572697320616320697073756D2E204E616D2076656C207269737573207574206C6563747573206D6F6C6C697320766976657272612E2043757261626974757220656C656D656E74756D206D6F6C6C6973206573742E204E756C6C616D20656C69742E20566573746962756C756D207375736369706974207072657469756D20656E696D2E20566573746962756C756D207574206D617373612E2050726F696E206E65632066656C69732E204D616563656E617320677261766964612C2061726375206E656320636F6E7365717561742073616769747469732C2065726F732074656C6C7573207363656C65726973717565206D61757269732C20766974616520616363756D73616E207175616D207175616D207574206E756E632E20496E7465676572206567657420616E74652065752076656C6974206C616F72656574206D616C6573756164612E204E756E632073616769747469732C206D617572697320766974616520706861726574726120766F6C75747061742C2074656C6C75732074656C6C757320656C656966656E642065726F732C2073697420616D65742072757472756D20697073756D206E69736920612076656C69742E205072616573656E7420766172697573206C656F20657520657261742E20566976616D757320636F6E73657175617420706C6163657261742070757275732E20446F6E6563207072657469756D20656C656D656E74756D206E6962682E2050726F696E20617420656C6974206E6F6E2073656D20616C6971756574206D61747469732E2053656420756C6C616D636F7270657220697073756D2073697420616D657420656C69742E0A0A4D617572697320696E206D657475732E2053757370656E6469737365206D61676E61206C6F72656D2C2066617563696275732076656C2C2074696E636964756E7420717569732C207363656C65726973717565206E6F6E2C2074656C6C75732E2046757363652071756973206C6F72656D2E2050726F696E2061206C616375732073697420616D6574206D617572697320696163756C69732070756C76696E61722E2053757370656E64697373652072686F6E6375732065726F73206E6563206D692E205072616573656E7420657569736D6F642C207475727069732076697461652072757472756D207072657469756D2C206F64696F206D6574757320766F6C7574706174206E657175652C20656765742074656D7075732073617069656E206E657175652073656420657261742E20446F6E6563206665726D656E74756D207075727573206174206C65637475732E204E756C6C616D2073656D2E2046757363652076656C206D6920717569732065726174206C6F626F7274697320706F73756572652E2041656E65616E20656765742075726E612E2053757370656E6469737365206C6967756C612E204475697320696E206E6973692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A4375726162697475722076756C707574617465206C656374757320696420706564652E2050686173656C6C75732065752076656C69742E20457469616D2076656E656E617469732061646970697363696E67206E6962682E20416C697175616D206375727375732070756C76696E61722074656C6C75732E20566573746962756C756D206E657175652E204D6175726973206E6563206A7573746F20657420657261742073656D7065722070656C6C656E7465737175652E204675736365206D61747469732064696374756D20646F6C6F722E20457469616D2065676574207075727573206575206D617373612076617269757320656C656D656E74756D2E2050656C6C656E746573717565206D617373612E20557420756C74726963696573206469616D2073656420697073756D2E204E756C6C616D206469616D2E2050656C6C656E746573717565206964206D61676E61206964206C696265726F2074726973746971756520616C697175616D2E0A0A557420656C656966656E642C20707572757320696420706C6163657261742076656E656E617469732C2075726E6120617567756520616C6971756574206C6967756C612C20696E20756C74726963696573206C656F2072697375732065742074656C6C75732E204D6175726973206574206E756C6C612069642075726E61207472697374697175652074656D7075732E20557420666163696C697369732C2075726E6120657520766573746962756C756D2072686F6E6375732C206C616375732065726F7320636F6E736563746574756572206D657475732C2065742072757472756D20647569206C656374757320696E2070757275732E204E756E632076656C206E69736C206E6F6E20697073756D2074696E636964756E74206D6F6C6C69732E204E616D207175616D206C616375732C206F726E6172652076697461652C2072686F6E637573206E6F6E2C20636F6E677565207365642C206F64696F2E2050726F696E206E696268206475692C20706F7274612076656C2C2076656E656E61746973206E6F6E2C2070656C6C656E7465737175652075742C206E6973692E20536564207472697374697175652066656C69732061206D61676E612E2053757370656E646973736520656765742074656C6C75732E2043726173206772617669646120696D706572646965742076656C69742E20496E74656765722068656E6472657269742072697375732E2050726F696E206F7263692E20416C697175616D20756C6C616D636F72706572206D61757269732071756973206D61757269732E204E756E63206C6163696E696120766573746962756C756D206D657475732E20447569732074656C6C75732E204E756C6C616D2066617563696275732C206C656F2061632076756C70757461746520736F6C6C696369747564696E2C206C656F20646F6C6F7220666175636962757320657261742C207175697320626962656E64756D206F726369206F64696F206E6F6E20617263752E0A0A4E756C6C616D20616363756D73616E206D617474697320646F6C6F722E20446F6E6563206574206475692E205072616573656E7420612066656C6973206D6F6C6C6973206C616375732073656D706572206C6163696E69612E204375726162697475722070656C6C656E746573717565206C7563747573206573742E2050726F696E206E756C6C61206475692C20636F6E64696D656E74756D2076656C2C206661756369627573206E6F6E2C20696E74657264756D2061632C20657261742E204D616563656E6173207363656C657269737175652C206C656374757320696420766F6C757470617420616363756D73616E2C2073617069656E20746F72746F722070656C6C656E746573717565206475692C207365642073656D706572206D61676E612073656D207574206C656F2E2050726F696E206E756C6C612E204E756C6C616D206461706962757320756C6C616D636F727065722073656D2E2053757370656E6469737365207665686963756C61206D6574757320696E206E756E632E2050656C6C656E746573717565206E6F6E207175616D2076656C206172637520756C74726963657320756C6C616D636F727065722E2050686173656C6C757320717569732066656C69732073697420616D65742074656C6C757320756C6C616D636F72706572206665726D656E74756D2E20536564207665686963756C6120736F6C6C696369747564696E2075726E612E20437572616269747572207068617265747261207363656C657269737175652072697375732E2050656C6C656E746573717565206964206D617373612071756973206D6574757320616C697175616D20696D706572646965742E20496E206E756E63206C616375732C206665756769617420696E2C206772617669646120656765742C2076656E656E617469732075742C2074656C6C75732E2053757370656E646973736520706F74656E74692E204E616D20636F6E7365717561742061646970697363696E67206475692E20496E206E756C6C61206E6973692C20666575676961742075742C206665726D656E74756D2076656C2C2067726176696461206E65632C20746F72746F722E20496E207365642061756775652E0A0A457469616D20756C6C616D636F7270657220617567756520617420656E696D2E20496E7465676572206469676E697373696D2E20416C697175616D2070756C76696E617220636F6E677565206E756C6C612E204D6F72626920656E696D206D617373612C206672696E67696C6C6120612C20616363756D73616E20656765742C20636F6E64696D656E74756D206E65632C20657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2041656E65616E2070686172657472612E20457469616D20706F72747469746F722070757275732061206D657475732E20416C697175616D20696E74657264756D2073656D2065676574206A7573746F2E205175697371756520766F6C7574706174206C7563747573206573742E2041656E65616E2061756775652E2050686173656C6C757320647569206C65637475732C20756C747269636573206E65632C20636F6D6D6F646F2076656C2C20617563746F722076656C2C206E6973692E20557420756C7472696365732070656C6C656E746573717565206E6973692E20496E74656765722061632076656C69742065742073656D20696D70657264696574206C75637475732E20467573636520766974616520747572706973206964206175677565206D6F6C6C697320636F6E7365637465747565722E0A0A4D616563656E6173206E6563206C616375732E204D616563656E617320636F6E64696D656E74756D206F64696F2065752066656C69732E204D6175726973207574206E69736C207669766572726120657261742066617563696275732061646970697363696E672E20457469616D20656765737461732E204E756E6320657420646F6C6F72207669746165207269737573206469676E697373696D20636F6D6D6F646F2E204D6F726269206C65637475732076656C69742C2074696E636964756E74206E65632C20616C69717565742076656C2C206D61747469732076697461652C206C6967756C612E204D616563656E617320756C747269636965732073656D70657220646F6C6F722E2053757370656E6469737365206D616C6573756164612E20496E7465676572206D617474697320656C69742E20446F6E656320616363756D73616E2C206C6163757320666163696C69736973207661726975732074656D7075732C206E756C6C6120656C697420706F72746120657261742C2065742072757472756D20656C69742073656D2073697420616D6574206475692E0A0A4D616563656E6173206D6F6C6C6973206D69206E6F6E206E756C6C612E20566976616D7573207475727069732E2053757370656E64697373652061206D657475732E20496E2071756973206D6920696E2074757270697320636F6E67756520617563746F722E204D616563656E6173206C616375732E2053757370656E646973736520736F6C6C696369747564696E2E2050686173656C6C757320706F727461206E756E63206E6F6E206E69736C2070756C76696E617220656765737461732E20536564206E756C6C612E20566573746962756C756D206163206D692E204D617572697320756C7472696369657320636F6E64696D656E74756D206E657175652E204E756C6C612074656D707573206A7573746F2076656C206D617373612E204E756C6C6120737573636970697420636F6E67756520617263752E205072616573656E74206964207475727069732E204D6175726973206E69626820706564652C20657569736D6F642073656D7065722C206D6F6C65737469652061632C2072686F6E6375732076697461652C20616E74652E204D616563656E617320657261742066656C69732C207669766572726120736F6C6C696369747564696E2C20736167697474697320656765742C2070656C6C656E746573717565206E65632C206F7263692E20467573636520756C74726963657320636F6E736571756174206C616375732E20416C697175616D2065726174206D61676E612C20666575676961742061742C207669766572726120612C206D6F6C6C6973206E6F6E2C207475727069732E0A0A446F6E6563206D692E204E616D2064696374756D2070656C6C656E7465737175652073656D2E20446F6E6563206D6F6C6C69732072686F6E63757320656C69742E2050686173656C6C75732072686F6E63757320706564652073697420616D65742072697375732E20446F6E656320656765742061756775652E204D616563656E6173206E6F6E206C65637475732E2050686173656C6C757320736F6C6C696369747564696E206E697369206E65632066656C69732E20416C697175616D207072657469756D2C2065737420656765742073656D70657220636F6E76616C6C69732C206E696268206E756E6320736F6C6C696369747564696E2070757275732C2069642074656D706F722070656465206475692076656C206D61676E612E20566976616D7573206163206C6F72656D2E20457469616D206E69736C20746F72746F722C2061646970697363696E672064696374756D2C20656C656D656E74756D20696E2C20666163696C69736973207365642C206E6962682E2050726F696E206D61757269732E2050726F696E2072757472756D206D6173736120656765742073656D2E204375726162697475722074656D706F722061646970697363696E6720656C69742E204375726162697475722070757275732074656C6C75732C206665726D656E74756D20656765742C20616C69717565742076697461652C20636F6E76616C6C69732061632C206D61757269732E0A0A496E746567657220636F6E7365717561742076656C69742065752065726F732074696E636964756E74207665686963756C612E204E756C6C616D206C6F72656D2073617069656E2C2072686F6E637573206E6F6E2C206D617474697320717569732C20756C747269636965732073697420616D65742C20656E696D2E2043757261626974757220636F6D6D6F646F2C206C696265726F20696E20657569736D6F642073757363697069742C2073656D207075727573206672696E67696C6C6120656E696D2C206163206D6F6C657374696520746F72746F72206F7263692065742076656C69742E20446F6E656320706564652E20457469616D20706C61636572617420636F6E64696D656E74756D207475727069732E2050686173656C6C7573206567657374617320656E696D206E6563206D61676E612E20566976616D757320636F6E64696D656E74756D2C206E756C6C612076656C206C7563747573207472697374697175652C2065726F7320726973757320766573746962756C756D206E756C6C612C20696E207665686963756C61206172637520697073756D2061742066656C69732E20446F6E656320616C697175616D20656C69742061742061756775652E205175697371756520612065726F73206575206C6967756C6120616363756D73616E2064696374756D2E20457469616D207665686963756C61207475727069732071756973206C696265726F2E20416C697175616D206E6F6E206D692E20446F6E6563206574206C656F2E2050726F696E206C656F206C696265726F2C20616C697175616D2074696E636964756E742C20636F6E677565206E65632C2061646970697363696E6720706F7274612C20656E696D2E204E756C6C61206C6F626F727469732C20746F72746F722073697420616D657420696D7065726469657420756C6C616D636F727065722C20646F6C6F72206F726369206D616C65737561646120706564652C207365642067726176696461206E6962682075726E612076656C206C6F72656D2E20536564207068617265747261206D616C6573756164612065726F732E205175697371756520657569736D6F6420616C697175657420657261742E2053757370656E646973736520616C6971756574206D61747469732070757275732E0A0A4E756E63206964206E756C6C612071756973206A7573746F20636F6E67756520736F6C6C696369747564696E2E205072616573656E742065726174207475727069732C2072686F6E6375732065752C207072657469756D2065752C2070656C6C656E74657371756520612C206E6962682E20566976616D75732074656D7075732E2043726173206E65632072697375732061742074757270697320696D70657264696574206C6F626F727469732E205574206D61747469732E204D616563656E6173206573742066656C69732C2070656C6C656E746573717565206E6F6E2C20696D70657264696574207365642C20656C656966656E642074696E636964756E742C206C6F72656D2E20496E2074696E636964756E742E205365642076656C206C656F2E20446F6E65632065742075726E6120696E207475727069732068656E64726572697420626C616E6469742E20446F6E656320636F6E64696D656E74756D20616363756D73616E206573742E2055742070686172657472612C206D65747573207669746165206D617474697320636F6E7365637465747565722C206C656F207175616D2076756C707574617465206F64696F2C206E6563206C616F72656574206E6973692076656C697420657520657261742E20496E7465676572206C65637475732061756775652C206567657374617320696E2C20696E74657264756D2065752C2076656E656E617469732076656C2C2073617069656E2E2051756973717565206574206573742076697461652065726F73206C616F72656574206C6F626F727469732E204E756C6C616D207574207269737573206E6F6E206E756C6C6120706C6163657261742061646970697363696E672E205072616573656E7420646170696275732E20457469616D20612066656C69732E20557420736F64616C657320636F6E736571756174206D61757269732E2044756973206C6F72656D2066656C69732C206C756374757320612C2074726973746971756520696E2C206D6F6C65737469652061742C2072697375732E20536564207665686963756C6120626962656E64756D2074656C6C75732E204E616D20636F6E73657175617420657569736D6F64206C616375732E0A0A41656E65616E20746F72746F7220656C69742C2067726176696461206E65632C206665726D656E74756D2065752C206C6F626F727469732069642C20697073756D2E204D616563656E61732065752070757275732E204372617320616320747572706973207574206E69736920696163756C69732072686F6E6375732E204E756C6C61207075727573206D657475732C206469676E697373696D206E65632C2074696E636964756E742076697461652C20646170696275732065752C206E6962682E204675736365206C6F626F727469732C206E756E63206174207669766572726120656C656966656E642C206A7573746F20747572706973207363656C657269737175652065726F732C2061632070656C6C656E746573717565206D65747573206E69736C2061742070757275732E2053656420656C656D656E74756D2074656C6C75732073656420656E696D20696E74657264756D20626C616E6469742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E746567657220756C7472696369657320616C6971756574206F64696F2E204D61757269732065676574206E756E63206120697073756D20756C74726963657320736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2041656E65616E20616363756D73616E2E20446F6E65632073617069656E206C65637475732C20636F6E6775652061742C20706F7274612069642C2068656E6472657269742076697461652C206E69736C2E204375726162697475722076656C207175616D2076656C206E6571756520616363756D73616E206C616F726565742E204D6F7262692073617069656E206573742C207072657469756D20696E2C20636F6E7365637465747565722061632C206D6F6C6C69732075742C206C696265726F2E20446F6E65632074696E636964756E742061646970697363696E67206D657475732E204E756E6320766573746962756C756D20656765737461732061756775652E20446F6E6563207363656C65726973717565206475692075742073656D2E2053757370656E64697373652076656C206D6574757320696420657374206D6F6C657374696520696163756C69732E0A0A566976616D75732070686172657472612C20656C6974206575206D616C65737561646120626C616E6469742C206469616D20746F72746F72206D6F6C6C6973206475692C207365642070756C76696E6172206D61737361206E756E63206574206D61676E612E2053656420706C61636572617420656C697420617563746F7220746F72746F722E204E756C6C6120616320657261742E2050656C6C656E74657371756520636F6E7365637465747565722C2064756920636F6E76616C6C69732074696E636964756E7420636F6E64696D656E74756D2C2073656D206F64696F20766F6C7574706174206C696265726F2C206E6F6E20656C656D656E74756D2066656C6973206E65717565206E6563206F64696F2E204D616563656E61732068656E6472657269742065726F73206964206469616D2E204D61757269732076656C207075727573206163206F72636920636F6E76616C6C697320636F6E76616C6C69732E205365642073697420616D6574206C616375732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652064696374756D20766172697573206C616375732E204D61757269732065676574206E69736C2E2053757370656E646973736520706C6163657261742C206E756C6C61206E6F6E206F726E617265206469676E697373696D2C206E69736C206469616D2073616769747469732074656C6C75732C20696E2073656D706572206E69736920646F6C6F72206174206E6962682E204475697320756C6C616D636F7270657220766976657272612066656C69732E20496E746567657220612074656C6C75732E2053757370656E64697373652065676574206E756E632E2041656E65616E206469616D206573742C20616363756D73616E2069642C20737573636970697420696E74657264756D2C206672696E67696C6C612076697461652C206A7573746F2E2050726F696E20706564652E204D616563656E6173206174206E6571756520696E206E6571756520766573746962756C756D20656C656966656E642E0A0A566573746962756C756D206E756C6C61206C6F72656D2C20706F72747469746F7220656765742C20657569736D6F642061632C20616C697175616D2061742C206E69736C2E204D616563656E6173206574206573742065676574206D6173736120766172697573206C6F626F727469732E20496E206D692E204475697320706F72747469746F72206665726D656E74756D2070757275732E20446F6E65632063757273757320696D70657264696574206C6967756C612E204D6F726269206574206C6967756C6120657420616E7465206D6F6C6573746965207665686963756C612E204D61757269732073656420646F6C6F722E2053656420696D706572646965742066656C69732075742073656D2E20536564207669746165206E6571756520656C656D656E74756D206C656F20617563746F72206665726D656E74756D2E2044756973206665756769617420756C6C616D636F7270657220657261742E2041656E65616E2070757275732E204D6F726269206665726D656E74756D20766573746962756C756D206573742E2050656C6C656E7465737175652076656E656E61746973206D61757269732E2050686173656C6C75732070756C76696E61722E20496E746567657220697073756D206C65637475732C20696163756C697320612C206C6163696E69612069642C20616363756D73616E2069642C20617263752E2050686173656C6C7573206174206573742E204675736365206E65717565207175616D2C20756C747269636965732069642C20696163756C69732076656C2C20646170696275732076697461652C206C616375732E20496E206C6F626F7274697320636F6E76616C6C697320616E74652E204E756C6C61206E756E632070757275732C2076756C70757461746520696E2C2068656E6472657269742065742C20626C616E6469742065742C206C6967756C612E0A0A50656C6C656E746573717565206C656F206D657475732C20736167697474697320696E2C206D6F6C65737469652076697461652C2064696374756D20696E2C20706564652E204D6F726269207072657469756D2066656C6973206E6563207175616D2E2050656C6C656E746573717565206D617474697320616E746520736564207175616D20736167697474697320646170696275732E2053757370656E64697373652073617069656E2E205072616573656E7420626962656E64756D20696163756C697320746F72746F722E20447569732061206E69736C2E2041656E65616E206D692E20446F6E65632064696374756D206172637520696E206573742E204D6F72626920696E74657264756D2076756C70757461746520697073756D2E2041656E65616E2073697420616D6574206D61676E61206E6F6E206E69736C2074726973746971756520706F73756572652E2050686173656C6C75732076656C6974206D657475732C2074656D706F722061632C206665726D656E74756D20656765742C20636F6E64696D656E74756D206E6F6E2C2076656C69742E20566573746962756C756D2073697420706F73756572652E0A0A4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204372617320616C6971756574206D61737361206E6563206475692E20437261732061726375206E756E632C2068656E6472657269742061632C20656C656966656E642065752C20756C6C616D636F72706572206E65632C2074656C6C75732E205365642070686172657472612070757275732073697420616D6574207175616D2E20437572616269747572206D6F6C6C69732E204E616D20766974616520706564652E20457469616D207269737573206D617373612C207665686963756C612073697420616D65742C207068617265747261206E65632C20736F6C6C696369747564696E2075742C206475692E20446F6E65632065676573746173206A7573746F206174207175616D2E2050726F696E206E69736C2072697375732C20766573746962756C756D206E65632C207072657469756D2076697461652C207472697374697175652061632C206C6F72656D2E20416C697175616D206572617420766F6C75747061742E204372617320736564206E6962682E2050656C6C656E74657371756520736F6C6C696369747564696E20657569736D6F642061756775652E0A0A457469616D206672696E67696C6C6120736F6C6C696369747564696E206F7263692E204D61757269732063757273757320656C69742071756973206C616375732E204372617320746F72746F722E20496E2061646970697363696E672C206C656374757320696420617563746F7220766573746962756C756D2C206E65717565207065646520616363756D73616E20646F6C6F722C206E6F6E20696D70657264696574206D61676E61206469616D20616363756D73616E2076656C69742E2053757370656E6469737365206174206C696265726F207574206E69736920626C616E6469742073616769747469732E2050686173656C6C7573206E6F6E206D61757269732E20467573636520656C656D656E74756D2073616769747469732073656D2E2053757370656E646973736520616C697175616D20656C656966656E642074656C6C75732E2050726F696E206C6967756C61206C6F72656D2C20696D7065726469657420717569732C2076656E656E617469732069642C20696163756C6973206D6F6C6C69732C206E69736C2E20457469616D20636F6E76616C6C69732070656465206174206D617373612E204D6F72626920616363756D73616E20647569206574206D61757269732E0A0A53656420736564206F7263692E204E756E632070757275732E2053757370656E646973736520706F74656E74692E205574206C7563747573206672696E67696C6C61206D61757269732E20446F6E6563206E6962682E2050686173656C6C757320706F7274612E2050686173656C6C75732073697420616D6574206F64696F20736564206D61676E6120736F64616C65732070686172657472612E2043726173206C65637475732E2053757370656E6469737365206C696265726F20697073756D2C20636F6D6D6F646F206E65632C20666163696C6973697320696E2C207375736369706974206C6F626F727469732C206C6967756C612E2044756973206D61737361206E756C6C612C2073656D7065722065742C20636F6E736571756174206E65632C2070686172657472612065752C20656C69742E20566976616D757320756C7472696369657320616C697175616D206F64696F2E20566573746962756C756D2073697420616D6574206D617373612E2053656420636F6E736571756174206C61637573207365642075726E612E20457469616D2066617563696275732066656C69732076656C206F7263692E2050686173656C6C757320756C6C616D636F727065722E2041656E65616E20636F6E736563746574756572206C61637573206174206C696265726F2E0A0A436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204475697320666163696C697369732C206C6967756C6120766974616520636F6E64696D656E74756D207363656C657269737175652C2076656C6974206F72636920677261766964612066656C69732C2076656C20756C74726963696573207175616D206D69206E6F6E206469616D2E20566976616D757320617563746F72206D65747573206E6F6E206C696265726F2E205072616573656E74206C6967756C61206E6973692C20636F6D6D6F646F20636F6E64696D656E74756D2C206D6F6C65737469652065742C20766976657272612065742C206A7573746F2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320736F6C6C696369747564696E2E204E756E6320626C616E6469742063757273757320697073756D2E2041656E65616E206E6563206C6967756C612075742074656C6C757320736F64616C6573206D61747469732E20496E74656765722073656D2E20416C697175616D206964206C6967756C612E2053656420746F72746F72206D61757269732C20626C616E6469742076697461652C206375727375732076656C2C20656C656D656E74756D2065742C206E756C6C612E20416C697175616D207363656C65726973717565206D65747573206574206E69736C2E20447569732061646970697363696E67206D61676E61206174206E657175652E20517569737175652076756C70757461746520656C656966656E64206E756E632E20416C697175616D206567657420656C69742E2050686173656C6C757320647569206F64696F2C20626962656E64756D2073616769747469732C20766573746962756C756D2069642C206469676E697373696D20696D706572646965742C206F7263692E204E756C6C616D2065752066656C6973206E6F6E206E756E63206C6163696E696120736F64616C65732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A53757370656E64697373652070656C6C656E7465737175652C206C696265726F206D617474697320756C7472696369657320616363756D73616E2C20746F72746F7220746F72746F72206D616C6573756164612073656D2C20657420736F64616C6573206C696265726F206F64696F20616320697073756D2E20566976616D75732071756973206D61676E61206E656320657374207375736369706974206C6F626F727469732E20437261732074656D70757320706F7375657265206E756E632E205175697371756520757420656E696D20612066656C697320656765737461732073656D7065722E20536564207068617265747261206D6174746973206E657175652E20467573636520747572706973206E756E632C20636F6E677565207365642C20636F6E736571756174206E6F6E2C20636F6E677565207365642C206E756C6C612E2053757370656E646973736520766172697573206C6F72656D20696420726973757320706F72746120766573746962756C756D2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204675736365207365642070757275732E20496E20612066656C69732E20496E7465676572206567657374617320617563746F72206F7263692E204D617572697320756C747269636573207375736369706974206E69736C2E204E756C6C616D2070757275732E0A0A437261732074656D706F722061646970697363696E6720697073756D2E2055742071756973206D692E204D616563656E617320696E206A7573746F207574206E756C6C6120636F6E6775652070686172657472612E2050656C6C656E746573717565207574206C696265726F20657520646F6C6F722076656E656E617469732073757363697069742E205072616573656E74206665756769617420636F6E736563746574756572206E6962682E204D6F7262692066617563696275732073656D206E6F6E2066656C69732E20496E2068656E6472657269742061726375206163206D617373612E20496E20616363756D73616E20756C747269636573206D692E2050726F696E206D616C65737561646120617563746F722066656C69732E2043757261626974757220696E74657264756D2E20536564206469616D20697073756D2C20756C7472696369657320696E2C2074656D706F722073697420616D65742C207669766572726120696D706572646965742C20656C69742E204D6F726269206D6F6C6573746965206E6973692E204D617572697320697073756D2E2046757363652064696374756D206D6F6C6C6973206D61676E612E204475697320636F6D6D6F646F206469676E697373696D206E756C6C612E20566573746962756C756D20617567756520656E696D2C20756C7472696369657320717569732C20696163756C6973206E65632C2074696E636964756E742076697461652C206469616D2E204D6175726973206C6163696E69612074656D70757320697073756D2E20536564206174206D61757269732E205574206C6F72656D2E20446F6E6563206C696265726F2E0A0A4475697320696163756C6973206C6163696E6961206C65637475732E2041656E65616E20636F6E76616C6C69732065726F7320616320616E74652E205365642071756973206F726369206E656320726973757320617563746F72206672696E67696C6C612E2050686173656C6C757320666163696C6973697320656C656D656E74756D206E6973692E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E6320706F727461206C61637573206E656320616E74652E204D6F726269206D617572697320657261742C2061646970697363696E6720696E2C2070756C76696E6172206E65632C206C6F626F72746973206E65632C206F64696F2E20557420656C656966656E64206C656374757320736564207175616D2E204E756C6C616D206D6F6C6C69732E20496E206E6F6E20747572706973206574206E69736C2068656E64726572697420626C616E6469742E204475697320656C656D656E74756D2E204E756E63206E6563206C696265726F2E2053757370656E646973736520766573746962756C756D207269737573206E6F6E20706564652E204D6F72626920696D70657264696574206F64696F2073697420616D6574206C696265726F2E2053656420736564206D6173736120766974616520697073756D206D61747469732074696E636964756E742E204E756C6C61206E656320746F72746F72207669746165206C696265726F20766F6C75747061742074656D7075732E20446F6E656320616C697175616D2E0A0A4475697320736564206E756E632E2043757261626974757220747572706973206E756C6C612C207665686963756C61207365642C206C756374757320717569732C20656C656D656E74756D20656765742C2066656C69732E204D616563656E61732065742070757275732E204D616563656E6173206C656F2074656C6C75732C2074696E636964756E7420612C20666163696C697369732076697461652C206C6F626F727469732073697420616D65742C2076656C69742E20446F6E656320636F6E76616C6C69732073617069656E2E204D616563656E6173206D6F6C6C6973206F64696F206575206E6962682E20457469616D20677261766964612E20496E7465676572206D6F6C65737469652C2073617069656E206575206D6F6C6573746965206C6163696E69612C206E756E63206E69626820616C697175616D206C6967756C612C2065752073616769747469732074656C6C7573206572617420736F6C6C696369747564696E206F64696F2E20447569732065742072697375732E2050686173656C6C7573206E697369206E657175652C20706C616365726174206E65632C20636F6E64696D656E74756D206E6F6E2C20756C7472696365732065752C2073656D2E20557420706564652E20457469616D206E756C6C61206D657475732C20766F6C75747061742069642C20636F6E76616C6C6973207365642C2073757363697069742076656C2C2075726E612E20446F6E65632076656C20656C69742E205574206C656F206E657175652C2076656E656E617469732066617563696275732C206C6163696E6961206E65632C2074696E636964756E742065752C20656E696D2E2043726173206964206475692061206C696265726F207068617265747261206469676E697373696D2E20446F6E65632065726F73206C656F2C20706F72746120717569732C206C616F726565742075742C2070656C6C656E74657371756520766F6C75747061742C206C65637475732E0A0A4E756C6C616D20626C616E6469742E20416C697175616D206572617420766F6C75747061742E2046757363652061646970697363696E6720656E696D2E2053757370656E6469737365206E6F6E206475692071756973206C6967756C6120706F72746120766573746962756C756D2E20446F6E65632065752074656C6C75732076656C206C6F72656D207072657469756D20706F72747469746F722E205072616573656E74206C75637475732E20416C697175616D2061632065726F7320696E206D6173736120646170696275732074696E636964756E742E20446F6E6563207574206D61676E612E20457469616D20617563746F72206C616375732073697420616D6574206C616375732E2053656420756C7472696369657320697073756D206E656320656C69742E205175697371756520612065737420696E207075727573207375736369706974207472697374697175652E0A0A41656E65616E20736564206475692076656C20646F6C6F722070756C76696E6172206C616F726565742E20566976616D7573207665686963756C61206C6F72656D20696E20706564652E20566976616D7573206574206469616D2E20496E7465676572206163206F64696F2076656C206469616D2068656E64726572697420626962656E64756D2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E756C6C612061206E6973692E2050686173656C6C75732074696E636964756E74206475692076697461652061756775652E20447569732066617563696275732C2064756920696E74657264756D206672696E67696C6C612074696E636964756E742C206F64696F20656C697420766573746962756C756D206C696265726F2C206163206D6F6C6573746965206D61676E61206C6563747573206964206C616375732E2041656E65616E206C6967756C612E204E756C6C6120666163696C6973692E0A0A46757363652076656C2073656D2065752076656C6974206672696E67696C6C61206F726E6172652E2053656420666575676961742074696E636964756E742066656C69732E204E756C6C616D2066656C6973206D692C20657569736D6F642073697420616D65742C206D6F6C6C69732061742C20736F64616C657320656765742C2061756775652E204E616D20696D70657264696574206E6962682061742076656C69742E2053656420757420657261742E20496E206475692E204E756C6C6120666163696C6973692E204E756C6C616D206175677565206C696265726F2C2074696E636964756E74206E65632C207072657469756D2065752C2070756C76696E617220696E2C206475692E204D6F7262692076697461652066656C69732E2050656C6C656E7465737175652076656C206A7573746F2076656C2076656C6974207361676974746973206D616C6573756164612E2050726F696E207665686963756C6120626C616E646974206D617373612E20457469616D2074696E636964756E742070686172657472612075726E612E20496E206D65747573206573742C20617563746F72206E65632C20626C616E64697420612C20637572737573206E65632C207175616D2E204D6175726973206163206D657475732061206C696265726F20636F6E6775652066617563696275732E204D6175726973206D617572697320646F6C6F722C20736F64616C657320696E2C206375727375732075742C20736F64616C65732072757472756D2C2065726F732E2051756973717565206D61757269732065726F732C2073616769747469732076697461652C206C6F626F727469732075742C20656C656966656E642069642C206E6973692E0A0A41656E65616E206E657175652E20566573746962756C756D20656765737461732070656C6C656E746573717565206C6967756C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2050686173656C6C7573207361676974746973206A7573746F2076656C2072697375732E20536564207072657469756D206E657175652076697461652075726E612E2050656C6C656E74657371756520636F6E677565206C696265726F206964206C6F72656D2E204D6175726973206C656F206C6F72656D2C20626C616E6469742073697420616D65742C20636F6E76616C6C697320717569732C20636F6E736563746574756572207365642C2065726F732E204D61757269732074696E636964756E742C20656E696D2061206772617669646120657569736D6F642C206D61676E61206E756C6C61206665726D656E74756D206C696265726F2C207669766572726120656765737461732076656C6974207175616D20657420746F72746F722E20566976616D757320616C6971756574206D61737361207669746165206A7573746F2E204E756C6C6120636F6E677565206C6163757320616320656C69742E0A0A50686173656C6C757320636F6D6D6F646F207175616D2076656C206C6967756C612E2050726F696E206E6F6E206D657475732061742065726F732070756C76696E6172206C75637475732E204D6175726973206469616D206C6F72656D2C20706F737565726520717569732C20677261766964612065742C2074696E636964756E74206E65632C206C6967756C612E20536564206469616D2E20416C697175616D20656C6974206C65637475732C2068656E6472657269742075742C20696D706572646965742073697420616D65742C207072657469756D2073697420616D65742C20697073756D2E204D6175726973207665686963756C61206E69736C20696E206475692E204375726162697475722065676574207175616D207574206D61676E6120656C656D656E74756D206665726D656E74756D2E204D6175726973207363656C657269737175652E2051756973717565206C616F726565742E20457469616D2074656D707573207475727069732E2050656C6C656E746573717565206175677565207175616D2C2068656E647265726974207365642C2074696E636964756E742061742C2070686172657472612061742C206E69736C2E20416C697175616D206C616375732E2053757370656E646973736520706F74656E74692E2041656E65616E2076656C6974206C696265726F2C20756C74726963657320696E2C206C6163696E69612065752C206C75637475732076656C2C20616E74652E20457469616D2064696374756D206D6920696E2066656C69732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20467573636520677261766964612064617069627573206E69736C2E2043726173207669746165206E69736C2E0A0A4D616563656E6173206469676E697373696D2C206C6967756C61206E6F6E20706F727461206375727375732C20656E696D206E756E63206D616C6573756164612073656D2C20657520706F72747469746F72206E756C6C612075726E61206575207175616D2E2046757363652065726F732E20416C697175616D2065726F732E204E616D20617563746F722E204E756C6C61206D6F6C657374696520706F727461206573742E2053757370656E646973736520706F74656E74692E20566976616D7573206D6F6C6573746965206C6F72656D2073656420657261742E20536564206567657420697073756D2E20496E746567657220616C697175616D2070756C76696E6172206E756C6C612E204372617320616C69717565742073656D207574206E756E632E2046757363652066617563696275732074656D707573206C65637475732E204372617320736F64616C65732C206E69736920616320666163696C6973697320756C7472696365732C2065726F73206172637520646170696275732073617069656E2C20657420756C747269636573206D61757269732074656C6C7573206E6F6E20646F6C6F722E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20437261732063757273757320766172697573206D657475732E205574207475727069732E20566976616D7573206567657420746F72746F722E0A0A536564206C616F726565742C2076656C6974206E6F6E20616363756D73616E206375727375732C206E756E632075726E6120706F7375657265206A7573746F2C20696E2064696374756D206C6563747573207065646520696420616E74652E20437261732076756C7075746174652E204372617320636F6E677565206475692073656420656C69742E2050726F696E206C616375732073656D2C20756C7472696365732061742C20636F6E73657175617420696E2C2074656D706F7220717569732C206D657475732E2050726F696E2076656C20617263752E204E616D20657569736D6F642068656E64726572697420656C69742E20557420657261742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2053656420706F73756572652E204D6F7262692065726F732075726E612C2073656D7065722061742C2073656D706572206E6F6E2C20636F6E76616C6C697320717569732C2076656C69742E204D616563656E6173206F7263692E20566573746962756C756D206C6F626F7274697320747269737469717565206D657475732E20566573746962756C756D206C6F72656D206E756C6C612C20736F6C6C696369747564696E2076697461652C20636F6E64696D656E74756D20717569732C20617563746F722075742C206475692E20566976616D757320766573746962756C756D206D61676E61207574206E6973692E2043757261626974757220656C656966656E64206475692076656C206E756E632E20437572616269747572206D6175726973206C616375732C206D616C6573756164612073697420616D65742C207375736369706974207365642C2072757472756D206C75637475732C2074656C6C75732E20496E746567657220666163696C697369732075726E61207669746165206C65637475732E0A0A41656E65616E207175616D206C656F2C206C6F626F7274697320717569732C206D616C6573756164612065752C2076756C7075746174652076697461652C206E69736C2E205072616573656E7420656765742065726F732E205574206665726D656E74756D20747572706973206964207175616D2E204E616D20746F72746F722E205072616573656E74206E6563206F7263692E204E756C6C6120626962656E64756D2061646970697363696E672061756775652E20557420636F6D6D6F646F2C206D61676E61206964206D616C65737561646120677261766964612C206175677565206F64696F206D616C657375616461206D692C20706F727461206D616C65737561646120656C697420657374207669746165206469616D2E204D6175726973206E6F6E206E756C6C612E2053757370656E64697373652074696E636964756E742C206E756E6320756C7472696369657320706F7274612076656E656E617469732C206D6920706564652074696E636964756E74206C696265726F2C20656765742076617269757320616E7465206C696265726F207574206C6967756C612E20437572616269747572207072657469756D20706F72747469746F7220746F72746F722E0A0A4D616563656E617320766974616520656C69742065676574206E69736920646170696275732064696374756D2E204E756E6320696E206C696265726F2E204E756C6C612064696374756D206F726369206575206572617420617563746F72206C6F626F727469732E2050686173656C6C75732072697375732E2053757370656E646973736520706F74656E74692E2053757370656E646973736520706F74656E74692E205072616573656E742061646970697363696E6720636F6E73657175617420656C69742E20496E74656765722069642061756775652E205072616573656E7420696E206A7573746F206E6563206D61676E6120646170696275732070756C76696E61722E2044756973206E69736C2E2053757370656E6469737365206163206F64696F2E20566976616D757320696D706572646965742E20446F6E6563206E6F6E2076656C69742073697420616D6574207269737573206469676E697373696D20636F6E6775652E204E616D20616C697175657420706F73756572652076656C69742E2043726173207475727069732E204D6F726269206D616C657375616461206469676E697373696D206D692E0A0A536564206C656F206E657175652C2076617269757320717569732C2076656E656E61746973207365642C207068617265747261207365642C206573742E204D6F72626920626C616E6469742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D2073656D7065722070656C6C656E746573717565206D692E2055742076656C206C6F72656D2E204E756E63206D6920746F72746F722C206C616F726565742061742C2066617563696275732065752C2074696E636964756E742073697420616D65742C20657261742E20447569732074656D706F72206D616C65737561646120697073756D2E2050686173656C6C757320616C69717565742E20446F6E656320657420656C69742E2050656C6C656E7465737175652070757275732E20566573746962756C756D2072757472756D2073656D706572206E6962682E204E756C6C6120666163696C6973692E2050686173656C6C757320657420656E696D2073697420616D657420616E746520766573746962756C756D207665686963756C612E2050686173656C6C7573206964206E69736C2E20446F6E6563206D6F6C6C6973206C656F2061742065726F732E204D61757269732070656C6C656E746573717565206E657175652061742070757275732E204D6F726269207175697320646F6C6F7220617420697073756D207363656C6572697371756520736F64616C65732E20457469616D20766F6C7574706174207475727069732061206D657475732E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206C6F72656D206C6F72656D2C20766573746962756C756D2061632C20657569736D6F6420656765742C20756C6C616D636F72706572206469676E697373696D2C2076656C69742E0A0A43756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204372617320756C7472696365732C206E6962682076656C20616C697175616D20766573746962756C756D2C2065726F7320656E696D2076656E656E61746973206475692C20696420696163756C697320656E696D206E756E632076656C206D617373612E204D6F72626920656C656966656E64206F726369206574206D617373612E20416C697175616D206572617420766F6C75747061742E204E756C6C61206D6F6C6C69732065676573746173207475727069732E20496E20736F64616C6573206E756E63206567657420746F72746F722E2053656420697073756D2065726F732C2074656D706F7220717569732C20616C69717565742076697461652C20696D70657264696574206E6F6E2C206C6F72656D2E2050656C6C656E746573717565207175697320656C6974206964206D69206C756374757320646170696275732E20536564206E756E6320617263752C2072686F6E637573206E65632C20636F6E76616C6C697320717569732C206375727375732061742C206E657175652E204D617572697320636F6E76616C6C697320707572757320617420657261742E2050656C6C656E74657371756520766573746962756C756D2E20566976616D7573206672696E67696C6C6120656C697420617420617263752E204E756C6C616D20616C697175657420656E696D206E656320617263752E204E616D20696420746F72746F722E204E756C6C612071756973206E756E632E20557420617263752E2053757370656E646973736520706F74656E74692E2050656C6C656E74657371756520756C6C616D636F72706572206C6967756C6120696420617263752E0A0A4E616D206E6F6E206C696265726F207669746165206E69736C207363656C65726973717565206672696E67696C6C612E20517569737175652076617269757320616E7465206964206D657475732072686F6E637573206672696E67696C6C612E204E756C6C6120666163696C6973692E205072616573656E7420656C656966656E6420706F72747469746F72206C6967756C612E20457469616D207175697320646F6C6F72206E6F6E20617567756520636F6D6D6F646F20617563746F722E20446F6E65632061206D692E20566573746962756C756D2074656D706F722E20446F6E65632066656C69732075726E612C20617563746F722061742C206375727375732064696374756D2C20677261766964612069642C20617263752E2041656E65616E2064696374756D206D616C65737561646120646F6C6F722E20566976616D7573206D61747469732E2050686173656C6C757320657520706564652E2046757363652061646970697363696E67206A7573746F206672696E67696C6C61206D657475732E20457469616D20616E74652E20496E7465676572206D6F6C6C6973206D617373612071756973206E756E632E20496E74656765722064696374756D206E65717565206C756374757320656E696D2E0A0A536564206575206C696265726F2E20496E74656765722074656D706F72206C6967756C6120696E2076656C69742E2055742074696E636964756E74206C6163696E69612073656D2E204E756C6C616D2076656C2072697375732E2053656420736F64616C657320616E7465206120646F6C6F722E204375726162697475722065726F732E2053656420736F64616C65732E20536564206E6F6E206D657475732E20566573746962756C756D20656C656D656E74756D20666175636962757320616E74652E204E756C6C612076656C206E6962682E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206E6563206C6F72656D20757420697073756D206C6163696E696120696163756C69732E204475697320657261742E20416C697175616D20657261742E204372617320696163756C69732E20496E206861632068616269746173736520706C617465612064696374756D73742E0A0A4E756C6C616D20616E74652E2043726173207669746165206573742E2050656C6C656E7465737175652076656C206D657475732061206C6967756C612064617069627573206D61747469732E2044756973206665756769617420616C69717565742066656C69732E20457469616D206964206E69736C207175697320657374206469676E697373696D20636F6E64696D656E74756D2E2053757370656E646973736520706F74656E74692E204D6F7262692076656C6974206C6F72656D2C206F726E61726520717569732C2070656C6C656E7465737175652076656C2C20706C61636572617420656765742C20746F72746F722E20566573746962756C756D2074696E636964756E74206D6F6C6573746965206C696265726F2E204E756C6C61206E756C6C6120656E696D2C206D616C6573756164612069642C20756C6C616D636F727065722076697461652C2064696374756D2061742C2070757275732E20446F6E6563206469676E697373696D206F64696F20757420656E696D2E2053757370656E6469737365206174206C65637475732E0A0A5072616573656E74206C6F626F727469732061756775652076656C206C65637475732E20557420696E206C6967756C612075742066656C697320636F6E6775652073757363697069742E2051756973717565206469676E697373696D20746F72746F72207574206D692E204675736365206D61676E61206E6973692C20656C656966656E642061632C206F726E6172652076656C2C20706F72747469746F722076697461652C207175616D2E20566573746962756C756D20736F64616C6573206A7573746F2071756973207475727069732E2046757363652075726E61206E6973692C2072686F6E63757320717569732C20636F6E64696D656E74756D2076656C2C2064696374756D2065752C206E756E632E20467573636520736564206E696268207669746165206F64696F20706F73756572652061646970697363696E672E2053656420706F72746120656C6974207175697320646F6C6F722E204E616D206C696265726F206E756C6C612C20617563746F72207365642C2074696E636964756E7420717569732C2066617563696275732073697420616D65742C206D692E2051756973717565206F7263692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E756C6C616D2069642073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632076656C2065726F732E0A0A566976616D7573206C7563747573206C6F626F72746973206C656F2E2053757370656E64697373652076656C20656C6974206120656E696D20756C6C616D636F7270657220706F73756572652E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20446F6E656320717569732070656465206D6174746973206C6563747573206D6F6C6C69732061646970697363696E672E2053656420616363756D73616E20706F737565726520657261742E205072616573656E7420657569736D6F642074696E636964756E742066656C69732E20446F6E6563206D692E20557420636F6D6D6F646F2061726375206C6163696E69612074656C6C75732E20416C697175616D2061206C696265726F2071756973206C65637475732073656D70657220766976657272612E20437572616269747572206C6163696E6961206D61757269732061742074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E756E632073697420616D6574206D61676E61206D6F6C6573746965206F726369207375736369706974206672696E67696C6C612E204675736365207072657469756D206D65747573206E6F6E2073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642068656E6472657269742E204E756C6C612066656C69732E2053757370656E646973736520706F74656E74692E20416C697175616D20626C616E64697420747269737469717565206E657175652E20437572616269747572207175697320657261742076656C206E756E6320616363756D73616E206D6F6C6C69732E0A0A447569732073616769747469732C2074656C6C757320757420616C697175616D206672696E67696C6C612C20646F6C6F72206D6920756C6C616D636F72706572206E69736C2C20757420747269737469717565207065646520656C697420736564206D61757269732E204375726162697475722069642066656C69732E20446F6E65632070756C76696E6172206C61637573206574206C65637475732E20416C697175616D2076756C7075746174652076756C707574617465206D657475732E20437572616269747572206D61676E612066656C69732C2061646970697363696E672061632C20616363756D73616E2076656C2C206D6F6C657374696520717569732C207175616D2E204D617572697320656C697420617263752C207072657469756D2076697461652C206D6F6C6C69732073697420616D65742C20736F6C6C696369747564696E2075742C206D692E20446F6E656320696D70657264696574206469676E697373696D206D692E204E756C6C616D2073697420616D657420746F72746F722E20416C697175616D206E65717565206E756C6C612C2076656E656E6174697320612C20706F72746120696E2C20706C6163657261742074656D7075732C206C616375732E205175697371756520766573746962756C756D20647569206574206C616375732E2050726F696E206469676E697373696D20636F6E7365637465747565722070757275732E20457469616D206772617669646120746F72746F7220696E206E756E632E2055742074656D706F722074726973746971756520746F72746F722E20536564206C616F726565742074696E636964756E74207175616D2E20566573746962756C756D20706F7274612074757270697320757420656C69742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20446F6E6563206E696268206475692C2066657567696174206E65632C206C616F726565742069642C206D616C65737561646120656765742C206E6973692E205574206E65717565206D617373612C207665686963756C612065752C20636F6D6D6F646F206E6F6E2C20756C747269636965732076697461652C2070757275732E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204D617572697320657569736D6F642C2066656C69732076656C2074656D706F7220616C69717565742C20746F72746F72206D6175726973206D616C657375616461206E756E632C2076656C206665726D656E74756D2073656D206469616D206964206475692E204E616D2072757472756D2073617069656E2065676574206F64696F2E20416C697175616D20736564206C696265726F206E6F6E206D692066617563696275732074656D7075732E2046757363652068656E6472657269742C206469616D206E6F6E20766F6C75747061742072757472756D2C2065726174206D657475732076656E656E61746973206C6967756C612C206E6F6E207363656C657269737175652070656465206C6967756C612076656C207175616D2E204D6F7262692072686F6E6375732065726F7320616320647569206665756769617420656C656D656E74756D2E2044756973206575206C696265726F2065742074656C6C757320636F6E67756520766976657272612E204D6F726269207175616D207175616D2C20656C656D656E74756D207365642C20756C6C616D636F7270657220696D706572646965742C20636F6D6D6F646F206E6F6E2C206F64696F2E204E616D20616C697175657420656765737461732075726E612E204D6175726973206F64696F2066656C69732C207661726975732065752C206C6163696E69612065752C20636F6E64696D656E74756D20612C206C65637475732E20536564206A7573746F206D617373612C2070756C76696E61722069642C2076617269757320612C20706F72747469746F72206E65632C206C696265726F2E20457469616D207661726975732E2043757261626974757220736F64616C65732C206F64696F20617420706F73756572652073656D7065722C2065726F73206E6962682074696E636964756E74206C65637475732C2076656C2072757472756D2073617069656E206E69736920696E206C6967756C612E2053757370656E6469737365206567657420617263752E2050686173656C6C757320696D70657264696574206573742061632073617069656E2E20446F6E6563206E756C6C6120746F72746F722C20706C6163657261742076656C2C2074656D70757320612C206C6F626F727469732076656C2C206E6962682E20416C697175616D20766172697573206E6973692E204E756C6C6120657420656E696D2E20467573636520636F6E76616C6C6973206C616F72656574206C616375732E0A0A50686173656C6C757320697073756D20646F6C6F722C206D6F6C657374696520717569732C20636F6E64696D656E74756D20696E2C20636F6D6D6F646F2065752C206469616D2E205175697371756520626962656E64756D206C6163696E6961206475692E204E756C6C616D20626C616E6469742076756C707574617465206F7263692E205574206C6163696E6961206D617373612076656C2061756775652E20416C697175616D20677261766964612C207175616D207175697320696D7065726469657420696D706572646965742C2074656C6C7573206469616D20706861726574726120657261742C206174207068617265747261206C61637573206E6962682065676573746173206D61676E612E204E756C6C61207361676974746973206C6F72656D207574206C6F72656D2E204475697320636F6E64696D656E74756D2C2064756920766974616520616C697175616D20706F73756572652C206469616D207175616D20636F6E76616C6C69732076656C69742C2075742067726176696461206C656F20697073756D206E6F6E2072697375732E205574206665726D656E74756D20736F6C6C696369747564696E20657261742E20446F6E6563207361676974746973207363656C657269737175652066656C69732E204E756E6320617263752E20457469616D2074656D7075732C206D61676E612073697420616D657420737573636970697420657569736D6F642C2065726F732073656D2072757472756D206475692C207669746165207361676974746973206E696268207075727573206E6F6E206C616375732E20536564206D6F6C6C69732061726375206567657420646F6C6F722E20446F6E6563206F726E6172652C20617263752073697420616D6574206665726D656E74756D2076756C7075746174652C20726973757320656E696D206665726D656E74756D206C696265726F2C2061206C6163696E696120646F6C6F72206D69206E6F6E2076656C69742E20457469616D206C6F626F72746973207075727573206120656C69742E204E756E63206E756C6C61206475692C206D617474697320717569732C20626962656E64756D20612C20756C7472696365732061632C2061756775652E20496E20616C697175616D207665686963756C61207475727069732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A496E7465676572206964206E69736C2E20517569737175652064696374756D20656C656D656E74756D206F64696F2E2041656E65616E206C75637475732E205365642065752073656D206120706564652076756C70757461746520636F6E64696D656E74756D2E2051756973717565206D61676E612E20446F6E656320616C697175616D206D617474697320697073756D2E204375726162697475722064696374756D20736F6C6C696369747564696E2073656D2E20416C697175616D2070756C76696E61722E204E756E6320736F6C6C696369747564696E207269737573206120657261742E20566976616D757320717569732074656C6C75732073697420616D6574206E69626820766573746962756C756D20636F6E7365717561742E204E756C6C61207072657469756D20736F6C6C696369747564696E20646F6C6F722E20416C697175616D20696163756C69732074696E636964756E74207475727069732E2050686173656C6C757320697073756D206C656F2C2076656E656E6174697320696E2C20736167697474697320696E2C206F726E6172652061742C206E756E632E0A0A50656C6C656E74657371756520756C7472696365732C2064756920657520696163756C6973206C75637475732C2074656C6C757320617567756520766F6C75747061742073617069656E2C20696E206469676E697373696D2075726E612066656C6973207574206D692E205365642061726375206475692C206469676E697373696D2069642C20706F72747469746F722075742C20696D706572646965742076697461652C20616E74652E204E756C6C61206475692073656D2C20636F6D6D6F646F206E65632C2073616769747469732065742C206C6163696E69612065742C20706564652E20457469616D20656C656966656E6420647569207574206E69736C2E20446F6E656320616E7465206D61757269732C2074656D7075732073697420616D65742C207661726975732076697461652C206772617669646120717569732C206D692E20496E207363656C657269737175652C2066656C697320766974616520766976657272612073616769747469732C2076656C6974206D6574757320756C74726963696573206E657175652C207175697320696D706572646965742076656C697420656C6974206574206D61676E612E2053757370656E646973736520706F74656E74692E205365642076656C69742065726F732C20657569736D6F64207365642C20636F6E64696D656E74756D206E65632C206661756369627573207365642C2073617069656E2E204E616D20616363756D73616E206C6967756C612073697420616D6574206E657175652E20416C697175616D206572617420766F6C75747061742E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E616D20657520706564652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642065752066656C69732073656420746F72746F722074656D706F72206665726D656E74756D2E2050686173656C6C757320636F6D6D6F646F2073656D2076656C206E69736C2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050726F696E206C656374757320656C69742C2070686172657472612073697420616D65742C20616363756D73616E207365642C2074696E636964756E742065742C206D61757269732E204475697320646170696275732070686172657472612073656D2E20496E746567657220696E206A7573746F2E205072616573656E742065726F732E20566573746962756C756D20616320616E74652E20416C697175616D207363656C657269737175652073656D2070656C6C656E746573717565206E69626820636F6E73656374657475657220736F64616C65732E20416C697175616D20636F6E736563746574756572206F64696F2E2044756973206C6563747573206F64696F2C206C75637475732065752C20636F6D6D6F646F20717569732C206D6F6C6C69732076697461652C2076656C69742E2043726173206E6563206E756E63206E6F6E20656C697420696163756C6973206D61747469732E2041656E65616E206A7573746F206E657175652C20736F6C6C696369747564696E20656765742C20756C6C616D636F7270657220656765742C20656765737461732069642C2073656D2E20496E2065752072697375732E2053656420656765737461732E0A0A496E7465676572206174206E657175652E20536564207072657469756D207363656C65726973717565206E756C6C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20467573636520757420706564652E20457469616D207669746165207175616D20612075726E612076617269757320696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2044756973207665686963756C612E20467573636520756C6C616D636F72706572206E696268206E6F6E20657261742E205175697371756520696E206E657175652E205072616573656E74206573742E2050656C6C656E74657371756520617263752E0A0A50726F696E20706F73756572652E2053757370656E646973736520706F74656E74692E20496E74656765722066656C6973206C616375732C20616C697175616D207365642C2076756C70757461746520696E2C206D6F6C6C69732076656C2C2074656C6C75732E20496E7465676572207665686963756C6120626962656E64756D206573742E204E756E63206E6F6E20646F6C6F7220696E2074656C6C7573206D617474697320666163696C697369732E20496E746567657220766573746962756C756D2C20617567756520617420636F6D6D6F646F20616C697175616D2C2064756920657374206D6174746973206C6967756C612C2073697420616D65742061646970697363696E67206F7263692073656D207669746165206D61676E612E205072616573656E7420656E696D2076656C69742C206D616C6573756164612061742C20636F6E677565206E65632C206C756374757320696E2C206A7573746F2E20536564207661726975732E204D6F7262692070686172657472612E20446F6E6563206575206D61737361206E65632074656C6C75732076756C7075746174652070756C76696E61722E20557420636F6D6D6F646F20747572706973206E6F6E2073656D2E20557420636F6E76616C6C697320756C6C616D636F727065722072697375732E20457469616D20696E74657264756D2070656465206964206E6973692E2043726173206D61676E612073617069656E2C20737573636970697420612C206C616F72656574206E6F6E2C2072686F6E6375732065742C2066656C69732E20496E7465676572206F726369206C6F72656D2C20766573746962756C756D2064696374756D2C20756C6C616D636F7270657220612C20706F72747469746F722065742C206475692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A4E756E63206574206D61676E612E2053656420626962656E64756D2074656C6C757320696E206469616D2E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E616D20766974616520746F72746F722E20496E7465676572206D61676E612E20447569732076656E656E617469732C206C656F2061632074656D706F72206C616F726565742C20656C6974206E756C6C6120706861726574726120706564652C206E6F6E206665726D656E74756D206E756E63206F64696F2061206F64696F2E2050726F696E206E6F6E2076656C69742E2053656420696D706572646965742061756775652071756973206E69736C2E20496E746567657220636F6E64696D656E74756D206E69736C206E6563206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20566976616D757320706C616365726174206C696265726F2E204475697320636F6E6775652064696374756D206D61676E612E20416C697175616D206461706962757320626962656E64756D20656E696D2E204E756E6320656C656966656E6420706564652076656C20697073756D2E0A0A457469616D2076697461652076656C69742E204D61757269732065726174206E756E632C206D616C6573756164612075742C20666575676961742061632C20706C61636572617420636F6E64696D656E74756D2C2061756775652E204E616D20766F6C75747061742E20416C697175616D207665686963756C6120697073756D206964206F64696F2E20566976616D757320736F6C6C696369747564696E207475727069732069642073617069656E2E20467573636520612066656C6973207669746165206F64696F20636F6E76616C6C697320626C616E6469742E204375726162697475722076697461652065726F732069642065726F7320706F727461207072657469756D2E204E756C6C6120696E206D61676E6120656765742075726E61206C6163696E696120636F6E76616C6C69732E20416C697175616D206D61747469732076656E656E617469732070757275732E2053656420736564206D69206567657420657261742074726973746971756520706F7274612E20446F6E656320617563746F7220646F6C6F72206120657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20496E206E6563206C6967756C612E204E756E6320656C656966656E642E20566573746962756C756D2071756973206E697369206567657420656C697420706F72747469746F7220636F6E6775652E204D616563656E61732066617563696275732C206D61676E6120656765742061646970697363696E672074696E636964756E742C20646F6C6F7220616E7465206D616C65737561646120656C69742C206E6F6E20656C656D656E74756D206C616375732074757270697320696E20706564652E0A0A5574206D616C657375616461206D69206E6563206D657475732E205072616573656E7420617563746F72206175677565206163206E69736C20756C7472696369657320666163696C697369732E204E616D2070757275732073617069656E2C2070656C6C656E746573717565206469676E697373696D2C20706F73756572652065752C206375727375732069642C206469616D2E205175697371756520736F6C6C696369747564696E2C20656C697420612070656C6C656E746573717565207363656C657269737175652C206C6F72656D20726973757320617563746F72207175616D2C207175697320636F6E7365717561742074656C6C7573206E657175652069642075726E612E2053757370656E6469737365206469616D20746F72746F722C20656C656966656E64206469676E697373696D2C20656765737461732075742C206C756374757320696E2C20616E74652E204475697320616E74652E204D616563656E6173206C75637475732E20437572616269747572206375727375732070686172657472612075726E612E204D616563656E617320696D706572646965742C2065726174206E6F6E20656C656D656E74756D20657569736D6F642C20746F72746F72206F64696F20657569736D6F64206C65637475732C20616320666163696C697369732073656D206E696268207669746165206E756C6C612E204E756E6320677261766964612E204D6F72626920736F6C6C696369747564696E206F64696F2071756973206C616375732E20416C697175616D2061206E696268206E6F6E2075726E6120706F72746120696D706572646965742E20416C697175616D206572617420766F6C75747061742E20496E20696163756C6973206C6163696E69612076656C69742E20536564206C696265726F206C616375732C207472697374697175652065752C206C6163696E69612061632C20616C697175657420656765742C2075726E612E0A0A457469616D206174206E69736C2E2050686173656C6C7573206661756369627573206C7563747573206C65637475732E20557420706C6163657261742076756C70757461746520646F6C6F722E2050686173656C6C75732076656C2076656C69742E204D6F72626920766976657272612E2050686173656C6C7573206F7263692E20496E7465676572206469676E697373696D206D6174746973206D61757269732E2050656C6C656E74657371756520706F7375657265206C656F20706F7375657265207175616D2E2051756973717565206E6563206D61676E61206174206469616D20766976657272612070656C6C656E7465737175652E2053757370656E64697373652076656C697420617263752C20756C7472696369657320717569732C20636F6E67756520612C2076656E656E6174697320656765742C206C616375732E20496E74656765722073616769747469732068656E64726572697420646F6C6F722E2046757363652074696E636964756E7420616E746520612073656D2E0A0A4D616563656E617320636F6E7365637465747565722C206A7573746F207365642072686F6E6375732076656E656E617469732C206E69626820617263752072757472756D20646F6C6F722C2073656420636F6E64696D656E74756D206C696265726F206C696265726F20657420697073756D2E20566976616D7573206D6174746973206A7573746F207574206C6F72656D2074696E636964756E74206C6F626F727469732E205574206E6F6E2076656C6974206964206E6571756520616C697175657420616363756D73616E2E205365642074656D7075732076697665727261206E756C6C612E2043757261626974757220756C6C616D636F727065722C206E6571756520717569732064617069627573207363656C657269737175652C2066656C6973206469616D2067726176696461206F7263692C206E6F6E20637572737573207175616D206E6571756520766974616520656C69742E20457469616D2070686172657472612074696E636964756E74206C616375732E204475697320657569736D6F64206672696E67696C6C61206573742E20457469616D206F726E6172652074696E636964756E74206C65637475732E2050726F696E20696E207475727069732E204E756E6320626C616E64697420626C616E646974207475727069732E2041656E65616E2075742061756775652E2044756973206F726369206A7573746F2C2074696E636964756E742065752C2072757472756D207365642C2072757472756D2065742C207475727069732E2043757261626974757220666163696C69736973206F64696F20696E20616E74652E20496E206861632068616269746173736520706C617465612064696374756D73742E205365642065726F73206573742C2070656C6C656E7465737175652061742C2074696E636964756E742065752C20756C74726963657320717569732C206D657475732E204D6F7262692073697420616D6574206A7573746F2E204D616563656E617320616320617263752E204D6175726973206469676E697373696D2E0A0A50656C6C656E74657371756520756C747269636965732072757472756D206F7263692E2041656E65616E206F726E6172652E20566976616D75732065752072697375732076656C206D6175726973206C6F626F727469732064696374756D2E205365642065742074757270697320617563746F72206D692072686F6E6375732070756C76696E61722E20536564206E6563206E756E6320612070757275732074656D706F7220766976657272612E2050656C6C656E7465737175652073757363697069742E20446F6E656320747269737469717565207269737573206E6F6E206E6962682E20457469616D206E69736C206D61676E612C20736F6C6C696369747564696E2075742C20756C7472696365732073697420616D65742C20656765737461732065752C206E756C6C612E20416C697175616D206572617420766F6C75747061742E20566573746962756C756D2070686172657472612E2053656420656765737461732C206D657475732073697420616D6574206C6F626F7274697320636F6E7365717561742C206572617420656C697420696D70657264696574206C696265726F2C20657520696E74657264756D207175616D206D61737361206567657420646F6C6F722E2053757370656E6469737365207669746165206F64696F2E2050726F696E20626C616E646974206D617572697320696163756C6973206D657475732E0A0A566976616D757320766573746962756C756D2E20457469616D206574206E69736C2E20416C697175616D20696E206469616D2076656C20656C697420706C6163657261742073757363697069742E204475697320736F64616C6573207075727573206163206E6962682E204E756C6C6120696E206F64696F206567657420656E696D206C756374757320626C616E6469742E2043757261626974757220756C74726963657320697073756D206E6F6E206E65717565206567657374617320656C656966656E642E20536564207475727069732E2050726F696E20636F6E7365637465747565722E20566976616D7573206D61747469732E20496E20616C69717565742E0A0A4E756E632069642065726F732E20446F6E65632076656E656E617469732C206E756C6C61206574206D6174746973206C75637475732C20616E7465206C656F2073656D706572206A7573746F2C206E6F6E2061646970697363696E67206F64696F20726973757320736564206C616375732E205072616573656E7420766974616520726973757320636F6E677565206C696265726F20636F6E6775652074656D7075732E2050686173656C6C75732061632065726F732E204E756C6C61207665686963756C612C206C6F72656D20696E20616C69717565742073757363697069742C2061726375206572617420656765737461732073656D2C2071756973206C6F626F72746973207175616D20616E7465206575206D617373612E20437572616269747572206E6F6E206D617373612E2053656420626962656E64756D206C6163696E6961206F64696F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20566976616D757320766F6C757470617420626C616E646974206C616375732E2050726F696E20706F7274612C2074656C6C757320757420617563746F72206C616F726565742C206C65637475732065726F73206665726D656E74756D206C65637475732C2069642073616769747469732061726375206A7573746F20696E207475727069732E2050686173656C6C757320636F6E7365717561742E204E616D2070656C6C656E7465737175652C206D69206964207669766572726120636F6E76616C6C69732C206E756E63206C696265726F20706C616365726174206C656F2C20656C656966656E6420706F7274612073656D206E69736C2076697461652073617069656E2E2050656C6C656E746573717565206C6967756C61206C696265726F2C20747269737469717565206E6F6E2C20706F72747469746F722072757472756D2C20706F72747469746F72206E6F6E2C20657261742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E74656765722064696374756D2074656C6C7573206120746F72746F722E20566976616D75732066656C6973206E756E632C206D6F6C6573746965206E6F6E2C2072686F6E63757320717569732C2070686172657472612069642C206475692E20446F6E6563207269737573206D657475732C206672696E67696C6C612076656C2C20616C69717565742065752C20706C6163657261742069642C206E657175652E0A0A53757370656E646973736520697073756D2E20566976616D7573206C65637475732E2053656420766976657272612C206D61737361206567657420636F6E76616C6C6973206D61747469732C207175616D2074757270697320636F6E736563746574756572206E756E632C206567657420706F7375657265206D61676E612073656D2069642076656C69742E20496E206E6563206D61757269732E2041656E65616E206120707572757320736564207175616D206C6F626F72746973206672696E67696C6C612E2050726F696E20756C74726963696573206C6163696E696120616E74652E205365642061646970697363696E67206572617420717569732076656C69742E204E756C6C616D207669746165206E69736C206964206A7573746F20736F6C6C696369747564696E206D6F6C65737469652E204E756C6C6120666163696C6973692E20536564206E65632075726E6120736564206E69736C206672696E67696C6C6120646170696275732E204E756C6C61206174206469616D2E20416C697175616D2065676574206E6962682E204E756E63206163206E6973692073697420616D65742074656C6C757320656765737461732074656D7075732E204E616D207363656C657269737175652075726E61206574206E657175652E20446F6E656320657374206F7263692C207361676974746973206E6F6E2C2076756C70757461746520612C20636F6D6D6F646F2065742C2061756775652E205574206461706962757320746F72746F722E205574206E756E632E20446F6E65632064696374756D2064617069627573206F64696F2E204E616D20756C7472696369657320756C6C616D636F72706572206C6967756C612E2050656C6C656E74657371756520616363756D73616E20766172697573206C656F2E0A0A4D6F72626920657569736D6F64206C616F7265657420657261742E20566976616D7573207175697320697073756D2E204D6F72626920657569736D6F642E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2053757370656E64697373652076656C2070757275732E204E756C6C616D206174206D61676E612E20437572616269747572206C61637573206C6F72656D2C20696163756C697320717569732C2064617069627573206E6F6E2C20766F6C75747061742076656C2C206E756C6C612E20446F6E656320757420617263752072686F6E63757320646F6C6F72207072657469756D2064696374756D2E204E756C6C616D2076656C206D657475732E20557420617263752E2050656C6C656E746573717565206E697369206E756E632C20706C61636572617420656765742C2074696E636964756E742076656C2C207068617265747261206E6F6E2C206E756E632E20496E74656765722074696E636964756E7420756C74726963696573206C65637475732E20496E74656765722073656D7065722C2070757275732073656420756C74726963657320666575676961742C206E756C6C61207065646520736F6C6C696369747564696E20657261742C2076656C20617563746F72206E756C6C6120697073756D2076656C206C65637475732E2041656E65616E206D692E0A0A4E756C6C616D20736564206E697369206574206172637520696D70657264696574206665726D656E74756D2E204D6175726973206E6563206D657475732E20496E20616320646F6C6F722E20496E206D6920617263752C20636F6E6775652061632C207068617265747261206E65632C207363656C657269737175652073697420616D65742C206D61676E612E20437572616269747572206C616375732E2043757261626974757220657420656C69742E20416C697175616D20756C6C616D636F72706572206E756E6320657520656C69742E2053656420636F6E76616C6C697320646F6C6F722061742076656C69742E20566573746962756C756D20646170696275732C20617567756520696420636F6E73656374657475657220706C6163657261742C206E756E63206D6173736120626C616E6469742073617069656E2C20696420616C697175616D20656C6974206E697369206964206D692E2050686173656C6C75732073617069656E206573742C20677261766964612065752C20626962656E64756D2075742C2061646970697363696E6720717569732C206573742E205574206D6F6C6573746965207175616D207669746165206F64696F2E20446F6E65632071756973207269737573206964206572617420666175636962757320736F6C6C696369747564696E2E204E616D2069642066656C69732E204D61757269732073656420656E696D207669746165206C656F20616363756D73616E207072657469756D2E0A0A4E616D206A7573746F2E20446F6E656320747572706973206E69736C2C20636F6D6D6F646F2065742C20696E74657264756D2061632C20636F6E736563746574756572206E6F6E2C206D617373612E2046757363652073656D206D657475732C206C616F72656574206E65632C20706F73756572652069642C20696D7065726469657420696E2C2076656C69742E20446F6E65632076756C707574617465206A7573746F2065676574207475727069732E204E756C6C6120706564652E204D6F7262692074696E636964756E742E20467573636520616C69717565742C207175616D20657420616C697175616D206672696E67696C6C612C20616E746520616E746520696163756C6973206475692C206E656320616C697175616D20617263752070757275732073656420657261742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050686173656C6C7573207375736369706974207175616D206574206573742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B0A0A496E7465676572207365642074656C6C75732E20536564207365642076656C697420756C74726963696573206C656F2072757472756D206C616F726565742E20536564206E6F6E2065726F7320616320707572757320736167697474697320666575676961742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E205365642068656E647265726974206C6967756C612073697420616D6574206E6962682E204D616563656E6173207475727069732E204D6F72626920636F6E7365637465747565722C20646F6C6F722065742061646970697363696E6720696D706572646965742C20616E7465206E65717565206665756769617420646F6C6F722C20617420706F727461207175616D206E657175652071756973206C6967756C612E204D61757269732073656D7065722076656C69742073697420616D657420697073756D2E2050656C6C656E7465737175652074656D7075732C20707572757320696E2072757472756D20636F6E7365717561742C20656E696D2065726174207665686963756C61206D617373612C20696420616363756D73616E206C656F2073617069656E206E65632070757275732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E20646F6C6F722E20496E746567657220666163696C69736973206C696265726F2073697420616D657420706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2055742076617269757320616C697175657420656E696D2E204E756C6C6120666163696C6973692E2043757261626974757220636F6E7365637465747565722C206F64696F206575207072657469756D2074696E636964756E742C206E756E63206E69736920616C6971756574206E657175652C2076656C20696D7065726469657420656C6974206D617373612073697420616D6574207475727069732E2050656C6C656E7465737175652074656D7075732C206F72636920766F6C757470617420626C616E646974206672696E67696C6C612C206F64696F2073656D20706F737565726520616E74652C20766974616520626962656E64756D2075726E61206C6F72656D2076697461652065726F732E205072616573656E7420766976657272612072686F6E63757320617263752E2053656420617563746F722C206573742073697420616D6574206D6F6C6C6973206D6F6C6C69732C207175616D207175616D20677261766964612073617069656E2C20696E20636F6D6D6F646F206D65747573206E756C6C6120617563746F7220656E696D2E20446F6E656320666163696C697369732E0A0A50726F696E2074696E636964756E742C2073617069656E206567657420756C747269636965732061646970697363696E672C20657374206F64696F2064696374756D20617263752C207574206D6F6C6C69732065726174206475692073697420616D65742076656C69742E204D6F726269206573742073656D2C20696E74657264756D2061742C20636F6E67756520612C20656C656D656E74756D2076697461652C206D657475732E2053757370656E64697373652069642061756775652E204D617572697320656E696D2073656D2C2070756C76696E617220656765742C2074656D70757320612C2074656D7075732073697420616D65742C2073617069656E2E20467573636520766573746962756C756D20636F6E736563746574756572206475692E2050656C6C656E74657371756520657261742E20536564206469676E697373696D20706C616365726174206F64696F2E204D616563656E61732073656D7065722072686F6E637573206C65637475732E2050686173656C6C7573207072657469756D2E2044756973206C696265726F20656C69742C20656C656966656E64206E65632C20656765737461732075742C20637572737573207365642C2066656C69732E204E616D206E69736C20617263752C20616C69717565742065742C20666163696C697369732065752C206C75637475732075742C2072697375732E20457469616D20756C7472696365732C20646F6C6F722073656420766F6C7574706174206D616C6573756164612C20747572706973206172637520696D7065726469657420746F72746F722C20657569736D6F6420636F6D6D6F646F206C696265726F206D61737361207574207175616D2E20496E7465676572206D6F6C6573746965207075727573206E6F6E20656C69742E2055742076656E656E617469732073656D70657220746F72746F722E20457469616D20626962656E64756D206567657374617320697073756D2E204D617572697320736F6C6C696369747564696E2073656D206E6563206E6962682E204E756C6C61207072657469756D206D65747573206575206D657475732E2050656C6C656E7465737175652073697420616D65742073656D2E0A0A53757370656E6469737365206163206E6973692E205574206C656F2E20566573746962756C756D2068656E647265726974207072657469756D20646F6C6F722E204E756E632066657567696174206D616C6573756164612070757275732E2043726173206574206E6962682E20437572616269747572206E756E6320657261742C206D616C6573756164612076697461652C206C616F726565742061632C20756C7472696369657320696E2C2070757275732E20566976616D75732074656C6C757320617263752C20736F64616C65732065752C20666163696C6973697320612C206C6163696E6961206E65632C206E756E632E2050656C6C656E7465737175652069642076656C69742E20496E206575206E6962682E204E756E63206E656320657261742E205365642064696374756D206E65717565207574206E69736C2E0A0A4D6F726269206C65637475732074656C6C75732C2074696E636964756E742061632C20706F72747469746F722061632C2074726973746971756520696E2C2065726F732E20446F6E6563206C7563747573206C7563747573206C656F2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2046757363652075742065737420657420656E696D207363656C6572697371756520616363756D73616E2E20446F6E6563206C6967756C612066656C69732C206C6163696E696120717569732C2070656C6C656E74657371756520696E2C2073656D70657220766573746962756C756D2C20656C69742E204D61757269732065676574206F72636920612066656C697320636F6E677565207665686963756C612E20557420736F6C6C696369747564696E2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204E756C6C616D20696420646F6C6F72207574206C6F72656D206469676E697373696D2076656E656E617469732E2053757370656E64697373652076697461652073617069656E2E2050726F696E206E6F6E206D61676E612075742065726F7320766976657272612070756C76696E61722E20446F6E65632071756973206F64696F2E204E756C6C616D206E6F6E20617263752076656C206C6F72656D20737573636970697420616C697175616D2E20416C697175616D2072757472756D2074757270697320696E206C656F2E0A0A5574206C7563747573206E6962682074726973746971756520657261742E2053757370656E646973736520626962656E64756D206F64696F20766974616520746F72746F722E20446F6E6563206C6163696E69612E204372617320736F64616C65732066656C6973206C7563747573206E756C6C612E204E616D20656C656966656E64207361676974746973206C6967756C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E64697373652076656C206E657175652E204D6F72626920616C6971756574207665686963756C61206D61676E612E2041656E65616E206174206F64696F2E20447569732070656C6C656E746573717565206D61676E612E204E756C6C6120617420746F72746F72207574206469616D2064696374756D2066617563696275732E204D617572697320717569732076656C69742E20446F6E6563206E6F6E2074656C6C7573207669746165206C6F72656D206672696E67696C6C6120706F72747469746F722E2046757363652075742073617069656E207175697320746F72746F7220666575676961742073616769747469732E20446F6E656320766976657272612073656D2076697461652073617069656E2E205072616573656E7420736F64616C65732C206C6163757320696E206672696E67696C6C6120766976657272612C206F64696F2061756775652061646970697363696E672075726E612C20766974616520696E74657264756D20616E74652073656D206E6F6E206E6973692E204E756C6C616D20746F72746F72206C6F72656D2C20656C656966656E642061632C206D6F6C6C6973206E6F6E2C206C616F726565742061632C2072697375732E20496E7465676572206F726E617265206C656F20736564206A7573746F2E2051756973717565206375727375732C2073656D206E6F6E20666163696C6973697320626962656E64756D2C206E697369206D69207661726975732066656C69732C206665726D656E74756D2066657567696174206C6F72656D2065726F73206C616F726565742072697375732E0A0A517569737175652073697420616D657420657374206574206C6F72656D207665686963756C61206C6163696E69612E20446F6E6563206E656320746F72746F722E2043726173206F64696F2E204E616D207363656C657269737175652076756C7075746174652075726E612E205072616573656E74206475692E20457469616D206E6563206E69736C206C6F626F7274697320697073756D20616C69717565742074656D7075732E204D616563656E6173207072657469756D20736F6C6C696369747564696E206D61757269732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206175677565206D617373612C20636F6E67756520656765742C20636F6E76616C6C697320656765742C207472697374697175652073697420616D65742C2065726F732E2053656420636F6E736571756174206E6973692065752066656C69732E2050656C6C656E746573717565206A7573746F2E2053757370656E6469737365206E6F6E2061756775652E20496E206469676E697373696D206C6F626F72746973206D61757269732E204D61757269732073616769747469732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E0A0A5365642061646970697363696E672E20446F6E656320612074656C6C75732076697461652065737420637572737573207665686963756C612E204E616D20616E74652073656D2C20736F64616C65732069642C206672696E67696C6C612076656C2C20636F6E64696D656E74756D2076656C2C206E756C6C612E205175697371756520736F64616C65732E20457469616D20696D7065726469657420656C6974206964206F64696F2E20416C697175616D206572617420766F6C75747061742E204D616563656E617320706F7274612074656D706F7220617263752E204E756C6C612073656D2061756775652C2070656C6C656E7465737175652061632C20636F6E7365717561742075742C20636F6E64696D656E74756D20657569736D6F642C2072697375732E2053656420616C697175616D2074696E636964756E74206D692E20496E20696E74657264756D206C6F626F72746973206F7263692E0A0A536564207665686963756C612068656E6472657269742070757275732E20457469616D2061206469616D2E2043757261626974757220636F6E76616C6C69732E2053757370656E64697373652061206E6973692E20446F6E6563206964206D61676E6120696E207175616D20736F6C6C696369747564696E20756C747269636965732E20446F6E656320766976657272612E205175697371756520766F6C757470617420657374207365642073656D2E20416C697175616D206A7573746F2E20566573746962756C756D20746F72746F72206D617373612C20706F72747469746F72207365642C2076617269757320717569732C20696163756C697320717569732C206F64696F2E20416C697175616D2065676574206E657175652E0A0A4D6175726973206E756C6C612E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566573746962756C756D206575207175616D20696E206E6571756520756C7472696365732070656C6C656E7465737175652E204372617320696E20646F6C6F722071756973207175616D207661726975732068656E6472657269742E20416C697175616D206E697369206C616375732C206C6F626F727469732065752C20636F6E76616C6C69732073697420616D65742C20666163696C697369732075742C206D692E20416C697175616D206174206E657175652E204372617320736167697474697320656C656D656E74756D206A7573746F2E20566573746962756C756D207574206C656374757320616C6971756574207075727573206D616C65737561646120766F6C75747061742E2044756973206174206C616375732061646970697363696E67206C696265726F2074696E636964756E7420766573746962756C756D2E204D6F7262692061206C696265726F2E20437261732070757275732E204D6F72626920757420617567756520657420707572757320696E74657264756D207363656C657269737175652E20496E74656765722061206475692E20496E206861632068616269746173736520706C617465612064696374756D73742E2044756973207068617265747261206D657475732065676574206D61757269732E20416C697175616D20696E74657264756D20756C6C616D636F72706572206D617373612E0A0A457469616D206F726E6172652E204E756C6C616D20657569736D6F642E2041656E65616E20636F6E7365717561742067726176696461206C6967756C612E20416C697175616D206573742E2050726F696E207669746165206C616375732E205072616573656E7420612065726F732073697420616D657420647569206C756374757320636F6D6D6F646F2E2050686173656C6C7573207665686963756C612061726375206567657420646F6C6F722E205072616573656E74206665726D656E74756D20636F6E677565206C656F2E20416C697175616D20766F6C7574706174207075727573207574206C6F72656D2E2046757363652068656E64726572697420656E696D206174206C656F2E20416C697175616D2072686F6E637573206E69736C2E20566976616D75732064696374756D2065676573746173206D692E2053757370656E64697373652070656C6C656E74657371756520626962656E64756D20646F6C6F722E2050656C6C656E7465737175652074696E636964756E742C207475727069732073656D7065722070656C6C656E74657371756520636F6E64696D656E74756D2C20697073756D206D6574757320736F64616C6573206C6967756C612C20696420766F6C7574706174206469616D2074757270697320757420656C69742E0A0A5072616573656E7420736564206C616375732E204E616D20656C656966656E64206D6F6C6573746965206D61757269732E20446F6E65632064617069627573206665726D656E74756D206D617373612E20446F6E656320766976657272612066617563696275732070757275732E2043757261626974757220636F6E6775652C206C696265726F20766974616520766976657272612070656C6C656E7465737175652C206469616D2076656C697420736F64616C657320656E696D2C20736564207375736369706974206C6563747573206E697369206E6563206E657175652E20566573746962756C756D206D616C6573756164612C206C616375732061742063757273757320636F6E6775652C2076656C6974206C65637475732074726973746971756520646F6C6F722C2073697420616D657420736F64616C6573206E6571756520697073756D2061206C696265726F2E20566573746962756C756D206574207175616D2E2043757261626974757220706C6163657261742E20437572616269747572206E756E6320617263752C20657569736D6F64206E65632C2076756C7075746174652068656E6472657269742C20616C697175657420656765742C207175616D2E204375726162697475722076656C20656E696D2E2053757370656E646973736520706F74656E74692E0A0A4E756E6320636F6E736571756174206F726369207574206C616375732E2046757363652076656C697420646F6C6F722C2064617069627573207365642C20626C616E6469742073697420616D65742C2072686F6E6375732069642C2072697375732E20447569732075726E61206E6962682C207363656C6572697371756520717569732C206461706962757320612C207363656C65726973717565207365642C206E6962682E20446F6E6563206C75637475732E205574206575206D617572697320637572737573206469616D206C6163696E69612072686F6E6375732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20416C697175616D207665686963756C61206D6F6C6573746965206A7573746F2E204D616563656E617320696D70657264696574207065646520736564206D692E2053757370656E6469737365206E756C6C6120646F6C6F722C2068656E64726572697420656765742C2068656E6472657269742069642C2064696374756D2076656C2C206C656F2E204475697320616363756D73616E2E2043757261626974757220696E2066656C69732E204E756E63206C6F72656D2E205574206C656F20646F6C6F722C206C616F72656574206E65632C2076756C7075746174652061742C20656C656966656E6420696E2C206E756C6C612E2051756973717565206E756E632070757275732C2076617269757320656765742C20616363756D73616E206E65632C20616C69717565742065742C206E6962682E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20437261732061646970697363696E67207669766572726120646F6C6F722E204D617572697320706F72747469746F7220756C7472696365732070757275732E204E756C6C6120666163696C6973692E205072616573656E7420666175636962757320616E7465207669746165206D61757269732E0A0A5072616573656E74206C6163696E6961206C656374757320736564206E69736C2E20496E2074656D70757320636F6E677565206D61757269732E20496E746567657220666163696C69736973206F726E61726520656E696D2E204E756C6C61206964206D617373612E20446F6E656320636F6D6D6F646F206469616D2061742074656C6C75732E204E616D20646170696275732076697665727261206573742E204E616D2074656C6C75732E205072616573656E742061206C696265726F2E20496E206661756369627573206573742065676574206E6962682E204E756C6C612065726F73206F7263692C20696D70657264696574206E6F6E2C20626C616E646974206E6F6E2C2074656D706F7220656765742C206D692E2050656C6C656E74657371756520636F6E76616C6C69732E0A0A517569737175652065676574206D69206163206C656F20657569736D6F642066617563696275732E2050686173656C6C75732072686F6E637573207075727573206964206475692E20566573746962756C756D206D616C65737561646120656C656966656E6420616E74652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050656C6C656E74657371756520626C616E646974206D6174746973206F64696F2E2053757370656E646973736520636F6E7365717561742C206C65637475732061632073656D70657220736F6C6C696369747564696E2C206D692076656C69742064696374756D2061756775652C2061632074656D70757320646F6C6F7220657261742073697420616D6574206475692E2050726F696E2068656E6472657269742C2066656C6973207175697320766F6C757470617420706F73756572652C206469616D206F64696F206D616C657375616461206F64696F2C206120696E74657264756D206F726369206469616D20717569732073617069656E2E2050656C6C656E746573717565206F64696F206F64696F2C20766976657272612076656C2C20677261766964612065752C206D6F6C6573746965207365642C206E756C6C612E2050686173656C6C7573206D617572697320706564652C20636F6D6D6F646F2075742C20657569736D6F642065752C2068656E6472657269742065752C206573742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C6120656C656D656E74756D206C616375732065752061756775652E2053656420657261742E2050726F696E20706F7274612E204D616563656E61732071756973206D692E2050686173656C6C757320617420656E696D206163206A7573746F206772617669646120756C7472696365732E2043726173206C656F2E0A0A496E746567657220757420617263752E20446F6E656320736564206D61676E612E2050726F696E2066656C69732E20496E20696163756C69732C206C6967756C61206964206672696E67696C6C61207072657469756D2C206E696268206469616D20616363756D73616E2074656C6C75732C206567657420616363756D73616E206D657475732064756920766172697573207475727069732E2050686173656C6C7573206F726369206D657475732C20656C656966656E64207365642C2074656D706F722061632C207363656C657269737175652061632C2075726E612E20496E74656765722076697665727261206E657175652061206D61757269732E204D617572697320706F72747469746F7220646F6C6F722065752076656C69742E20496E7465676572206F64696F20656C69742C20766573746962756C756D2075742C20766F6C75747061742069642C2072686F6E63757320636F6D6D6F646F2C2075726E612E20457469616D20706C61636572617420706861726574726120657261742E2055742074656D706F72206573742E20496E7465676572206469676E697373696D20626C616E6469742074656C6C75732E204D6F726269206E69626820646F6C6F722C207363656C657269737175652069642C20636F6D6D6F646F206D616C6573756164612C206D61747469732061742C206D692E20437261732074696E636964756E7420636F6D6D6F646F2070757275732E20496E2074696E636964756E742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D20756C6C616D636F727065722E2055742068656E6472657269742E204D6F72626920756C7472696365732E0A0A5072616573656E7420696163756C69732C2065726F73206163206567657374617320736F64616C65732C2075726E61206C656F206665726D656E74756D206C6967756C612C2073697420616D657420616C697175616D2076656C69742073656D206E6F6E2070757275732E20446F6E65632072757472756D206172637520717569732070757275732E204E616D20706F73756572652C206C6163757320617420636F6E73657175617420706C6163657261742C206E756C6C61207065646520706F7375657265206F7263692C206E6F6E20657569736D6F6420747572706973206475692071756973206E69736C2E2050726F696E20706F7274612061646970697363696E67206E6962682E20446F6E65632074726973746971756520646F6C6F722061742074656C6C75732E20446F6E6563206E65717565206D617373612C20617563746F722069642C2066617563696275732076697461652C20756C6C616D636F727065722076656C2C206E6973692E2050726F696E206D6F6C6573746965206E6571756520736564206D617373612E204E616D2074656D706F722E204D6F72626920616C697175616D2073617069656E2061742074656C6C75732E2046757363652071756973207269737573206574206D69207072657469756D2070756C76696E61722E2046757363652073697420616D6574206C6967756C612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E646973736520657520656E696D2065742066656C6973207363656C65726973717565206C6F626F727469732E205072616573656E7420626962656E64756D2E20566976616D7573207665686963756C612E20496E7465676572206174206E696268207365642076656C69742072686F6E637573206D6F6C65737469652E2043726173206C616375732E2053656420756C6C616D636F727065722065726F732076656C20657261742E20467573636520657520746F72746F722073697420616D6574206469616D20657569736D6F642073616769747469732E204E756E632071756973206C61637573206964206E69626820636F6E76616C6C6973207661726975732E2053757370656E6469737365207669746165206D692E20566573746962756C756D207472697374697175652E20446F6E6563206D616C65737561646120697073756D206964206E657175652E204E756C6C616D20736564206C616375732E204475697320656765737461732C206A7573746F20757420636F6E677565206F726E6172652C2061756775652073617069656E206C7563747573206469616D2C20617420616363756D73616E20657261742073617069656E207574206C696265726F2E2050686173656C6C75732076656C206E756C6C612E2053757370656E646973736520617263752074656C6C75732C20706F72747469746F7220612C2070686172657472612066617563696275732C20616C697175616D2073697420616D65742C206D617373612E204E756C6C6120706F72747469746F722074696E636964756E74206C6F72656D2E204E756E6320646F6C6F72206F64696F2C20736167697474697320696E2C206C6F626F727469732076656C2C20766F6C7574706174207365642C206E6962682E0A0A5175697371756520626C616E646974206C656F2075742073617069656E2074656D70757320666163696C697369732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2041656E65616E20756C7472696369657320706F72747469746F72206A7573746F2E2046757363652072757472756D2065726F732075742075726E612E2050726F696E2071756973207175616D20656765742064756920616C697175616D20616363756D73616E2E20446F6E656320737573636970697420656C656966656E6420656C69742E2050656C6C656E746573717565206D61747469732C2066656C697320736F64616C657320696163756C697320696D706572646965742C206C616375732073656D20636F6E76616C6C69732061756775652C2073697420616D657420616C69717565742061726375207075727573206672696E67696C6C612072697375732E20496E206575206F64696F206964206D61676E61207068617265747261206F726E6172652E20416C697175616D20696E74657264756D2070756C76696E617220697073756D2E20536564206E657175652E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D2073697420616D6574206E6973692E2055742061742061756775652E204D617572697320766F6C757470617420626C616E646974206C6967756C612E204E756C6C61206575206D657475732E20566573746962756C756D206567657420656C69742E205072616573656E7420706F73756572652E20566573746962756C756D2069642073656D206E6F6E206C6563747573206D6F6C6C69732074696E636964756E742E20416C697175616D2069642066656C697320617420616E7465206F726E6172652074656D706F722E204E756C6C61206C61637573207475727069732C20666575676961742076697461652C2063757273757320717569732C20636F6E736563746574756572206E6F6E2C206D61757269732E204675736365206C61637573206D617373612C20706F72747469746F722075742C206D6F6C65737469652075742C2076656E656E6174697320612C206C6F72656D2E205072616573656E742073697420616D6574206F7263692E204D61757269732072686F6E6375732066656C69732076697461652066656C69732061646970697363696E6720696D706572646965742E204D616563656E6173206D6F6C6C6973206469616D206E6563206C656F2E0A0A467573636520656E696D20697073756D2C20756C7472696365732065752C206D6F6C65737469652069642C20656C656D656E74756D2069642C2073617069656E2E20496E746567657220612075726E612E204E616D2076656C6974206C696265726F2C2076656E656E6174697320656765742C2074656D706F722073697420616D65742C20666575676961742076697461652C20616E74652E204675736365206E756E632E205365642073656D706572206E69736C206E65632072697375732E20496E20736564206C696265726F2E2050726F696E20746F72746F72206E657175652C2074696E636964756E742061632C2074656D706F722061632C20706861726574726120717569732C2076656C69742E2044756973206C65637475732061756775652C20756C747269636965732076656C2C20636F6E7365717561742069642C20696163756C69732069642C20616E74652E20566976616D757320617563746F72206D65747573206120616E74652E204375726162697475722061726375206E6973692C20666163696C697369732061742C206C616F7265657420696E2C20636F6E736563746574756572207365642C206D61757269732E205175697371756520706C616365726174206469616D20736564206475692E20566976616D7573207072657469756D20636F6E64696D656E74756D206C6F72656D2E20437572616269747572206C616F726565742E2041656E65616E206F726369206C6967756C612C2063757273757320656765742C206C6163696E6961206E6F6E2C2066617563696275732076656C2C206C6F72656D2E0A0A416C697175616D206572617420766F6C75747061742E204375726162697475722065726F7320646F6C6F722C20636F6E67756520612C20636F6E64696D656E74756D207365642C206C75637475732075742C206E6962682E204D616563656E6173206E6F6E20746F72746F72206E65632074757270697320636F6D6D6F646F2070656C6C656E7465737175652E205072616573656E7420657569736D6F6420706C616365726174206D692E2053757370656E646973736520706F74656E74692E2050686173656C6C7573207574206E65717565207669746165206F726369206D617474697320696163756C69732E20496E746567657220656765742074656C6C75732E20446F6E656320617420616E74652E204E616D206C6163696E6961206C656F206567657420657261742E204D616563656E617320657569736D6F64206D61676E6120636F6E67756520746F72746F722E204D6F726269206E6563206D6173736120657520656E696D206D616C65737561646120736F6C6C696369747564696E2E2053656420616363756D73616E2E204E756C6C616D20697073756D2E205574206F64696F2E20416C697175616D206572617420766F6C75747061742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2050656C6C656E7465737175652069642076656C69742E204E616D206F64696F2073656D2C20616C69717565742075742C2074656D7075732073697420616D65742C20657569736D6F642065742C206E756E632E0A0A50656C6C656E746573717565206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205072616573656E74206D6175726973206E756E632C207661726975732075742C20636F6E76616C6C6973206D6F6C65737469652C206C75637475732073697420616D65742C206C656F2E205365642064696374756D206C6F72656D20657420617263752E204E756E632076656E656E617469732070656C6C656E746573717565206D617373612E204E756C6C6120666163696C6973692E2050686173656C6C757320696E20746F72746F722065676574207269737573207363656C657269737175652076756C7075746174652E20536564206E69626820656C69742C2073616769747469732061632C20636F6E64696D656E74756D206E65632C20636F6E76616C6C69732065742C206A7573746F2E20467573636520766F6C7574706174206D657475732E204E756E6320617563746F722E20566573746962756C756D206C656F2065726F732C2070656C6C656E7465737175652061632C206D6F6C6C697320756C7472696365732C2072686F6E637573206E6F6E2C20646F6C6F722E204D6175726973207665686963756C6120706C616365726174206E69736C2E20566573746962756C756D20626962656E64756D2C2061726375207175697320636F6E67756520656C656D656E74756D2C2076656C6974206E756E6320656C656966656E64207475727069732C206964206C7563747573207269737573206E69736C2073697420616D65742074656C6C75732E2050686173656C6C75732070656465206E657175652C20626C616E646974206E6F6E2C20636F6D6D6F646F2076697461652C20756C7472696369657320656765742C206D61676E612E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120666163696C6973692E20416C697175616D20616320616E74652E20437261732072697375732E204D6F726269206D6175726973206C616375732C20706F73756572652065752C20626C616E6469742065742C2070686172657472612061742C206D692E2050726F696E2061632070757275732E204475697320637572737573206E69736C2072757472756D207175616D2E20416C697175616D2061206F64696F206E6F6E206D61676E612070656C6C656E74657371756520756C747269636965732E204D616563656E6173206163206D6173736120717569732073617069656E20756C6C616D636F727065722074656D7075732E2043726173206375727375732076656C6974207365642073617069656E2E2050726F696E206E756C6C612E20566976616D757320736F64616C657320616C697175616D206E6962682E20457469616D206574206572617420757420616E7465206C6163696E696120657569736D6F642E204675736365206E6973692E2050726F696E2071756973206E756C6C612E0A0A517569737175652076656E656E617469732C2065726F7320736564206C616F7265657420736F6C6C696369747564696E2C206F72636920616E74652070656C6C656E746573717565206E69736C2C2073697420616D65742076697665727261207175616D2065726174206E6F6E2072697375732E20437261732065676574206C696265726F2E2053656420656C6974206D61676E612C2073656D7065722065752C206672696E67696C6C6120696E2C206469676E697373696D20736F64616C65732C20657261742E20566976616D757320666575676961742073656D2076656C206475692E20446F6E656320636F6E76616C6C697320736F6C6C696369747564696E206469616D2E2043726173207365642070757275732E20446F6E65632066656C69732065726F732C2073656D70657220656765742C2074656D706F7220636F6E7365637465747565722C20736167697474697320717569732C206E69736C2E204475697320696E20616E74652E2043726173206E6F6E207475727069732E204E756C6C612074656D706F722076656C697420616C697175657420747572706973206D6F6C657374696520706C6163657261742E2050726F696E20656C656D656E74756D206665726D656E74756D206D61757269732E20566976616D757320736564206F726369206C6163696E69612064756920706C6163657261742076656E656E617469732E20566573746962756C756D20666575676961742C2074656C6C757320696E20766F6C75747061742072757472756D2C206D61676E61206E69736920756C6C616D636F727065722065726F732C2069642070756C76696E6172206E657175652065726174207574206C616375732E20566976616D7573207365642061756775652E204E756C6C6120666163696C6973692E204D616563656E617320616E74652061756775652C20656C656D656E74756D2075742C20736F64616C65732076697461652C20636F6E64696D656E74756D206E65632C206C6F72656D2E20447569732070656465206F7263692C206672696E67696C6C612061742C20656C656966656E64206E65632C207072657469756D20696E2C20657261742E204E616D2073616769747469732C2074757270697320766974616520636F6E76616C6C69732070686172657472612C206F64696F2073656D207363656C65726973717565206C616375732C206E6563206C6F626F7274697320647569206469616D2076656C2065726F732E20496E2073656D7065722067726176696461206E657175652E0A0A496E7465676572206E756E632E205574207072657469756D20697073756D2073697420616D657420656C69742E20496E206E656320617263752E2053656420766573746962756C756D2076756C70757461746520697073756D2E2050656C6C656E7465737175652074696E636964756E742E204E756C6C61206772617669646120646F6C6F7220696E2074656C6C75732E2043726173207665686963756C612C20646F6C6F722075742070656C6C656E74657371756520616C697175616D2C206572617420656E696D20617563746F72206D617373612C207665686963756C61206C6F626F72746973206F64696F2065726F732071756973207175616D2E2050726F696E2064617069627573206E6571756520696E20656E696D2E2050726F696E20656C69742E20496E74656765722072686F6E6375732074696E636964756E7420656C69742E204675736365206C6F72656D206D657475732C2073656D7065722061632C20766F6C75747061742076697461652C20666163696C697369732075742C2074656C6C75732E20446F6E65632076656C20747572706973207669746165206E69736920706861726574726120706F72747469746F722E204D616563656E617320746F72746F722E204675736365206D692E204E756C6C616D206E6563207475727069732E2053656420736F64616C657320766573746962756C756D206E756E632E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A50656C6C656E74657371756520646F6C6F7220646F6C6F722C206C616F726565742065752C20616C697175657420717569732C207363656C657269737175652073697420616D65742C20617263752E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C616D206375727375732075726E61206567657420656C69742E205175697371756520626C616E6469742073617069656E20616320616E74652E2050726F696E206E756C6C612065726F732C206772617669646120766F6C75747061742C20736F64616C65732076656C2C206D6F6C6C69732065752C206D617373612E204E756C6C612074726973746971756520736F6C6C696369747564696E206E69736C2E20437572616269747572207669746165206C6F72656D2076697461652076656C69742065676573746173206F726E6172652E2041656E65616E20656765742065726F732E20416C697175616D206572617420766F6C75747061742E20467573636520612075726E61206964206F64696F20616C697175657420636F6E76616C6C69732E204375726162697475722073697420616D6574206E69736C20706F7375657265206C656F20706F737565726520646170696275732E2044756973206D6574757320657261742C206C75637475732076656C2C2072686F6E6375732061742C20636F6E76616C6C69732073697420616D65742C20656E696D2E20566976616D75732068656E6472657269742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D206567657420656C69742E0A0A4E756C6C616D2061206E756E632E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206D657475732075726E612C2074696E636964756E742065742C206C6163696E69612073697420616D65742C206C6F626F727469732076697461652C206C6967756C612E2050726F696E206574206D6175726973207669746165206D6920616363756D73616E2070656C6C656E7465737175652E20457469616D207175616D2070757275732C2068656E647265726974207365642C20666575676961742076697461652C20657569736D6F6420656765742C20746F72746F722E20557420616C697175616D206D61676E61207669746165206A7573746F2E2053757370656E6469737365206E6F6E206A7573746F2076656C2076656C697420636F6E64696D656E74756D2074656D7075732E20447569732074656D70757320697073756D2076697461652074656C6C75732E2050726F696E20696E206D617373612E20457469616D20756C6C616D636F727065722064696374756D2074656C6C75732E2050726F696E20616C69717565742066656C6973206174206C656F206C616F726565742070756C76696E61722E20566573746962756C756D20617263752070757275732C206D616C6573756164612073697420616D65742C206375727375732065752C20706C6163657261742073697420616D65742C206E756E632E204E616D206D61737361206F64696F2C20736F6C6C696369747564696E20696E2C2061646970697363696E6720612C20616C697175616D206E65632C2072697375732E20416C697175616D20626C616E6469742068656E647265726974206C696265726F2E204D617572697320677261766964612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204375726162697475722061206E6962682E20557420696E74657264756D206665726D656E74756D206E657175652E2050656C6C656E74657371756520736564206E756E632E204D6175726973207665686963756C61206E697369206574206E756E632E205072616573656E74206C6F72656D2E20446F6E65632073656D7065722E20496E7465676572206575206C6163757320696E2065737420616C697175616D2068656E6472657269742E20566573746962756C756D2065676574206E657175652E205365642073656D706572206C75637475732076656C69742E20437572616269747572206E6962682061756775652C20636F6E6775652065752C2068656E6472657269742069642C20636F6E6775652065742C20656E696D2E20496E746567657220706C61636572617420616C697175616D206C65637475732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20566976616D75732076697461652065726F732E20446F6E65632076656C206E69736C2E0A0A496E20766573746962756C756D20666163696C697369732075726E612E2055742072697375732E204D61757269732070686172657472612E2050656C6C656E746573717565206D61747469732E20496E746567657220737573636970697420616C697175616D20697073756D2E204475697320626C616E6469742C2073617069656E20657420756C7472696369657320636F6E64696D656E74756D2C2066656C6973206D6920656C656D656E74756D20706564652C206E6563207361676974746973206D65747573206D61757269732071756973207175616D2E205175697371756520616363756D73616E20617263752076656C206E756C6C612E20437261732073656D2073617069656E2C20706F72747469746F722069642C20756C747269636965732073616769747469732C206C75637475732065752C206E756C6C612E20496E746567657220717569732065726F732E204D6F726269207365642075726E6120612074656C6C7573207665686963756C612076756C7075746174652E20457469616D206E656320617567756520656765742066656C69732073656D706572207472697374697175652E205175697371756520757420646F6C6F722076656C2072697375732064696374756D20636F6E7365717561742E20536564206567657420646F6C6F7220736564206E756E63206C6163696E696120616C69717565742E2053757370656E646973736520616320746F72746F7220696E20697073756D20706F73756572652076656E656E617469732E20536564206567657420657261742E204E756C6C612066617563696275732E2044756973206C616F726565742C206D6173736120706F72747469746F7220616C697175657420656765737461732C20697073756D206C65637475732072686F6E637573207175616D2C20696E2061646970697363696E672065726F732073656D2075742074656C6C75732E2050656C6C656E74657371756520666575676961742074656D707573207175616D2E20566976616D757320696420646F6C6F7220656765742073617069656E20636F6E7365637465747565722074656D706F722E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120696163756C6973206665726D656E74756D206C696265726F2E204375726162697475722066617563696275732C206D61737361206D616C657375616461206375727375732074696E636964756E742C20657261742073656D20656C656966656E64206D61757269732C20736564206672696E67696C6C61206D6920616E74652061632070757275732E204475697320656C656D656E74756D206C65637475732E204E756E63206F726E617265206172637520657520746F72746F722E20566573746962756C756D2076656C20646F6C6F72206174207075727573206C6163696E6961206672696E67696C6C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E616D20696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204D616563656E61732074696E636964756E742C2065726F73206120656765737461732070656C6C656E7465737175652C2072697375732072697375732064696374756D206C696265726F2C20696420616C6971756574206D65747573206A7573746F20696E206D617373612E2050726F696E20612074656C6C75732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205365642070757275732E20536564206E6F6E20706564652E2041656E65616E206D617373612073617069656E2C20736F64616C65732073697420616D65742C20636F6E7365717561742064696374756D2C20656C656966656E642076697461652C20746F72746F722E20446F6E656320756C747269636573206C6163696E696120656C69742E0A0A4D6F7262692061646970697363696E6720736F64616C657320646F6C6F722E20557420756C6C616D636F7270657220756C74726963696573206573742E20496E2076656E656E617469732074656D7075732061756775652E2053757370656E646973736520746F72746F7220646F6C6F722C20616363756D73616E2065742C20737573636970697420612C2074696E636964756E742075742C206C696265726F2E20416C697175616D207363656C65726973717565206D61676E61207365642066656C69732E2051756973717565207574206E756E632061206D61676E612076756C70757461746520706C6163657261742E20416C697175616D2072686F6E637573207665686963756C61206475692E2053656420746F72746F722E204E756C6C616D2073697420616D6574206469616D2E204E756E63207365642065726F732E20536564206574206F64696F2074696E636964756E7420656C6974206772617669646120636F6E76616C6C69732E20437572616269747572207175697320746F72746F722061206C616375732073656D706572207661726975732E204D6175726973206174206175677565206E6F6E206D6920736F6C6C696369747564696E20616C697175616D2E20496E746567657220756C6C616D636F727065722E2050656C6C656E746573717565207375736369706974207175616D206E6F6E2070757275732E20416C697175616D2061632065726F73206174206172637520756C6C616D636F7270657220636F6E7365637465747565722E2053757370656E6469737365207072657469756D206D6174746973206C656F2E0A0A44756973206174206E756E632E2053656420646F6C6F72206573742C207661726975732061632C20706F7274612065742C2074696E636964756E742068656E6472657269742C2072697375732E20566976616D7573207574206D61676E612E205072616573656E74207574206D61757269732E20496E207075727573206C616375732C206D6174746973207365642C20766573746962756C756D206E65632C2074656D706F722061742C206E69736C2E204372617320756C6C616D636F727065722076656E656E617469732074656C6C75732E20557420646F6C6F722E204D616563656E6173206D616C6573756164612C207065646520612070756C76696E6172206D61747469732C2061726375206469616D207665686963756C612072697375732C207175697320706F72747469746F72206175677565206D6173736120696E2076656C69742E204E756E6320636F6E6775652E204D6F7262692076656C6974206D657475732C2072686F6E6375732065742C20616C697175616D20636F6E7365637465747565722C20756C74726963696573206D616C6573756164612C206C6967756C612E205365642076656C6974206E69736C2C2073616769747469732076697461652C20706861726574726120612C20706F7375657265207365642C206D617373612E204E756C6C6120666163696C6973692E20496E207661726975732C206C6967756C61206964206C6F626F7274697320736F64616C65732C206175677565206F726369206665726D656E74756D2074656C6C75732C2065752070756C76696E6172207269737573206C6967756C6120612073617069656E2E204D6F726269206C616F7265657420697073756D206E6F6E206D692E204E616D20637572737573206C6F72656D207574206D692E20566976616D7573206D61676E6120656E696D2C20706F7375657265206E6F6E2C2073656D70657220717569732C20736F64616C65732065752C20617263752E20457469616D206D692070757275732C207072657469756D20666575676961742C20766172697573207365642C2070656C6C656E74657371756520656765742C206C6967756C612E20496E206C656F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E6563207669746165206F726369206575206F72636920736F6C6C696369747564696E20666575676961742E0A0A5072616573656E74207075727573206D617373612C20657569736D6F642076697461652C2074656D707573206E65632C20636F6E7365717561742068656E6472657269742C206D657475732E2041656E65616E2066656C6973206573742C20656765737461732076697461652C20616363756D73616E20656765742C2070656C6C656E74657371756520696E2C2073617069656E2E204475697320646170696275732070656465206E6F6E2073617069656E2E204E756E632075726E612E20496E74656765722076656C206C696265726F2E204475697320617567756520617263752C2064617069627573206E6F6E2C20666163696C697369732076697461652C20706F73756572652075742C2065726F732E20446F6E6563207669746165206E756E632073697420616D6574206172637520696D706572646965742064696374756D2E204D6F72626920656C656966656E642C206C6F72656D20657520636F6E73656374657475657220766573746962756C756D2C206469616D206E756E63206F726E61726520617263752C2061632074656D706F722066656C697320646F6C6F7220656765742065726F732E2050686173656C6C7573206D617373612073656D2C20736F6C6C696369747564696E2061632C20736F64616C657320677261766964612C206C756374757320612C207175616D2E204E616D206E65717565207175616D2C20766976657272612061742C2076656E656E6174697320717569732C207361676974746973206E6F6E2C20656E696D2E0A0A4E756C6C6120666163696C6973692E2050656C6C656E7465737175652065676573746173206C6163696E6961206573742E205365642074696E636964756E742C2070656465207365642074696E636964756E7420766573746962756C756D2C2075726E6120646F6C6F722061646970697363696E672070757275732C207669746165206672696E67696C6C612066656C697320656C697420696E206E6962682E204E756C6C6120736564206E6973692E204D6175726973207375736369706974207363656C6572697371756520617263752E20457469616D206E6F6E20656E696D2076656C2065726F7320616363756D73616E206D616C6573756164612E204E756E632074696E636964756E7420636F6D6D6F646F206D61757269732E20496E2074696E636964756E7420726973757320717569732075726E612E204E756C6C61206469616D20746F72746F722C20616C69717565742065742C2074696E636964756E7420717569732C20736F6C6C696369747564696E2061632C20746F72746F722E2043726173206E69736C206E657175652C2076756C7075746174652073757363697069742C206D6F6C657374696520717569732C2070756C76696E61722061742C206E756C6C612E204E756C6C616D206163206D65747573206E6563206F64696F20706F7375657265207661726975732E2043726173207365642070656465206E65632064756920706F737565726520626962656E64756D2E204475697320657569736D6F6420756C6C616D636F72706572206C696265726F2E20416C697175616D2066617563696275732070756C76696E6172207475727069732E0A0A496E207574206E65717565206964206E756E63206665756769617420636F6D6D6F646F2E20437572616269747572206469676E697373696D2C2066656C697320617420736F6C6C696369747564696E206C6163696E69612C20656E696D20656C6974207375736369706974206E657175652C20736564206C7563747573206C6F72656D20697073756D20696E206C656F2E204475697320646170696275732C206F64696F207175697320617563746F7220636F6D6D6F646F2C206E69736C206F64696F206D61747469732074656C6C75732C206E65632074696E636964756E7420747572706973206469616D20696E20617263752E2043757261626974757220612073656D2E204E756C6C616D20766F6C7574706174206D61676E612E2050656C6C656E7465737175652073616769747469732C206E6571756520636F6E736571756174207072657469756D206375727375732C20646F6C6F72206C6163757320636F6E73656374657475657220617263752C20736564206C616F72656574206573742075726E61206574206D657475732E2053757370656E646973736520706C6163657261742C20647569206120706F7274612074656D706F722C206C6F72656D20647569206C6F626F72746973206E657175652C207365642076656E656E61746973206469616D20656E696D2069642065726F732E20457469616D206574206E69736C206E6F6E206C656374757320666175636962757320636F6E7365637465747565722E204D6F726269207363656C657269737175652C2073656D206E65632074656D70757320756C6C616D636F727065722C20697073756D206469616D2066657567696174206C6F72656D2C2061206672696E67696C6C612073617069656E20656C69742071756973206E6962682E204E756C6C616D206469616D2075726E612C2076697665727261207365642C2070686172657472612072686F6E6375732C2074696E636964756E742076656C2C206F7263692E20496E746567657220616363756D73616E206D617474697320657261742E204E616D2064696374756D2E204D6175726973206E6563206C656F2E204E756C6C6120696163756C69732E204E756C6C61206E69736C206D692C206461706962757320717569732C207665686963756C6120612C2063757273757320656765742C206F64696F2E0A0A50686173656C6C7573206461706962757320657569736D6F64206E6962682E20566976616D757320696D7065726469657420616E746520696E206C6967756C612E2050656C6C656E74657371756520616363756D73616E2E20496E20696D706572646965742C20647569206120617563746F72206672696E67696C6C612C206D65747573206E6973692063757273757320646F6C6F722C2076656C206C7563747573206C6967756C61206C6F72656D207669746165206D61757269732E205072616573656E74206D617474697320766573746962756C756D20656C69742E20416C697175616D20656E696D206C616375732C2070756C76696E6172206E6F6E2C206C6163696E69612073697420616D65742C20656C656966656E64206E6F6E2C2076656C69742E20566573746962756C756D206163206C656F2E204D617572697320696D70657264696574206A7573746F206163206C65637475732E20536564206D6F6C6573746965206C656374757320736564206475692E20536564206665726D656E74756D2074656D707573206D61757269732E204E616D206F726E617265206F7263692061632074656C6C75732E205574206D616C6573756164612C206C61637573206964206C6163696E696120616363756D73616E2C206469616D20656C69742061646970697363696E67206D657475732C20657420626962656E64756D2073617069656E206E69626820626C616E646974206F7263692E2053757370656E646973736520697073756D2074656C6C75732C20736167697474697320717569732C20766573746962756C756D206E6F6E2C2076756C7075746174652065752C2065726F732E205072616573656E74206174206E756C6C612069642070656465207363656C6572697371756520756C747269636965732E204372617320626C616E646974207072657469756D2074656C6C75732E204D616563656E6173206461706962757320636F6E64696D656E74756D2061756775652E2050686173656C6C75732074696E636964756E74207068617265747261206C6F72656D2E204D6F726269206E6F6E2065726F732E205365642074656D706F722C206E69736C20612074696E636964756E742074696E636964756E742C2065726F73206469616D2064696374756D2073656D2C2076656C206469676E697373696D20616E7465206469616D20736564206D61676E612E205072616573656E74206E6F6E206C6967756C61206964206D65747573206D6F6C657374696520636F6E7365637465747565722E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E64697373652076656C206D692E2043757261626974757220616E7465206E756C6C612C2072757472756D20612C20636F6E76616C6C69732076656C2C207665686963756C612061632C206E756E632E204E756E632073616769747469732C20656E696D2073697420616D657420617563746F722072757472756D2C206D617572697320617263752076756C707574617465206E657175652C20657420657569736D6F64206573742066656C6973207175697320616E74652E20566573746962756C756D207475727069732074656C6C75732C2068656E64726572697420696E2C206C6163696E696120636F6D6D6F646F2C20756C6C616D636F7270657220677261766964612C2072697375732E204D61757269732072686F6E637573206C6163696E69612072697375732E204D616563656E617320736F6C6C696369747564696E2065726174207669746165206E756E632E205072616573656E74207072657469756D2070656C6C656E7465737175652061756775652E20446F6E656320696E74657264756D2E205072616573656E742061632065726F732076697461652065726174206C6F626F72746973206672696E67696C6C612E2041656E65616E20636F6E7365717561742074656C6C75732E204E756C6C6120616363756D73616E20626962656E64756D2066656C69732E204D616563656E6173207072657469756D20616E7465206964206E6973692E2041656E65616E206D6920617263752C2073656D706572207365642C206D61747469732065752C2076656E656E617469732073697420616D65742C20617263752E20446F6E656320616C697175657420657569736D6F64206C656F2E2050726F696E206D61676E61206A7573746F2C2074726973746971756520612C2073656D7065722061632C20736F6C6C696369747564696E20612C206C6967756C612E204D6F7262692076656C69742E20416C697175616D2076656C206E6973692E0A0A496E2061206C6F72656D207574206E756E63206665756769617420636F6E6775652E20446F6E6563206665726D656E74756D20626962656E64756D206475692E2050726F696E207661726975732065737420717569732076656C69742E20446F6E656320616C69717565742073656D20616363756D73616E206D692E2053656420706C6163657261742E204E756C6C616D206163206E6973692061206D61737361206C6F626F727469732073757363697069742E204E756E63206964206C656F2E20416C697175616D206574206D617373612E204E756C6C616D20766573746962756C756D20656C656D656E74756D206D657475732E20496E20636F6E736563746574756572206E6973692076656C206A7573746F2E204D616563656E6173206567657420707572757320736564206D61737361207661726975732070656C6C656E7465737175652E2050686173656C6C75732066617563696275732066656C697320717569732066656C69732E2041656E65616E206F64696F20617263752C20626C616E64697420717569732C20666163696C6973697320696E2C20696D706572646965742065752C206C6F72656D2E204E616D20706F73756572652070756C76696E6172206D692E204675736365207472697374697175652C206D617572697320657420636F6E73656374657475657220756C747269636965732C206D6175726973206C65637475732074656D706F72206A7573746F2C206174206672696E67696C6C61206573742065737420736564206E6973692E20517569737175652066617563696275732E2053656420696E20746F72746F722074696E636964756E7420657374206C6163696E696120696163756C69732E204D616563656E61732061206D617373612E2050656C6C656E7465737175652061206E69626820617420707572757320706F7274612068656E6472657269742E0A0A4E756C6C616D207475727069732E2046757363652061632073656D20736564206F64696F2070656C6C656E74657371756520696D706572646965742E2043757261626974757220696E20617263752E205072616573656E74206C61637573206C616375732C20666575676961742069642C2070756C76696E617220696E2C2074696E636964756E74207365642C206E657175652E204D616563656E61732076697665727261206F64696F206567657420746F72746F722E20496E746567657220616C697175616D2C206C6F72656D2072757472756D2076656E656E61746973206469676E697373696D2C206C6967756C61206D61676E61206D616C65737561646120617263752C2076656C2066657567696174206C6F72656D20697073756D2071756973206D617373612E204D6F72626920616E74652E20566573746962756C756D206D6175726973206C696265726F2C20756C6C616D636F7270657220717569732C20756C74726963657320717569732C20666163696C69736973206E6F6E2C206D617373612E204D616563656E617320696D706572646965742E20416C697175616D206572617420766F6C75747061742E2050656C6C656E746573717565206469676E697373696D2067726176696461206C65637475732E20496E206E696268206F64696F2C20617563746F7220656765742C206461706962757320717569732C206469676E697373696D2076656E656E617469732C20617263752E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20447569732070656C6C656E746573717565206C6967756C612071756973206D617373612E2043757261626974757220636F6E64696D656E74756D2C206A7573746F2065676574206F726E617265206C75637475732C206C6F72656D206C6967756C6120736167697474697320706564652C206120706F727461206E756E63206E756E6320696E206E657175652E20517569737175652066656C6973206D61757269732C20636F6E64696D656E74756D2076697461652C20617563746F722076697461652C2074696E636964756E7420717569732C20706564652E204E756E63206C6163696E696120616E746520696E206C656F2E2050656C6C656E746573717565206C696265726F2E2041656E65616E2061206C6967756C61206574206E756E6320766573746962756C756D20636F6E7365637465747565722E0A0A4675736365206F726E6172652E205072616573656E742069642075726E612E20496E74656765722076656E656E617469732C207175616D206E6F6E20736167697474697320616363756D73616E2C20616E7465206E6962682073616769747469732061756775652C20736F6C6C696369747564696E2061646970697363696E6720646F6C6F722076656C697420657520657261742E2050726F696E207175697320656E696D206575207075727573207665686963756C6120616C697175616D2E204E756C6C612076656C20656E696D2076656C20656C697420736F6C6C696369747564696E206672696E67696C6C612E20416C697175616D206572617420766F6C75747061742E205365642073757363697069742066656C6973207574207475727069732E20457469616D2072757472756D20726973757320696D70657264696574206573742E20416C697175616D20612074656C6C75732061742074656C6C757320636F6D6D6F646F20646170696275732E204D61757269732072757472756D206D61676E61206574206F64696F2E20496E20617420646F6C6F722E20437572616269747572207665686963756C61206C656374757320696E20746F72746F722E204675736365206A7573746F2070757275732C206C75637475732076697461652C206D6F6C6C697320696E2C2070686172657472612061632C2070757275732E204E756C6C616D20706F737565726520696E74657264756D206A7573746F2E20437572616269747572207669746165206C616375732076656C206C656F20636F6E6775652070756C76696E61722E0A0A41656E65616E20656C656966656E64206E6962682076617269757320746F72746F722E2053757370656E64697373652076656C2065726F732E2050726F696E206E6563206469616D206120746F72746F7220756C747269636573206F726E6172652E20416C697175616D207363656C657269737175652066657567696174206A7573746F2E20566976616D757320616E74652075726E612C2061646970697363696E672076697461652C20706F72747469746F722065752C20736F64616C65732065742C2066656C69732E2053757370656E646973736520706F74656E74692E20437572616269747572206163206D6173736120696E206E69736C207361676974746973206D6F6C6C69732E204E616D207175616D206C6967756C612C20636F6E73656374657475657220656765742C20696163756C69732061742C207661726975732065752C206C656F2E204475697320646F6C6F72206C6967756C612C2074696E636964756E742061742C20756C6C616D636F72706572207365642C20616363756D73616E20616C697175616D2C206C6967756C612E2050686173656C6C75732076756C7075746174652C206C6F72656D2061742074696E636964756E742070686172657472612C207269737573206C6563747573206C6163696E6961206D61676E612C20717569732072757472756D20656E696D206D61676E612061742073656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E20447569732069642073656D2061206D617572697320736F6C6C696369747564696E2074696E636964756E742E20457469616D2065752070757275732065752061726375206672696E67696C6C612061646970697363696E672E20566976616D7573206F726E6172652074656D707573206469616D2E2050726F696E20747572706973207175616D2C206C6163696E6961206E6F6E2C20656765737461732061742C20636F6D6D6F646F20656765742C20706564652E205072616573656E742076756C70757461746520726973757320696E206573742E204E756C6C6120666163696C6973692E0A0A557420656C656D656E74756D206C6163696E69612070757275732E2050726F696E2076697461652061726375206163206E756C6C6120636F6E76616C6C697320616C697175616D2E204E756C6C6120636F6E6775652C206C696265726F2069642070656C6C656E746573717565206D61747469732C207175616D206C656374757320706F72747469746F72206469616D2C2061207363656C6572697371756520647569206C696265726F20696E2073617069656E2E204E756C6C616D2066656C6973206469616D2C207665686963756C612076656C2C206D6F6C65737469652075742C20766573746962756C756D20616C697175616D2C2073617069656E2E20446F6E656320636F6E76616C6C69732C2065737420757420656C656D656E74756D20766F6C75747061742C206D617572697320697073756D20677261766964612073656D2C20636F6D6D6F646F20666163696C697369732073617069656E206C65637475732073656D706572206C65637475732E205175697371756520706F72747469746F722065726F73207574206E6962682E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20457469616D206D617474697320726973757320736564206F64696F2E20566573746962756C756D206574206F64696F2E20496E206861632068616269746173736520706C617465612064696374756D73742E204E616D20747269737469717565206D61737361207574206C6967756C612E2051756973717565206E6962682074656C6C75732C207665686963756C612073697420616D65742C2061646970697363696E672061742C20636F6E76616C6C6973206E65632C206C6967756C612E20566573746962756C756D207072657469756D2C206D69206E6563206672696E67696C6C6120626962656E64756D2C20647569206E756E6320736F64616C657320706564652C20612073656D706572206D61676E61206E696268206E6F6E206469616D2E20446F6E6563206D61737361206E756E632C20766976657272612076656C2C20636F6E73656374657475657220706F7274612C2064617069627573206E6F6E2C20697073756D2E2044756973206E69736C206D61757269732C206375727375732076656C2C2073656D706572206E6F6E2C20736F6C6C696369747564696E20626962656E64756D2C2066656C69732E20566573746962756C756D206575206E657175652E0A0A43726173206E656320646F6C6F722E20446F6E6563206C616F726565742074656D707573206C65637475732E20437261732073656420746F72746F7220696E74657264756D206C6163757320656C656966656E64206469676E697373696D2E204D616563656E61732073697420616D657420656C69742E204E756C6C616D207175697320646F6C6F722076656C20647569207068617265747261206C75637475732E20496E2073697420616D6574207175616D2073697420616D6574207065646520756C74726963657320756C7472696365732E204D616563656E6173206469616D2E20496E74656765722075726E612E204375726162697475722064696374756D2C2076656C69742073656420706C6163657261742073757363697069742C206572617420747572706973206665726D656E74756D206A7573746F2C2073656420696E74657264756D206E657175652073656D206574206E6962682E20566976616D757320636F6E73657175617420636F6E76616C6C6973206D61676E612E204E616D20616C697175616D2C2065737420616320626962656E64756D20636F6D6D6F646F2C206D61676E61206573742064696374756D206D692C207669746165206D616C65737561646120656C6974206D61676E61207669746165206F64696F2E204D616563656E61732074656D706F722076756C7075746174652074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206475692E20457469616D20616363756D73616E207065646520636F6E67756520746F72746F722E0A0A4D6F7262692074656D706F72206C696265726F206163206C6F72656D2E20496E20616C697175657420766172697573206D61676E612E20496E20617263752E2050686173656C6C7573206F64696F2E2046757363652074696E636964756E7420616C69717565742066656C69732E20517569737175652076656C69742E20536564206C75637475732E20416C697175616D2066657567696174206672696E67696C6C61206D692E20416C697175616D206D6F6C657374696520766976657272612072697375732E2050726F696E20617263752E20566573746962756C756D206C6F626F727469732074656D707573206E6973692E205072616573656E742061206172637520696E2076656C697420766976657272612072757472756D2E0A0A496E20736564206C65637475732E20446F6E656320726973757320646F6C6F722C20626C616E6469742073697420616D65742C20656C656D656E74756D20636F6E76616C6C69732C20706861726574726120717569732C20706564652E20496E7465676572206F726E6172652E2041656E65616E20656765737461732064617069627573206A7573746F2E20536564207175616D206C656F2C20706F73756572652061742C20656C656D656E74756D2076697461652C20636F6D6D6F646F20656765742C206573742E20416C697175616D206D6F6C65737469652072686F6E63757320656E696D2E2043757261626974757220696163756C697320756C74726963657320706564652E204D6F72626920616C69717565742072757472756D206C616375732E20416C697175616D207175616D2E2053656420636F6D6D6F646F2C2074757270697320696E20706861726574726120706F73756572652C206D6920726973757320696D7065726469657420657261742C206120766573746962756C756D206D617373612074656C6C7573207665686963756C612073656D2E204D6175726973206672696E67696C6C6120756C747269636573206E756E632E204E616D206E69736920656E696D2C20656C656966656E642073697420616D65742C20756C747269636573207365642C206665726D656E74756D206E6F6E2C2061756775652E2050726F696E20636F6E677565206C6F626F72746973206E6973692E204D616563656E61732068656E6472657269742E204E616D20736564206E69736C2E204E756E6320656C656D656E74756D206F64696F2065752072697375732E20496E206D657475732E2050686173656C6C75732067726176696461207072657469756D206C6967756C612E204E756C6C61207669746165206E657175652E204E616D206E69736920746F72746F722C206F726E617265206E6F6E2C20626C616E6469742061742C206375727375732065752C20746F72746F722E0A0A4475697320626962656E64756D20697073756D20696E206E756E6320637572737573206D6F6C65737469652E204E756E63206F7263692E204E756C6C616D206E656320616E7465206E6F6E20657374206469676E697373696D20766976657272612E204D617572697320626C616E6469742C2076656C69742069642066657567696174207072657469756D2C20656C6974206D61676E612070656C6C656E74657371756520646F6C6F722C206174207361676974746973206C616375732076656C69742065676573746173206D61676E612E2050656C6C656E746573717565206375727375732C206469616D20636F6E736563746574756572207361676974746973206672696E67696C6C612C20746F72746F72206E6973692061646970697363696E67206E756E632C20657520766172697573206C6163757320726973757320616320656C69742E204D6175726973206964206E6973692071756973206C656F20657569736D6F642076656E656E617469732E2050656C6C656E74657371756520616320616E74652E204D617572697320617263752073617069656E2C2074656D706F722061742C20706F72747469746F722069642C20636F6E64696D656E74756D2075742C206475692E20457469616D206665726D656E74756D20756C747269636965732061756775652E20437261732075742065726F73206174206A7573746F20756C7472696369657320696163756C69732E2044756973206469676E697373696D2C206E69736C20657420666163696C69736973206665726D656E74756D2C2065726174207075727573206D6F6C65737469652074656C6C75732C20717569732074656D70757320697073756D206C656374757320617420656C69742E204E756C6C61207669746165206C6F72656D2E0A0A41656E65616E2076656C2073656D206574206469616D2073656D70657220636F6E6775652E20496E20626962656E64756D206469616D20717569732074656C6C75732E204E756E6320666163696C6973697320756C74726963696573206E6962682E2043726173206E756E6320656E696D2C2066657567696174207365642C20756C7472696365732076697461652C2073616769747469732076697461652C20697073756D2E204675736365207669746165206E756C6C612E20446F6E65632070656C6C656E7465737175652C2076656C697420696E20706F72747469746F7220656C656966656E642C20657374206E65717565206C6F626F727469732076656C69742C2073697420616D65742072757472756D20616E746520746F72746F72206E656320646F6C6F722E20446F6E6563207665686963756C612E204E756C6C6120666163696C6973692E20536564206567657374617320756C747269636573206E6962682E20446F6E656320656C6974206C65637475732C20636F6E76616C6C697320706F72747469746F722C20616C697175657420646170696275732C206665756769617420656765742C206C6967756C612E2053656420636F6E736563746574756572206A7573746F2E204D616563656E617320612073617069656E2073697420616D6574206E6973692064617069627573206C6F626F727469732E20566976616D7573206C7563747573206C6F72656D206E6F6E206E756C6C612E2053656420656765742065726174207669746165206C696265726F20696E74657264756D20706F73756572652E20437261732070756C76696E61722E204E756C6C616D20696D706572646965742C20646F6C6F722074656D706F72206469676E697373696D20626C616E6469742C206475692073617069656E2072686F6E637573206E657175652C206964206D616C657375616461206175677565206D61676E612073697420616D65742075726E612E204475697320736564206D61757269732E0A0A4D6F72626920616363756D73616E2E20536564206D61757269732061756775652C206672696E67696C6C61206E6F6E2C20617563746F722075742C20617563746F722065742C206F7263692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320757420706564652E20446F6E6563207669766572726120656E696D2076656C206C6F72656D2E2050656C6C656E746573717565206E65717565206D61757269732C20696E74657264756D2065752C2076656E656E617469732069642C20636F6E64696D656E74756D2065752C2073617069656E2E20446F6E656320697073756D20617263752C206C6163696E69612061646970697363696E672C206C616F726565742065742C206375727375732076656C2C2076656C69742E205574207361676974746973206D617572697320717569732072697375732E20496E7465676572206575206F64696F207669746165206C61637573207669766572726120616363756D73616E2E204D6F726269206C656F20616E74652C206469676E697373696D207365642C2076617269757320717569732C20766F6C75747061742076697461652C206E6973692E204E756C6C6120706C61636572617420696E74657264756D20656C69742E20446F6E6563206E65717565206475692C2073616769747469732076697461652C20736F6C6C696369747564696E20717569732C20636F6D6D6F646F2076697461652C206E657175652E204E756C6C612071756973206C6967756C61206F726E617265206C6967756C612064696374756D206F726E6172652E204D61757269732072757472756D2072757472756D206E657175652E2041656E65616E207665686963756C612074656D707573206573742E20446F6E656320766172697573207363656C6572697371756520706564652E20446F6E656320706C6163657261742076756C707574617465206C656F2E204E756C6C616D206E756E63206E69736C2C20706F7375657265206E6F6E2C20666575676961742076697461652C2070656C6C656E74657371756520717569732C206D61757269732E20496E20647569206E657175652C2063757273757320656765742C20736167697474697320656765742C20646170696275732076697461652C206D692E2050726F696E2065676574206573742E0A0A467573636520706F727461206573742E204D6175726973206D61676E612E20416C697175616D20697073756D206C616375732C20756C747269636965732069642C20766573746962756C756D206C75637475732C20616363756D73616E2075742C20616E74652E20536564206D61757269732E205365642061646970697363696E67206C656F2073697420616D6574206D61676E612E2053757370656E646973736520706F74656E74692E204E756E63206D6173736120656C69742C206672696E67696C6C6120656765742C20656765737461732076697461652C206C75637475732076697461652C20646F6C6F722E2050686173656C6C75732071756973206E756C6C61206575206E69736920696E74657264756D20736F6C6C696369747564696E2E204E756C6C616D2069642074656C6C75732E20496E746567657220696163756C697320646F6C6F722061632070757275732E205365642076656C206D692E20437572616269747572206E6F6E206D61676E612073697420616D6574206A7573746F20636F6E64696D656E74756D2076756C7075746174652E20517569737175652074696E636964756E742070656465206575206E69736C2E20566976616D7573206C6F626F727469732E204E756E63206D65747573206D657475732C20636F6E677565207365642C2074696E636964756E74207365642C207072657469756D2061742C206F64696F2E20446F6E6563206120617263752E20496E2073656D206A7573746F2C207665686963756C61207365642C207661726975732069642C20766F6C75747061742061742C2072697375732E205072616573656E7420696163756C6973206D617373612E20496E206172637520656C69742C2068656E64726572697420656765742C20756C6C616D636F7270657220696E2C20706F7274612069642C2074656C6C75732E20446F6E65632073616769747469732068656E647265726974206469616D2E0A0A53757370656E646973736520706F74656E74692E20536564206574206469616D206574206175677565207361676974746973206C6F626F727469732E2050686173656C6C757320646F6C6F722E2055742065742061726375206567657420616E74652074656D706F7220706F73756572652E20416C697175616D206665726D656E74756D207363656C65726973717565206475692E204D61757269732061742070757275732E20446F6E656320657261742073656D2C20766573746962756C756D206E65632C2066617563696275732061632C206D617474697320612C206C656F2E2053757370656E64697373652061646970697363696E67206C6163696E69612073656D2E204E756C6C616D206F72636920617263752C2064696374756D2065742C20666175636962757320766976657272612C20646170696275732065742C206E657175652E2043726173206E756E63206469616D2C2061646970697363696E67206E6F6E2C20736F6C6C696369747564696E20696E2C20696E74657264756D2076656C2C206D617373612E204D61757269732073616769747469732C206A7573746F206174207472697374697175652074656D7075732C206D6175726973206D617572697320616C697175616D20616E74652C2073697420616D657420706F7375657265206469616D206475692065676574206C6967756C612E20496E206469676E697373696D2C206E69736C207574206C6163696E696120636F6E64696D656E74756D2C2065726174206A7573746F20706F72747469746F72206E756C6C612C206E6F6E2067726176696461206C6967756C61206D61676E612065676574206D617373612E20566573746962756C756D207669746165206C6967756C61206174206D6920766573746962756C756D2073757363697069742E2044756973206C616F726565742E204E756C6C6120636F6D6D6F646F206C696265726F2073697420616D6574206C6F72656D2E20557420656C656D656E74756D2073656D2E20496E74656765722076656C20646F6C6F722E204E616D20666163696C69736973206D6920717569732073656D20756C7472696365732073616769747469732E205365642071756973207175616D206174206D65747573206D6F6C657374696520626962656E64756D2E0A0A50726F696E2064756920656E696D2C206C6163696E696120612C20666575676961742061632C20706C6163657261742076697461652C20706564652E205175697371756520656765737461732C206C656F206567657420616C697175616D207072657469756D2C206C696265726F206A7573746F2074696E636964756E742065726F732C2075742065676573746173206175677565207065646520656C656D656E74756D206E6962682E20437572616269747572206D6F6C6C697320736F64616C657320656E696D2E20446F6E65632061756775652E2050686173656C6C757320696420697073756D20706F737565726520647569207072657469756D2066617563696275732E204D6175726973206C756374757320616E74652073656D706572206E69736920696E74657264756D2061646970697363696E672E204475697320646170696275732C206F64696F207175697320766976657272612072686F6E6375732C206A7573746F207175616D20626962656E64756D20646F6C6F722C20696420646170696275732076656C697420657261742076656C20657261742E2046757363652073697420616D6574206E69736C2076656E656E61746973207175616D20756C74726963657320636F6E64696D656E74756D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632072686F6E637573207363656C65726973717565206C6967756C612E20566573746962756C756D206D69206F64696F2C20616363756D73616E2065742C2061646970697363696E6720656765742C206F726E6172652075742C207175616D2E204E756C6C616D20626C616E646974206D6F6C6573746965206D61757269732E20437572616269747572206469676E697373696D206D6175726973206574206C6F72656D2E2053757370656E64697373652061206A7573746F2E204E616D206D617474697320666175636962757320617263752E204475697320626C616E64697420656E696D206E6F6E206D617373612E0A0A4E756C6C616D206C6F72656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E204D617572697320636F6E73656374657475657220706F7375657265206D61757269732E204D616563656E61732074696E636964756E74206D617572697320696E2065726F732E204E756C6C61206575206D65747573206575206F72636920736F6C6C696369747564696E2066617563696275732E2053757370656E646973736520616C697175616D206D6175726973206964206573742E204372617320626C616E646974206475692065742075726E612E204E756C6C6120617263752E2053656420612075726E612E204E756C6C612064617069627573207665686963756C6120746F72746F722E20446F6E65632072697375732E20536564207175616D206D657475732C20656765737461732065752C206375727375732075742C2076697665727261206E6F6E2C206F64696F2E205574206A7573746F206A7573746F2C206D616C6573756164612073697420616D65742C20626C616E6469742073757363697069742C206D6F6C657374696520696E2C206A7573746F2E20566573746962756C756D20636F6E7365717561742C207175616D20616320666575676961742074696E636964756E742C20697073756D206C696265726F20656C656966656E64206F64696F2C206E6F6E20656C656966656E64207065646520697073756D206E6F6E20616E74652E204E756C6C616D2061206D657475732E0A0A4E616D206163206E6973692061742066656C697320637572737573206D61747469732E2050656C6C656E74657371756520636F6E7365717561742073656D2071756973206F7263692E20517569737175652074656D7075732E2041656E65616E20696D70657264696574206D6F6C657374696520706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652065752074656C6C75732E204E756C6C61206469616D2065726F732C20736F64616C65732075742C20736F64616C6573206E65632C2074696E636964756E742061632C206E756E632E204E756E63206C6163696E696120666175636962757320697073756D2E20566976616D75732076656C206E6571756520696E2065726174206665726D656E74756D206C75637475732E204E756C6C612065676574206D65747573206E656320617567756520626962656E64756D20706C6163657261742E20566976616D75732074656D7075732E205072616573656E7420636F6E677565206F726E61726520697073756D2E20457469616D206D61747469732066657567696174206A7573746F2E0A0A416C697175616D206475692E2041656E65616E20636F6D6D6F646F20746F72746F72207669746165206E756C6C612E204D6F72626920657420697073756D2E204D617572697320616320697073756D2E204E616D2076656C207269737573207574206C6563747573206D6F6C6C697320766976657272612E2043757261626974757220656C656D656E74756D206D6F6C6C6973206573742E204E756C6C616D20656C69742E20566573746962756C756D207375736369706974207072657469756D20656E696D2E20566573746962756C756D207574206D617373612E2050726F696E206E65632066656C69732E204D616563656E617320677261766964612C2061726375206E656320636F6E7365717561742073616769747469732C2065726F732074656C6C7573207363656C65726973717565206D61757269732C20766974616520616363756D73616E207175616D207175616D207574206E756E632E20496E7465676572206567657420616E74652065752076656C6974206C616F72656574206D616C6573756164612E204E756E632073616769747469732C206D617572697320766974616520706861726574726120766F6C75747061742C2074656C6C75732074656C6C757320656C656966656E642065726F732C2073697420616D65742072757472756D20697073756D206E69736920612076656C69742E205072616573656E7420766172697573206C656F20657520657261742E20566976616D757320636F6E73657175617420706C6163657261742070757275732E20446F6E6563207072657469756D20656C656D656E74756D206E6962682E2050726F696E20617420656C6974206E6F6E2073656D20616C6971756574206D61747469732E2053656420756C6C616D636F7270657220697073756D2073697420616D657420656C69742E0A0A4D617572697320696E206D657475732E2053757370656E6469737365206D61676E61206C6F72656D2C2066617563696275732076656C2C2074696E636964756E7420717569732C207363656C65726973717565206E6F6E2C2074656C6C75732E2046757363652071756973206C6F72656D2E2050726F696E2061206C616375732073697420616D6574206D617572697320696163756C69732070756C76696E61722E2053757370656E64697373652072686F6E6375732065726F73206E6563206D692E205072616573656E7420657569736D6F642C207475727069732076697461652072757472756D207072657469756D2C206F64696F206D6574757320766F6C7574706174206E657175652C20656765742074656D7075732073617069656E206E657175652073656420657261742E20446F6E6563206665726D656E74756D207075727573206174206C65637475732E204E756C6C616D2073656D2E2046757363652076656C206D6920717569732065726174206C6F626F7274697320706F73756572652E2041656E65616E20656765742075726E612E2053757370656E6469737365206C6967756C612E204475697320696E206E6973692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A4375726162697475722076756C707574617465206C656374757320696420706564652E2050686173656C6C75732065752076656C69742E20457469616D2076656E656E617469732061646970697363696E67206E6962682E20416C697175616D206375727375732070756C76696E61722074656C6C75732E20566573746962756C756D206E657175652E204D6175726973206E6563206A7573746F20657420657261742073656D7065722070656C6C656E7465737175652E204675736365206D61747469732064696374756D20646F6C6F722E20457469616D2065676574207075727573206575206D617373612076617269757320656C656D656E74756D2E2050656C6C656E746573717565206D617373612E20557420756C74726963696573206469616D2073656420697073756D2E204E756C6C616D206469616D2E2050656C6C656E746573717565206964206D61676E61206964206C696265726F2074726973746971756520616C697175616D2E0A0A557420656C656966656E642C20707572757320696420706C6163657261742076656E656E617469732C2075726E6120617567756520616C6971756574206C6967756C612C20696E20756C74726963696573206C656F2072697375732065742074656C6C75732E204D6175726973206574206E756C6C612069642075726E61207472697374697175652074656D7075732E20557420666163696C697369732C2075726E6120657520766573746962756C756D2072686F6E6375732C206C616375732065726F7320636F6E736563746574756572206D657475732C2065742072757472756D20647569206C656374757320696E2070757275732E204E756E632076656C206E69736C206E6F6E20697073756D2074696E636964756E74206D6F6C6C69732E204E616D207175616D206C616375732C206F726E6172652076697461652C2072686F6E637573206E6F6E2C20636F6E677565207365642C206F64696F2E2050726F696E206E696268206475692C20706F7274612076656C2C2076656E656E61746973206E6F6E2C2070656C6C656E7465737175652075742C206E6973692E20536564207472697374697175652066656C69732061206D61676E612E2053757370656E646973736520656765742074656C6C75732E2043726173206772617669646120696D706572646965742076656C69742E20496E74656765722068656E6472657269742072697375732E2050726F696E206F7263692E20416C697175616D20756C6C616D636F72706572206D61757269732071756973206D61757269732E204E756E63206C6163696E696120766573746962756C756D206D657475732E20447569732074656C6C75732E204E756C6C616D2066617563696275732C206C656F2061632076756C70757461746520736F6C6C696369747564696E2C206C656F20646F6C6F7220666175636962757320657261742C207175697320626962656E64756D206F726369206F64696F206E6F6E20617263752E0A0A4E756C6C616D20616363756D73616E206D617474697320646F6C6F722E20446F6E6563206574206475692E205072616573656E7420612066656C6973206D6F6C6C6973206C616375732073656D706572206C6163696E69612E204375726162697475722070656C6C656E746573717565206C7563747573206573742E2050726F696E206E756C6C61206475692C20636F6E64696D656E74756D2076656C2C206661756369627573206E6F6E2C20696E74657264756D2061632C20657261742E204D616563656E6173207363656C657269737175652C206C656374757320696420766F6C757470617420616363756D73616E2C2073617069656E20746F72746F722070656C6C656E746573717565206475692C207365642073656D706572206D61676E612073656D207574206C656F2E2050726F696E206E756C6C612E204E756C6C616D206461706962757320756C6C616D636F727065722073656D2E2053757370656E6469737365207665686963756C61206D6574757320696E206E756E632E2050656C6C656E746573717565206E6F6E207175616D2076656C206172637520756C74726963657320756C6C616D636F727065722E2050686173656C6C757320717569732066656C69732073697420616D65742074656C6C757320756C6C616D636F72706572206665726D656E74756D2E20536564207665686963756C6120736F6C6C696369747564696E2075726E612E20437572616269747572207068617265747261207363656C657269737175652072697375732E2050656C6C656E746573717565206964206D617373612071756973206D6574757320616C697175616D20696D706572646965742E20496E206E756E63206C616375732C206665756769617420696E2C206772617669646120656765742C2076656E656E617469732075742C2074656C6C75732E2053757370656E646973736520706F74656E74692E204E616D20636F6E7365717561742061646970697363696E67206475692E20496E206E756C6C61206E6973692C20666575676961742075742C206665726D656E74756D2076656C2C2067726176696461206E65632C20746F72746F722E20496E207365642061756775652E0A0A457469616D20756C6C616D636F7270657220617567756520617420656E696D2E20496E7465676572206469676E697373696D2E20416C697175616D2070756C76696E617220636F6E677565206E756C6C612E204D6F72626920656E696D206D617373612C206672696E67696C6C6120612C20616363756D73616E20656765742C20636F6E64696D656E74756D206E65632C20657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2041656E65616E2070686172657472612E20457469616D20706F72747469746F722070757275732061206D657475732E20416C697175616D20696E74657264756D2073656D2065676574206A7573746F2E205175697371756520766F6C7574706174206C7563747573206573742E2041656E65616E2061756775652E2050686173656C6C757320647569206C65637475732C20756C747269636573206E65632C20636F6D6D6F646F2076656C2C20617563746F722076656C2C206E6973692E20557420756C7472696365732070656C6C656E746573717565206E6973692E20496E74656765722061632076656C69742065742073656D20696D70657264696574206C75637475732E20467573636520766974616520747572706973206964206175677565206D6F6C6C697320636F6E7365637465747565722E0A0A4D616563656E6173206E6563206C616375732E204D616563656E617320636F6E64696D656E74756D206F64696F2065752066656C69732E204D6175726973207574206E69736C207669766572726120657261742066617563696275732061646970697363696E672E20457469616D20656765737461732E204E756E6320657420646F6C6F72207669746165207269737573206469676E697373696D20636F6D6D6F646F2E204D6F726269206C65637475732076656C69742C2074696E636964756E74206E65632C20616C69717565742076656C2C206D61747469732076697461652C206C6967756C612E204D616563656E617320756C747269636965732073656D70657220646F6C6F722E2053757370656E6469737365206D616C6573756164612E20496E7465676572206D617474697320656C69742E20446F6E656320616363756D73616E2C206C6163757320666163696C69736973207661726975732074656D7075732C206E756C6C6120656C697420706F72746120657261742C2065742072757472756D20656C69742073656D2073697420616D6574206475692E0A0A4D616563656E6173206D6F6C6C6973206D69206E6F6E206E756C6C612E20566976616D7573207475727069732E2053757370656E64697373652061206D657475732E20496E2071756973206D6920696E2074757270697320636F6E67756520617563746F722E204D616563656E6173206C616375732E2053757370656E646973736520736F6C6C696369747564696E2E2050686173656C6C757320706F727461206E756E63206E6F6E206E69736C2070756C76696E617220656765737461732E20536564206E756C6C612E20566573746962756C756D206163206D692E204D617572697320756C7472696369657320636F6E64696D656E74756D206E657175652E204E756C6C612074656D707573206A7573746F2076656C206D617373612E204E756C6C6120737573636970697420636F6E67756520617263752E205072616573656E74206964207475727069732E204D6175726973206E69626820706564652C20657569736D6F642073656D7065722C206D6F6C65737469652061632C2072686F6E6375732076697461652C20616E74652E204D616563656E617320657261742066656C69732C207669766572726120736F6C6C696369747564696E2C20736167697474697320656765742C2070656C6C656E746573717565206E65632C206F7263692E20467573636520756C74726963657320636F6E736571756174206C616375732E20416C697175616D2065726174206D61676E612C20666575676961742061742C207669766572726120612C206D6F6C6C6973206E6F6E2C207475727069732E0A0A446F6E6563206D692E204E616D2064696374756D2070656C6C656E7465737175652073656D2E20446F6E6563206D6F6C6C69732072686F6E63757320656C69742E2050686173656C6C75732072686F6E63757320706564652073697420616D65742072697375732E20446F6E656320656765742061756775652E204D616563656E6173206E6F6E206C65637475732E2050686173656C6C757320736F6C6C696369747564696E206E697369206E65632066656C69732E20416C697175616D207072657469756D2C2065737420656765742073656D70657220636F6E76616C6C69732C206E696268206E756E6320736F6C6C696369747564696E2070757275732C2069642074656D706F722070656465206475692076656C206D61676E612E20566976616D7573206163206C6F72656D2E20457469616D206E69736C20746F72746F722C2061646970697363696E672064696374756D2C20656C656D656E74756D20696E2C20666163696C69736973207365642C206E6962682E2050726F696E206D61757269732E2050726F696E2072757472756D206D6173736120656765742073656D2E204375726162697475722074656D706F722061646970697363696E6720656C69742E204375726162697475722070757275732074656C6C75732C206665726D656E74756D20656765742C20616C69717565742076697461652C20636F6E76616C6C69732061632C206D61757269732E0A0A496E746567657220636F6E7365717561742076656C69742065752065726F732074696E636964756E74207665686963756C612E204E756C6C616D206C6F72656D2073617069656E2C2072686F6E637573206E6F6E2C206D617474697320717569732C20756C747269636965732073697420616D65742C20656E696D2E2043757261626974757220636F6D6D6F646F2C206C696265726F20696E20657569736D6F642073757363697069742C2073656D207075727573206672696E67696C6C6120656E696D2C206163206D6F6C657374696520746F72746F72206F7263692065742076656C69742E20446F6E656320706564652E20457469616D20706C61636572617420636F6E64696D656E74756D207475727069732E2050686173656C6C7573206567657374617320656E696D206E6563206D61676E612E20566976616D757320636F6E64696D656E74756D2C206E756C6C612076656C206C7563747573207472697374697175652C2065726F7320726973757320766573746962756C756D206E756C6C612C20696E207665686963756C61206172637520697073756D2061742066656C69732E20446F6E656320616C697175616D20656C69742061742061756775652E205175697371756520612065726F73206575206C6967756C6120616363756D73616E2064696374756D2E20457469616D207665686963756C61207475727069732071756973206C696265726F2E20416C697175616D206E6F6E206D692E20446F6E6563206574206C656F2E2050726F696E206C656F206C696265726F2C20616C697175616D2074696E636964756E742C20636F6E677565206E65632C2061646970697363696E6720706F7274612C20656E696D2E204E756C6C61206C6F626F727469732C20746F72746F722073697420616D657420696D7065726469657420756C6C616D636F727065722C20646F6C6F72206F726369206D616C65737561646120706564652C207365642067726176696461206E6962682075726E612076656C206C6F72656D2E20536564207068617265747261206D616C6573756164612065726F732E205175697371756520657569736D6F6420616C697175657420657261742E2053757370656E646973736520616C6971756574206D61747469732070757275732E0A0A4E756E63206964206E756C6C612071756973206A7573746F20636F6E67756520736F6C6C696369747564696E2E205072616573656E742065726174207475727069732C2072686F6E6375732065752C207072657469756D2065752C2070656C6C656E74657371756520612C206E6962682E20566976616D75732074656D7075732E2043726173206E65632072697375732061742074757270697320696D70657264696574206C6F626F727469732E205574206D61747469732E204D616563656E6173206573742066656C69732C2070656C6C656E746573717565206E6F6E2C20696D70657264696574207365642C20656C656966656E642074696E636964756E742C206C6F72656D2E20496E2074696E636964756E742E205365642076656C206C656F2E20446F6E65632065742075726E6120696E207475727069732068656E64726572697420626C616E6469742E20446F6E656320636F6E64696D656E74756D20616363756D73616E206573742E2055742070686172657472612C206D65747573207669746165206D617474697320636F6E7365637465747565722C206C656F207175616D2076756C707574617465206F64696F2C206E6563206C616F72656574206E6973692076656C697420657520657261742E20496E7465676572206C65637475732061756775652C206567657374617320696E2C20696E74657264756D2065752C2076656E656E617469732076656C2C2073617069656E2E2051756973717565206574206573742076697461652065726F73206C616F72656574206C6F626F727469732E204E756C6C616D207574207269737573206E6F6E206E756C6C6120706C6163657261742061646970697363696E672E205072616573656E7420646170696275732E20457469616D20612066656C69732E20557420736F64616C657320636F6E736571756174206D61757269732E2044756973206C6F72656D2066656C69732C206C756374757320612C2074726973746971756520696E2C206D6F6C65737469652061742C2072697375732E20536564207665686963756C6120626962656E64756D2074656C6C75732E204E616D20636F6E73657175617420657569736D6F64206C616375732E0A0A41656E65616E20746F72746F7220656C69742C2067726176696461206E65632C206665726D656E74756D2065752C206C6F626F727469732069642C20697073756D2E204D616563656E61732065752070757275732E204372617320616320747572706973207574206E69736920696163756C69732072686F6E6375732E204E756C6C61207075727573206D657475732C206469676E697373696D206E65632C2074696E636964756E742076697461652C20646170696275732065752C206E6962682E204675736365206C6F626F727469732C206E756E63206174207669766572726120656C656966656E642C206A7573746F20747572706973207363656C657269737175652065726F732C2061632070656C6C656E746573717565206D65747573206E69736C2061742070757275732E2053656420656C656D656E74756D2074656C6C75732073656420656E696D20696E74657264756D20626C616E6469742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E746567657220756C7472696369657320616C6971756574206F64696F2E204D61757269732065676574206E756E63206120697073756D20756C74726963657320736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2041656E65616E20616363756D73616E2E20446F6E65632073617069656E206C65637475732C20636F6E6775652061742C20706F7274612069642C2068656E6472657269742076697461652C206E69736C2E204375726162697475722076656C207175616D2076656C206E6571756520616363756D73616E206C616F726565742E204D6F7262692073617069656E206573742C207072657469756D20696E2C20636F6E7365637465747565722061632C206D6F6C6C69732075742C206C696265726F2E20446F6E65632074696E636964756E742061646970697363696E67206D657475732E204E756E6320766573746962756C756D20656765737461732061756775652E20446F6E6563207363656C65726973717565206475692075742073656D2E2053757370656E64697373652076656C206D6574757320696420657374206D6F6C657374696520696163756C69732E0A0A566976616D75732070686172657472612C20656C6974206575206D616C65737561646120626C616E6469742C206469616D20746F72746F72206D6F6C6C6973206475692C207365642070756C76696E6172206D61737361206E756E63206574206D61676E612E2053656420706C61636572617420656C697420617563746F7220746F72746F722E204E756C6C6120616320657261742E2050656C6C656E74657371756520636F6E7365637465747565722C2064756920636F6E76616C6C69732074696E636964756E7420636F6E64696D656E74756D2C2073656D206F64696F20766F6C7574706174206C696265726F2C206E6F6E20656C656D656E74756D2066656C6973206E65717565206E6563206F64696F2E204D616563656E61732068656E6472657269742065726F73206964206469616D2E204D61757269732076656C207075727573206163206F72636920636F6E76616C6C697320636F6E76616C6C69732E205365642073697420616D6574206C616375732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652064696374756D20766172697573206C616375732E204D61757269732065676574206E69736C2E2053757370656E646973736520706C6163657261742C206E756C6C61206E6F6E206F726E617265206469676E697373696D2C206E69736C206469616D2073616769747469732074656C6C75732C20696E2073656D706572206E69736920646F6C6F72206174206E6962682E204475697320756C6C616D636F7270657220766976657272612066656C69732E20496E746567657220612074656C6C75732E2053757370656E64697373652065676574206E756E632E2041656E65616E206469616D206573742C20616363756D73616E2069642C20737573636970697420696E74657264756D2C206672696E67696C6C612076697461652C206A7573746F2E2050726F696E20706564652E204D616563656E6173206174206E6571756520696E206E6571756520766573746962756C756D20656C656966656E642E0A0A566573746962756C756D206E756C6C61206C6F72656D2C20706F72747469746F7220656765742C20657569736D6F642061632C20616C697175616D2061742C206E69736C2E204D616563656E6173206574206573742065676574206D6173736120766172697573206C6F626F727469732E20496E206D692E204475697320706F72747469746F72206665726D656E74756D2070757275732E20446F6E65632063757273757320696D70657264696574206C6967756C612E204D6F726269206574206C6967756C6120657420616E7465206D6F6C6573746965207665686963756C612E204D61757269732073656420646F6C6F722E2053656420696D706572646965742066656C69732075742073656D2E20536564207669746165206E6571756520656C656D656E74756D206C656F20617563746F72206665726D656E74756D2E2044756973206665756769617420756C6C616D636F7270657220657261742E2041656E65616E2070757275732E204D6F726269206665726D656E74756D20766573746962756C756D206573742E2050656C6C656E7465737175652076656E656E61746973206D61757269732E2050686173656C6C75732070756C76696E61722E20496E746567657220697073756D206C65637475732C20696163756C697320612C206C6163696E69612069642C20616363756D73616E2069642C20617263752E2050686173656C6C7573206174206573742E204675736365206E65717565207175616D2C20756C747269636965732069642C20696163756C69732076656C2C20646170696275732076697461652C206C616375732E20496E206C6F626F7274697320636F6E76616C6C697320616E74652E204E756C6C61206E756E632070757275732C2076756C70757461746520696E2C2068656E6472657269742065742C20626C616E6469742065742C206C6967756C612E0A0A50656C6C656E746573717565206C656F206D657475732C20736167697474697320696E2C206D6F6C65737469652076697461652C2064696374756D20696E2C20706564652E204D6F726269207072657469756D2066656C6973206E6563207175616D2E2050656C6C656E746573717565206D617474697320616E746520736564207175616D20736167697474697320646170696275732E2053757370656E64697373652073617069656E2E205072616573656E7420626962656E64756D20696163756C697320746F72746F722E20447569732061206E69736C2E2041656E65616E206D692E20446F6E65632064696374756D206172637520696E206573742E204D6F72626920696E74657264756D2076756C70757461746520697073756D2E2041656E65616E2073697420616D6574206D61676E61206E6F6E206E69736C2074726973746971756520706F73756572652E2050686173656C6C75732076656C6974206D657475732C2074656D706F722061632C206665726D656E74756D20656765742C20636F6E64696D656E74756D206E6F6E2C2076656C69742E20566573746962756C756D2073697420706F73756572652E0A0A4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204372617320616C6971756574206D61737361206E6563206475692E20437261732061726375206E756E632C2068656E6472657269742061632C20656C656966656E642065752C20756C6C616D636F72706572206E65632C2074656C6C75732E205365642070686172657472612070757275732073697420616D6574207175616D2E20437572616269747572206D6F6C6C69732E204E616D20766974616520706564652E20457469616D207269737573206D617373612C207665686963756C612073697420616D65742C207068617265747261206E65632C20736F6C6C696369747564696E2075742C206475692E20446F6E65632065676573746173206A7573746F206174207175616D2E2050726F696E206E69736C2072697375732C20766573746962756C756D206E65632C207072657469756D2076697461652C207472697374697175652061632C206C6F72656D2E20416C697175616D206572617420766F6C75747061742E204372617320736564206E6962682E2050656C6C656E74657371756520736F6C6C696369747564696E20657569736D6F642061756775652E0A0A457469616D206672696E67696C6C6120736F6C6C696369747564696E206F7263692E204D61757269732063757273757320656C69742071756973206C616375732E204372617320746F72746F722E20496E2061646970697363696E672C206C656374757320696420617563746F7220766573746962756C756D2C206E65717565207065646520616363756D73616E20646F6C6F722C206E6F6E20696D70657264696574206D61676E61206469616D20616363756D73616E2076656C69742E2053757370656E6469737365206174206C696265726F207574206E69736920626C616E6469742073616769747469732E2050686173656C6C7573206E6F6E206D61757269732E20467573636520656C656D656E74756D2073616769747469732073656D2E2053757370656E646973736520616C697175616D20656C656966656E642074656C6C75732E2050726F696E206C6967756C61206C6F72656D2C20696D7065726469657420717569732C2076656E656E617469732069642C20696163756C6973206D6F6C6C69732C206E69736C2E20457469616D20636F6E76616C6C69732070656465206174206D617373612E204D6F72626920616363756D73616E20647569206574206D61757269732E0A0A53656420736564206F7263692E204E756E632070757275732E2053757370656E646973736520706F74656E74692E205574206C7563747573206672696E67696C6C61206D61757269732E20446F6E6563206E6962682E2050686173656C6C757320706F7274612E2050686173656C6C75732073697420616D6574206F64696F20736564206D61676E6120736F64616C65732070686172657472612E2043726173206C65637475732E2053757370656E6469737365206C696265726F20697073756D2C20636F6D6D6F646F206E65632C20666163696C6973697320696E2C207375736369706974206C6F626F727469732C206C6967756C612E2044756973206D61737361206E756C6C612C2073656D7065722065742C20636F6E736571756174206E65632C2070686172657472612065752C20656C69742E20566976616D757320756C7472696369657320616C697175616D206F64696F2E20566573746962756C756D2073697420616D6574206D617373612E2053656420636F6E736571756174206C61637573207365642075726E612E20457469616D2066617563696275732066656C69732076656C206F7263692E2050686173656C6C757320756C6C616D636F727065722E2041656E65616E20636F6E736563746574756572206C61637573206174206C696265726F2E0A0A436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204475697320666163696C697369732C206C6967756C6120766974616520636F6E64696D656E74756D207363656C657269737175652C2076656C6974206F72636920677261766964612066656C69732C2076656C20756C74726963696573207175616D206D69206E6F6E206469616D2E20566976616D757320617563746F72206D65747573206E6F6E206C696265726F2E205072616573656E74206C6967756C61206E6973692C20636F6D6D6F646F20636F6E64696D656E74756D2C206D6F6C65737469652065742C20766976657272612065742C206A7573746F2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320736F6C6C696369747564696E2E204E756E6320626C616E6469742063757273757320697073756D2E2041656E65616E206E6563206C6967756C612075742074656C6C757320736F64616C6573206D61747469732E20496E74656765722073656D2E20416C697175616D206964206C6967756C612E2053656420746F72746F72206D61757269732C20626C616E6469742076697461652C206375727375732076656C2C20656C656D656E74756D2065742C206E756C6C612E20416C697175616D207363656C65726973717565206D65747573206574206E69736C2E20447569732061646970697363696E67206D61676E61206174206E657175652E20517569737175652076756C70757461746520656C656966656E64206E756E632E20416C697175616D206567657420656C69742E2050686173656C6C757320647569206F64696F2C20626962656E64756D2073616769747469732C20766573746962756C756D2069642C206469676E697373696D20696D706572646965742C206F7263692E204E756C6C616D2065752066656C6973206E6F6E206E756E63206C6163696E696120736F64616C65732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A53757370656E64697373652070656C6C656E7465737175652C206C696265726F206D617474697320756C7472696369657320616363756D73616E2C20746F72746F7220746F72746F72206D616C6573756164612073656D2C20657420736F64616C6573206C696265726F206F64696F20616320697073756D2E20566976616D75732071756973206D61676E61206E656320657374207375736369706974206C6F626F727469732E20437261732074656D70757320706F7375657265206E756E632E205175697371756520757420656E696D20612066656C697320656765737461732073656D7065722E20536564207068617265747261206D6174746973206E657175652E20467573636520747572706973206E756E632C20636F6E677565207365642C20636F6E736571756174206E6F6E2C20636F6E677565207365642C206E756C6C612E2053757370656E646973736520766172697573206C6F72656D20696420726973757320706F72746120766573746962756C756D2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204675736365207365642070757275732E20496E20612066656C69732E20496E7465676572206567657374617320617563746F72206F7263692E204D617572697320756C747269636573207375736369706974206E69736C2E204E756C6C616D2070757275732E0A0A437261732074656D706F722061646970697363696E6720697073756D2E2055742071756973206D692E204D616563656E617320696E206A7573746F207574206E756C6C6120636F6E6775652070686172657472612E2050656C6C656E746573717565207574206C696265726F20657520646F6C6F722076656E656E617469732073757363697069742E205072616573656E74206665756769617420636F6E736563746574756572206E6962682E204D6F7262692066617563696275732073656D206E6F6E2066656C69732E20496E2068656E6472657269742061726375206163206D617373612E20496E20616363756D73616E20756C747269636573206D692E2050726F696E206D616C65737561646120617563746F722066656C69732E2043757261626974757220696E74657264756D2E20536564206469616D20697073756D2C20756C7472696369657320696E2C2074656D706F722073697420616D65742C207669766572726120696D706572646965742C20656C69742E204D6F726269206D6F6C6573746965206E6973692E204D617572697320697073756D2E2046757363652064696374756D206D6F6C6C6973206D61676E612E204475697320636F6D6D6F646F206469676E697373696D206E756C6C612E20566573746962756C756D20617567756520656E696D2C20756C7472696369657320717569732C20696163756C6973206E65632C2074696E636964756E742076697461652C206469616D2E204D6175726973206C6163696E69612074656D70757320697073756D2E20536564206174206D61757269732E205574206C6F72656D2E20446F6E6563206C696265726F2E0A0A4475697320696163756C6973206C6163696E6961206C65637475732E2041656E65616E20636F6E76616C6C69732065726F7320616320616E74652E205365642071756973206F726369206E656320726973757320617563746F72206672696E67696C6C612E2050686173656C6C757320666163696C6973697320656C656D656E74756D206E6973692E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E6320706F727461206C61637573206E656320616E74652E204D6F726269206D617572697320657261742C2061646970697363696E6720696E2C2070756C76696E6172206E65632C206C6F626F72746973206E65632C206F64696F2E20557420656C656966656E64206C656374757320736564207175616D2E204E756C6C616D206D6F6C6C69732E20496E206E6F6E20747572706973206574206E69736C2068656E64726572697420626C616E6469742E204475697320656C656D656E74756D2E204E756E63206E6563206C696265726F2E2053757370656E646973736520766573746962756C756D207269737573206E6F6E20706564652E204D6F72626920696D70657264696574206F64696F2073697420616D6574206C696265726F2E2053656420736564206D6173736120766974616520697073756D206D61747469732074696E636964756E742E204E756C6C61206E656320746F72746F72207669746165206C696265726F20766F6C75747061742074656D7075732E20446F6E656320616C697175616D2E0A0A4475697320736564206E756E632E2043757261626974757220747572706973206E756C6C612C207665686963756C61207365642C206C756374757320717569732C20656C656D656E74756D20656765742C2066656C69732E204D616563656E61732065742070757275732E204D616563656E6173206C656F2074656C6C75732C2074696E636964756E7420612C20666163696C697369732076697461652C206C6F626F727469732073697420616D65742C2076656C69742E20446F6E656320636F6E76616C6C69732073617069656E2E204D616563656E6173206D6F6C6C6973206F64696F206575206E6962682E20457469616D20677261766964612E20496E7465676572206D6F6C65737469652C2073617069656E206575206D6F6C6573746965206C6163696E69612C206E756E63206E69626820616C697175616D206C6967756C612C2065752073616769747469732074656C6C7573206572617420736F6C6C696369747564696E206F64696F2E20447569732065742072697375732E2050686173656C6C7573206E697369206E657175652C20706C616365726174206E65632C20636F6E64696D656E74756D206E6F6E2C20756C7472696365732065752C2073656D2E20557420706564652E20457469616D206E756C6C61206D657475732C20766F6C75747061742069642C20636F6E76616C6C6973207365642C2073757363697069742076656C2C2075726E612E20446F6E65632076656C20656C69742E205574206C656F206E657175652C2076656E656E617469732066617563696275732C206C6163696E6961206E65632C2074696E636964756E742065752C20656E696D2E2043726173206964206475692061206C696265726F207068617265747261206469676E697373696D2E20446F6E65632065726F73206C656F2C20706F72746120717569732C206C616F726565742075742C2070656C6C656E74657371756520766F6C75747061742C206C65637475732E0A0A4E756C6C616D20626C616E6469742E20416C697175616D206572617420766F6C75747061742E2046757363652061646970697363696E6720656E696D2E2053757370656E6469737365206E6F6E206475692071756973206C6967756C6120706F72746120766573746962756C756D2E20446F6E65632065752074656C6C75732076656C206C6F72656D207072657469756D20706F72747469746F722E205072616573656E74206C75637475732E20416C697175616D2061632065726F7320696E206D6173736120646170696275732074696E636964756E742E20446F6E6563207574206D61676E612E20457469616D20617563746F72206C616375732073697420616D6574206C616375732E2053656420756C7472696369657320697073756D206E656320656C69742E205175697371756520612065737420696E207075727573207375736369706974207472697374697175652E0A0A41656E65616E20736564206475692076656C20646F6C6F722070756C76696E6172206C616F726565742E20566976616D7573207665686963756C61206C6F72656D20696E20706564652E20566976616D7573206574206469616D2E20496E7465676572206163206F64696F2076656C206469616D2068656E64726572697420626962656E64756D2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E756C6C612061206E6973692E2050686173656C6C75732074696E636964756E74206475692076697461652061756775652E20447569732066617563696275732C2064756920696E74657264756D206672696E67696C6C612074696E636964756E742C206F64696F20656C697420766573746962756C756D206C696265726F2C206163206D6F6C6573746965206D61676E61206C6563747573206964206C616375732E2041656E65616E206C6967756C612E204E756C6C6120666163696C6973692E0A0A46757363652076656C2073656D2065752076656C6974206672696E67696C6C61206F726E6172652E2053656420666575676961742074696E636964756E742066656C69732E204E756C6C616D2066656C6973206D692C20657569736D6F642073697420616D65742C206D6F6C6C69732061742C20736F64616C657320656765742C2061756775652E204E616D20696D70657264696574206E6962682061742076656C69742E2053656420757420657261742E20496E206475692E204E756C6C6120666163696C6973692E204E756C6C616D206175677565206C696265726F2C2074696E636964756E74206E65632C207072657469756D2065752C2070756C76696E617220696E2C206475692E204D6F7262692076697461652066656C69732E2050656C6C656E7465737175652076656C206A7573746F2076656C2076656C6974207361676974746973206D616C6573756164612E2050726F696E207665686963756C6120626C616E646974206D617373612E20457469616D2074696E636964756E742070686172657472612075726E612E20496E206D65747573206573742C20617563746F72206E65632C20626C616E64697420612C20637572737573206E65632C207175616D2E204D6175726973206163206D657475732061206C696265726F20636F6E6775652066617563696275732E204D6175726973206D617572697320646F6C6F722C20736F64616C657320696E2C206375727375732075742C20736F64616C65732072757472756D2C2065726F732E2051756973717565206D61757269732065726F732C2073616769747469732076697461652C206C6F626F727469732075742C20656C656966656E642069642C206E6973692E0A0A41656E65616E206E657175652E20566573746962756C756D20656765737461732070656C6C656E746573717565206C6967756C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2050686173656C6C7573207361676974746973206A7573746F2076656C2072697375732E20536564207072657469756D206E657175652076697461652075726E612E2050656C6C656E74657371756520636F6E677565206C696265726F206964206C6F72656D2E204D6175726973206C656F206C6F72656D2C20626C616E6469742073697420616D65742C20636F6E76616C6C697320717569732C20636F6E736563746574756572207365642C2065726F732E204D61757269732074696E636964756E742C20656E696D2061206772617669646120657569736D6F642C206D61676E61206E756C6C61206665726D656E74756D206C696265726F2C207669766572726120656765737461732076656C6974207175616D20657420746F72746F722E20566976616D757320616C6971756574206D61737361207669746165206A7573746F2E204E756C6C6120636F6E677565206C6163757320616320656C69742E0A0A50686173656C6C757320636F6D6D6F646F207175616D2076656C206C6967756C612E2050726F696E206E6F6E206D657475732061742065726F732070756C76696E6172206C75637475732E204D6175726973206469616D206C6F72656D2C20706F737565726520717569732C20677261766964612065742C2074696E636964756E74206E65632C206C6967756C612E20536564206469616D2E20416C697175616D20656C6974206C65637475732C2068656E6472657269742075742C20696D706572646965742073697420616D65742C207072657469756D2073697420616D65742C20697073756D2E204D6175726973207665686963756C61206E69736C20696E206475692E204375726162697475722065676574207175616D207574206D61676E6120656C656D656E74756D206665726D656E74756D2E204D6175726973207363656C657269737175652E2051756973717565206C616F726565742E20457469616D2074656D707573207475727069732E2050656C6C656E746573717565206175677565207175616D2C2068656E647265726974207365642C2074696E636964756E742061742C2070686172657472612061742C206E69736C2E20416C697175616D206C616375732E2053757370656E646973736520706F74656E74692E2041656E65616E2076656C6974206C696265726F2C20756C74726963657320696E2C206C6163696E69612065752C206C75637475732076656C2C20616E74652E20457469616D2064696374756D206D6920696E2066656C69732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20467573636520677261766964612064617069627573206E69736C2E2043726173207669746165206E69736C2E0A0A4D616563656E6173206469676E697373696D2C206C6967756C61206E6F6E20706F727461206375727375732C20656E696D206E756E63206D616C6573756164612073656D2C20657520706F72747469746F72206E756C6C612075726E61206575207175616D2E2046757363652065726F732E20416C697175616D2065726F732E204E616D20617563746F722E204E756C6C61206D6F6C657374696520706F727461206573742E2053757370656E646973736520706F74656E74692E20566976616D7573206D6F6C6573746965206C6F72656D2073656420657261742E20536564206567657420697073756D2E20496E746567657220616C697175616D2070756C76696E6172206E756C6C612E204372617320616C69717565742073656D207574206E756E632E2046757363652066617563696275732074656D707573206C65637475732E204372617320736F64616C65732C206E69736920616320666163696C6973697320756C7472696365732C2065726F73206172637520646170696275732073617069656E2C20657420756C747269636573206D61757269732074656C6C7573206E6F6E20646F6C6F722E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20437261732063757273757320766172697573206D657475732E205574207475727069732E20566976616D7573206567657420746F72746F722E0A0A536564206C616F726565742C2076656C6974206E6F6E20616363756D73616E206375727375732C206E756E632075726E6120706F7375657265206A7573746F2C20696E2064696374756D206C6563747573207065646520696420616E74652E20437261732076756C7075746174652E204372617320636F6E677565206475692073656420656C69742E2050726F696E206C616375732073656D2C20756C7472696365732061742C20636F6E73657175617420696E2C2074656D706F7220717569732C206D657475732E2050726F696E2076656C20617263752E204E616D20657569736D6F642068656E64726572697420656C69742E20557420657261742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2053656420706F73756572652E204D6F7262692065726F732075726E612C2073656D7065722061742C2073656D706572206E6F6E2C20636F6E76616C6C697320717569732C2076656C69742E204D616563656E6173206F7263692E20566573746962756C756D206C6F626F7274697320747269737469717565206D657475732E20566573746962756C756D206C6F72656D206E756C6C612C20736F6C6C696369747564696E2076697461652C20636F6E64696D656E74756D20717569732C20617563746F722075742C206475692E20566976616D757320766573746962756C756D206D61676E61207574206E6973692E2043757261626974757220656C656966656E64206475692076656C206E756E632E20437572616269747572206D6175726973206C616375732C206D616C6573756164612073697420616D65742C207375736369706974207365642C2072757472756D206C75637475732C2074656C6C75732E20496E746567657220666163696C697369732075726E61207669746165206C65637475732E0A0A41656E65616E207175616D206C656F2C206C6F626F7274697320717569732C206D616C6573756164612065752C2076756C7075746174652076697461652C206E69736C2E205072616573656E7420656765742065726F732E205574206665726D656E74756D20747572706973206964207175616D2E204E616D20746F72746F722E205072616573656E74206E6563206F7263692E204E756C6C6120626962656E64756D2061646970697363696E672061756775652E20557420636F6D6D6F646F2C206D61676E61206964206D616C65737561646120677261766964612C206175677565206F64696F206D616C657375616461206D692C20706F727461206D616C65737561646120656C697420657374207669746165206469616D2E204D6175726973206E6F6E206E756C6C612E2053757370656E64697373652074696E636964756E742C206E756E6320756C7472696369657320706F7274612076656E656E617469732C206D6920706564652074696E636964756E74206C696265726F2C20656765742076617269757320616E7465206C696265726F207574206C6967756C612E20437572616269747572207072657469756D20706F72747469746F7220746F72746F722E0A0A4D616563656E617320766974616520656C69742065676574206E69736920646170696275732064696374756D2E204E756E6320696E206C696265726F2E204E756C6C612064696374756D206F726369206575206572617420617563746F72206C6F626F727469732E2050686173656C6C75732072697375732E2053757370656E646973736520706F74656E74692E2053757370656E646973736520706F74656E74692E205072616573656E742061646970697363696E6720636F6E73657175617420656C69742E20496E74656765722069642061756775652E205072616573656E7420696E206A7573746F206E6563206D61676E6120646170696275732070756C76696E61722E2044756973206E69736C2E2053757370656E6469737365206163206F64696F2E20566976616D757320696D706572646965742E20446F6E6563206E6F6E2076656C69742073697420616D6574207269737573206469676E697373696D20636F6E6775652E204E616D20616C697175657420706F73756572652076656C69742E2043726173207475727069732E204D6F726269206D616C657375616461206469676E697373696D206D692E0A0A536564206C656F206E657175652C2076617269757320717569732C2076656E656E61746973207365642C207068617265747261207365642C206573742E204D6F72626920626C616E6469742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D2073656D7065722070656C6C656E746573717565206D692E2055742076656C206C6F72656D2E204E756E63206D6920746F72746F722C206C616F726565742061742C2066617563696275732065752C2074696E636964756E742073697420616D65742C20657261742E20447569732074656D706F72206D616C65737561646120697073756D2E2050686173656C6C757320616C69717565742E20446F6E656320657420656C69742E2050656C6C656E7465737175652070757275732E20566573746962756C756D2072757472756D2073656D706572206E6962682E204E756C6C6120666163696C6973692E2050686173656C6C757320657420656E696D2073697420616D657420616E746520766573746962756C756D207665686963756C612E2050686173656C6C7573206964206E69736C2E20446F6E6563206D6F6C6C6973206C656F2061742065726F732E204D61757269732070656C6C656E746573717565206E657175652061742070757275732E204D6F726269207175697320646F6C6F7220617420697073756D207363656C6572697371756520736F64616C65732E20457469616D20766F6C7574706174207475727069732061206D657475732E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206C6F72656D206C6F72656D2C20766573746962756C756D2061632C20657569736D6F6420656765742C20756C6C616D636F72706572206469676E697373696D2C2076656C69742E0A0A43756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204372617320756C7472696365732C206E6962682076656C20616C697175616D20766573746962756C756D2C2065726F7320656E696D2076656E656E61746973206475692C20696420696163756C697320656E696D206E756E632076656C206D617373612E204D6F72626920656C656966656E64206F726369206574206D617373612E20416C697175616D206572617420766F6C75747061742E204E756C6C61206D6F6C6C69732065676573746173207475727069732E20496E20736F64616C6573206E756E63206567657420746F72746F722E2053656420697073756D2065726F732C2074656D706F7220717569732C20616C69717565742076697461652C20696D70657264696574206E6F6E2C206C6F72656D2E2050656C6C656E746573717565207175697320656C6974206964206D69206C756374757320646170696275732E20536564206E756E6320617263752C2072686F6E637573206E65632C20636F6E76616C6C697320717569732C206375727375732061742C206E657175652E204D617572697320636F6E76616C6C697320707572757320617420657261742E2050656C6C656E74657371756520766573746962756C756D2E20566976616D7573206672696E67696C6C6120656C697420617420617263752E204E756C6C616D20616C697175657420656E696D206E656320617263752E204E616D20696420746F72746F722E204E756C6C612071756973206E756E632E20557420617263752E2053757370656E646973736520706F74656E74692E2050656C6C656E74657371756520756C6C616D636F72706572206C6967756C6120696420617263752E0A0A4E616D206E6F6E206C696265726F207669746165206E69736C207363656C65726973717565206672696E67696C6C612E20517569737175652076617269757320616E7465206964206D657475732072686F6E637573206672696E67696C6C612E204E756C6C6120666163696C6973692E205072616573656E7420656C656966656E6420706F72747469746F72206C6967756C612E20457469616D207175697320646F6C6F72206E6F6E20617567756520636F6D6D6F646F20617563746F722E20446F6E65632061206D692E20566573746962756C756D2074656D706F722E20446F6E65632066656C69732075726E612C20617563746F722061742C206375727375732064696374756D2C20677261766964612069642C20617263752E2041656E65616E2064696374756D206D616C65737561646120646F6C6F722E20566976616D7573206D61747469732E2050686173656C6C757320657520706564652E2046757363652061646970697363696E67206A7573746F206672696E67696C6C61206D657475732E20457469616D20616E74652E20496E7465676572206D6F6C6C6973206D617373612071756973206E756E632E20496E74656765722064696374756D206E65717565206C756374757320656E696D2E0A0A536564206575206C696265726F2E20496E74656765722074656D706F72206C6967756C6120696E2076656C69742E2055742074696E636964756E74206C6163696E69612073656D2E204E756C6C616D2076656C2072697375732E2053656420736F64616C657320616E7465206120646F6C6F722E204375726162697475722065726F732E2053656420736F64616C65732E20536564206E6F6E206D657475732E20566573746962756C756D20656C656D656E74756D20666175636962757320616E74652E204E756C6C612076656C206E6962682E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206E6563206C6F72656D20757420697073756D206C6163696E696120696163756C69732E204475697320657261742E20416C697175616D20657261742E204372617320696163756C69732E20496E206861632068616269746173736520706C617465612064696374756D73742E0A0A4E756C6C616D20616E74652E2043726173207669746165206573742E2050656C6C656E7465737175652076656C206D657475732061206C6967756C612064617069627573206D61747469732E2044756973206665756769617420616C69717565742066656C69732E20457469616D206964206E69736C207175697320657374206469676E697373696D20636F6E64696D656E74756D2E2053757370656E646973736520706F74656E74692E204D6F7262692076656C6974206C6F72656D2C206F726E61726520717569732C2070656C6C656E7465737175652076656C2C20706C61636572617420656765742C20746F72746F722E20566573746962756C756D2074696E636964756E74206D6F6C6573746965206C696265726F2E204E756C6C61206E756C6C6120656E696D2C206D616C6573756164612069642C20756C6C616D636F727065722076697461652C2064696374756D2061742C2070757275732E20446F6E6563206469676E697373696D206F64696F20757420656E696D2E2053757370656E6469737365206174206C65637475732E0A0A5072616573656E74206C6F626F727469732061756775652076656C206C65637475732E20557420696E206C6967756C612075742066656C697320636F6E6775652073757363697069742E2051756973717565206469676E697373696D20746F72746F72207574206D692E204675736365206D61676E61206E6973692C20656C656966656E642061632C206F726E6172652076656C2C20706F72747469746F722076697461652C207175616D2E20566573746962756C756D20736F64616C6573206A7573746F2071756973207475727069732E2046757363652075726E61206E6973692C2072686F6E63757320717569732C20636F6E64696D656E74756D2076656C2C2064696374756D2065752C206E756E632E20467573636520736564206E696268207669746165206F64696F20706F73756572652061646970697363696E672E2053656420706F72746120656C6974207175697320646F6C6F722E204E616D206C696265726F206E756C6C612C20617563746F72207365642C2074696E636964756E7420717569732C2066617563696275732073697420616D65742C206D692E2051756973717565206F7263692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E756C6C616D2069642073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632076656C2065726F732E0A0A566976616D7573206C7563747573206C6F626F72746973206C656F2E2053757370656E64697373652076656C20656C6974206120656E696D20756C6C616D636F7270657220706F73756572652E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20446F6E656320717569732070656465206D6174746973206C6563747573206D6F6C6C69732061646970697363696E672E2053656420616363756D73616E20706F737565726520657261742E205072616573656E7420657569736D6F642074696E636964756E742066656C69732E20446F6E6563206D692E20557420636F6D6D6F646F2061726375206C6163696E69612074656C6C75732E20416C697175616D2061206C696265726F2071756973206C65637475732073656D70657220766976657272612E20437572616269747572206C6163696E6961206D61757269732061742074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E756E632073697420616D6574206D61676E61206D6F6C6573746965206F726369207375736369706974206672696E67696C6C612E204675736365207072657469756D206D65747573206E6F6E2073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642068656E6472657269742E204E756C6C612066656C69732E2053757370656E646973736520706F74656E74692E20416C697175616D20626C616E64697420747269737469717565206E657175652E20437572616269747572207175697320657261742076656C206E756E6320616363756D73616E206D6F6C6C69732E0A0A447569732073616769747469732C2074656C6C757320757420616C697175616D206672696E67696C6C612C20646F6C6F72206D6920756C6C616D636F72706572206E69736C2C20757420747269737469717565207065646520656C697420736564206D61757269732E204375726162697475722069642066656C69732E20446F6E65632070756C76696E6172206C61637573206574206C65637475732E20416C697175616D2076756C7075746174652076756C707574617465206D657475732E20437572616269747572206D61676E612066656C69732C2061646970697363696E672061632C20616363756D73616E2076656C2C206D6F6C657374696520717569732C207175616D2E204D617572697320656C697420617263752C207072657469756D2076697461652C206D6F6C6C69732073697420616D65742C20736F6C6C696369747564696E2075742C206D692E20446F6E656320696D70657264696574206469676E697373696D206D692E204E756C6C616D2073697420616D657420746F72746F722E20416C697175616D206E65717565206E756C6C612C2076656E656E6174697320612C20706F72746120696E2C20706C6163657261742074656D7075732C206C616375732E205175697371756520766573746962756C756D20647569206574206C616375732E2050726F696E206469676E697373696D20636F6E7365637465747565722070757275732E20457469616D206772617669646120746F72746F7220696E206E756E632E2055742074656D706F722074726973746971756520746F72746F722E20536564206C616F726565742074696E636964756E74207175616D2E20566573746962756C756D20706F7274612074757270697320757420656C69742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20446F6E6563206E696268206475692C2066657567696174206E65632C206C616F726565742069642C206D616C65737561646120656765742C206E6973692E205574206E65717565206D617373612C207665686963756C612065752C20636F6D6D6F646F206E6F6E2C20756C747269636965732076697461652C2070757275732E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204D617572697320657569736D6F642C2066656C69732076656C2074656D706F7220616C69717565742C20746F72746F72206D6175726973206D616C657375616461206E756E632C2076656C206665726D656E74756D2073656D206469616D206964206475692E204E616D2072757472756D2073617069656E2065676574206F64696F2E20416C697175616D20736564206C696265726F206E6F6E206D692066617563696275732074656D7075732E2046757363652068656E6472657269742C206469616D206E6F6E20766F6C75747061742072757472756D2C2065726174206D657475732076656E656E61746973206C6967756C612C206E6F6E207363656C657269737175652070656465206C6967756C612076656C207175616D2E204D6F7262692072686F6E6375732065726F7320616320647569206665756769617420656C656D656E74756D2E2044756973206575206C696265726F2065742074656C6C757320636F6E67756520766976657272612E204D6F726269207175616D207175616D2C20656C656D656E74756D207365642C20756C6C616D636F7270657220696D706572646965742C20636F6D6D6F646F206E6F6E2C206F64696F2E204E616D20616C697175657420656765737461732075726E612E204D6175726973206F64696F2066656C69732C207661726975732065752C206C6163696E69612065752C20636F6E64696D656E74756D20612C206C65637475732E20536564206A7573746F206D617373612C2070756C76696E61722069642C2076617269757320612C20706F72747469746F72206E65632C206C696265726F2E20457469616D207661726975732E2043757261626974757220736F64616C65732C206F64696F20617420706F73756572652073656D7065722C2065726F73206E6962682074696E636964756E74206C65637475732C2076656C2072757472756D2073617069656E206E69736920696E206C6967756C612E2053757370656E6469737365206567657420617263752E2050686173656C6C757320696D70657264696574206573742061632073617069656E2E20446F6E6563206E756C6C6120746F72746F722C20706C6163657261742076656C2C2074656D70757320612C206C6F626F727469732076656C2C206E6962682E20416C697175616D20766172697573206E6973692E204E756C6C6120657420656E696D2E20467573636520636F6E76616C6C6973206C616F72656574206C616375732E0A0A50686173656C6C757320697073756D20646F6C6F722C206D6F6C657374696520717569732C20636F6E64696D656E74756D20696E2C20636F6D6D6F646F2065752C206469616D2E205175697371756520626962656E64756D206C6163696E6961206475692E204E756C6C616D20626C616E6469742076756C707574617465206F7263692E205574206C6163696E6961206D617373612076656C2061756775652E20416C697175616D20677261766964612C207175616D207175697320696D7065726469657420696D706572646965742C2074656C6C7573206469616D20706861726574726120657261742C206174207068617265747261206C61637573206E6962682065676573746173206D61676E612E204E756C6C61207361676974746973206C6F72656D207574206C6F72656D2E204475697320636F6E64696D656E74756D2C2064756920766974616520616C697175616D20706F73756572652C206469616D207175616D20636F6E76616C6C69732076656C69742C2075742067726176696461206C656F20697073756D206E6F6E2072697375732E205574206665726D656E74756D20736F6C6C696369747564696E20657261742E20446F6E6563207361676974746973207363656C657269737175652066656C69732E204E756E6320617263752E20457469616D2074656D7075732C206D61676E612073697420616D657420737573636970697420657569736D6F642C2065726F732073656D2072757472756D206475692C207669746165207361676974746973206E696268207075727573206E6F6E206C616375732E20536564206D6F6C6C69732061726375206567657420646F6C6F722E20446F6E6563206F726E6172652C20617263752073697420616D6574206665726D656E74756D2076756C7075746174652C20726973757320656E696D206665726D656E74756D206C696265726F2C2061206C6163696E696120646F6C6F72206D69206E6F6E2076656C69742E20457469616D206C6F626F72746973207075727573206120656C69742E204E756E63206E756C6C61206475692C206D617474697320717569732C20626962656E64756D20612C20756C7472696365732061632C2061756775652E20496E20616C697175616D207665686963756C61207475727069732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A496E7465676572206964206E69736C2E20517569737175652064696374756D20656C656D656E74756D206F64696F2E2041656E65616E206C75637475732E205365642065752073656D206120706564652076756C70757461746520636F6E64696D656E74756D2E2051756973717565206D61676E612E20446F6E656320616C697175616D206D617474697320697073756D2E204375726162697475722064696374756D20736F6C6C696369747564696E2073656D2E20416C697175616D2070756C76696E61722E204E756E6320736F6C6C696369747564696E207269737573206120657261742E20566976616D757320717569732074656C6C75732073697420616D6574206E69626820766573746962756C756D20636F6E7365717561742E204E756C6C61207072657469756D20736F6C6C696369747564696E20646F6C6F722E20416C697175616D20696163756C69732074696E636964756E74207475727069732E2050686173656C6C757320697073756D206C656F2C2076656E656E6174697320696E2C20736167697474697320696E2C206F726E6172652061742C206E756E632E0A0A50656C6C656E74657371756520756C7472696365732C2064756920657520696163756C6973206C75637475732C2074656C6C757320617567756520766F6C75747061742073617069656E2C20696E206469676E697373696D2075726E612066656C6973207574206D692E205365642061726375206475692C206469676E697373696D2069642C20706F72747469746F722075742C20696D706572646965742076697461652C20616E74652E204E756C6C61206475692073656D2C20636F6D6D6F646F206E65632C2073616769747469732065742C206C6163696E69612065742C20706564652E20457469616D20656C656966656E6420647569207574206E69736C2E20446F6E656320616E7465206D61757269732C2074656D7075732073697420616D65742C207661726975732076697461652C206772617669646120717569732C206D692E20496E207363656C657269737175652C2066656C697320766974616520766976657272612073616769747469732C2076656C6974206D6574757320756C74726963696573206E657175652C207175697320696D706572646965742076656C697420656C6974206574206D61676E612E2053757370656E646973736520706F74656E74692E205365642076656C69742065726F732C20657569736D6F64207365642C20636F6E64696D656E74756D206E65632C206661756369627573207365642C2073617069656E2E204E616D20616363756D73616E206C6967756C612073697420616D6574206E657175652E20416C697175616D206572617420766F6C75747061742E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E616D20657520706564652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642065752066656C69732073656420746F72746F722074656D706F72206665726D656E74756D2E2050686173656C6C757320636F6D6D6F646F2073656D2076656C206E69736C2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050726F696E206C656374757320656C69742C2070686172657472612073697420616D65742C20616363756D73616E207365642C2074696E636964756E742065742C206D61757269732E204475697320646170696275732070686172657472612073656D2E20496E746567657220696E206A7573746F2E205072616573656E742065726F732E20566573746962756C756D20616320616E74652E20416C697175616D207363656C657269737175652073656D2070656C6C656E746573717565206E69626820636F6E73656374657475657220736F64616C65732E20416C697175616D20636F6E736563746574756572206F64696F2E2044756973206C6563747573206F64696F2C206C75637475732065752C20636F6D6D6F646F20717569732C206D6F6C6C69732076697461652C2076656C69742E2043726173206E6563206E756E63206E6F6E20656C697420696163756C6973206D61747469732E2041656E65616E206A7573746F206E657175652C20736F6C6C696369747564696E20656765742C20756C6C616D636F7270657220656765742C20656765737461732069642C2073656D2E20496E2065752072697375732E2053656420656765737461732E0A0A496E7465676572206174206E657175652E20536564207072657469756D207363656C65726973717565206E756C6C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20467573636520757420706564652E20457469616D207669746165207175616D20612075726E612076617269757320696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2044756973207665686963756C612E20467573636520756C6C616D636F72706572206E696268206E6F6E20657261742E205175697371756520696E206E657175652E205072616573656E74206573742E2050656C6C656E74657371756520617263752E0A0A50726F696E20706F73756572652E2053757370656E646973736520706F74656E74692E20496E74656765722066656C6973206C616375732C20616C697175616D207365642C2076756C70757461746520696E2C206D6F6C6C69732076656C2C2074656C6C75732E20496E7465676572207665686963756C6120626962656E64756D206573742E204E756E63206E6F6E20646F6C6F7220696E2074656C6C7573206D617474697320666163696C697369732E20496E746567657220766573746962756C756D2C20617567756520617420636F6D6D6F646F20616C697175616D2C2064756920657374206D6174746973206C6967756C612C2073697420616D65742061646970697363696E67206F7263692073656D207669746165206D61676E612E205072616573656E7420656E696D2076656C69742C206D616C6573756164612061742C20636F6E677565206E65632C206C756374757320696E2C206A7573746F2E20536564207661726975732E204D6F7262692070686172657472612E20446F6E6563206575206D61737361206E65632074656C6C75732076756C7075746174652070756C76696E61722E20557420636F6D6D6F646F20747572706973206E6F6E2073656D2E20557420636F6E76616C6C697320756C6C616D636F727065722072697375732E20457469616D20696E74657264756D2070656465206964206E6973692E2043726173206D61676E612073617069656E2C20737573636970697420612C206C616F72656574206E6F6E2C2072686F6E6375732065742C2066656C69732E20496E7465676572206F726369206C6F72656D2C20766573746962756C756D2064696374756D2C20756C6C616D636F7270657220612C20706F72747469746F722065742C206475692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A4E756E63206574206D61676E612E2053656420626962656E64756D2074656C6C757320696E206469616D2E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E616D20766974616520746F72746F722E20496E7465676572206D61676E612E20447569732076656E656E617469732C206C656F2061632074656D706F72206C616F726565742C20656C6974206E756C6C6120706861726574726120706564652C206E6F6E206665726D656E74756D206E756E63206F64696F2061206F64696F2E2050726F696E206E6F6E2076656C69742E2053656420696D706572646965742061756775652071756973206E69736C2E20496E746567657220636F6E64696D656E74756D206E69736C206E6563206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20566976616D757320706C616365726174206C696265726F2E204475697320636F6E6775652064696374756D206D61676E612E20416C697175616D206461706962757320626962656E64756D20656E696D2E204E756E6320656C656966656E6420706564652076656C20697073756D2E0A0A457469616D2076697461652076656C69742E204D61757269732065726174206E756E632C206D616C6573756164612075742C20666575676961742061632C20706C61636572617420636F6E64696D656E74756D2C2061756775652E204E616D20766F6C75747061742E20416C697175616D207665686963756C6120697073756D206964206F64696F2E20566976616D757320736F6C6C696369747564696E207475727069732069642073617069656E2E20467573636520612066656C6973207669746165206F64696F20636F6E76616C6C697320626C616E6469742E204375726162697475722076697461652065726F732069642065726F7320706F727461207072657469756D2E204E756C6C6120696E206D61676E6120656765742075726E61206C6163696E696120636F6E76616C6C69732E20416C697175616D206D61747469732076656E656E617469732070757275732E2053656420736564206D69206567657420657261742074726973746971756520706F7274612E20446F6E656320617563746F7220646F6C6F72206120657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20496E206E6563206C6967756C612E204E756E6320656C656966656E642E20566573746962756C756D2071756973206E697369206567657420656C697420706F72747469746F7220636F6E6775652E204D616563656E61732066617563696275732C206D61676E6120656765742061646970697363696E672074696E636964756E742C20646F6C6F7220616E7465206D616C65737561646120656C69742C206E6F6E20656C656D656E74756D206C616375732074757270697320696E20706564652E0A0A5574206D616C657375616461206D69206E6563206D657475732E205072616573656E7420617563746F72206175677565206163206E69736C20756C7472696369657320666163696C697369732E204E616D2070757275732073617069656E2C2070656C6C656E746573717565206469676E697373696D2C20706F73756572652065752C206375727375732069642C206469616D2E205175697371756520736F6C6C696369747564696E2C20656C697420612070656C6C656E746573717565207363656C657269737175652C206C6F72656D20726973757320617563746F72207175616D2C207175697320636F6E7365717561742074656C6C7573206E657175652069642075726E612E2053757370656E6469737365206469616D20746F72746F722C20656C656966656E64206469676E697373696D2C20656765737461732075742C206C756374757320696E2C20616E74652E204475697320616E74652E204D616563656E6173206C75637475732E20437572616269747572206375727375732070686172657472612075726E612E204D616563656E617320696D706572646965742C2065726174206E6F6E20656C656D656E74756D20657569736D6F642C20746F72746F72206F64696F20657569736D6F64206C65637475732C20616320666163696C697369732073656D206E696268207669746165206E756C6C612E204E756E6320677261766964612E204D6F72626920736F6C6C696369747564696E206F64696F2071756973206C616375732E20416C697175616D2061206E696268206E6F6E2075726E6120706F72746120696D706572646965742E20416C697175616D206572617420766F6C75747061742E20496E20696163756C6973206C6163696E69612076656C69742E20536564206C696265726F206C616375732C207472697374697175652065752C206C6163696E69612061632C20616C697175657420656765742C2075726E612E0A0A457469616D206174206E69736C2E2050686173656C6C7573206661756369627573206C7563747573206C65637475732E20557420706C6163657261742076756C70757461746520646F6C6F722E2050686173656C6C75732076656C2076656C69742E204D6F72626920766976657272612E2050686173656C6C7573206F7263692E20496E7465676572206469676E697373696D206D6174746973206D61757269732E2050656C6C656E74657371756520706F7375657265206C656F20706F7375657265207175616D2E2051756973717565206E6563206D61676E61206174206469616D20766976657272612070656C6C656E7465737175652E2053757370656E64697373652076656C697420617263752C20756C7472696369657320717569732C20636F6E67756520612C2076656E656E6174697320656765742C206C616375732E20496E74656765722073616769747469732068656E64726572697420646F6C6F722E2046757363652074696E636964756E7420616E746520612073656D2E0A0A4D616563656E617320636F6E7365637465747565722C206A7573746F207365642072686F6E6375732076656E656E617469732C206E69626820617263752072757472756D20646F6C6F722C2073656420636F6E64696D656E74756D206C696265726F206C696265726F20657420697073756D2E20566976616D7573206D6174746973206A7573746F207574206C6F72656D2074696E636964756E74206C6F626F727469732E205574206E6F6E2076656C6974206964206E6571756520616C697175657420616363756D73616E2E205365642074656D7075732076697665727261206E756C6C612E2043757261626974757220756C6C616D636F727065722C206E6571756520717569732064617069627573207363656C657269737175652C2066656C6973206469616D2067726176696461206F7263692C206E6F6E20637572737573207175616D206E6571756520766974616520656C69742E20457469616D2070686172657472612074696E636964756E74206C616375732E204475697320657569736D6F64206672696E67696C6C61206573742E20457469616D206F726E6172652074696E636964756E74206C65637475732E2050726F696E20696E207475727069732E204E756E6320626C616E64697420626C616E646974207475727069732E2041656E65616E2075742061756775652E2044756973206F726369206A7573746F2C2074696E636964756E742065752C2072757472756D207365642C2072757472756D2065742C207475727069732E2043757261626974757220666163696C69736973206F64696F20696E20616E74652E20496E206861632068616269746173736520706C617465612064696374756D73742E205365642065726F73206573742C2070656C6C656E7465737175652061742C2074696E636964756E742065752C20756C74726963657320717569732C206D657475732E204D6F7262692073697420616D6574206A7573746F2E204D616563656E617320616320617263752E204D6175726973206469676E697373696D2E0A0A50656C6C656E74657371756520756C747269636965732072757472756D206F7263692E2041656E65616E206F726E6172652E20566976616D75732065752072697375732076656C206D6175726973206C6F626F727469732064696374756D2E205365642065742074757270697320617563746F72206D692072686F6E6375732070756C76696E61722E20536564206E6563206E756E6320612070757275732074656D706F7220766976657272612E2050656C6C656E7465737175652073757363697069742E20446F6E656320747269737469717565207269737573206E6F6E206E6962682E20457469616D206E69736C206D61676E612C20736F6C6C696369747564696E2075742C20756C7472696365732073697420616D65742C20656765737461732065752C206E756C6C612E20416C697175616D206572617420766F6C75747061742E20566573746962756C756D2070686172657472612E2053656420656765737461732C206D657475732073697420616D6574206C6F626F7274697320636F6E7365717561742C206572617420656C697420696D70657264696574206C696265726F2C20657520696E74657264756D207175616D206D61737361206567657420646F6C6F722E2053757370656E6469737365207669746165206F64696F2E2050726F696E20626C616E646974206D617572697320696163756C6973206D657475732E0A0A566976616D757320766573746962756C756D2E20457469616D206574206E69736C2E20416C697175616D20696E206469616D2076656C20656C697420706C6163657261742073757363697069742E204475697320736F64616C6573207075727573206163206E6962682E204E756C6C6120696E206F64696F206567657420656E696D206C756374757320626C616E6469742E2043757261626974757220756C74726963657320697073756D206E6F6E206E65717565206567657374617320656C656966656E642E20536564207475727069732E2050726F696E20636F6E7365637465747565722E20566976616D7573206D61747469732E20496E20616C69717565742E0A0A4E756E632069642065726F732E20446F6E65632076656E656E617469732C206E756C6C61206574206D6174746973206C75637475732C20616E7465206C656F2073656D706572206A7573746F2C206E6F6E2061646970697363696E67206F64696F20726973757320736564206C616375732E205072616573656E7420766974616520726973757320636F6E677565206C696265726F20636F6E6775652074656D7075732E2050686173656C6C75732061632065726F732E204E756C6C61207665686963756C612C206C6F72656D20696E20616C69717565742073757363697069742C2061726375206572617420656765737461732073656D2C2071756973206C6F626F72746973207175616D20616E7465206575206D617373612E20437572616269747572206E6F6E206D617373612E2053656420626962656E64756D206C6163696E6961206F64696F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20566976616D757320766F6C757470617420626C616E646974206C616375732E2050726F696E20706F7274612C2074656C6C757320757420617563746F72206C616F726565742C206C65637475732065726F73206665726D656E74756D206C65637475732C2069642073616769747469732061726375206A7573746F20696E207475727069732E2050686173656C6C757320636F6E7365717561742E204E616D2070656C6C656E7465737175652C206D69206964207669766572726120636F6E76616C6C69732C206E756E63206C696265726F20706C616365726174206C656F2C20656C656966656E6420706F7274612073656D206E69736C2076697461652073617069656E2E2050656C6C656E746573717565206C6967756C61206C696265726F2C20747269737469717565206E6F6E2C20706F72747469746F722072757472756D2C20706F72747469746F72206E6F6E2C20657261742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E74656765722064696374756D2074656C6C7573206120746F72746F722E20566976616D75732066656C6973206E756E632C206D6F6C6573746965206E6F6E2C2072686F6E63757320717569732C2070686172657472612069642C206475692E20446F6E6563207269737573206D657475732C206672696E67696C6C612076656C2C20616C69717565742065752C20706C6163657261742069642C206E657175652E0A0A53757370656E646973736520697073756D2E20566976616D7573206C65637475732E2053656420766976657272612C206D61737361206567657420636F6E76616C6C6973206D61747469732C207175616D2074757270697320636F6E736563746574756572206E756E632C206567657420706F7375657265206D61676E612073656D2069642076656C69742E20496E206E6563206D61757269732E2041656E65616E206120707572757320736564207175616D206C6F626F72746973206672696E67696C6C612E2050726F696E20756C74726963696573206C6163696E696120616E74652E205365642061646970697363696E67206572617420717569732076656C69742E204E756C6C616D207669746165206E69736C206964206A7573746F20736F6C6C696369747564696E206D6F6C65737469652E204E756C6C6120666163696C6973692E20536564206E65632075726E6120736564206E69736C206672696E67696C6C6120646170696275732E204E756C6C61206174206469616D2E20416C697175616D2065676574206E6962682E204E756E63206163206E6973692073697420616D65742074656C6C757320656765737461732074656D7075732E204E616D207363656C657269737175652075726E61206574206E657175652E20446F6E656320657374206F7263692C207361676974746973206E6F6E2C2076756C70757461746520612C20636F6D6D6F646F2065742C2061756775652E205574206461706962757320746F72746F722E205574206E756E632E20446F6E65632064696374756D2064617069627573206F64696F2E204E616D20756C7472696369657320756C6C616D636F72706572206C6967756C612E2050656C6C656E74657371756520616363756D73616E20766172697573206C656F2E0A0A4D6F72626920657569736D6F64206C616F7265657420657261742E20566976616D7573207175697320697073756D2E204D6F72626920657569736D6F642E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2053757370656E64697373652076656C2070757275732E204E756C6C616D206174206D61676E612E20437572616269747572206C61637573206C6F72656D2C20696163756C697320717569732C2064617069627573206E6F6E2C20766F6C75747061742076656C2C206E756C6C612E20446F6E656320757420617263752072686F6E63757320646F6C6F72207072657469756D2064696374756D2E204E756C6C616D2076656C206D657475732E20557420617263752E2050656C6C656E746573717565206E697369206E756E632C20706C61636572617420656765742C2074696E636964756E742076656C2C207068617265747261206E6F6E2C206E756E632E20496E74656765722074696E636964756E7420756C74726963696573206C65637475732E20496E74656765722073656D7065722C2070757275732073656420756C74726963657320666575676961742C206E756C6C61207065646520736F6C6C696369747564696E20657261742C2076656C20617563746F72206E756C6C6120697073756D2076656C206C65637475732E2041656E65616E206D692E0A0A4E756C6C616D20736564206E697369206574206172637520696D70657264696574206665726D656E74756D2E204D6175726973206E6563206D657475732E20496E20616320646F6C6F722E20496E206D6920617263752C20636F6E6775652061632C207068617265747261206E65632C207363656C657269737175652073697420616D65742C206D61676E612E20437572616269747572206C616375732E2043757261626974757220657420656C69742E20416C697175616D20756C6C616D636F72706572206E756E6320657520656C69742E2053656420636F6E76616C6C697320646F6C6F722061742076656C69742E20566573746962756C756D20646170696275732C20617567756520696420636F6E73656374657475657220706C6163657261742C206E756E63206D6173736120626C616E6469742073617069656E2C20696420616C697175616D20656C6974206E697369206964206D692E2050686173656C6C75732073617069656E206573742C20677261766964612065752C20626962656E64756D2075742C2061646970697363696E6720717569732C206573742E205574206D6F6C6573746965207175616D207669746165206F64696F2E20446F6E65632071756973207269737573206964206572617420666175636962757320736F6C6C696369747564696E2E204E616D2069642066656C69732E204D61757269732073656420656E696D207669746165206C656F20616363756D73616E207072657469756D2E0A0A4E616D206A7573746F2E20446F6E656320747572706973206E69736C2C20636F6D6D6F646F2065742C20696E74657264756D2061632C20636F6E736563746574756572206E6F6E2C206D617373612E2046757363652073656D206D657475732C206C616F72656574206E65632C20706F73756572652069642C20696D7065726469657420696E2C2076656C69742E20446F6E65632076756C707574617465206A7573746F2065676574207475727069732E204E756C6C6120706564652E204D6F7262692074696E636964756E742E20467573636520616C69717565742C207175616D20657420616C697175616D206672696E67696C6C612C20616E746520616E746520696163756C6973206475692C206E656320616C697175616D20617263752070757275732073656420657261742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050686173656C6C7573207375736369706974207175616D206574206573742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B0A0A496E7465676572207365642074656C6C75732E20536564207365642076656C697420756C74726963696573206C656F2072757472756D206C616F726565742E20536564206E6F6E2065726F7320616320707572757320736167697474697320666575676961742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E205365642068656E647265726974206C6967756C612073697420616D6574206E6962682E204D616563656E6173207475727069732E204D6F72626920636F6E7365637465747565722C20646F6C6F722065742061646970697363696E6720696D706572646965742C20616E7465206E65717565206665756769617420646F6C6F722C20617420706F727461207175616D206E657175652071756973206C6967756C612E204D61757269732073656D7065722076656C69742073697420616D657420697073756D2E2050656C6C656E7465737175652074656D7075732C20707572757320696E2072757472756D20636F6E7365717561742C20656E696D2065726174207665686963756C61206D617373612C20696420616363756D73616E206C656F2073617069656E206E65632070757275732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E20646F6C6F722E20496E746567657220666163696C69736973206C696265726F2073697420616D657420706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2055742076617269757320616C697175657420656E696D2E204E756C6C6120666163696C6973692E2043757261626974757220636F6E7365637465747565722C206F64696F206575207072657469756D2074696E636964756E742C206E756E63206E69736920616C6971756574206E657175652C2076656C20696D7065726469657420656C6974206D617373612073697420616D6574207475727069732E2050656C6C656E7465737175652074656D7075732C206F72636920766F6C757470617420626C616E646974206672696E67696C6C612C206F64696F2073656D20706F737565726520616E74652C20766974616520626962656E64756D2075726E61206C6F72656D2076697461652065726F732E205072616573656E7420766976657272612072686F6E63757320617263752E2053656420617563746F722C206573742073697420616D6574206D6F6C6C6973206D6F6C6C69732C207175616D207175616D20677261766964612073617069656E2C20696E20636F6D6D6F646F206D65747573206E756C6C6120617563746F7220656E696D2E20446F6E656320666163696C697369732E0A0A50726F696E2074696E636964756E742C2073617069656E206567657420756C747269636965732061646970697363696E672C20657374206F64696F2064696374756D20617263752C207574206D6F6C6C69732065726174206475692073697420616D65742076656C69742E204D6F726269206573742073656D2C20696E74657264756D2061742C20636F6E67756520612C20656C656D656E74756D2076697461652C206D657475732E2053757370656E64697373652069642061756775652E204D617572697320656E696D2073656D2C2070756C76696E617220656765742C2074656D70757320612C2074656D7075732073697420616D65742C2073617069656E2E20467573636520766573746962756C756D20636F6E736563746574756572206475692E2050656C6C656E74657371756520657261742E20536564206469676E697373696D20706C616365726174206F64696F2E204D616563656E61732073656D7065722072686F6E637573206C65637475732E2050686173656C6C7573207072657469756D2E2044756973206C696265726F20656C69742C20656C656966656E64206E65632C20656765737461732075742C20637572737573207365642C2066656C69732E204E616D206E69736C20617263752C20616C69717565742065742C20666163696C697369732065752C206C75637475732075742C2072697375732E20457469616D20756C7472696365732C20646F6C6F722073656420766F6C7574706174206D616C6573756164612C20747572706973206172637520696D7065726469657420746F72746F722C20657569736D6F6420636F6D6D6F646F206C696265726F206D61737361207574207175616D2E20496E7465676572206D6F6C6573746965207075727573206E6F6E20656C69742E2055742076656E656E617469732073656D70657220746F72746F722E20457469616D20626962656E64756D206567657374617320697073756D2E204D617572697320736F6C6C696369747564696E2073656D206E6563206E6962682E204E756C6C61207072657469756D206D65747573206575206D657475732E2050656C6C656E7465737175652073697420616D65742073656D2E0A0A53757370656E6469737365206163206E6973692E205574206C656F2E20566573746962756C756D2068656E647265726974207072657469756D20646F6C6F722E204E756E632066657567696174206D616C6573756164612070757275732E2043726173206574206E6962682E20437572616269747572206E756E6320657261742C206D616C6573756164612076697461652C206C616F726565742061632C20756C7472696369657320696E2C2070757275732E20566976616D75732074656C6C757320617263752C20736F64616C65732065752C20666163696C6973697320612C206C6163696E6961206E65632C206E756E632E2050656C6C656E7465737175652069642076656C69742E20496E206575206E6962682E204E756E63206E656320657261742E205365642064696374756D206E65717565207574206E69736C2E0A0A4D6F726269206C65637475732074656C6C75732C2074696E636964756E742061632C20706F72747469746F722061632C2074726973746971756520696E2C2065726F732E20446F6E6563206C7563747573206C7563747573206C656F2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2046757363652075742065737420657420656E696D207363656C6572697371756520616363756D73616E2E20446F6E6563206C6967756C612066656C69732C206C6163696E696120717569732C2070656C6C656E74657371756520696E2C2073656D70657220766573746962756C756D2C20656C69742E204D61757269732065676574206F72636920612066656C697320636F6E677565207665686963756C612E20557420736F6C6C696369747564696E2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204E756C6C616D20696420646F6C6F72207574206C6F72656D206469676E697373696D2076656E656E617469732E2053757370656E64697373652076697461652073617069656E2E2050726F696E206E6F6E206D61676E612075742065726F7320766976657272612070756C76696E61722E20446F6E65632071756973206F64696F2E204E756C6C616D206E6F6E20617263752076656C206C6F72656D20737573636970697420616C697175616D2E20416C697175616D2072757472756D2074757270697320696E206C656F2E0A0A5574206C7563747573206E6962682074726973746971756520657261742E2053757370656E646973736520626962656E64756D206F64696F20766974616520746F72746F722E20446F6E6563206C6163696E69612E204372617320736F64616C65732066656C6973206C7563747573206E756C6C612E204E616D20656C656966656E64207361676974746973206C6967756C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E64697373652076656C206E657175652E204D6F72626920616C6971756574207665686963756C61206D61676E612E2041656E65616E206174206F64696F2E20447569732070656C6C656E746573717565206D61676E612E204E756C6C6120617420746F72746F72207574206469616D2064696374756D2066617563696275732E204D617572697320717569732076656C69742E20446F6E6563206E6F6E2074656C6C7573207669746165206C6F72656D206672696E67696C6C6120706F72747469746F722E2046757363652075742073617069656E207175697320746F72746F7220666575676961742073616769747469732E20446F6E656320766976657272612073656D2076697461652073617069656E2E205072616573656E7420736F64616C65732C206C6163757320696E206672696E67696C6C6120766976657272612C206F64696F2061756775652061646970697363696E672075726E612C20766974616520696E74657264756D20616E74652073656D206E6F6E206E6973692E204E756C6C616D20746F72746F72206C6F72656D2C20656C656966656E642061632C206D6F6C6C6973206E6F6E2C206C616F726565742061632C2072697375732E20496E7465676572206F726E617265206C656F20736564206A7573746F2E2051756973717565206375727375732C2073656D206E6F6E20666163696C6973697320626962656E64756D2C206E697369206D69207661726975732066656C69732C206665726D656E74756D2066657567696174206C6F72656D2065726F73206C616F726565742072697375732E0A0A517569737175652073697420616D657420657374206574206C6F72656D207665686963756C61206C6163696E69612E20446F6E6563206E656320746F72746F722E2043726173206F64696F2E204E616D207363656C657269737175652076756C7075746174652075726E612E205072616573656E74206475692E20457469616D206E6563206E69736C206C6F626F7274697320697073756D20616C69717565742074656D7075732E204D616563656E6173207072657469756D20736F6C6C696369747564696E206D61757269732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206175677565206D617373612C20636F6E67756520656765742C20636F6E76616C6C697320656765742C207472697374697175652073697420616D65742C2065726F732E2053656420636F6E736571756174206E6973692065752066656C69732E2050656C6C656E746573717565206A7573746F2E2053757370656E6469737365206E6F6E2061756775652E20496E206469676E697373696D206C6F626F72746973206D61757269732E204D61757269732073616769747469732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E0A0A5365642061646970697363696E672E20446F6E656320612074656C6C75732076697461652065737420637572737573207665686963756C612E204E616D20616E74652073656D2C20736F64616C65732069642C206672696E67696C6C612076656C2C20636F6E64696D656E74756D2076656C2C206E756C6C612E205175697371756520736F64616C65732E20457469616D20696D7065726469657420656C6974206964206F64696F2E20416C697175616D206572617420766F6C75747061742E204D616563656E617320706F7274612074656D706F7220617263752E204E756C6C612073656D2061756775652C2070656C6C656E7465737175652061632C20636F6E7365717561742075742C20636F6E64696D656E74756D20657569736D6F642C2072697375732E2053656420616C697175616D2074696E636964756E74206D692E20496E20696E74657264756D206C6F626F72746973206F7263692E0A0A536564207665686963756C612068656E6472657269742070757275732E20457469616D2061206469616D2E2043757261626974757220636F6E76616C6C69732E2053757370656E64697373652061206E6973692E20446F6E6563206964206D61676E6120696E207175616D20736F6C6C696369747564696E20756C747269636965732E20446F6E656320766976657272612E205175697371756520766F6C757470617420657374207365642073656D2E20416C697175616D206A7573746F2E20566573746962756C756D20746F72746F72206D617373612C20706F72747469746F72207365642C2076617269757320717569732C20696163756C697320717569732C206F64696F2E20416C697175616D2065676574206E657175652E0A0A4D6175726973206E756C6C612E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566573746962756C756D206575207175616D20696E206E6571756520756C7472696365732070656C6C656E7465737175652E204372617320696E20646F6C6F722071756973207175616D207661726975732068656E6472657269742E20416C697175616D206E697369206C616375732C206C6F626F727469732065752C20636F6E76616C6C69732073697420616D65742C20666163696C697369732075742C206D692E20416C697175616D206174206E657175652E204372617320736167697474697320656C656D656E74756D206A7573746F2E20566573746962756C756D207574206C656374757320616C6971756574207075727573206D616C65737561646120766F6C75747061742E2044756973206174206C616375732061646970697363696E67206C696265726F2074696E636964756E7420766573746962756C756D2E204D6F7262692061206C696265726F2E20437261732070757275732E204D6F72626920757420617567756520657420707572757320696E74657264756D207363656C657269737175652E20496E74656765722061206475692E20496E206861632068616269746173736520706C617465612064696374756D73742E2044756973207068617265747261206D657475732065676574206D61757269732E20416C697175616D20696E74657264756D20756C6C616D636F72706572206D617373612E0A0A457469616D206F726E6172652E204E756C6C616D20657569736D6F642E2041656E65616E20636F6E7365717561742067726176696461206C6967756C612E20416C697175616D206573742E2050726F696E207669746165206C616375732E205072616573656E7420612065726F732073697420616D657420647569206C756374757320636F6D6D6F646F2E2050686173656C6C7573207665686963756C612061726375206567657420646F6C6F722E205072616573656E74206665726D656E74756D20636F6E677565206C656F2E20416C697175616D20766F6C7574706174207075727573207574206C6F72656D2E2046757363652068656E64726572697420656E696D206174206C656F2E20416C697175616D2072686F6E637573206E69736C2E20566976616D75732064696374756D2065676573746173206D692E2053757370656E64697373652070656C6C656E74657371756520626962656E64756D20646F6C6F722E2050656C6C656E7465737175652074696E636964756E742C207475727069732073656D7065722070656C6C656E74657371756520636F6E64696D656E74756D2C20697073756D206D6574757320736F64616C6573206C6967756C612C20696420766F6C7574706174206469616D2074757270697320757420656C69742E0A0A5072616573656E7420736564206C616375732E204E616D20656C656966656E64206D6F6C6573746965206D61757269732E20446F6E65632064617069627573206665726D656E74756D206D617373612E20446F6E656320766976657272612066617563696275732070757275732E2043757261626974757220636F6E6775652C206C696265726F20766974616520766976657272612070656C6C656E7465737175652C206469616D2076656C697420736F64616C657320656E696D2C20736564207375736369706974206C6563747573206E697369206E6563206E657175652E20566573746962756C756D206D616C6573756164612C206C616375732061742063757273757320636F6E6775652C2076656C6974206C65637475732074726973746971756520646F6C6F722C2073697420616D657420736F64616C6573206E6571756520697073756D2061206C696265726F2E20566573746962756C756D206574207175616D2E2043757261626974757220706C6163657261742E20437572616269747572206E756E6320617263752C20657569736D6F64206E65632C2076756C7075746174652068656E6472657269742C20616C697175657420656765742C207175616D2E204375726162697475722076656C20656E696D2E2053757370656E646973736520706F74656E74692E0A0A4E756E6320636F6E736571756174206F726369207574206C616375732E2046757363652076656C697420646F6C6F722C2064617069627573207365642C20626C616E6469742073697420616D65742C2072686F6E6375732069642C2072697375732E20447569732075726E61206E6962682C207363656C6572697371756520717569732C206461706962757320612C207363656C65726973717565207365642C206E6962682E20446F6E6563206C75637475732E205574206575206D617572697320637572737573206469616D206C6163696E69612072686F6E6375732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20416C697175616D207665686963756C61206D6F6C6573746965206A7573746F2E204D616563656E617320696D70657264696574207065646520736564206D692E2053757370656E6469737365206E756C6C6120646F6C6F722C2068656E64726572697420656765742C2068656E6472657269742069642C2064696374756D2076656C2C206C656F2E204475697320616363756D73616E2E2043757261626974757220696E2066656C69732E204E756E63206C6F72656D2E205574206C656F20646F6C6F722C206C616F72656574206E65632C2076756C7075746174652061742C20656C656966656E6420696E2C206E756C6C612E2051756973717565206E756E632070757275732C2076617269757320656765742C20616363756D73616E206E65632C20616C69717565742065742C206E6962682E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20437261732061646970697363696E67207669766572726120646F6C6F722E204D617572697320706F72747469746F7220756C7472696365732070757275732E204E756C6C6120666163696C6973692E205072616573656E7420666175636962757320616E7465207669746165206D61757269732E0A0A5072616573656E74206C6163696E6961206C656374757320736564206E69736C2E20496E2074656D70757320636F6E677565206D61757269732E20496E746567657220666163696C69736973206F726E61726520656E696D2E204E756C6C61206964206D617373612E20446F6E656320636F6D6D6F646F206469616D2061742074656C6C75732E204E616D20646170696275732076697665727261206573742E204E616D2074656C6C75732E205072616573656E742061206C696265726F2E20496E206661756369627573206573742065676574206E6962682E204E756C6C612065726F73206F7263692C20696D70657264696574206E6F6E2C20626C616E646974206E6F6E2C2074656D706F7220656765742C206D692E2050656C6C656E74657371756520636F6E76616C6C69732E0A0A517569737175652065676574206D69206163206C656F20657569736D6F642066617563696275732E2050686173656C6C75732072686F6E637573207075727573206964206475692E20566573746962756C756D206D616C65737561646120656C656966656E6420616E74652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050656C6C656E74657371756520626C616E646974206D6174746973206F64696F2E2053757370656E646973736520636F6E7365717561742C206C65637475732061632073656D70657220736F6C6C696369747564696E2C206D692076656C69742064696374756D2061756775652C2061632074656D70757320646F6C6F7220657261742073697420616D6574206475692E2050726F696E2068656E6472657269742C2066656C6973207175697320766F6C757470617420706F73756572652C206469616D206F64696F206D616C657375616461206F64696F2C206120696E74657264756D206F726369206469616D20717569732073617069656E2E2050656C6C656E746573717565206F64696F206F64696F2C20766976657272612076656C2C20677261766964612065752C206D6F6C6573746965207365642C206E756C6C612E2050686173656C6C7573206D617572697320706564652C20636F6D6D6F646F2075742C20657569736D6F642065752C2068656E6472657269742065752C206573742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C6120656C656D656E74756D206C616375732065752061756775652E2053656420657261742E2050726F696E20706F7274612E204D616563656E61732071756973206D692E2050686173656C6C757320617420656E696D206163206A7573746F206772617669646120756C7472696365732E2043726173206C656F2E0A0A496E746567657220757420617263752E20446F6E656320736564206D61676E612E2050726F696E2066656C69732E20496E20696163756C69732C206C6967756C61206964206672696E67696C6C61207072657469756D2C206E696268206469616D20616363756D73616E2074656C6C75732C206567657420616363756D73616E206D657475732064756920766172697573207475727069732E2050686173656C6C7573206F726369206D657475732C20656C656966656E64207365642C2074656D706F722061632C207363656C657269737175652061632C2075726E612E20496E74656765722076697665727261206E657175652061206D61757269732E204D617572697320706F72747469746F7220646F6C6F722065752076656C69742E20496E7465676572206F64696F20656C69742C20766573746962756C756D2075742C20766F6C75747061742069642C2072686F6E63757320636F6D6D6F646F2C2075726E612E20457469616D20706C61636572617420706861726574726120657261742E2055742074656D706F72206573742E20496E7465676572206469676E697373696D20626C616E6469742074656C6C75732E204D6F726269206E69626820646F6C6F722C207363656C657269737175652069642C20636F6D6D6F646F206D616C6573756164612C206D61747469732061742C206D692E20437261732074696E636964756E7420636F6D6D6F646F2070757275732E20496E2074696E636964756E742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D20756C6C616D636F727065722E2055742068656E6472657269742E204D6F72626920756C7472696365732E0A0A5072616573656E7420696163756C69732C2065726F73206163206567657374617320736F64616C65732C2075726E61206C656F206665726D656E74756D206C6967756C612C2073697420616D657420616C697175616D2076656C69742073656D206E6F6E2070757275732E20446F6E65632072757472756D206172637520717569732070757275732E204E616D20706F73756572652C206C6163757320617420636F6E73657175617420706C6163657261742C206E756C6C61207065646520706F7375657265206F7263692C206E6F6E20657569736D6F6420747572706973206475692071756973206E69736C2E2050726F696E20706F7274612061646970697363696E67206E6962682E20446F6E65632074726973746971756520646F6C6F722061742074656C6C75732E20446F6E6563206E65717565206D617373612C20617563746F722069642C2066617563696275732076697461652C20756C6C616D636F727065722076656C2C206E6973692E2050726F696E206D6F6C6573746965206E6571756520736564206D617373612E204E616D2074656D706F722E204D6F72626920616C697175616D2073617069656E2061742074656C6C75732E2046757363652071756973207269737573206574206D69207072657469756D2070756C76696E61722E2046757363652073697420616D6574206C6967756C612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E646973736520657520656E696D2065742066656C6973207363656C65726973717565206C6F626F727469732E205072616573656E7420626962656E64756D2E20566976616D7573207665686963756C612E20496E7465676572206174206E696268207365642076656C69742072686F6E637573206D6F6C65737469652E2043726173206C616375732E2053656420756C6C616D636F727065722065726F732076656C20657261742E20467573636520657520746F72746F722073697420616D6574206469616D20657569736D6F642073616769747469732E204E756E632071756973206C61637573206964206E69626820636F6E76616C6C6973207661726975732E2053757370656E6469737365207669746165206D692E20566573746962756C756D207472697374697175652E20446F6E6563206D616C65737561646120697073756D206964206E657175652E204E756C6C616D20736564206C616375732E204475697320656765737461732C206A7573746F20757420636F6E677565206F726E6172652C2061756775652073617069656E206C7563747573206469616D2C20617420616363756D73616E20657261742073617069656E207574206C696265726F2E2050686173656C6C75732076656C206E756C6C612E2053757370656E646973736520617263752074656C6C75732C20706F72747469746F7220612C2070686172657472612066617563696275732C20616C697175616D2073697420616D65742C206D617373612E204E756C6C6120706F72747469746F722074696E636964756E74206C6F72656D2E204E756E6320646F6C6F72206F64696F2C20736167697474697320696E2C206C6F626F727469732076656C2C20766F6C7574706174207365642C206E6962682E0A0A5175697371756520626C616E646974206C656F2075742073617069656E2074656D70757320666163696C697369732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2041656E65616E20756C7472696369657320706F72747469746F72206A7573746F2E2046757363652072757472756D2065726F732075742075726E612E2050726F696E2071756973207175616D20656765742064756920616C697175616D20616363756D73616E2E20446F6E656320737573636970697420656C656966656E6420656C69742E2050656C6C656E746573717565206D61747469732C2066656C697320736F64616C657320696163756C697320696D706572646965742C206C616375732073656D20636F6E76616C6C69732061756775652C2073697420616D657420616C69717565742061726375207075727573206672696E67696C6C612072697375732E20496E206575206F64696F206964206D61676E61207068617265747261206F726E6172652E20416C697175616D20696E74657264756D2070756C76696E617220697073756D2E20536564206E657175652E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D2073697420616D6574206E6973692E2055742061742061756775652E204D617572697320766F6C757470617420626C616E646974206C6967756C612E204E756C6C61206575206D657475732E20566573746962756C756D206567657420656C69742E205072616573656E7420706F73756572652E20566573746962756C756D2069642073656D206E6F6E206C6563747573206D6F6C6C69732074696E636964756E742E20416C697175616D2069642066656C697320617420616E7465206F726E6172652074656D706F722E204E756C6C61206C61637573207475727069732C20666575676961742076697461652C2063757273757320717569732C20636F6E736563746574756572206E6F6E2C206D61757269732E204675736365206C61637573206D617373612C20706F72747469746F722075742C206D6F6C65737469652075742C2076656E656E6174697320612C206C6F72656D2E205072616573656E742073697420616D6574206F7263692E204D61757269732072686F6E6375732066656C69732076697461652066656C69732061646970697363696E6720696D706572646965742E204D616563656E6173206D6F6C6C6973206469616D206E6563206C656F2E0A0A467573636520656E696D20697073756D2C20756C7472696365732065752C206D6F6C65737469652069642C20656C656D656E74756D2069642C2073617069656E2E20496E746567657220612075726E612E204E616D2076656C6974206C696265726F2C2076656E656E6174697320656765742C2074656D706F722073697420616D65742C20666575676961742076697461652C20616E74652E204675736365206E756E632E205365642073656D706572206E69736C206E65632072697375732E20496E20736564206C696265726F2E2050726F696E20746F72746F72206E657175652C2074696E636964756E742061632C2074656D706F722061632C20706861726574726120717569732C2076656C69742E2044756973206C65637475732061756775652C20756C747269636965732076656C2C20636F6E7365717561742069642C20696163756C69732069642C20616E74652E20566976616D757320617563746F72206D65747573206120616E74652E204375726162697475722061726375206E6973692C20666163696C697369732061742C206C616F7265657420696E2C20636F6E736563746574756572207365642C206D61757269732E205175697371756520706C616365726174206469616D20736564206475692E20566976616D7573207072657469756D20636F6E64696D656E74756D206C6F72656D2E20437572616269747572206C616F726565742E2041656E65616E206F726369206C6967756C612C2063757273757320656765742C206C6163696E6961206E6F6E2C2066617563696275732076656C2C206C6F72656D2E0A0A416C697175616D206572617420766F6C75747061742E204375726162697475722065726F7320646F6C6F722C20636F6E67756520612C20636F6E64696D656E74756D207365642C206C75637475732075742C206E6962682E204D616563656E6173206E6F6E20746F72746F72206E65632074757270697320636F6D6D6F646F2070656C6C656E7465737175652E205072616573656E7420657569736D6F6420706C616365726174206D692E2053757370656E646973736520706F74656E74692E2050686173656C6C7573207574206E65717565207669746165206F726369206D617474697320696163756C69732E20496E746567657220656765742074656C6C75732E20446F6E656320617420616E74652E204E616D206C6163696E6961206C656F206567657420657261742E204D616563656E617320657569736D6F64206D61676E6120636F6E67756520746F72746F722E204D6F726269206E6563206D6173736120657520656E696D206D616C65737561646120736F6C6C696369747564696E2E2053656420616363756D73616E2E204E756C6C616D20697073756D2E205574206F64696F2E20416C697175616D206572617420766F6C75747061742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2050656C6C656E7465737175652069642076656C69742E204E616D206F64696F2073656D2C20616C69717565742075742C2074656D7075732073697420616D65742C20657569736D6F642065742C206E756E632E0A0A50656C6C656E746573717565206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205072616573656E74206D6175726973206E756E632C207661726975732075742C20636F6E76616C6C6973206D6F6C65737469652C206C75637475732073697420616D65742C206C656F2E205365642064696374756D206C6F72656D20657420617263752E204E756E632076656E656E617469732070656C6C656E746573717565206D617373612E204E756C6C6120666163696C6973692E2050686173656C6C757320696E20746F72746F722065676574207269737573207363656C657269737175652076756C7075746174652E20536564206E69626820656C69742C2073616769747469732061632C20636F6E64696D656E74756D206E65632C20636F6E76616C6C69732065742C206A7573746F2E20467573636520766F6C7574706174206D657475732E204E756E6320617563746F722E20566573746962756C756D206C656F2065726F732C2070656C6C656E7465737175652061632C206D6F6C6C697320756C7472696365732C2072686F6E637573206E6F6E2C20646F6C6F722E204D6175726973207665686963756C6120706C616365726174206E69736C2E20566573746962756C756D20626962656E64756D2C2061726375207175697320636F6E67756520656C656D656E74756D2C2076656C6974206E756E6320656C656966656E64207475727069732C206964206C7563747573207269737573206E69736C2073697420616D65742074656C6C75732E2050686173656C6C75732070656465206E657175652C20626C616E646974206E6F6E2C20636F6D6D6F646F2076697461652C20756C7472696369657320656765742C206D61676E612E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120666163696C6973692E20416C697175616D20616320616E74652E20437261732072697375732E204D6F726269206D6175726973206C616375732C20706F73756572652065752C20626C616E6469742065742C2070686172657472612061742C206D692E2050726F696E2061632070757275732E204475697320637572737573206E69736C2072757472756D207175616D2E20416C697175616D2061206F64696F206E6F6E206D61676E612070656C6C656E74657371756520756C747269636965732E204D616563656E6173206163206D6173736120717569732073617069656E20756C6C616D636F727065722074656D7075732E2043726173206375727375732076656C6974207365642073617069656E2E2050726F696E206E756C6C612E20566976616D757320736F64616C657320616C697175616D206E6962682E20457469616D206574206572617420757420616E7465206C6163696E696120657569736D6F642E204675736365206E6973692E2050726F696E2071756973206E756C6C612E0A0A517569737175652076656E656E617469732C2065726F7320736564206C616F7265657420736F6C6C696369747564696E2C206F72636920616E74652070656C6C656E746573717565206E69736C2C2073697420616D65742076697665727261207175616D2065726174206E6F6E2072697375732E20437261732065676574206C696265726F2E2053656420656C6974206D61676E612C2073656D7065722065752C206672696E67696C6C6120696E2C206469676E697373696D20736F64616C65732C20657261742E20566976616D757320666575676961742073656D2076656C206475692E20446F6E656320636F6E76616C6C697320736F6C6C696369747564696E206469616D2E2043726173207365642070757275732E20446F6E65632066656C69732065726F732C2073656D70657220656765742C2074656D706F7220636F6E7365637465747565722C20736167697474697320717569732C206E69736C2E204475697320696E20616E74652E2043726173206E6F6E207475727069732E204E756C6C612074656D706F722076656C697420616C697175657420747572706973206D6F6C657374696520706C6163657261742E2050726F696E20656C656D656E74756D206665726D656E74756D206D61757269732E20566976616D757320736564206F726369206C6163696E69612064756920706C6163657261742076656E656E617469732E20566573746962756C756D20666575676961742C2074656C6C757320696E20766F6C75747061742072757472756D2C206D61676E61206E69736920756C6C616D636F727065722065726F732C2069642070756C76696E6172206E657175652065726174207574206C616375732E20566976616D7573207365642061756775652E204E756C6C6120666163696C6973692E204D616563656E617320616E74652061756775652C20656C656D656E74756D2075742C20736F64616C65732076697461652C20636F6E64696D656E74756D206E65632C206C6F72656D2E20447569732070656465206F7263692C206672696E67696C6C612061742C20656C656966656E64206E65632C207072657469756D20696E2C20657261742E204E616D2073616769747469732C2074757270697320766974616520636F6E76616C6C69732070686172657472612C206F64696F2073656D207363656C65726973717565206C616375732C206E6563206C6F626F7274697320647569206469616D2076656C2065726F732E20496E2073656D7065722067726176696461206E657175652E0A0A496E7465676572206E756E632E205574207072657469756D20697073756D2073697420616D657420656C69742E20496E206E656320617263752E2053656420766573746962756C756D2076756C70757461746520697073756D2E2050656C6C656E7465737175652074696E636964756E742E204E756C6C61206772617669646120646F6C6F7220696E2074656C6C75732E2043726173207665686963756C612C20646F6C6F722075742070656C6C656E74657371756520616C697175616D2C206572617420656E696D20617563746F72206D617373612C207665686963756C61206C6F626F72746973206F64696F2065726F732071756973207175616D2E2050726F696E2064617069627573206E6571756520696E20656E696D2E2050726F696E20656C69742E20496E74656765722072686F6E6375732074696E636964756E7420656C69742E204675736365206C6F72656D206D657475732C2073656D7065722061632C20766F6C75747061742076697461652C20666163696C697369732075742C2074656C6C75732E20446F6E65632076656C20747572706973207669746165206E69736920706861726574726120706F72747469746F722E204D616563656E617320746F72746F722E204675736365206D692E204E756C6C616D206E6563207475727069732E2053656420736F64616C657320766573746962756C756D206E756E632E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A50656C6C656E74657371756520646F6C6F7220646F6C6F722C206C616F726565742065752C20616C697175657420717569732C207363656C657269737175652073697420616D65742C20617263752E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C616D206375727375732075726E61206567657420656C69742E205175697371756520626C616E6469742073617069656E20616320616E74652E2050726F696E206E756C6C612065726F732C206772617669646120766F6C75747061742C20736F64616C65732076656C2C206D6F6C6C69732065752C206D617373612E204E756C6C612074726973746971756520736F6C6C696369747564696E206E69736C2E20437572616269747572207669746165206C6F72656D2076697461652076656C69742065676573746173206F726E6172652E2041656E65616E20656765742065726F732E20416C697175616D206572617420766F6C75747061742E20467573636520612075726E61206964206F64696F20616C697175657420636F6E76616C6C69732E204375726162697475722073697420616D6574206E69736C20706F7375657265206C656F20706F737565726520646170696275732E2044756973206D6574757320657261742C206C75637475732076656C2C2072686F6E6375732061742C20636F6E76616C6C69732073697420616D65742C20656E696D2E20566976616D75732068656E6472657269742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D206567657420656C69742E0A0A4E756C6C616D2061206E756E632E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206D657475732075726E612C2074696E636964756E742065742C206C6163696E69612073697420616D65742C206C6F626F727469732076697461652C206C6967756C612E2050726F696E206574206D6175726973207669746165206D6920616363756D73616E2070656C6C656E7465737175652E20457469616D207175616D2070757275732C2068656E647265726974207365642C20666575676961742076697461652C20657569736D6F6420656765742C20746F72746F722E20557420616C697175616D206D61676E61207669746165206A7573746F2E2053757370656E6469737365206E6F6E206A7573746F2076656C2076656C697420636F6E64696D656E74756D2074656D7075732E20447569732074656D70757320697073756D2076697461652074656C6C75732E2050726F696E20696E206D617373612E20457469616D20756C6C616D636F727065722064696374756D2074656C6C75732E2050726F696E20616C69717565742066656C6973206174206C656F206C616F726565742070756C76696E61722E20566573746962756C756D20617263752070757275732C206D616C6573756164612073697420616D65742C206375727375732065752C20706C6163657261742073697420616D65742C206E756E632E204E616D206D61737361206F64696F2C20736F6C6C696369747564696E20696E2C2061646970697363696E6720612C20616C697175616D206E65632C2072697375732E20416C697175616D20626C616E6469742068656E647265726974206C696265726F2E204D617572697320677261766964612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204375726162697475722061206E6962682E20557420696E74657264756D206665726D656E74756D206E657175652E2050656C6C656E74657371756520736564206E756E632E204D6175726973207665686963756C61206E697369206574206E756E632E205072616573656E74206C6F72656D2E20446F6E65632073656D7065722E20496E7465676572206575206C6163757320696E2065737420616C697175616D2068656E6472657269742E20566573746962756C756D2065676574206E657175652E205365642073656D706572206C75637475732076656C69742E20437572616269747572206E6962682061756775652C20636F6E6775652065752C2068656E6472657269742069642C20636F6E6775652065742C20656E696D2E20496E746567657220706C61636572617420616C697175616D206C65637475732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20566976616D75732076697461652065726F732E20446F6E65632076656C206E69736C2E0A0A496E20766573746962756C756D20666163696C697369732075726E612E2055742072697375732E204D61757269732070686172657472612E2050656C6C656E746573717565206D61747469732E20496E746567657220737573636970697420616C697175616D20697073756D2E204475697320626C616E6469742C2073617069656E20657420756C7472696369657320636F6E64696D656E74756D2C2066656C6973206D6920656C656D656E74756D20706564652C206E6563207361676974746973206D65747573206D61757269732071756973207175616D2E205175697371756520616363756D73616E20617263752076656C206E756C6C612E20437261732073656D2073617069656E2C20706F72747469746F722069642C20756C747269636965732073616769747469732C206C75637475732065752C206E756C6C612E20496E746567657220717569732065726F732E204D6F726269207365642075726E6120612074656C6C7573207665686963756C612076756C7075746174652E20457469616D206E656320617567756520656765742066656C69732073656D706572207472697374697175652E205175697371756520757420646F6C6F722076656C2072697375732064696374756D20636F6E7365717561742E20536564206567657420646F6C6F7220736564206E756E63206C6163696E696120616C69717565742E2053757370656E646973736520616320746F72746F7220696E20697073756D20706F73756572652076656E656E617469732E20536564206567657420657261742E204E756C6C612066617563696275732E2044756973206C616F726565742C206D6173736120706F72747469746F7220616C697175657420656765737461732C20697073756D206C65637475732072686F6E637573207175616D2C20696E2061646970697363696E672065726F732073656D2075742074656C6C75732E2050656C6C656E74657371756520666575676961742074656D707573207175616D2E20566976616D757320696420646F6C6F7220656765742073617069656E20636F6E7365637465747565722074656D706F722E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120696163756C6973206665726D656E74756D206C696265726F2E204375726162697475722066617563696275732C206D61737361206D616C657375616461206375727375732074696E636964756E742C20657261742073656D20656C656966656E64206D61757269732C20736564206672696E67696C6C61206D6920616E74652061632070757275732E204475697320656C656D656E74756D206C65637475732E204E756E63206F726E617265206172637520657520746F72746F722E20566573746962756C756D2076656C20646F6C6F72206174207075727573206C6163696E6961206672696E67696C6C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E616D20696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204D616563656E61732074696E636964756E742C2065726F73206120656765737461732070656C6C656E7465737175652C2072697375732072697375732064696374756D206C696265726F2C20696420616C6971756574206D65747573206A7573746F20696E206D617373612E2050726F696E20612074656C6C75732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205365642070757275732E20536564206E6F6E20706564652E2041656E65616E206D617373612073617069656E2C20736F64616C65732073697420616D65742C20636F6E7365717561742064696374756D2C20656C656966656E642076697461652C20746F72746F722E20446F6E656320756C747269636573206C6163696E696120656C69742E0A0A4D6F7262692061646970697363696E6720736F64616C657320646F6C6F722E20557420756C6C616D636F7270657220756C74726963696573206573742E20496E2076656E656E617469732074656D7075732061756775652E2053757370656E646973736520746F72746F7220646F6C6F722C20616363756D73616E2065742C20737573636970697420612C2074696E636964756E742075742C206C696265726F2E20416C697175616D207363656C65726973717565206D61676E61207365642066656C69732E2051756973717565207574206E756E632061206D61676E612076756C70757461746520706C6163657261742E20416C697175616D2072686F6E637573207665686963756C61206475692E2053656420746F72746F722E204E756C6C616D2073697420616D6574206469616D2E204E756E63207365642065726F732E20536564206574206F64696F2074696E636964756E7420656C6974206772617669646120636F6E76616C6C69732E20437572616269747572207175697320746F72746F722061206C616375732073656D706572207661726975732E204D6175726973206174206175677565206E6F6E206D6920736F6C6C696369747564696E20616C697175616D2E20496E746567657220756C6C616D636F727065722E2050656C6C656E746573717565207375736369706974207175616D206E6F6E2070757275732E20416C697175616D2061632065726F73206174206172637520756C6C616D636F7270657220636F6E7365637465747565722E2053757370656E6469737365207072657469756D206D6174746973206C656F2E0A0A44756973206174206E756E632E2053656420646F6C6F72206573742C207661726975732061632C20706F7274612065742C2074696E636964756E742068656E6472657269742C2072697375732E20566976616D7573207574206D61676E612E205072616573656E74207574206D61757269732E20496E207075727573206C616375732C206D6174746973207365642C20766573746962756C756D206E65632C2074656D706F722061742C206E69736C2E204372617320756C6C616D636F727065722076656E656E617469732074656C6C75732E20557420646F6C6F722E204D616563656E6173206D616C6573756164612C207065646520612070756C76696E6172206D61747469732C2061726375206469616D207665686963756C612072697375732C207175697320706F72747469746F72206175677565206D6173736120696E2076656C69742E204E756E6320636F6E6775652E204D6F7262692076656C6974206D657475732C2072686F6E6375732065742C20616C697175616D20636F6E7365637465747565722C20756C74726963696573206D616C6573756164612C206C6967756C612E205365642076656C6974206E69736C2C2073616769747469732076697461652C20706861726574726120612C20706F7375657265207365642C206D617373612E204E756C6C6120666163696C6973692E20496E207661726975732C206C6967756C61206964206C6F626F7274697320736F64616C65732C206175677565206F726369206665726D656E74756D2074656C6C75732C2065752070756C76696E6172207269737573206C6967756C6120612073617069656E2E204D6F726269206C616F7265657420697073756D206E6F6E206D692E204E616D20637572737573206C6F72656D207574206D692E20566976616D7573206D61676E6120656E696D2C20706F7375657265206E6F6E2C2073656D70657220717569732C20736F64616C65732065752C20617263752E20457469616D206D692070757275732C207072657469756D20666575676961742C20766172697573207365642C2070656C6C656E74657371756520656765742C206C6967756C612E20496E206C656F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E6563207669746165206F726369206575206F72636920736F6C6C696369747564696E20666575676961742E0A0A5072616573656E74207075727573206D617373612C20657569736D6F642076697461652C2074656D707573206E65632C20636F6E7365717561742068656E6472657269742C206D657475732E2041656E65616E2066656C6973206573742C20656765737461732076697461652C20616363756D73616E20656765742C2070656C6C656E74657371756520696E2C2073617069656E2E204475697320646170696275732070656465206E6F6E2073617069656E2E204E756E632075726E612E20496E74656765722076656C206C696265726F2E204475697320617567756520617263752C2064617069627573206E6F6E2C20666163696C697369732076697461652C20706F73756572652075742C2065726F732E20446F6E6563207669746165206E756E632073697420616D6574206172637520696D706572646965742064696374756D2E204D6F72626920656C656966656E642C206C6F72656D20657520636F6E73656374657475657220766573746962756C756D2C206469616D206E756E63206F726E61726520617263752C2061632074656D706F722066656C697320646F6C6F7220656765742065726F732E2050686173656C6C7573206D617373612073656D2C20736F6C6C696369747564696E2061632C20736F64616C657320677261766964612C206C756374757320612C207175616D2E204E616D206E65717565207175616D2C20766976657272612061742C2076656E656E6174697320717569732C207361676974746973206E6F6E2C20656E696D2E0A0A4E756C6C6120666163696C6973692E2050656C6C656E7465737175652065676573746173206C6163696E6961206573742E205365642074696E636964756E742C2070656465207365642074696E636964756E7420766573746962756C756D2C2075726E6120646F6C6F722061646970697363696E672070757275732C207669746165206672696E67696C6C612066656C697320656C697420696E206E6962682E204E756C6C6120736564206E6973692E204D6175726973207375736369706974207363656C6572697371756520617263752E20457469616D206E6F6E20656E696D2076656C2065726F7320616363756D73616E206D616C6573756164612E204E756E632074696E636964756E7420636F6D6D6F646F206D61757269732E20496E2074696E636964756E7420726973757320717569732075726E612E204E756C6C61206469616D20746F72746F722C20616C69717565742065742C2074696E636964756E7420717569732C20736F6C6C696369747564696E2061632C20746F72746F722E2043726173206E69736C206E657175652C2076756C7075746174652073757363697069742C206D6F6C657374696520717569732C2070756C76696E61722061742C206E756C6C612E204E756C6C616D206163206D65747573206E6563206F64696F20706F7375657265207661726975732E2043726173207365642070656465206E65632064756920706F737565726520626962656E64756D2E204475697320657569736D6F6420756C6C616D636F72706572206C696265726F2E20416C697175616D2066617563696275732070756C76696E6172207475727069732E0A0A496E207574206E65717565206964206E756E63206665756769617420636F6D6D6F646F2E20437572616269747572206469676E697373696D2C2066656C697320617420736F6C6C696369747564696E206C6163696E69612C20656E696D20656C6974207375736369706974206E657175652C20736564206C7563747573206C6F72656D20697073756D20696E206C656F2E204475697320646170696275732C206F64696F207175697320617563746F7220636F6D6D6F646F2C206E69736C206F64696F206D61747469732074656C6C75732C206E65632074696E636964756E7420747572706973206469616D20696E20617263752E2043757261626974757220612073656D2E204E756C6C616D20766F6C7574706174206D61676E612E2050656C6C656E7465737175652073616769747469732C206E6571756520636F6E736571756174207072657469756D206375727375732C20646F6C6F72206C6163757320636F6E73656374657475657220617263752C20736564206C616F72656574206573742075726E61206574206D657475732E2053757370656E646973736520706C6163657261742C20647569206120706F7274612074656D706F722C206C6F72656D20647569206C6F626F72746973206E657175652C207365642076656E656E61746973206469616D20656E696D2069642065726F732E20457469616D206574206E69736C206E6F6E206C656374757320666175636962757320636F6E7365637465747565722E204D6F726269207363656C657269737175652C2073656D206E65632074656D70757320756C6C616D636F727065722C20697073756D206469616D2066657567696174206C6F72656D2C2061206672696E67696C6C612073617069656E20656C69742071756973206E6962682E204E756C6C616D206469616D2075726E612C2076697665727261207365642C2070686172657472612072686F6E6375732C2074696E636964756E742076656C2C206F7263692E20496E746567657220616363756D73616E206D617474697320657261742E204E616D2064696374756D2E204D6175726973206E6563206C656F2E204E756C6C6120696163756C69732E204E756C6C61206E69736C206D692C206461706962757320717569732C207665686963756C6120612C2063757273757320656765742C206F64696F2E0A0A50686173656C6C7573206461706962757320657569736D6F64206E6962682E20566976616D757320696D7065726469657420616E746520696E206C6967756C612E2050656C6C656E74657371756520616363756D73616E2E20496E20696D706572646965742C20647569206120617563746F72206672696E67696C6C612C206D65747573206E6973692063757273757320646F6C6F722C2076656C206C7563747573206C6967756C61206C6F72656D207669746165206D61757269732E205072616573656E74206D617474697320766573746962756C756D20656C69742E20416C697175616D20656E696D206C616375732C2070756C76696E6172206E6F6E2C206C6163696E69612073697420616D65742C20656C656966656E64206E6F6E2C2076656C69742E20566573746962756C756D206163206C656F2E204D617572697320696D70657264696574206A7573746F206163206C65637475732E20536564206D6F6C6573746965206C656374757320736564206475692E20536564206665726D656E74756D2074656D707573206D61757269732E204E616D206F726E617265206F7263692061632074656C6C75732E205574206D616C6573756164612C206C61637573206964206C6163696E696120616363756D73616E2C206469616D20656C69742061646970697363696E67206D657475732C20657420626962656E64756D2073617069656E206E69626820626C616E646974206F7263692E2053757370656E646973736520697073756D2074656C6C75732C20736167697474697320717569732C20766573746962756C756D206E6F6E2C2076756C7075746174652065752C2065726F732E205072616573656E74206174206E756C6C612069642070656465207363656C6572697371756520756C747269636965732E204372617320626C616E646974207072657469756D2074656C6C75732E204D616563656E6173206461706962757320636F6E64696D656E74756D2061756775652E2050686173656C6C75732074696E636964756E74207068617265747261206C6F72656D2E204D6F726269206E6F6E2065726F732E205365642074656D706F722C206E69736C20612074696E636964756E742074696E636964756E742C2065726F73206469616D2064696374756D2073656D2C2076656C206469676E697373696D20616E7465206469616D20736564206D61676E612E205072616573656E74206E6F6E206C6967756C61206964206D65747573206D6F6C657374696520636F6E7365637465747565722E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E64697373652076656C206D692E2043757261626974757220616E7465206E756C6C612C2072757472756D20612C20636F6E76616C6C69732076656C2C207665686963756C612061632C206E756E632E204E756E632073616769747469732C20656E696D2073697420616D657420617563746F722072757472756D2C206D617572697320617263752076756C707574617465206E657175652C20657420657569736D6F64206573742066656C6973207175697320616E74652E20566573746962756C756D207475727069732074656C6C75732C2068656E64726572697420696E2C206C6163696E696120636F6D6D6F646F2C20756C6C616D636F7270657220677261766964612C2072697375732E204D61757269732072686F6E637573206C6163696E69612072697375732E204D616563656E617320736F6C6C696369747564696E2065726174207669746165206E756E632E205072616573656E74207072657469756D2070656C6C656E7465737175652061756775652E20446F6E656320696E74657264756D2E205072616573656E742061632065726F732076697461652065726174206C6F626F72746973206672696E67696C6C612E2041656E65616E20636F6E7365717561742074656C6C75732E204E756C6C6120616363756D73616E20626962656E64756D2066656C69732E204D616563656E6173207072657469756D20616E7465206964206E6973692E2041656E65616E206D6920617263752C2073656D706572207365642C206D61747469732065752C2076656E656E617469732073697420616D65742C20617263752E20446F6E656320616C697175657420657569736D6F64206C656F2E2050726F696E206D61676E61206A7573746F2C2074726973746971756520612C2073656D7065722061632C20736F6C6C696369747564696E20612C206C6967756C612E204D6F7262692076656C69742E20416C697175616D2076656C206E6973692E0A0A496E2061206C6F72656D207574206E756E63206665756769617420636F6E6775652E20446F6E6563206665726D656E74756D20626962656E64756D206475692E2050726F696E207661726975732065737420717569732076656C69742E20446F6E656320616C69717565742073656D20616363756D73616E206D692E2053656420706C6163657261742E204E756C6C616D206163206E6973692061206D61737361206C6F626F727469732073757363697069742E204E756E63206964206C656F2E20416C697175616D206574206D617373612E204E756C6C616D20766573746962756C756D20656C656D656E74756D206D657475732E20496E20636F6E736563746574756572206E6973692076656C206A7573746F2E204D616563656E6173206567657420707572757320736564206D61737361207661726975732070656C6C656E7465737175652E2050686173656C6C75732066617563696275732066656C697320717569732066656C69732E2041656E65616E206F64696F20617263752C20626C616E64697420717569732C20666163696C6973697320696E2C20696D706572646965742065752C206C6F72656D2E204E616D20706F73756572652070756C76696E6172206D692E204675736365207472697374697175652C206D617572697320657420636F6E73656374657475657220756C747269636965732C206D6175726973206C65637475732074656D706F72206A7573746F2C206174206672696E67696C6C61206573742065737420736564206E6973692E20517569737175652066617563696275732E2053656420696E20746F72746F722074696E636964756E7420657374206C6163696E696120696163756C69732E204D616563656E61732061206D617373612E2050656C6C656E7465737175652061206E69626820617420707572757320706F7274612068656E6472657269742E0A0A4E756C6C616D207475727069732E2046757363652061632073656D20736564206F64696F2070656C6C656E74657371756520696D706572646965742E2043757261626974757220696E20617263752E205072616573656E74206C61637573206C616375732C20666575676961742069642C2070756C76696E617220696E2C2074696E636964756E74207365642C206E657175652E204D616563656E61732076697665727261206F64696F206567657420746F72746F722E20496E746567657220616C697175616D2C206C6F72656D2072757472756D2076656E656E61746973206469676E697373696D2C206C6967756C61206D61676E61206D616C65737561646120617263752C2076656C2066657567696174206C6F72656D20697073756D2071756973206D617373612E204D6F72626920616E74652E20566573746962756C756D206D6175726973206C696265726F2C20756C6C616D636F7270657220717569732C20756C74726963657320717569732C20666163696C69736973206E6F6E2C206D617373612E204D616563656E617320696D706572646965742E20416C697175616D206572617420766F6C75747061742E2050656C6C656E746573717565206469676E697373696D2067726176696461206C65637475732E20496E206E696268206F64696F2C20617563746F7220656765742C206461706962757320717569732C206469676E697373696D2076656E656E617469732C20617263752E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20447569732070656C6C656E746573717565206C6967756C612071756973206D617373612E2043757261626974757220636F6E64696D656E74756D2C206A7573746F2065676574206F726E617265206C75637475732C206C6F72656D206C6967756C6120736167697474697320706564652C206120706F727461206E756E63206E756E6320696E206E657175652E20517569737175652066656C6973206D61757269732C20636F6E64696D656E74756D2076697461652C20617563746F722076697461652C2074696E636964756E7420717569732C20706564652E204E756E63206C6163696E696120616E746520696E206C656F2E2050656C6C656E746573717565206C696265726F2E2041656E65616E2061206C6967756C61206574206E756E6320766573746962756C756D20636F6E7365637465747565722E0A0A4675736365206F726E6172652E205072616573656E742069642075726E612E20496E74656765722076656E656E617469732C207175616D206E6F6E20736167697474697320616363756D73616E2C20616E7465206E6962682073616769747469732061756775652C20736F6C6C696369747564696E2061646970697363696E6720646F6C6F722076656C697420657520657261742E2050726F696E207175697320656E696D206575207075727573207665686963756C6120616C697175616D2E204E756C6C612076656C20656E696D2076656C20656C697420736F6C6C696369747564696E206672696E67696C6C612E20416C697175616D206572617420766F6C75747061742E205365642073757363697069742066656C6973207574207475727069732E20457469616D2072757472756D20726973757320696D70657264696574206573742E20416C697175616D20612074656C6C75732061742074656C6C757320636F6D6D6F646F20646170696275732E204D61757269732072757472756D206D61676E61206574206F64696F2E20496E20617420646F6C6F722E20437572616269747572207665686963756C61206C656374757320696E20746F72746F722E204675736365206A7573746F2070757275732C206C75637475732076697461652C206D6F6C6C697320696E2C2070686172657472612061632C2070757275732E204E756C6C616D20706F737565726520696E74657264756D206A7573746F2E20437572616269747572207669746165206C616375732076656C206C656F20636F6E6775652070756C76696E61722E0A0A41656E65616E20656C656966656E64206E6962682076617269757320746F72746F722E2053757370656E64697373652076656C2065726F732E2050726F696E206E6563206469616D206120746F72746F7220756C747269636573206F726E6172652E20416C697175616D207363656C657269737175652066657567696174206A7573746F2E20566976616D757320616E74652075726E612C2061646970697363696E672076697461652C20706F72747469746F722065752C20736F64616C65732065742C2066656C69732E2053757370656E646973736520706F74656E74692E20437572616269747572206163206D6173736120696E206E69736C207361676974746973206D6F6C6C69732E204E616D207175616D206C6967756C612C20636F6E73656374657475657220656765742C20696163756C69732061742C207661726975732065752C206C656F2E204475697320646F6C6F72206C6967756C612C2074696E636964756E742061742C20756C6C616D636F72706572207365642C20616363756D73616E20616C697175616D2C206C6967756C612E2050686173656C6C75732076756C7075746174652C206C6F72656D2061742074696E636964756E742070686172657472612C207269737573206C6563747573206C6163696E6961206D61676E612C20717569732072757472756D20656E696D206D61676E612061742073656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E20447569732069642073656D2061206D617572697320736F6C6C696369747564696E2074696E636964756E742E20457469616D2065752070757275732065752061726375206672696E67696C6C612061646970697363696E672E20566976616D7573206F726E6172652074656D707573206469616D2E2050726F696E20747572706973207175616D2C206C6163696E6961206E6F6E2C20656765737461732061742C20636F6D6D6F646F20656765742C20706564652E205072616573656E742076756C70757461746520726973757320696E206573742E204E756C6C6120666163696C6973692E0A0A557420656C656D656E74756D206C6163696E69612070757275732E2050726F696E2076697461652061726375206163206E756C6C6120636F6E76616C6C697320616C697175616D2E204E756C6C6120636F6E6775652C206C696265726F2069642070656C6C656E746573717565206D61747469732C207175616D206C656374757320706F72747469746F72206469616D2C2061207363656C6572697371756520647569206C696265726F20696E2073617069656E2E204E756C6C616D2066656C6973206469616D2C207665686963756C612076656C2C206D6F6C65737469652075742C20766573746962756C756D20616C697175616D2C2073617069656E2E20446F6E656320636F6E76616C6C69732C2065737420757420656C656D656E74756D20766F6C75747061742C206D617572697320697073756D20677261766964612073656D2C20636F6D6D6F646F20666163696C697369732073617069656E206C65637475732073656D706572206C65637475732E205175697371756520706F72747469746F722065726F73207574206E6962682E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20457469616D206D617474697320726973757320736564206F64696F2E20566573746962756C756D206574206F64696F2E20496E206861632068616269746173736520706C617465612064696374756D73742E204E616D20747269737469717565206D61737361207574206C6967756C612E2051756973717565206E6962682074656C6C75732C207665686963756C612073697420616D65742C2061646970697363696E672061742C20636F6E76616C6C6973206E65632C206C6967756C612E20566573746962756C756D207072657469756D2C206D69206E6563206672696E67696C6C6120626962656E64756D2C20647569206E756E6320736F64616C657320706564652C20612073656D706572206D61676E61206E696268206E6F6E206469616D2E20446F6E6563206D61737361206E756E632C20766976657272612076656C2C20636F6E73656374657475657220706F7274612C2064617069627573206E6F6E2C20697073756D2E2044756973206E69736C206D61757269732C206375727375732076656C2C2073656D706572206E6F6E2C20736F6C6C696369747564696E20626962656E64756D2C2066656C69732E20566573746962756C756D206575206E657175652E0A0A43726173206E656320646F6C6F722E20446F6E6563206C616F726565742074656D707573206C65637475732E20437261732073656420746F72746F7220696E74657264756D206C6163757320656C656966656E64206469676E697373696D2E204D616563656E61732073697420616D657420656C69742E204E756C6C616D207175697320646F6C6F722076656C20647569207068617265747261206C75637475732E20496E2073697420616D6574207175616D2073697420616D6574207065646520756C74726963657320756C7472696365732E204D616563656E6173206469616D2E20496E74656765722075726E612E204375726162697475722064696374756D2C2076656C69742073656420706C6163657261742073757363697069742C206572617420747572706973206665726D656E74756D206A7573746F2C2073656420696E74657264756D206E657175652073656D206574206E6962682E20566976616D757320636F6E73657175617420636F6E76616C6C6973206D61676E612E204E616D20616C697175616D2C2065737420616320626962656E64756D20636F6D6D6F646F2C206D61676E61206573742064696374756D206D692C207669746165206D616C65737561646120656C6974206D61676E61207669746165206F64696F2E204D616563656E61732074656D706F722076756C7075746174652074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206475692E20457469616D20616363756D73616E207065646520636F6E67756520746F72746F722E0A0A4D6F7262692074656D706F72206C696265726F206163206C6F72656D2E20496E20616C697175657420766172697573206D61676E612E20496E20617263752E2050686173656C6C7573206F64696F2E2046757363652074696E636964756E7420616C69717565742066656C69732E20517569737175652076656C69742E20536564206C75637475732E20416C697175616D2066657567696174206672696E67696C6C61206D692E20416C697175616D206D6F6C657374696520766976657272612072697375732E2050726F696E20617263752E20566573746962756C756D206C6F626F727469732074656D707573206E6973692E205072616573656E742061206172637520696E2076656C697420766976657272612072757472756D2E0A0A496E20736564206C65637475732E20446F6E656320726973757320646F6C6F722C20626C616E6469742073697420616D65742C20656C656D656E74756D20636F6E76616C6C69732C20706861726574726120717569732C20706564652E20496E7465676572206F726E6172652E2041656E65616E20656765737461732064617069627573206A7573746F2E20536564207175616D206C656F2C20706F73756572652061742C20656C656D656E74756D2076697461652C20636F6D6D6F646F20656765742C206573742E20416C697175616D206D6F6C65737469652072686F6E63757320656E696D2E2043757261626974757220696163756C697320756C74726963657320706564652E204D6F72626920616C69717565742072757472756D206C616375732E20416C697175616D207175616D2E2053656420636F6D6D6F646F2C2074757270697320696E20706861726574726120706F73756572652C206D6920726973757320696D7065726469657420657261742C206120766573746962756C756D206D617373612074656C6C7573207665686963756C612073656D2E204D6175726973206672696E67696C6C6120756C747269636573206E756E632E204E616D206E69736920656E696D2C20656C656966656E642073697420616D65742C20756C747269636573207365642C206665726D656E74756D206E6F6E2C2061756775652E2050726F696E20636F6E677565206C6F626F72746973206E6973692E204D616563656E61732068656E6472657269742E204E616D20736564206E69736C2E204E756E6320656C656D656E74756D206F64696F2065752072697375732E20496E206D657475732E2050686173656C6C75732067726176696461207072657469756D206C6967756C612E204E756C6C61207669746165206E657175652E204E616D206E69736920746F72746F722C206F726E617265206E6F6E2C20626C616E6469742061742C206375727375732065752C20746F72746F722E0A0A4475697320626962656E64756D20697073756D20696E206E756E6320637572737573206D6F6C65737469652E204E756E63206F7263692E204E756C6C616D206E656320616E7465206E6F6E20657374206469676E697373696D20766976657272612E204D617572697320626C616E6469742C2076656C69742069642066657567696174207072657469756D2C20656C6974206D61676E612070656C6C656E74657371756520646F6C6F722C206174207361676974746973206C616375732076656C69742065676573746173206D61676E612E2050656C6C656E746573717565206375727375732C206469616D20636F6E736563746574756572207361676974746973206672696E67696C6C612C20746F72746F72206E6973692061646970697363696E67206E756E632C20657520766172697573206C6163757320726973757320616320656C69742E204D6175726973206964206E6973692071756973206C656F20657569736D6F642076656E656E617469732E2050656C6C656E74657371756520616320616E74652E204D617572697320617263752073617069656E2C2074656D706F722061742C20706F72747469746F722069642C20636F6E64696D656E74756D2075742C206475692E20457469616D206665726D656E74756D20756C747269636965732061756775652E20437261732075742065726F73206174206A7573746F20756C7472696369657320696163756C69732E2044756973206469676E697373696D2C206E69736C20657420666163696C69736973206665726D656E74756D2C2065726174207075727573206D6F6C65737469652074656C6C75732C20717569732074656D70757320697073756D206C656374757320617420656C69742E204E756C6C61207669746165206C6F72656D2E0A0A41656E65616E2076656C2073656D206574206469616D2073656D70657220636F6E6775652E20496E20626962656E64756D206469616D20717569732074656C6C75732E204E756E6320666163696C6973697320756C74726963696573206E6962682E2043726173206E756E6320656E696D2C2066657567696174207365642C20756C7472696365732076697461652C2073616769747469732076697461652C20697073756D2E204675736365207669746165206E756C6C612E20446F6E65632070656C6C656E7465737175652C2076656C697420696E20706F72747469746F7220656C656966656E642C20657374206E65717565206C6F626F727469732076656C69742C2073697420616D65742072757472756D20616E746520746F72746F72206E656320646F6C6F722E20446F6E6563207665686963756C612E204E756C6C6120666163696C6973692E20536564206567657374617320756C747269636573206E6962682E20446F6E656320656C6974206C65637475732C20636F6E76616C6C697320706F72747469746F722C20616C697175657420646170696275732C206665756769617420656765742C206C6967756C612E2053656420636F6E736563746574756572206A7573746F2E204D616563656E617320612073617069656E2073697420616D6574206E6973692064617069627573206C6F626F727469732E20566976616D7573206C7563747573206C6F72656D206E6F6E206E756C6C612E2053656420656765742065726174207669746165206C696265726F20696E74657264756D20706F73756572652E20437261732070756C76696E61722E204E756C6C616D20696D706572646965742C20646F6C6F722074656D706F72206469676E697373696D20626C616E6469742C206475692073617069656E2072686F6E637573206E657175652C206964206D616C657375616461206175677565206D61676E612073697420616D65742075726E612E204475697320736564206D61757269732E0A0A4D6F72626920616363756D73616E2E20536564206D61757269732061756775652C206672696E67696C6C61206E6F6E2C20617563746F722075742C20617563746F722065742C206F7263692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320757420706564652E20446F6E6563207669766572726120656E696D2076656C206C6F72656D2E2050656C6C656E746573717565206E65717565206D61757269732C20696E74657264756D2065752C2076656E656E617469732069642C20636F6E64696D656E74756D2065752C2073617069656E2E20446F6E656320697073756D20617263752C206C6163696E69612061646970697363696E672C206C616F726565742065742C206375727375732076656C2C2076656C69742E205574207361676974746973206D617572697320717569732072697375732E20496E7465676572206575206F64696F207669746165206C61637573207669766572726120616363756D73616E2E204D6F726269206C656F20616E74652C206469676E697373696D207365642C2076617269757320717569732C20766F6C75747061742076697461652C206E6973692E204E756C6C6120706C61636572617420696E74657264756D20656C69742E20446F6E6563206E65717565206475692C2073616769747469732076697461652C20736F6C6C696369747564696E20717569732C20636F6D6D6F646F2076697461652C206E657175652E204E756C6C612071756973206C6967756C61206F726E617265206C6967756C612064696374756D206F726E6172652E204D61757269732072757472756D2072757472756D206E657175652E2041656E65616E207665686963756C612074656D707573206573742E20446F6E656320766172697573207363656C6572697371756520706564652E20446F6E656320706C6163657261742076756C707574617465206C656F2E204E756C6C616D206E756E63206E69736C2C20706F7375657265206E6F6E2C20666575676961742076697461652C2070656C6C656E74657371756520717569732C206D61757269732E20496E20647569206E657175652C2063757273757320656765742C20736167697474697320656765742C20646170696275732076697461652C206D692E2050726F696E2065676574206573742E0A0A467573636520706F727461206573742E204D6175726973206D61676E612E20416C697175616D20697073756D206C616375732C20756C747269636965732069642C20766573746962756C756D206C75637475732C20616363756D73616E2075742C20616E74652E20536564206D61757269732E205365642061646970697363696E67206C656F2073697420616D6574206D61676E612E2053757370656E646973736520706F74656E74692E204E756E63206D6173736120656C69742C206672696E67696C6C6120656765742C20656765737461732076697461652C206C75637475732076697461652C20646F6C6F722E2050686173656C6C75732071756973206E756C6C61206575206E69736920696E74657264756D20736F6C6C696369747564696E2E204E756C6C616D2069642074656C6C75732E20496E746567657220696163756C697320646F6C6F722061632070757275732E205365642076656C206D692E20437572616269747572206E6F6E206D61676E612073697420616D6574206A7573746F20636F6E64696D656E74756D2076756C7075746174652E20517569737175652074696E636964756E742070656465206575206E69736C2E20566976616D7573206C6F626F727469732E204E756E63206D65747573206D657475732C20636F6E677565207365642C2074696E636964756E74207365642C207072657469756D2061742C206F64696F2E20446F6E6563206120617263752E20496E2073656D206A7573746F2C207665686963756C61207365642C207661726975732069642C20766F6C75747061742061742C2072697375732E205072616573656E7420696163756C6973206D617373612E20496E206172637520656C69742C2068656E64726572697420656765742C20756C6C616D636F7270657220696E2C20706F7274612069642C2074656C6C75732E20446F6E65632073616769747469732068656E647265726974206469616D2E0A0A53757370656E646973736520706F74656E74692E20536564206574206469616D206574206175677565207361676974746973206C6F626F727469732E2050686173656C6C757320646F6C6F722E2055742065742061726375206567657420616E74652074656D706F7220706F73756572652E20416C697175616D206665726D656E74756D207363656C65726973717565206475692E204D61757269732061742070757275732E20446F6E656320657261742073656D2C20766573746962756C756D206E65632C2066617563696275732061632C206D617474697320612C206C656F2E2053757370656E64697373652061646970697363696E67206C6163696E69612073656D2E204E756C6C616D206F72636920617263752C2064696374756D2065742C20666175636962757320766976657272612C20646170696275732065742C206E657175652E2043726173206E756E63206469616D2C2061646970697363696E67206E6F6E2C20736F6C6C696369747564696E20696E2C20696E74657264756D2076656C2C206D617373612E204D61757269732073616769747469732C206A7573746F206174207472697374697175652074656D7075732C206D6175726973206D617572697320616C697175616D20616E74652C2073697420616D657420706F7375657265206469616D206475692065676574206C6967756C612E20496E206469676E697373696D2C206E69736C207574206C6163696E696120636F6E64696D656E74756D2C2065726174206A7573746F20706F72747469746F72206E756C6C612C206E6F6E2067726176696461206C6967756C61206D61676E612065676574206D617373612E20566573746962756C756D207669746165206C6967756C61206174206D6920766573746962756C756D2073757363697069742E2044756973206C616F726565742E204E756C6C6120636F6D6D6F646F206C696265726F2073697420616D6574206C6F72656D2E20557420656C656D656E74756D2073656D2E20496E74656765722076656C20646F6C6F722E204E616D20666163696C69736973206D6920717569732073656D20756C7472696365732073616769747469732E205365642071756973207175616D206174206D65747573206D6F6C657374696520626962656E64756D2E0A0A50726F696E2064756920656E696D2C206C6163696E696120612C20666575676961742061632C20706C6163657261742076697461652C20706564652E205175697371756520656765737461732C206C656F206567657420616C697175616D207072657469756D2C206C696265726F206A7573746F2074696E636964756E742065726F732C2075742065676573746173206175677565207065646520656C656D656E74756D206E6962682E20437572616269747572206D6F6C6C697320736F64616C657320656E696D2E20446F6E65632061756775652E2050686173656C6C757320696420697073756D20706F737565726520647569207072657469756D2066617563696275732E204D6175726973206C756374757320616E74652073656D706572206E69736920696E74657264756D2061646970697363696E672E204475697320646170696275732C206F64696F207175697320766976657272612072686F6E6375732C206A7573746F207175616D20626962656E64756D20646F6C6F722C20696420646170696275732076656C697420657261742076656C20657261742E2046757363652073697420616D6574206E69736C2076656E656E61746973207175616D20756C74726963657320636F6E64696D656E74756D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632072686F6E637573207363656C65726973717565206C6967756C612E20566573746962756C756D206D69206F64696F2C20616363756D73616E2065742C2061646970697363696E6720656765742C206F726E6172652075742C207175616D2E204E756C6C616D20626C616E646974206D6F6C6573746965206D61757269732E20437572616269747572206469676E697373696D206D6175726973206574206C6F72656D2E2053757370656E64697373652061206A7573746F2E204E616D206D617474697320666175636962757320617263752E204475697320626C616E64697420656E696D206E6F6E206D617373612E0A0A4E756C6C616D206C6F72656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E204D617572697320636F6E73656374657475657220706F7375657265206D61757269732E204D616563656E61732074696E636964756E74206D617572697320696E2065726F732E204E756C6C61206575206D65747573206575206F72636920736F6C6C696369747564696E2066617563696275732E2053757370656E646973736520616C697175616D206D6175726973206964206573742E204372617320626C616E646974206475692065742075726E612E204E756C6C6120617263752E2053656420612075726E612E204E756C6C612064617069627573207665686963756C6120746F72746F722E20446F6E65632072697375732E20536564207175616D206D657475732C20656765737461732065752C206375727375732075742C2076697665727261206E6F6E2C206F64696F2E205574206A7573746F206A7573746F2C206D616C6573756164612073697420616D65742C20626C616E6469742073757363697069742C206D6F6C657374696520696E2C206A7573746F2E20566573746962756C756D20636F6E7365717561742C207175616D20616320666575676961742074696E636964756E742C20697073756D206C696265726F20656C656966656E64206F64696F2C206E6F6E20656C656966656E64207065646520697073756D206E6F6E20616E74652E204E756C6C616D2061206D657475732E0A0A4E616D206163206E6973692061742066656C697320637572737573206D61747469732E2050656C6C656E74657371756520636F6E7365717561742073656D2071756973206F7263692E20517569737175652074656D7075732E2041656E65616E20696D70657264696574206D6F6C657374696520706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652065752074656C6C75732E204E756C6C61206469616D2065726F732C20736F64616C65732075742C20736F64616C6573206E65632C2074696E636964756E742061632C206E756E632E204E756E63206C6163696E696120666175636962757320697073756D2E20566976616D75732076656C206E6571756520696E2065726174206665726D656E74756D206C75637475732E204E756C6C612065676574206D65747573206E656320617567756520626962656E64756D20706C6163657261742E20566976616D75732074656D7075732E205072616573656E7420636F6E677565206F726E61726520697073756D2E20457469616D206D61747469732066657567696174206A7573746F2E0A0A416C697175616D206475692E2041656E65616E20636F6D6D6F646F20746F72746F72207669746165206E756C6C612E204D6F72626920657420697073756D2E204D617572697320616320697073756D2E204E616D2076656C207269737573207574206C6563747573206D6F6C6C697320766976657272612E2043757261626974757220656C656D656E74756D206D6F6C6C6973206573742E204E756C6C616D20656C69742E20566573746962756C756D207375736369706974207072657469756D20656E696D2E20566573746962756C756D207574206D617373612E2050726F696E206E65632066656C69732E204D616563656E617320677261766964612C2061726375206E656320636F6E7365717561742073616769747469732C2065726F732074656C6C7573207363656C65726973717565206D61757269732C20766974616520616363756D73616E207175616D207175616D207574206E756E632E20496E7465676572206567657420616E74652065752076656C6974206C616F72656574206D616C6573756164612E204E756E632073616769747469732C206D617572697320766974616520706861726574726120766F6C75747061742C2074656C6C75732074656C6C757320656C656966656E642065726F732C2073697420616D65742072757472756D20697073756D206E69736920612076656C69742E205072616573656E7420766172697573206C656F20657520657261742E20566976616D757320636F6E73657175617420706C6163657261742070757275732E20446F6E6563207072657469756D20656C656D656E74756D206E6962682E2050726F696E20617420656C6974206E6F6E2073656D20616C6971756574206D61747469732E2053656420756C6C616D636F7270657220697073756D2073697420616D657420656C69742E0A0A4D617572697320696E206D657475732E2053757370656E6469737365206D61676E61206C6F72656D2C2066617563696275732076656C2C2074696E636964756E7420717569732C207363656C65726973717565206E6F6E2C2074656C6C75732E2046757363652071756973206C6F72656D2E2050726F696E2061206C616375732073697420616D6574206D617572697320696163756C69732070756C76696E61722E2053757370656E64697373652072686F6E6375732065726F73206E6563206D692E205072616573656E7420657569736D6F642C207475727069732076697461652072757472756D207072657469756D2C206F64696F206D6574757320766F6C7574706174206E657175652C20656765742074656D7075732073617069656E206E657175652073656420657261742E20446F6E6563206665726D656E74756D207075727573206174206C65637475732E204E756C6C616D2073656D2E2046757363652076656C206D6920717569732065726174206C6F626F7274697320706F73756572652E2041656E65616E20656765742075726E612E2053757370656E6469737365206C6967756C612E204475697320696E206E6973692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A4375726162697475722076756C707574617465206C656374757320696420706564652E2050686173656C6C75732065752076656C69742E20457469616D2076656E656E617469732061646970697363696E67206E6962682E20416C697175616D206375727375732070756C76696E61722074656C6C75732E20566573746962756C756D206E657175652E204D6175726973206E6563206A7573746F20657420657261742073656D7065722070656C6C656E7465737175652E204675736365206D61747469732064696374756D20646F6C6F722E20457469616D2065676574207075727573206575206D617373612076617269757320656C656D656E74756D2E2050656C6C656E746573717565206D617373612E20557420756C74726963696573206469616D2073656420697073756D2E204E756C6C616D206469616D2E2050656C6C656E746573717565206964206D61676E61206964206C696265726F2074726973746971756520616C697175616D2E0A0A557420656C656966656E642C20707572757320696420706C6163657261742076656E656E617469732C2075726E6120617567756520616C6971756574206C6967756C612C20696E20756C74726963696573206C656F2072697375732065742074656C6C75732E204D6175726973206574206E756C6C612069642075726E61207472697374697175652074656D7075732E20557420666163696C697369732C2075726E6120657520766573746962756C756D2072686F6E6375732C206C616375732065726F7320636F6E736563746574756572206D657475732C2065742072757472756D20647569206C656374757320696E2070757275732E204E756E632076656C206E69736C206E6F6E20697073756D2074696E636964756E74206D6F6C6C69732E204E616D207175616D206C616375732C206F726E6172652076697461652C2072686F6E637573206E6F6E2C20636F6E677565207365642C206F64696F2E2050726F696E206E696268206475692C20706F7274612076656C2C2076656E656E61746973206E6F6E2C2070656C6C656E7465737175652075742C206E6973692E20536564207472697374697175652066656C69732061206D61676E612E2053757370656E646973736520656765742074656C6C75732E2043726173206772617669646120696D706572646965742076656C69742E20496E74656765722068656E6472657269742072697375732E2050726F696E206F7263692E20416C697175616D20756C6C616D636F72706572206D61757269732071756973206D61757269732E204E756E63206C6163696E696120766573746962756C756D206D657475732E20447569732074656C6C75732E204E756C6C616D2066617563696275732C206C656F2061632076756C70757461746520736F6C6C696369747564696E2C206C656F20646F6C6F7220666175636962757320657261742C207175697320626962656E64756D206F726369206F64696F206E6F6E20617263752E0A0A4E756C6C616D20616363756D73616E206D617474697320646F6C6F722E20446F6E6563206574206475692E205072616573656E7420612066656C6973206D6F6C6C6973206C616375732073656D706572206C6163696E69612E204375726162697475722070656C6C656E746573717565206C7563747573206573742E2050726F696E206E756C6C61206475692C20636F6E64696D656E74756D2076656C2C206661756369627573206E6F6E2C20696E74657264756D2061632C20657261742E204D616563656E6173207363656C657269737175652C206C656374757320696420766F6C757470617420616363756D73616E2C2073617069656E20746F72746F722070656C6C656E746573717565206475692C207365642073656D706572206D61676E612073656D207574206C656F2E2050726F696E206E756C6C612E204E756C6C616D206461706962757320756C6C616D636F727065722073656D2E2053757370656E6469737365207665686963756C61206D6574757320696E206E756E632E2050656C6C656E746573717565206E6F6E207175616D2076656C206172637520756C74726963657320756C6C616D636F727065722E2050686173656C6C757320717569732066656C69732073697420616D65742074656C6C757320756C6C616D636F72706572206665726D656E74756D2E20536564207665686963756C6120736F6C6C696369747564696E2075726E612E20437572616269747572207068617265747261207363656C657269737175652072697375732E2050656C6C656E746573717565206964206D617373612071756973206D6574757320616C697175616D20696D706572646965742E20496E206E756E63206C616375732C206665756769617420696E2C206772617669646120656765742C2076656E656E617469732075742C2074656C6C75732E2053757370656E646973736520706F74656E74692E204E616D20636F6E7365717561742061646970697363696E67206475692E20496E206E756C6C61206E6973692C20666575676961742075742C206665726D656E74756D2076656C2C2067726176696461206E65632C20746F72746F722E20496E207365642061756775652E0A0A457469616D20756C6C616D636F7270657220617567756520617420656E696D2E20496E7465676572206469676E697373696D2E20416C697175616D2070756C76696E617220636F6E677565206E756C6C612E204D6F72626920656E696D206D617373612C206672696E67696C6C6120612C20616363756D73616E20656765742C20636F6E64696D656E74756D206E65632C20657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2041656E65616E2070686172657472612E20457469616D20706F72747469746F722070757275732061206D657475732E20416C697175616D20696E74657264756D2073656D2065676574206A7573746F2E205175697371756520766F6C7574706174206C7563747573206573742E2041656E65616E2061756775652E2050686173656C6C757320647569206C65637475732C20756C747269636573206E65632C20636F6D6D6F646F2076656C2C20617563746F722076656C2C206E6973692E20557420756C7472696365732070656C6C656E746573717565206E6973692E20496E74656765722061632076656C69742065742073656D20696D70657264696574206C75637475732E20467573636520766974616520747572706973206964206175677565206D6F6C6C697320636F6E7365637465747565722E0A0A4D616563656E6173206E6563206C616375732E204D616563656E617320636F6E64696D656E74756D206F64696F2065752066656C69732E204D6175726973207574206E69736C207669766572726120657261742066617563696275732061646970697363696E672E20457469616D20656765737461732E204E756E6320657420646F6C6F72207669746165207269737573206469676E697373696D20636F6D6D6F646F2E204D6F726269206C65637475732076656C69742C2074696E636964756E74206E65632C20616C69717565742076656C2C206D61747469732076697461652C206C6967756C612E204D616563656E617320756C747269636965732073656D70657220646F6C6F722E2053757370656E6469737365206D616C6573756164612E20496E7465676572206D617474697320656C69742E20446F6E656320616363756D73616E2C206C6163757320666163696C69736973207661726975732074656D7075732C206E756C6C6120656C697420706F72746120657261742C2065742072757472756D20656C69742073656D2073697420616D6574206475692E0A0A4D616563656E6173206D6F6C6C6973206D69206E6F6E206E756C6C612E20566976616D7573207475727069732E2053757370656E64697373652061206D657475732E20496E2071756973206D6920696E2074757270697320636F6E67756520617563746F722E204D616563656E6173206C616375732E2053757370656E646973736520736F6C6C696369747564696E2E2050686173656C6C757320706F727461206E756E63206E6F6E206E69736C2070756C76696E617220656765737461732E20536564206E756C6C612E20566573746962756C756D206163206D692E204D617572697320756C7472696369657320636F6E64696D656E74756D206E657175652E204E756C6C612074656D707573206A7573746F2076656C206D617373612E204E756C6C6120737573636970697420636F6E67756520617263752E205072616573656E74206964207475727069732E204D6175726973206E69626820706564652C20657569736D6F642073656D7065722C206D6F6C65737469652061632C2072686F6E6375732076697461652C20616E74652E204D616563656E617320657261742066656C69732C207669766572726120736F6C6C696369747564696E2C20736167697474697320656765742C2070656C6C656E746573717565206E65632C206F7263692E20467573636520756C74726963657320636F6E736571756174206C616375732E20416C697175616D2065726174206D61676E612C20666575676961742061742C207669766572726120612C206D6F6C6C6973206E6F6E2C207475727069732E0A0A446F6E6563206D692E204E616D2064696374756D2070656C6C656E7465737175652073656D2E20446F6E6563206D6F6C6C69732072686F6E63757320656C69742E2050686173656C6C75732072686F6E63757320706564652073697420616D65742072697375732E20446F6E656320656765742061756775652E204D616563656E6173206E6F6E206C65637475732E2050686173656C6C757320736F6C6C696369747564696E206E697369206E65632066656C69732E20416C697175616D207072657469756D2C2065737420656765742073656D70657220636F6E76616C6C69732C206E696268206E756E6320736F6C6C696369747564696E2070757275732C2069642074656D706F722070656465206475692076656C206D61676E612E20566976616D7573206163206C6F72656D2E20457469616D206E69736C20746F72746F722C2061646970697363696E672064696374756D2C20656C656D656E74756D20696E2C20666163696C69736973207365642C206E6962682E2050726F696E206D61757269732E2050726F696E2072757472756D206D6173736120656765742073656D2E204375726162697475722074656D706F722061646970697363696E6720656C69742E204375726162697475722070757275732074656C6C75732C206665726D656E74756D20656765742C20616C69717565742076697461652C20636F6E76616C6C69732061632C206D61757269732E0A0A496E746567657220636F6E7365717561742076656C69742065752065726F732074696E636964756E74207665686963756C612E204E756C6C616D206C6F72656D2073617069656E2C2072686F6E637573206E6F6E2C206D617474697320717569732C20756C747269636965732073697420616D65742C20656E696D2E2043757261626974757220636F6D6D6F646F2C206C696265726F20696E20657569736D6F642073757363697069742C2073656D207075727573206672696E67696C6C6120656E696D2C206163206D6F6C657374696520746F72746F72206F7263692065742076656C69742E20446F6E656320706564652E20457469616D20706C61636572617420636F6E64696D656E74756D207475727069732E2050686173656C6C7573206567657374617320656E696D206E6563206D61676E612E20566976616D757320636F6E64696D656E74756D2C206E756C6C612076656C206C7563747573207472697374697175652C2065726F7320726973757320766573746962756C756D206E756C6C612C20696E207665686963756C61206172637520697073756D2061742066656C69732E20446F6E656320616C697175616D20656C69742061742061756775652E205175697371756520612065726F73206575206C6967756C6120616363756D73616E2064696374756D2E20457469616D207665686963756C61207475727069732071756973206C696265726F2E20416C697175616D206E6F6E206D692E20446F6E6563206574206C656F2E2050726F696E206C656F206C696265726F2C20616C697175616D2074696E636964756E742C20636F6E677565206E65632C2061646970697363696E6720706F7274612C20656E696D2E204E756C6C61206C6F626F727469732C20746F72746F722073697420616D657420696D7065726469657420756C6C616D636F727065722C20646F6C6F72206F726369206D616C65737561646120706564652C207365642067726176696461206E6962682075726E612076656C206C6F72656D2E20536564207068617265747261206D616C6573756164612065726F732E205175697371756520657569736D6F6420616C697175657420657261742E2053757370656E646973736520616C6971756574206D61747469732070757275732E0A0A4E756E63206964206E756C6C612071756973206A7573746F20636F6E67756520736F6C6C696369747564696E2E205072616573656E742065726174207475727069732C2072686F6E6375732065752C207072657469756D2065752C2070656C6C656E74657371756520612C206E6962682E20566976616D75732074656D7075732E2043726173206E65632072697375732061742074757270697320696D70657264696574206C6F626F727469732E205574206D61747469732E204D616563656E6173206573742066656C69732C2070656C6C656E746573717565206E6F6E2C20696D70657264696574207365642C20656C656966656E642074696E636964756E742C206C6F72656D2E20496E2074696E636964756E742E205365642076656C206C656F2E20446F6E65632065742075726E6120696E207475727069732068656E64726572697420626C616E6469742E20446F6E656320636F6E64696D656E74756D20616363756D73616E206573742E2055742070686172657472612C206D65747573207669746165206D617474697320636F6E7365637465747565722C206C656F207175616D2076756C707574617465206F64696F2C206E6563206C616F72656574206E6973692076656C697420657520657261742E20496E7465676572206C65637475732061756775652C206567657374617320696E2C20696E74657264756D2065752C2076656E656E617469732076656C2C2073617069656E2E2051756973717565206574206573742076697461652065726F73206C616F72656574206C6F626F727469732E204E756C6C616D207574207269737573206E6F6E206E756C6C6120706C6163657261742061646970697363696E672E205072616573656E7420646170696275732E20457469616D20612066656C69732E20557420736F64616C657320636F6E736571756174206D61757269732E2044756973206C6F72656D2066656C69732C206C756374757320612C2074726973746971756520696E2C206D6F6C65737469652061742C2072697375732E20536564207665686963756C6120626962656E64756D2074656C6C75732E204E616D20636F6E73657175617420657569736D6F64206C616375732E0A0A41656E65616E20746F72746F7220656C69742C2067726176696461206E65632C206665726D656E74756D2065752C206C6F626F727469732069642C20697073756D2E204D616563656E61732065752070757275732E204372617320616320747572706973207574206E69736920696163756C69732072686F6E6375732E204E756C6C61207075727573206D657475732C206469676E697373696D206E65632C2074696E636964756E742076697461652C20646170696275732065752C206E6962682E204675736365206C6F626F727469732C206E756E63206174207669766572726120656C656966656E642C206A7573746F20747572706973207363656C657269737175652065726F732C2061632070656C6C656E746573717565206D65747573206E69736C2061742070757275732E2053656420656C656D656E74756D2074656C6C75732073656420656E696D20696E74657264756D20626C616E6469742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E746567657220756C7472696369657320616C6971756574206F64696F2E204D61757269732065676574206E756E63206120697073756D20756C74726963657320736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2041656E65616E20616363756D73616E2E20446F6E65632073617069656E206C65637475732C20636F6E6775652061742C20706F7274612069642C2068656E6472657269742076697461652C206E69736C2E204375726162697475722076656C207175616D2076656C206E6571756520616363756D73616E206C616F726565742E204D6F7262692073617069656E206573742C207072657469756D20696E2C20636F6E7365637465747565722061632C206D6F6C6C69732075742C206C696265726F2E20446F6E65632074696E636964756E742061646970697363696E67206D657475732E204E756E6320766573746962756C756D20656765737461732061756775652E20446F6E6563207363656C65726973717565206475692075742073656D2E2053757370656E64697373652076656C206D6574757320696420657374206D6F6C657374696520696163756C69732E0A0A566976616D75732070686172657472612C20656C6974206575206D616C65737561646120626C616E6469742C206469616D20746F72746F72206D6F6C6C6973206475692C207365642070756C76696E6172206D61737361206E756E63206574206D61676E612E2053656420706C61636572617420656C697420617563746F7220746F72746F722E204E756C6C6120616320657261742E2050656C6C656E74657371756520636F6E7365637465747565722C2064756920636F6E76616C6C69732074696E636964756E7420636F6E64696D656E74756D2C2073656D206F64696F20766F6C7574706174206C696265726F2C206E6F6E20656C656D656E74756D2066656C6973206E65717565206E6563206F64696F2E204D616563656E61732068656E6472657269742065726F73206964206469616D2E204D61757269732076656C207075727573206163206F72636920636F6E76616C6C697320636F6E76616C6C69732E205365642073697420616D6574206C616375732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652064696374756D20766172697573206C616375732E204D61757269732065676574206E69736C2E2053757370656E646973736520706C6163657261742C206E756C6C61206E6F6E206F726E617265206469676E697373696D2C206E69736C206469616D2073616769747469732074656C6C75732C20696E2073656D706572206E69736920646F6C6F72206174206E6962682E204475697320756C6C616D636F7270657220766976657272612066656C69732E20496E746567657220612074656C6C75732E2053757370656E64697373652065676574206E756E632E2041656E65616E206469616D206573742C20616363756D73616E2069642C20737573636970697420696E74657264756D2C206672696E67696C6C612076697461652C206A7573746F2E2050726F696E20706564652E204D616563656E6173206174206E6571756520696E206E6571756520766573746962756C756D20656C656966656E642E0A0A566573746962756C756D206E756C6C61206C6F72656D2C20706F72747469746F7220656765742C20657569736D6F642061632C20616C697175616D2061742C206E69736C2E204D616563656E6173206574206573742065676574206D6173736120766172697573206C6F626F727469732E20496E206D692E204475697320706F72747469746F72206665726D656E74756D2070757275732E20446F6E65632063757273757320696D70657264696574206C6967756C612E204D6F726269206574206C6967756C6120657420616E7465206D6F6C6573746965207665686963756C612E204D61757269732073656420646F6C6F722E2053656420696D706572646965742066656C69732075742073656D2E20536564207669746165206E6571756520656C656D656E74756D206C656F20617563746F72206665726D656E74756D2E2044756973206665756769617420756C6C616D636F7270657220657261742E2041656E65616E2070757275732E204D6F726269206665726D656E74756D20766573746962756C756D206573742E2050656C6C656E7465737175652076656E656E61746973206D61757269732E2050686173656C6C75732070756C76696E61722E20496E746567657220697073756D206C65637475732C20696163756C697320612C206C6163696E69612069642C20616363756D73616E2069642C20617263752E2050686173656C6C7573206174206573742E204675736365206E65717565207175616D2C20756C747269636965732069642C20696163756C69732076656C2C20646170696275732076697461652C206C616375732E20496E206C6F626F7274697320636F6E76616C6C697320616E74652E204E756C6C61206E756E632070757275732C2076756C70757461746520696E2C2068656E6472657269742065742C20626C616E6469742065742C206C6967756C612E0A0A50656C6C656E746573717565206C656F206D657475732C20736167697474697320696E2C206D6F6C65737469652076697461652C2064696374756D20696E2C20706564652E204D6F726269207072657469756D2066656C6973206E6563207175616D2E2050656C6C656E746573717565206D617474697320616E746520736564207175616D20736167697474697320646170696275732E2053757370656E64697373652073617069656E2E205072616573656E7420626962656E64756D20696163756C697320746F72746F722E20447569732061206E69736C2E2041656E65616E206D692E20446F6E65632064696374756D206172637520696E206573742E204D6F72626920696E74657264756D2076756C70757461746520697073756D2E2041656E65616E2073697420616D6574206D61676E61206E6F6E206E69736C2074726973746971756520706F73756572652E2050686173656C6C75732076656C6974206D657475732C2074656D706F722061632C206665726D656E74756D20656765742C20636F6E64696D656E74756D206E6F6E2C2076656C69742E20566573746962756C756D2073697420706F73756572652E0A0A4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204372617320616C6971756574206D61737361206E6563206475692E20437261732061726375206E756E632C2068656E6472657269742061632C20656C656966656E642065752C20756C6C616D636F72706572206E65632C2074656C6C75732E205365642070686172657472612070757275732073697420616D6574207175616D2E20437572616269747572206D6F6C6C69732E204E616D20766974616520706564652E20457469616D207269737573206D617373612C207665686963756C612073697420616D65742C207068617265747261206E65632C20736F6C6C696369747564696E2075742C206475692E20446F6E65632065676573746173206A7573746F206174207175616D2E2050726F696E206E69736C2072697375732C20766573746962756C756D206E65632C207072657469756D2076697461652C207472697374697175652061632C206C6F72656D2E20416C697175616D206572617420766F6C75747061742E204372617320736564206E6962682E2050656C6C656E74657371756520736F6C6C696369747564696E20657569736D6F642061756775652E0A0A457469616D206672696E67696C6C6120736F6C6C696369747564696E206F7263692E204D61757269732063757273757320656C69742071756973206C616375732E204372617320746F72746F722E20496E2061646970697363696E672C206C656374757320696420617563746F7220766573746962756C756D2C206E65717565207065646520616363756D73616E20646F6C6F722C206E6F6E20696D70657264696574206D61676E61206469616D20616363756D73616E2076656C69742E2053757370656E6469737365206174206C696265726F207574206E69736920626C616E6469742073616769747469732E2050686173656C6C7573206E6F6E206D61757269732E20467573636520656C656D656E74756D2073616769747469732073656D2E2053757370656E646973736520616C697175616D20656C656966656E642074656C6C75732E2050726F696E206C6967756C61206C6F72656D2C20696D7065726469657420717569732C2076656E656E617469732069642C20696163756C6973206D6F6C6C69732C206E69736C2E20457469616D20636F6E76616C6C69732070656465206174206D617373612E204D6F72626920616363756D73616E20647569206574206D61757269732E0A0A53656420736564206F7263692E204E756E632070757275732E2053757370656E646973736520706F74656E74692E205574206C7563747573206672696E67696C6C61206D61757269732E20446F6E6563206E6962682E2050686173656C6C757320706F7274612E2050686173656C6C75732073697420616D6574206F64696F20736564206D61676E6120736F64616C65732070686172657472612E2043726173206C65637475732E2053757370656E6469737365206C696265726F20697073756D2C20636F6D6D6F646F206E65632C20666163696C6973697320696E2C207375736369706974206C6F626F727469732C206C6967756C612E2044756973206D61737361206E756C6C612C2073656D7065722065742C20636F6E736571756174206E65632C2070686172657472612065752C20656C69742E20566976616D757320756C7472696369657320616C697175616D206F64696F2E20566573746962756C756D2073697420616D6574206D617373612E2053656420636F6E736571756174206C61637573207365642075726E612E20457469616D2066617563696275732066656C69732076656C206F7263692E2050686173656C6C757320756C6C616D636F727065722E2041656E65616E20636F6E736563746574756572206C61637573206174206C696265726F2E0A0A436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204475697320666163696C697369732C206C6967756C6120766974616520636F6E64696D656E74756D207363656C657269737175652C2076656C6974206F72636920677261766964612066656C69732C2076656C20756C74726963696573207175616D206D69206E6F6E206469616D2E20566976616D757320617563746F72206D65747573206E6F6E206C696265726F2E205072616573656E74206C6967756C61206E6973692C20636F6D6D6F646F20636F6E64696D656E74756D2C206D6F6C65737469652065742C20766976657272612065742C206A7573746F2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320736F6C6C696369747564696E2E204E756E6320626C616E6469742063757273757320697073756D2E2041656E65616E206E6563206C6967756C612075742074656C6C757320736F64616C6573206D61747469732E20496E74656765722073656D2E20416C697175616D206964206C6967756C612E2053656420746F72746F72206D61757269732C20626C616E6469742076697461652C206375727375732076656C2C20656C656D656E74756D2065742C206E756C6C612E20416C697175616D207363656C65726973717565206D65747573206574206E69736C2E20447569732061646970697363696E67206D61676E61206174206E657175652E20517569737175652076756C70757461746520656C656966656E64206E756E632E20416C697175616D206567657420656C69742E2050686173656C6C757320647569206F64696F2C20626962656E64756D2073616769747469732C20766573746962756C756D2069642C206469676E697373696D20696D706572646965742C206F7263692E204E756C6C616D2065752066656C6973206E6F6E206E756E63206C6163696E696120736F64616C65732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A53757370656E64697373652070656C6C656E7465737175652C206C696265726F206D617474697320756C7472696369657320616363756D73616E2C20746F72746F7220746F72746F72206D616C6573756164612073656D2C20657420736F64616C6573206C696265726F206F64696F20616320697073756D2E20566976616D75732071756973206D61676E61206E656320657374207375736369706974206C6F626F727469732E20437261732074656D70757320706F7375657265206E756E632E205175697371756520757420656E696D20612066656C697320656765737461732073656D7065722E20536564207068617265747261206D6174746973206E657175652E20467573636520747572706973206E756E632C20636F6E677565207365642C20636F6E736571756174206E6F6E2C20636F6E677565207365642C206E756C6C612E2053757370656E646973736520766172697573206C6F72656D20696420726973757320706F72746120766573746962756C756D2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204675736365207365642070757275732E20496E20612066656C69732E20496E7465676572206567657374617320617563746F72206F7263692E204D617572697320756C747269636573207375736369706974206E69736C2E204E756C6C616D2070757275732E0A0A437261732074656D706F722061646970697363696E6720697073756D2E2055742071756973206D692E204D616563656E617320696E206A7573746F207574206E756C6C6120636F6E6775652070686172657472612E2050656C6C656E746573717565207574206C696265726F20657520646F6C6F722076656E656E617469732073757363697069742E205072616573656E74206665756769617420636F6E736563746574756572206E6962682E204D6F7262692066617563696275732073656D206E6F6E2066656C69732E20496E2068656E6472657269742061726375206163206D617373612E20496E20616363756D73616E20756C747269636573206D692E2050726F696E206D616C65737561646120617563746F722066656C69732E2043757261626974757220696E74657264756D2E20536564206469616D20697073756D2C20756C7472696369657320696E2C2074656D706F722073697420616D65742C207669766572726120696D706572646965742C20656C69742E204D6F726269206D6F6C6573746965206E6973692E204D617572697320697073756D2E2046757363652064696374756D206D6F6C6C6973206D61676E612E204475697320636F6D6D6F646F206469676E697373696D206E756C6C612E20566573746962756C756D20617567756520656E696D2C20756C7472696369657320717569732C20696163756C6973206E65632C2074696E636964756E742076697461652C206469616D2E204D6175726973206C6163696E69612074656D70757320697073756D2E20536564206174206D61757269732E205574206C6F72656D2E20446F6E6563206C696265726F2E0A0A4475697320696163756C6973206C6163696E6961206C65637475732E2041656E65616E20636F6E76616C6C69732065726F7320616320616E74652E205365642071756973206F726369206E656320726973757320617563746F72206672696E67696C6C612E2050686173656C6C757320666163696C6973697320656C656D656E74756D206E6973692E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E6320706F727461206C61637573206E656320616E74652E204D6F726269206D617572697320657261742C2061646970697363696E6720696E2C2070756C76696E6172206E65632C206C6F626F72746973206E65632C206F64696F2E20557420656C656966656E64206C656374757320736564207175616D2E204E756C6C616D206D6F6C6C69732E20496E206E6F6E20747572706973206574206E69736C2068656E64726572697420626C616E6469742E204475697320656C656D656E74756D2E204E756E63206E6563206C696265726F2E2053757370656E646973736520766573746962756C756D207269737573206E6F6E20706564652E204D6F72626920696D70657264696574206F64696F2073697420616D6574206C696265726F2E2053656420736564206D6173736120766974616520697073756D206D61747469732074696E636964756E742E204E756C6C61206E656320746F72746F72207669746165206C696265726F20766F6C75747061742074656D7075732E20446F6E656320616C697175616D2E0A0A4475697320736564206E756E632E2043757261626974757220747572706973206E756C6C612C207665686963756C61207365642C206C756374757320717569732C20656C656D656E74756D20656765742C2066656C69732E204D616563656E61732065742070757275732E204D616563656E6173206C656F2074656C6C75732C2074696E636964756E7420612C20666163696C697369732076697461652C206C6F626F727469732073697420616D65742C2076656C69742E20446F6E656320636F6E76616C6C69732073617069656E2E204D616563656E6173206D6F6C6C6973206F64696F206575206E6962682E20457469616D20677261766964612E20496E7465676572206D6F6C65737469652C2073617069656E206575206D6F6C6573746965206C6163696E69612C206E756E63206E69626820616C697175616D206C6967756C612C2065752073616769747469732074656C6C7573206572617420736F6C6C696369747564696E206F64696F2E20447569732065742072697375732E2050686173656C6C7573206E697369206E657175652C20706C616365726174206E65632C20636F6E64696D656E74756D206E6F6E2C20756C7472696365732065752C2073656D2E20557420706564652E20457469616D206E756C6C61206D657475732C20766F6C75747061742069642C20636F6E76616C6C6973207365642C2073757363697069742076656C2C2075726E612E20446F6E65632076656C20656C69742E205574206C656F206E657175652C2076656E656E617469732066617563696275732C206C6163696E6961206E65632C2074696E636964756E742065752C20656E696D2E2043726173206964206475692061206C696265726F207068617265747261206469676E697373696D2E20446F6E65632065726F73206C656F2C20706F72746120717569732C206C616F726565742075742C2070656C6C656E74657371756520766F6C75747061742C206C65637475732E0A0A4E756C6C616D20626C616E6469742E20416C697175616D206572617420766F6C75747061742E2046757363652061646970697363696E6720656E696D2E2053757370656E6469737365206E6F6E206475692071756973206C6967756C6120706F72746120766573746962756C756D2E20446F6E65632065752074656C6C75732076656C206C6F72656D207072657469756D20706F72747469746F722E205072616573656E74206C75637475732E20416C697175616D2061632065726F7320696E206D6173736120646170696275732074696E636964756E742E20446F6E6563207574206D61676E612E20457469616D20617563746F72206C616375732073697420616D6574206C616375732E2053656420756C7472696369657320697073756D206E656320656C69742E205175697371756520612065737420696E207075727573207375736369706974207472697374697175652E0A0A41656E65616E20736564206475692076656C20646F6C6F722070756C76696E6172206C616F726565742E20566976616D7573207665686963756C61206C6F72656D20696E20706564652E20566976616D7573206574206469616D2E20496E7465676572206163206F64696F2076656C206469616D2068656E64726572697420626962656E64756D2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E756C6C612061206E6973692E2050686173656C6C75732074696E636964756E74206475692076697461652061756775652E20447569732066617563696275732C2064756920696E74657264756D206672696E67696C6C612074696E636964756E742C206F64696F20656C697420766573746962756C756D206C696265726F2C206163206D6F6C6573746965206D61676E61206C6563747573206964206C616375732E2041656E65616E206C6967756C612E204E756C6C6120666163696C6973692E0A0A46757363652076656C2073656D2065752076656C6974206672696E67696C6C61206F726E6172652E2053656420666575676961742074696E636964756E742066656C69732E204E756C6C616D2066656C6973206D692C20657569736D6F642073697420616D65742C206D6F6C6C69732061742C20736F64616C657320656765742C2061756775652E204E616D20696D70657264696574206E6962682061742076656C69742E2053656420757420657261742E20496E206475692E204E756C6C6120666163696C6973692E204E756C6C616D206175677565206C696265726F2C2074696E636964756E74206E65632C207072657469756D2065752C2070756C76696E617220696E2C206475692E204D6F7262692076697461652066656C69732E2050656C6C656E7465737175652076656C206A7573746F2076656C2076656C6974207361676974746973206D616C6573756164612E2050726F696E207665686963756C6120626C616E646974206D617373612E20457469616D2074696E636964756E742070686172657472612075726E612E20496E206D65747573206573742C20617563746F72206E65632C20626C616E64697420612C20637572737573206E65632C207175616D2E204D6175726973206163206D657475732061206C696265726F20636F6E6775652066617563696275732E204D6175726973206D617572697320646F6C6F722C20736F64616C657320696E2C206375727375732075742C20736F64616C65732072757472756D2C2065726F732E2051756973717565206D61757269732065726F732C2073616769747469732076697461652C206C6F626F727469732075742C20656C656966656E642069642C206E6973692E0A0A41656E65616E206E657175652E20566573746962756C756D20656765737461732070656C6C656E746573717565206C6967756C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2050686173656C6C7573207361676974746973206A7573746F2076656C2072697375732E20536564207072657469756D206E657175652076697461652075726E612E2050656C6C656E74657371756520636F6E677565206C696265726F206964206C6F72656D2E204D6175726973206C656F206C6F72656D2C20626C616E6469742073697420616D65742C20636F6E76616C6C697320717569732C20636F6E736563746574756572207365642C2065726F732E204D61757269732074696E636964756E742C20656E696D2061206772617669646120657569736D6F642C206D61676E61206E756C6C61206665726D656E74756D206C696265726F2C207669766572726120656765737461732076656C6974207175616D20657420746F72746F722E20566976616D757320616C6971756574206D61737361207669746165206A7573746F2E204E756C6C6120636F6E677565206C6163757320616320656C69742E0A0A50686173656C6C757320636F6D6D6F646F207175616D2076656C206C6967756C612E2050726F696E206E6F6E206D657475732061742065726F732070756C76696E6172206C75637475732E204D6175726973206469616D206C6F72656D2C20706F737565726520717569732C20677261766964612065742C2074696E636964756E74206E65632C206C6967756C612E20536564206469616D2E20416C697175616D20656C6974206C65637475732C2068656E6472657269742075742C20696D706572646965742073697420616D65742C207072657469756D2073697420616D65742C20697073756D2E204D6175726973207665686963756C61206E69736C20696E206475692E204375726162697475722065676574207175616D207574206D61676E6120656C656D656E74756D206665726D656E74756D2E204D6175726973207363656C657269737175652E2051756973717565206C616F726565742E20457469616D2074656D707573207475727069732E2050656C6C656E746573717565206175677565207175616D2C2068656E647265726974207365642C2074696E636964756E742061742C2070686172657472612061742C206E69736C2E20416C697175616D206C616375732E2053757370656E646973736520706F74656E74692E2041656E65616E2076656C6974206C696265726F2C20756C74726963657320696E2C206C6163696E69612065752C206C75637475732076656C2C20616E74652E20457469616D2064696374756D206D6920696E2066656C69732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20467573636520677261766964612064617069627573206E69736C2E2043726173207669746165206E69736C2E0A0A4D616563656E6173206469676E697373696D2C206C6967756C61206E6F6E20706F727461206375727375732C20656E696D206E756E63206D616C6573756164612073656D2C20657520706F72747469746F72206E756C6C612075726E61206575207175616D2E2046757363652065726F732E20416C697175616D2065726F732E204E616D20617563746F722E204E756C6C61206D6F6C657374696520706F727461206573742E2053757370656E646973736520706F74656E74692E20566976616D7573206D6F6C6573746965206C6F72656D2073656420657261742E20536564206567657420697073756D2E20496E746567657220616C697175616D2070756C76696E6172206E756C6C612E204372617320616C69717565742073656D207574206E756E632E2046757363652066617563696275732074656D707573206C65637475732E204372617320736F64616C65732C206E69736920616320666163696C6973697320756C7472696365732C2065726F73206172637520646170696275732073617069656E2C20657420756C747269636573206D61757269732074656C6C7573206E6F6E20646F6C6F722E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20437261732063757273757320766172697573206D657475732E205574207475727069732E20566976616D7573206567657420746F72746F722E0A0A536564206C616F726565742C2076656C6974206E6F6E20616363756D73616E206375727375732C206E756E632075726E6120706F7375657265206A7573746F2C20696E2064696374756D206C6563747573207065646520696420616E74652E20437261732076756C7075746174652E204372617320636F6E677565206475692073656420656C69742E2050726F696E206C616375732073656D2C20756C7472696365732061742C20636F6E73657175617420696E2C2074656D706F7220717569732C206D657475732E2050726F696E2076656C20617263752E204E616D20657569736D6F642068656E64726572697420656C69742E20557420657261742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2053656420706F73756572652E204D6F7262692065726F732075726E612C2073656D7065722061742C2073656D706572206E6F6E2C20636F6E76616C6C697320717569732C2076656C69742E204D616563656E6173206F7263692E20566573746962756C756D206C6F626F7274697320747269737469717565206D657475732E20566573746962756C756D206C6F72656D206E756C6C612C20736F6C6C696369747564696E2076697461652C20636F6E64696D656E74756D20717569732C20617563746F722075742C206475692E20566976616D757320766573746962756C756D206D61676E61207574206E6973692E2043757261626974757220656C656966656E64206475692076656C206E756E632E20437572616269747572206D6175726973206C616375732C206D616C6573756164612073697420616D65742C207375736369706974207365642C2072757472756D206C75637475732C2074656C6C75732E20496E746567657220666163696C697369732075726E61207669746165206C65637475732E0A0A41656E65616E207175616D206C656F2C206C6F626F7274697320717569732C206D616C6573756164612065752C2076756C7075746174652076697461652C206E69736C2E205072616573656E7420656765742065726F732E205574206665726D656E74756D20747572706973206964207175616D2E204E616D20746F72746F722E205072616573656E74206E6563206F7263692E204E756C6C6120626962656E64756D2061646970697363696E672061756775652E20557420636F6D6D6F646F2C206D61676E61206964206D616C65737561646120677261766964612C206175677565206F64696F206D616C657375616461206D692C20706F727461206D616C65737561646120656C697420657374207669746165206469616D2E204D6175726973206E6F6E206E756C6C612E2053757370656E64697373652074696E636964756E742C206E756E6320756C7472696369657320706F7274612076656E656E617469732C206D6920706564652074696E636964756E74206C696265726F2C20656765742076617269757320616E7465206C696265726F207574206C6967756C612E20437572616269747572207072657469756D20706F72747469746F7220746F72746F722E0A0A4D616563656E617320766974616520656C69742065676574206E69736920646170696275732064696374756D2E204E756E6320696E206C696265726F2E204E756C6C612064696374756D206F726369206575206572617420617563746F72206C6F626F727469732E2050686173656C6C75732072697375732E2053757370656E646973736520706F74656E74692E2053757370656E646973736520706F74656E74692E205072616573656E742061646970697363696E6720636F6E73657175617420656C69742E20496E74656765722069642061756775652E205072616573656E7420696E206A7573746F206E6563206D61676E6120646170696275732070756C76696E61722E2044756973206E69736C2E2053757370656E6469737365206163206F64696F2E20566976616D757320696D706572646965742E20446F6E6563206E6F6E2076656C69742073697420616D6574207269737573206469676E697373696D20636F6E6775652E204E616D20616C697175657420706F73756572652076656C69742E2043726173207475727069732E204D6F726269206D616C657375616461206469676E697373696D206D692E0A0A536564206C656F206E657175652C2076617269757320717569732C2076656E656E61746973207365642C207068617265747261207365642C206573742E204D6F72626920626C616E6469742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D2073656D7065722070656C6C656E746573717565206D692E2055742076656C206C6F72656D2E204E756E63206D6920746F72746F722C206C616F726565742061742C2066617563696275732065752C2074696E636964756E742073697420616D65742C20657261742E20447569732074656D706F72206D616C65737561646120697073756D2E2050686173656C6C757320616C69717565742E20446F6E656320657420656C69742E2050656C6C656E7465737175652070757275732E20566573746962756C756D2072757472756D2073656D706572206E6962682E204E756C6C6120666163696C6973692E2050686173656C6C757320657420656E696D2073697420616D657420616E746520766573746962756C756D207665686963756C612E2050686173656C6C7573206964206E69736C2E20446F6E6563206D6F6C6C6973206C656F2061742065726F732E204D61757269732070656C6C656E746573717565206E657175652061742070757275732E204D6F726269207175697320646F6C6F7220617420697073756D207363656C6572697371756520736F64616C65732E20457469616D20766F6C7574706174207475727069732061206D657475732E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206C6F72656D206C6F72656D2C20766573746962756C756D2061632C20657569736D6F6420656765742C20756C6C616D636F72706572206469676E697373696D2C2076656C69742E0A0A43756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204372617320756C7472696365732C206E6962682076656C20616C697175616D20766573746962756C756D2C2065726F7320656E696D2076656E656E61746973206475692C20696420696163756C697320656E696D206E756E632076656C206D617373612E204D6F72626920656C656966656E64206F726369206574206D617373612E20416C697175616D206572617420766F6C75747061742E204E756C6C61206D6F6C6C69732065676573746173207475727069732E20496E20736F64616C6573206E756E63206567657420746F72746F722E2053656420697073756D2065726F732C2074656D706F7220717569732C20616C69717565742076697461652C20696D70657264696574206E6F6E2C206C6F72656D2E2050656C6C656E746573717565207175697320656C6974206964206D69206C756374757320646170696275732E20536564206E756E6320617263752C2072686F6E637573206E65632C20636F6E76616C6C697320717569732C206375727375732061742C206E657175652E204D617572697320636F6E76616C6C697320707572757320617420657261742E2050656C6C656E74657371756520766573746962756C756D2E20566976616D7573206672696E67696C6C6120656C697420617420617263752E204E756C6C616D20616C697175657420656E696D206E656320617263752E204E616D20696420746F72746F722E204E756C6C612071756973206E756E632E20557420617263752E2053757370656E646973736520706F74656E74692E2050656C6C656E74657371756520756C6C616D636F72706572206C6967756C6120696420617263752E0A0A4E616D206E6F6E206C696265726F207669746165206E69736C207363656C65726973717565206672696E67696C6C612E20517569737175652076617269757320616E7465206964206D657475732072686F6E637573206672696E67696C6C612E204E756C6C6120666163696C6973692E205072616573656E7420656C656966656E6420706F72747469746F72206C6967756C612E20457469616D207175697320646F6C6F72206E6F6E20617567756520636F6D6D6F646F20617563746F722E20446F6E65632061206D692E20566573746962756C756D2074656D706F722E20446F6E65632066656C69732075726E612C20617563746F722061742C206375727375732064696374756D2C20677261766964612069642C20617263752E2041656E65616E2064696374756D206D616C65737561646120646F6C6F722E20566976616D7573206D61747469732E2050686173656C6C757320657520706564652E2046757363652061646970697363696E67206A7573746F206672696E67696C6C61206D657475732E20457469616D20616E74652E20496E7465676572206D6F6C6C6973206D617373612071756973206E756E632E20496E74656765722064696374756D206E65717565206C756374757320656E696D2E0A0A536564206575206C696265726F2E20496E74656765722074656D706F72206C6967756C6120696E2076656C69742E2055742074696E636964756E74206C6163696E69612073656D2E204E756C6C616D2076656C2072697375732E2053656420736F64616C657320616E7465206120646F6C6F722E204375726162697475722065726F732E2053656420736F64616C65732E20536564206E6F6E206D657475732E20566573746962756C756D20656C656D656E74756D20666175636962757320616E74652E204E756C6C612076656C206E6962682E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206E6563206C6F72656D20757420697073756D206C6163696E696120696163756C69732E204475697320657261742E20416C697175616D20657261742E204372617320696163756C69732E20496E206861632068616269746173736520706C617465612064696374756D73742E0A0A4E756C6C616D20616E74652E2043726173207669746165206573742E2050656C6C656E7465737175652076656C206D657475732061206C6967756C612064617069627573206D61747469732E2044756973206665756769617420616C69717565742066656C69732E20457469616D206964206E69736C207175697320657374206469676E697373696D20636F6E64696D656E74756D2E2053757370656E646973736520706F74656E74692E204D6F7262692076656C6974206C6F72656D2C206F726E61726520717569732C2070656C6C656E7465737175652076656C2C20706C61636572617420656765742C20746F72746F722E20566573746962756C756D2074696E636964756E74206D6F6C6573746965206C696265726F2E204E756C6C61206E756C6C6120656E696D2C206D616C6573756164612069642C20756C6C616D636F727065722076697461652C2064696374756D2061742C2070757275732E20446F6E6563206469676E697373696D206F64696F20757420656E696D2E2053757370656E6469737365206174206C65637475732E0A0A5072616573656E74206C6F626F727469732061756775652076656C206C65637475732E20557420696E206C6967756C612075742066656C697320636F6E6775652073757363697069742E2051756973717565206469676E697373696D20746F72746F72207574206D692E204675736365206D61676E61206E6973692C20656C656966656E642061632C206F726E6172652076656C2C20706F72747469746F722076697461652C207175616D2E20566573746962756C756D20736F64616C6573206A7573746F2071756973207475727069732E2046757363652075726E61206E6973692C2072686F6E63757320717569732C20636F6E64696D656E74756D2076656C2C2064696374756D2065752C206E756E632E20467573636520736564206E696268207669746165206F64696F20706F73756572652061646970697363696E672E2053656420706F72746120656C6974207175697320646F6C6F722E204E616D206C696265726F206E756C6C612C20617563746F72207365642C2074696E636964756E7420717569732C2066617563696275732073697420616D65742C206D692E2051756973717565206F7263692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E756C6C616D2069642073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632076656C2065726F732E0A0A566976616D7573206C7563747573206C6F626F72746973206C656F2E2053757370656E64697373652076656C20656C6974206120656E696D20756C6C616D636F7270657220706F73756572652E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20446F6E656320717569732070656465206D6174746973206C6563747573206D6F6C6C69732061646970697363696E672E2053656420616363756D73616E20706F737565726520657261742E205072616573656E7420657569736D6F642074696E636964756E742066656C69732E20446F6E6563206D692E20557420636F6D6D6F646F2061726375206C6163696E69612074656C6C75732E20416C697175616D2061206C696265726F2071756973206C65637475732073656D70657220766976657272612E20437572616269747572206C6163696E6961206D61757269732061742074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E756E632073697420616D6574206D61676E61206D6F6C6573746965206F726369207375736369706974206672696E67696C6C612E204675736365207072657469756D206D65747573206E6F6E2073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642068656E6472657269742E204E756C6C612066656C69732E2053757370656E646973736520706F74656E74692E20416C697175616D20626C616E64697420747269737469717565206E657175652E20437572616269747572207175697320657261742076656C206E756E6320616363756D73616E206D6F6C6C69732E0A0A447569732073616769747469732C2074656C6C757320757420616C697175616D206672696E67696C6C612C20646F6C6F72206D6920756C6C616D636F72706572206E69736C2C20757420747269737469717565207065646520656C697420736564206D61757269732E204375726162697475722069642066656C69732E20446F6E65632070756C76696E6172206C61637573206574206C65637475732E20416C697175616D2076756C7075746174652076756C707574617465206D657475732E20437572616269747572206D61676E612066656C69732C2061646970697363696E672061632C20616363756D73616E2076656C2C206D6F6C657374696520717569732C207175616D2E204D617572697320656C697420617263752C207072657469756D2076697461652C206D6F6C6C69732073697420616D65742C20736F6C6C696369747564696E2075742C206D692E20446F6E656320696D70657264696574206469676E697373696D206D692E204E756C6C616D2073697420616D657420746F72746F722E20416C697175616D206E65717565206E756C6C612C2076656E656E6174697320612C20706F72746120696E2C20706C6163657261742074656D7075732C206C616375732E205175697371756520766573746962756C756D20647569206574206C616375732E2050726F696E206469676E697373696D20636F6E7365637465747565722070757275732E20457469616D206772617669646120746F72746F7220696E206E756E632E2055742074656D706F722074726973746971756520746F72746F722E20536564206C616F726565742074696E636964756E74207175616D2E20566573746962756C756D20706F7274612074757270697320757420656C69742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20446F6E6563206E696268206475692C2066657567696174206E65632C206C616F726565742069642C206D616C65737561646120656765742C206E6973692E205574206E65717565206D617373612C207665686963756C612065752C20636F6D6D6F646F206E6F6E2C20756C747269636965732076697461652C2070757275732E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204D617572697320657569736D6F642C2066656C69732076656C2074656D706F7220616C69717565742C20746F72746F72206D6175726973206D616C657375616461206E756E632C2076656C206665726D656E74756D2073656D206469616D206964206475692E204E616D2072757472756D2073617069656E2065676574206F64696F2E20416C697175616D20736564206C696265726F206E6F6E206D692066617563696275732074656D7075732E2046757363652068656E6472657269742C206469616D206E6F6E20766F6C75747061742072757472756D2C2065726174206D657475732076656E656E61746973206C6967756C612C206E6F6E207363656C657269737175652070656465206C6967756C612076656C207175616D2E204D6F7262692072686F6E6375732065726F7320616320647569206665756769617420656C656D656E74756D2E2044756973206575206C696265726F2065742074656C6C757320636F6E67756520766976657272612E204D6F726269207175616D207175616D2C20656C656D656E74756D207365642C20756C6C616D636F7270657220696D706572646965742C20636F6D6D6F646F206E6F6E2C206F64696F2E204E616D20616C697175657420656765737461732075726E612E204D6175726973206F64696F2066656C69732C207661726975732065752C206C6163696E69612065752C20636F6E64696D656E74756D20612C206C65637475732E20536564206A7573746F206D617373612C2070756C76696E61722069642C2076617269757320612C20706F72747469746F72206E65632C206C696265726F2E20457469616D207661726975732E2043757261626974757220736F64616C65732C206F64696F20617420706F73756572652073656D7065722C2065726F73206E6962682074696E636964756E74206C65637475732C2076656C2072757472756D2073617069656E206E69736920696E206C6967756C612E2053757370656E6469737365206567657420617263752E2050686173656C6C757320696D70657264696574206573742061632073617069656E2E20446F6E6563206E756C6C6120746F72746F722C20706C6163657261742076656C2C2074656D70757320612C206C6F626F727469732076656C2C206E6962682E20416C697175616D20766172697573206E6973692E204E756C6C6120657420656E696D2E20467573636520636F6E76616C6C6973206C616F72656574206C616375732E0A0A50686173656C6C757320697073756D20646F6C6F722C206D6F6C657374696520717569732C20636F6E64696D656E74756D20696E2C20636F6D6D6F646F2065752C206469616D2E205175697371756520626962656E64756D206C6163696E6961206475692E204E756C6C616D20626C616E6469742076756C707574617465206F7263692E205574206C6163696E6961206D617373612076656C2061756775652E20416C697175616D20677261766964612C207175616D207175697320696D7065726469657420696D706572646965742C2074656C6C7573206469616D20706861726574726120657261742C206174207068617265747261206C61637573206E6962682065676573746173206D61676E612E204E756C6C61207361676974746973206C6F72656D207574206C6F72656D2E204475697320636F6E64696D656E74756D2C2064756920766974616520616C697175616D20706F73756572652C206469616D207175616D20636F6E76616C6C69732076656C69742C2075742067726176696461206C656F20697073756D206E6F6E2072697375732E205574206665726D656E74756D20736F6C6C696369747564696E20657261742E20446F6E6563207361676974746973207363656C657269737175652066656C69732E204E756E6320617263752E20457469616D2074656D7075732C206D61676E612073697420616D657420737573636970697420657569736D6F642C2065726F732073656D2072757472756D206475692C207669746165207361676974746973206E696268207075727573206E6F6E206C616375732E20536564206D6F6C6C69732061726375206567657420646F6C6F722E20446F6E6563206F726E6172652C20617263752073697420616D6574206665726D656E74756D2076756C7075746174652C20726973757320656E696D206665726D656E74756D206C696265726F2C2061206C6163696E696120646F6C6F72206D69206E6F6E2076656C69742E20457469616D206C6F626F72746973207075727573206120656C69742E204E756E63206E756C6C61206475692C206D617474697320717569732C20626962656E64756D20612C20756C7472696365732061632C2061756775652E20496E20616C697175616D207665686963756C61207475727069732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A496E7465676572206964206E69736C2E20517569737175652064696374756D20656C656D656E74756D206F64696F2E2041656E65616E206C75637475732E205365642065752073656D206120706564652076756C70757461746520636F6E64696D656E74756D2E2051756973717565206D61676E612E20446F6E656320616C697175616D206D617474697320697073756D2E204375726162697475722064696374756D20736F6C6C696369747564696E2073656D2E20416C697175616D2070756C76696E61722E204E756E6320736F6C6C696369747564696E207269737573206120657261742E20566976616D757320717569732074656C6C75732073697420616D6574206E69626820766573746962756C756D20636F6E7365717561742E204E756C6C61207072657469756D20736F6C6C696369747564696E20646F6C6F722E20416C697175616D20696163756C69732074696E636964756E74207475727069732E2050686173656C6C757320697073756D206C656F2C2076656E656E6174697320696E2C20736167697474697320696E2C206F726E6172652061742C206E756E632E0A0A50656C6C656E74657371756520756C7472696365732C2064756920657520696163756C6973206C75637475732C2074656C6C757320617567756520766F6C75747061742073617069656E2C20696E206469676E697373696D2075726E612066656C6973207574206D692E205365642061726375206475692C206469676E697373696D2069642C20706F72747469746F722075742C20696D706572646965742076697461652C20616E74652E204E756C6C61206475692073656D2C20636F6D6D6F646F206E65632C2073616769747469732065742C206C6163696E69612065742C20706564652E20457469616D20656C656966656E6420647569207574206E69736C2E20446F6E656320616E7465206D61757269732C2074656D7075732073697420616D65742C207661726975732076697461652C206772617669646120717569732C206D692E20496E207363656C657269737175652C2066656C697320766974616520766976657272612073616769747469732C2076656C6974206D6574757320756C74726963696573206E657175652C207175697320696D706572646965742076656C697420656C6974206574206D61676E612E2053757370656E646973736520706F74656E74692E205365642076656C69742065726F732C20657569736D6F64207365642C20636F6E64696D656E74756D206E65632C206661756369627573207365642C2073617069656E2E204E616D20616363756D73616E206C6967756C612073697420616D6574206E657175652E20416C697175616D206572617420766F6C75747061742E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E616D20657520706564652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642065752066656C69732073656420746F72746F722074656D706F72206665726D656E74756D2E2050686173656C6C757320636F6D6D6F646F2073656D2076656C206E69736C2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050726F696E206C656374757320656C69742C2070686172657472612073697420616D65742C20616363756D73616E207365642C2074696E636964756E742065742C206D61757269732E204475697320646170696275732070686172657472612073656D2E20496E746567657220696E206A7573746F2E205072616573656E742065726F732E20566573746962756C756D20616320616E74652E20416C697175616D207363656C657269737175652073656D2070656C6C656E746573717565206E69626820636F6E73656374657475657220736F64616C65732E20416C697175616D20636F6E736563746574756572206F64696F2E2044756973206C6563747573206F64696F2C206C75637475732065752C20636F6D6D6F646F20717569732C206D6F6C6C69732076697461652C2076656C69742E2043726173206E6563206E756E63206E6F6E20656C697420696163756C6973206D61747469732E2041656E65616E206A7573746F206E657175652C20736F6C6C696369747564696E20656765742C20756C6C616D636F7270657220656765742C20656765737461732069642C2073656D2E20496E2065752072697375732E2053656420656765737461732E0A0A496E7465676572206174206E657175652E20536564207072657469756D207363656C65726973717565206E756C6C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20467573636520757420706564652E20457469616D207669746165207175616D20612075726E612076617269757320696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2044756973207665686963756C612E20467573636520756C6C616D636F72706572206E696268206E6F6E20657261742E205175697371756520696E206E657175652E205072616573656E74206573742E2050656C6C656E74657371756520617263752E0A0A50726F696E20706F73756572652E2053757370656E646973736520706F74656E74692E20496E74656765722066656C6973206C616375732C20616C697175616D207365642C2076756C70757461746520696E2C206D6F6C6C69732076656C2C2074656C6C75732E20496E7465676572207665686963756C6120626962656E64756D206573742E204E756E63206E6F6E20646F6C6F7220696E2074656C6C7573206D617474697320666163696C697369732E20496E746567657220766573746962756C756D2C20617567756520617420636F6D6D6F646F20616C697175616D2C2064756920657374206D6174746973206C6967756C612C2073697420616D65742061646970697363696E67206F7263692073656D207669746165206D61676E612E205072616573656E7420656E696D2076656C69742C206D616C6573756164612061742C20636F6E677565206E65632C206C756374757320696E2C206A7573746F2E20536564207661726975732E204D6F7262692070686172657472612E20446F6E6563206575206D61737361206E65632074656C6C75732076756C7075746174652070756C76696E61722E20557420636F6D6D6F646F20747572706973206E6F6E2073656D2E20557420636F6E76616C6C697320756C6C616D636F727065722072697375732E20457469616D20696E74657264756D2070656465206964206E6973692E2043726173206D61676E612073617069656E2C20737573636970697420612C206C616F72656574206E6F6E2C2072686F6E6375732065742C2066656C69732E20496E7465676572206F726369206C6F72656D2C20766573746962756C756D2064696374756D2C20756C6C616D636F7270657220612C20706F72747469746F722065742C206475692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A4E756E63206574206D61676E612E2053656420626962656E64756D2074656C6C757320696E206469616D2E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E616D20766974616520746F72746F722E20496E7465676572206D61676E612E20447569732076656E656E617469732C206C656F2061632074656D706F72206C616F726565742C20656C6974206E756C6C6120706861726574726120706564652C206E6F6E206665726D656E74756D206E756E63206F64696F2061206F64696F2E2050726F696E206E6F6E2076656C69742E2053656420696D706572646965742061756775652071756973206E69736C2E20496E746567657220636F6E64696D656E74756D206E69736C206E6563206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20566976616D757320706C616365726174206C696265726F2E204475697320636F6E6775652064696374756D206D61676E612E20416C697175616D206461706962757320626962656E64756D20656E696D2E204E756E6320656C656966656E6420706564652076656C20697073756D2E0A0A457469616D2076697461652076656C69742E204D61757269732065726174206E756E632C206D616C6573756164612075742C20666575676961742061632C20706C61636572617420636F6E64696D656E74756D2C2061756775652E204E616D20766F6C75747061742E20416C697175616D207665686963756C6120697073756D206964206F64696F2E20566976616D757320736F6C6C696369747564696E207475727069732069642073617069656E2E20467573636520612066656C6973207669746165206F64696F20636F6E76616C6C697320626C616E6469742E204375726162697475722076697461652065726F732069642065726F7320706F727461207072657469756D2E204E756C6C6120696E206D61676E6120656765742075726E61206C6163696E696120636F6E76616C6C69732E20416C697175616D206D61747469732076656E656E617469732070757275732E2053656420736564206D69206567657420657261742074726973746971756520706F7274612E20446F6E656320617563746F7220646F6C6F72206120657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20496E206E6563206C6967756C612E204E756E6320656C656966656E642E20566573746962756C756D2071756973206E697369206567657420656C697420706F72747469746F7220636F6E6775652E204D616563656E61732066617563696275732C206D61676E6120656765742061646970697363696E672074696E636964756E742C20646F6C6F7220616E7465206D616C65737561646120656C69742C206E6F6E20656C656D656E74756D206C616375732074757270697320696E20706564652E0A0A5574206D616C657375616461206D69206E6563206D657475732E205072616573656E7420617563746F72206175677565206163206E69736C20756C7472696369657320666163696C697369732E204E616D2070757275732073617069656E2C2070656C6C656E746573717565206469676E697373696D2C20706F73756572652065752C206375727375732069642C206469616D2E205175697371756520736F6C6C696369747564696E2C20656C697420612070656C6C656E746573717565207363656C657269737175652C206C6F72656D20726973757320617563746F72207175616D2C207175697320636F6E7365717561742074656C6C7573206E657175652069642075726E612E2053757370656E6469737365206469616D20746F72746F722C20656C656966656E64206469676E697373696D2C20656765737461732075742C206C756374757320696E2C20616E74652E204475697320616E74652E204D616563656E6173206C75637475732E20437572616269747572206375727375732070686172657472612075726E612E204D616563656E617320696D706572646965742C2065726174206E6F6E20656C656D656E74756D20657569736D6F642C20746F72746F72206F64696F20657569736D6F64206C65637475732C20616320666163696C697369732073656D206E696268207669746165206E756C6C612E204E756E6320677261766964612E204D6F72626920736F6C6C696369747564696E206F64696F2071756973206C616375732E20416C697175616D2061206E696268206E6F6E2075726E6120706F72746120696D706572646965742E20416C697175616D206572617420766F6C75747061742E20496E20696163756C6973206C6163696E69612076656C69742E20536564206C696265726F206C616375732C207472697374697175652065752C206C6163696E69612061632C20616C697175657420656765742C2075726E612E0A0A457469616D206174206E69736C2E2050686173656C6C7573206661756369627573206C7563747573206C65637475732E20557420706C6163657261742076756C70757461746520646F6C6F722E2050686173656C6C75732076656C2076656C69742E204D6F72626920766976657272612E2050686173656C6C7573206F7263692E20496E7465676572206469676E697373696D206D6174746973206D61757269732E2050656C6C656E74657371756520706F7375657265206C656F20706F7375657265207175616D2E2051756973717565206E6563206D61676E61206174206469616D20766976657272612070656C6C656E7465737175652E2053757370656E64697373652076656C697420617263752C20756C7472696369657320717569732C20636F6E67756520612C2076656E656E6174697320656765742C206C616375732E20496E74656765722073616769747469732068656E64726572697420646F6C6F722E2046757363652074696E636964756E7420616E746520612073656D2E0A0A4D616563656E617320636F6E7365637465747565722C206A7573746F207365642072686F6E6375732076656E656E617469732C206E69626820617263752072757472756D20646F6C6F722C2073656420636F6E64696D656E74756D206C696265726F206C696265726F20657420697073756D2E20566976616D7573206D6174746973206A7573746F207574206C6F72656D2074696E636964756E74206C6F626F727469732E205574206E6F6E2076656C6974206964206E6571756520616C697175657420616363756D73616E2E205365642074656D7075732076697665727261206E756C6C612E2043757261626974757220756C6C616D636F727065722C206E6571756520717569732064617069627573207363656C657269737175652C2066656C6973206469616D2067726176696461206F7263692C206E6F6E20637572737573207175616D206E6571756520766974616520656C69742E20457469616D2070686172657472612074696E636964756E74206C616375732E204475697320657569736D6F64206672696E67696C6C61206573742E20457469616D206F726E6172652074696E636964756E74206C65637475732E2050726F696E20696E207475727069732E204E756E6320626C616E64697420626C616E646974207475727069732E2041656E65616E2075742061756775652E2044756973206F726369206A7573746F2C2074696E636964756E742065752C2072757472756D207365642C2072757472756D2065742C207475727069732E2043757261626974757220666163696C69736973206F64696F20696E20616E74652E20496E206861632068616269746173736520706C617465612064696374756D73742E205365642065726F73206573742C2070656C6C656E7465737175652061742C2074696E636964756E742065752C20756C74726963657320717569732C206D657475732E204D6F7262692073697420616D6574206A7573746F2E204D616563656E617320616320617263752E204D6175726973206469676E697373696D2E0A0A50656C6C656E74657371756520756C747269636965732072757472756D206F7263692E2041656E65616E206F726E6172652E20566976616D75732065752072697375732076656C206D6175726973206C6F626F727469732064696374756D2E205365642065742074757270697320617563746F72206D692072686F6E6375732070756C76696E61722E20536564206E6563206E756E6320612070757275732074656D706F7220766976657272612E2050656C6C656E7465737175652073757363697069742E20446F6E656320747269737469717565207269737573206E6F6E206E6962682E20457469616D206E69736C206D61676E612C20736F6C6C696369747564696E2075742C20756C7472696365732073697420616D65742C20656765737461732065752C206E756C6C612E20416C697175616D206572617420766F6C75747061742E20566573746962756C756D2070686172657472612E2053656420656765737461732C206D657475732073697420616D6574206C6F626F7274697320636F6E7365717561742C206572617420656C697420696D70657264696574206C696265726F2C20657520696E74657264756D207175616D206D61737361206567657420646F6C6F722E2053757370656E6469737365207669746165206F64696F2E2050726F696E20626C616E646974206D617572697320696163756C6973206D657475732E0A0A566976616D757320766573746962756C756D2E20457469616D206574206E69736C2E20416C697175616D20696E206469616D2076656C20656C697420706C6163657261742073757363697069742E204475697320736F64616C6573207075727573206163206E6962682E204E756C6C6120696E206F64696F206567657420656E696D206C756374757320626C616E6469742E2043757261626974757220756C74726963657320697073756D206E6F6E206E65717565206567657374617320656C656966656E642E20536564207475727069732E2050726F696E20636F6E7365637465747565722E20566976616D7573206D61747469732E20496E20616C69717565742E0A0A4E756E632069642065726F732E20446F6E65632076656E656E617469732C206E756C6C61206574206D6174746973206C75637475732C20616E7465206C656F2073656D706572206A7573746F2C206E6F6E2061646970697363696E67206F64696F20726973757320736564206C616375732E205072616573656E7420766974616520726973757320636F6E677565206C696265726F20636F6E6775652074656D7075732E2050686173656C6C75732061632065726F732E204E756C6C61207665686963756C612C206C6F72656D20696E20616C69717565742073757363697069742C2061726375206572617420656765737461732073656D2C2071756973206C6F626F72746973207175616D20616E7465206575206D617373612E20437572616269747572206E6F6E206D617373612E2053656420626962656E64756D206C6163696E6961206F64696F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20566976616D757320766F6C757470617420626C616E646974206C616375732E2050726F696E20706F7274612C2074656C6C757320757420617563746F72206C616F726565742C206C65637475732065726F73206665726D656E74756D206C65637475732C2069642073616769747469732061726375206A7573746F20696E207475727069732E2050686173656C6C757320636F6E7365717561742E204E616D2070656C6C656E7465737175652C206D69206964207669766572726120636F6E76616C6C69732C206E756E63206C696265726F20706C616365726174206C656F2C20656C656966656E6420706F7274612073656D206E69736C2076697461652073617069656E2E2050656C6C656E746573717565206C6967756C61206C696265726F2C20747269737469717565206E6F6E2C20706F72747469746F722072757472756D2C20706F72747469746F72206E6F6E2C20657261742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E74656765722064696374756D2074656C6C7573206120746F72746F722E20566976616D75732066656C6973206E756E632C206D6F6C6573746965206E6F6E2C2072686F6E63757320717569732C2070686172657472612069642C206475692E20446F6E6563207269737573206D657475732C206672696E67696C6C612076656C2C20616C69717565742065752C20706C6163657261742069642C206E657175652E0A0A53757370656E646973736520697073756D2E20566976616D7573206C65637475732E2053656420766976657272612C206D61737361206567657420636F6E76616C6C6973206D61747469732C207175616D2074757270697320636F6E736563746574756572206E756E632C206567657420706F7375657265206D61676E612073656D2069642076656C69742E20496E206E6563206D61757269732E2041656E65616E206120707572757320736564207175616D206C6F626F72746973206672696E67696C6C612E2050726F696E20756C74726963696573206C6163696E696120616E74652E205365642061646970697363696E67206572617420717569732076656C69742E204E756C6C616D207669746165206E69736C206964206A7573746F20736F6C6C696369747564696E206D6F6C65737469652E204E756C6C6120666163696C6973692E20536564206E65632075726E6120736564206E69736C206672696E67696C6C6120646170696275732E204E756C6C61206174206469616D2E20416C697175616D2065676574206E6962682E204E756E63206163206E6973692073697420616D65742074656C6C757320656765737461732074656D7075732E204E616D207363656C657269737175652075726E61206574206E657175652E20446F6E656320657374206F7263692C207361676974746973206E6F6E2C2076756C70757461746520612C20636F6D6D6F646F2065742C2061756775652E205574206461706962757320746F72746F722E205574206E756E632E20446F6E65632064696374756D2064617069627573206F64696F2E204E616D20756C7472696369657320756C6C616D636F72706572206C6967756C612E2050656C6C656E74657371756520616363756D73616E20766172697573206C656F2E0A0A4D6F72626920657569736D6F64206C616F7265657420657261742E20566976616D7573207175697320697073756D2E204D6F72626920657569736D6F642E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2053757370656E64697373652076656C2070757275732E204E756C6C616D206174206D61676E612E20437572616269747572206C61637573206C6F72656D2C20696163756C697320717569732C2064617069627573206E6F6E2C20766F6C75747061742076656C2C206E756C6C612E20446F6E656320757420617263752072686F6E63757320646F6C6F72207072657469756D2064696374756D2E204E756C6C616D2076656C206D657475732E20557420617263752E2050656C6C656E746573717565206E697369206E756E632C20706C61636572617420656765742C2074696E636964756E742076656C2C207068617265747261206E6F6E2C206E756E632E20496E74656765722074696E636964756E7420756C74726963696573206C65637475732E20496E74656765722073656D7065722C2070757275732073656420756C74726963657320666575676961742C206E756C6C61207065646520736F6C6C696369747564696E20657261742C2076656C20617563746F72206E756C6C6120697073756D2076656C206C65637475732E2041656E65616E206D692E0A0A4E756C6C616D20736564206E697369206574206172637520696D70657264696574206665726D656E74756D2E204D6175726973206E6563206D657475732E20496E20616320646F6C6F722E20496E206D6920617263752C20636F6E6775652061632C207068617265747261206E65632C207363656C657269737175652073697420616D65742C206D61676E612E20437572616269747572206C616375732E2043757261626974757220657420656C69742E20416C697175616D20756C6C616D636F72706572206E756E6320657520656C69742E2053656420636F6E76616C6C697320646F6C6F722061742076656C69742E20566573746962756C756D20646170696275732C20617567756520696420636F6E73656374657475657220706C6163657261742C206E756E63206D6173736120626C616E6469742073617069656E2C20696420616C697175616D20656C6974206E697369206964206D692E2050686173656C6C75732073617069656E206573742C20677261766964612065752C20626962656E64756D2075742C2061646970697363696E6720717569732C206573742E205574206D6F6C6573746965207175616D207669746165206F64696F2E20446F6E65632071756973207269737573206964206572617420666175636962757320736F6C6C696369747564696E2E204E616D2069642066656C69732E204D61757269732073656420656E696D207669746165206C656F20616363756D73616E207072657469756D2E0A0A4E616D206A7573746F2E20446F6E656320747572706973206E69736C2C20636F6D6D6F646F2065742C20696E74657264756D2061632C20636F6E736563746574756572206E6F6E2C206D617373612E2046757363652073656D206D657475732C206C616F72656574206E65632C20706F73756572652069642C20696D7065726469657420696E2C2076656C69742E20446F6E65632076756C707574617465206A7573746F2065676574207475727069732E204E756C6C6120706564652E204D6F7262692074696E636964756E742E20467573636520616C69717565742C207175616D20657420616C697175616D206672696E67696C6C612C20616E746520616E746520696163756C6973206475692C206E656320616C697175616D20617263752070757275732073656420657261742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050686173656C6C7573207375736369706974207175616D206574206573742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B0A0A496E7465676572207365642074656C6C75732E20536564207365642076656C697420756C74726963696573206C656F2072757472756D206C616F726565742E20536564206E6F6E2065726F7320616320707572757320736167697474697320666575676961742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E205365642068656E647265726974206C6967756C612073697420616D6574206E6962682E204D616563656E6173207475727069732E204D6F72626920636F6E7365637465747565722C20646F6C6F722065742061646970697363696E6720696D706572646965742C20616E7465206E65717565206665756769617420646F6C6F722C20617420706F727461207175616D206E657175652071756973206C6967756C612E204D61757269732073656D7065722076656C69742073697420616D657420697073756D2E2050656C6C656E7465737175652074656D7075732C20707572757320696E2072757472756D20636F6E7365717561742C20656E696D2065726174207665686963756C61206D617373612C20696420616363756D73616E206C656F2073617069656E206E65632070757275732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E20646F6C6F722E20496E746567657220666163696C69736973206C696265726F2073697420616D657420706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2055742076617269757320616C697175657420656E696D2E204E756C6C6120666163696C6973692E2043757261626974757220636F6E7365637465747565722C206F64696F206575207072657469756D2074696E636964756E742C206E756E63206E69736920616C6971756574206E657175652C2076656C20696D7065726469657420656C6974206D617373612073697420616D6574207475727069732E2050656C6C656E7465737175652074656D7075732C206F72636920766F6C757470617420626C616E646974206672696E67696C6C612C206F64696F2073656D20706F737565726520616E74652C20766974616520626962656E64756D2075726E61206C6F72656D2076697461652065726F732E205072616573656E7420766976657272612072686F6E63757320617263752E2053656420617563746F722C206573742073697420616D6574206D6F6C6C6973206D6F6C6C69732C207175616D207175616D20677261766964612073617069656E2C20696E20636F6D6D6F646F206D65747573206E756C6C6120617563746F7220656E696D2E20446F6E656320666163696C697369732E0A0A50726F696E2074696E636964756E742C2073617069656E206567657420756C747269636965732061646970697363696E672C20657374206F64696F2064696374756D20617263752C207574206D6F6C6C69732065726174206475692073697420616D65742076656C69742E204D6F726269206573742073656D2C20696E74657264756D2061742C20636F6E67756520612C20656C656D656E74756D2076697461652C206D657475732E2053757370656E64697373652069642061756775652E204D617572697320656E696D2073656D2C2070756C76696E617220656765742C2074656D70757320612C2074656D7075732073697420616D65742C2073617069656E2E20467573636520766573746962756C756D20636F6E736563746574756572206475692E2050656C6C656E74657371756520657261742E20536564206469676E697373696D20706C616365726174206F64696F2E204D616563656E61732073656D7065722072686F6E637573206C65637475732E2050686173656C6C7573207072657469756D2E2044756973206C696265726F20656C69742C20656C656966656E64206E65632C20656765737461732075742C20637572737573207365642C2066656C69732E204E616D206E69736C20617263752C20616C69717565742065742C20666163696C697369732065752C206C75637475732075742C2072697375732E20457469616D20756C7472696365732C20646F6C6F722073656420766F6C7574706174206D616C6573756164612C20747572706973206172637520696D7065726469657420746F72746F722C20657569736D6F6420636F6D6D6F646F206C696265726F206D61737361207574207175616D2E20496E7465676572206D6F6C6573746965207075727573206E6F6E20656C69742E2055742076656E656E617469732073656D70657220746F72746F722E20457469616D20626962656E64756D206567657374617320697073756D2E204D617572697320736F6C6C696369747564696E2073656D206E6563206E6962682E204E756C6C61207072657469756D206D65747573206575206D657475732E2050656C6C656E7465737175652073697420616D65742073656D2E0A0A53757370656E6469737365206163206E6973692E205574206C656F2E20566573746962756C756D2068656E647265726974207072657469756D20646F6C6F722E204E756E632066657567696174206D616C6573756164612070757275732E2043726173206574206E6962682E20437572616269747572206E756E6320657261742C206D616C6573756164612076697461652C206C616F726565742061632C20756C7472696369657320696E2C2070757275732E20566976616D75732074656C6C757320617263752C20736F64616C65732065752C20666163696C6973697320612C206C6163696E6961206E65632C206E756E632E2050656C6C656E7465737175652069642076656C69742E20496E206575206E6962682E204E756E63206E656320657261742E205365642064696374756D206E65717565207574206E69736C2E0A0A4D6F726269206C65637475732074656C6C75732C2074696E636964756E742061632C20706F72747469746F722061632C2074726973746971756520696E2C2065726F732E20446F6E6563206C7563747573206C7563747573206C656F2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2046757363652075742065737420657420656E696D207363656C6572697371756520616363756D73616E2E20446F6E6563206C6967756C612066656C69732C206C6163696E696120717569732C2070656C6C656E74657371756520696E2C2073656D70657220766573746962756C756D2C20656C69742E204D61757269732065676574206F72636920612066656C697320636F6E677565207665686963756C612E20557420736F6C6C696369747564696E2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204E756C6C616D20696420646F6C6F72207574206C6F72656D206469676E697373696D2076656E656E617469732E2053757370656E64697373652076697461652073617069656E2E2050726F696E206E6F6E206D61676E612075742065726F7320766976657272612070756C76696E61722E20446F6E65632071756973206F64696F2E204E756C6C616D206E6F6E20617263752076656C206C6F72656D20737573636970697420616C697175616D2E20416C697175616D2072757472756D2074757270697320696E206C656F2E0A0A5574206C7563747573206E6962682074726973746971756520657261742E2053757370656E646973736520626962656E64756D206F64696F20766974616520746F72746F722E20446F6E6563206C6163696E69612E204372617320736F64616C65732066656C6973206C7563747573206E756C6C612E204E616D20656C656966656E64207361676974746973206C6967756C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E64697373652076656C206E657175652E204D6F72626920616C6971756574207665686963756C61206D61676E612E2041656E65616E206174206F64696F2E20447569732070656C6C656E746573717565206D61676E612E204E756C6C6120617420746F72746F72207574206469616D2064696374756D2066617563696275732E204D617572697320717569732076656C69742E20446F6E6563206E6F6E2074656C6C7573207669746165206C6F72656D206672696E67696C6C6120706F72747469746F722E2046757363652075742073617069656E207175697320746F72746F7220666575676961742073616769747469732E20446F6E656320766976657272612073656D2076697461652073617069656E2E205072616573656E7420736F64616C65732C206C6163757320696E206672696E67696C6C6120766976657272612C206F64696F2061756775652061646970697363696E672075726E612C20766974616520696E74657264756D20616E74652073656D206E6F6E206E6973692E204E756C6C616D20746F72746F72206C6F72656D2C20656C656966656E642061632C206D6F6C6C6973206E6F6E2C206C616F726565742061632C2072697375732E20496E7465676572206F726E617265206C656F20736564206A7573746F2E2051756973717565206375727375732C2073656D206E6F6E20666163696C6973697320626962656E64756D2C206E697369206D69207661726975732066656C69732C206665726D656E74756D2066657567696174206C6F72656D2065726F73206C616F726565742072697375732E0A0A517569737175652073697420616D657420657374206574206C6F72656D207665686963756C61206C6163696E69612E20446F6E6563206E656320746F72746F722E2043726173206F64696F2E204E616D207363656C657269737175652076756C7075746174652075726E612E205072616573656E74206475692E20457469616D206E6563206E69736C206C6F626F7274697320697073756D20616C69717565742074656D7075732E204D616563656E6173207072657469756D20736F6C6C696369747564696E206D61757269732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206175677565206D617373612C20636F6E67756520656765742C20636F6E76616C6C697320656765742C207472697374697175652073697420616D65742C2065726F732E2053656420636F6E736571756174206E6973692065752066656C69732E2050656C6C656E746573717565206A7573746F2E2053757370656E6469737365206E6F6E2061756775652E20496E206469676E697373696D206C6F626F72746973206D61757269732E204D61757269732073616769747469732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E0A0A5365642061646970697363696E672E20446F6E656320612074656C6C75732076697461652065737420637572737573207665686963756C612E204E616D20616E74652073656D2C20736F64616C65732069642C206672696E67696C6C612076656C2C20636F6E64696D656E74756D2076656C2C206E756C6C612E205175697371756520736F64616C65732E20457469616D20696D7065726469657420656C6974206964206F64696F2E20416C697175616D206572617420766F6C75747061742E204D616563656E617320706F7274612074656D706F7220617263752E204E756C6C612073656D2061756775652C2070656C6C656E7465737175652061632C20636F6E7365717561742075742C20636F6E64696D656E74756D20657569736D6F642C2072697375732E2053656420616C697175616D2074696E636964756E74206D692E20496E20696E74657264756D206C6F626F72746973206F7263692E0A0A536564207665686963756C612068656E6472657269742070757275732E20457469616D2061206469616D2E2043757261626974757220636F6E76616C6C69732E2053757370656E64697373652061206E6973692E20446F6E6563206964206D61676E6120696E207175616D20736F6C6C696369747564696E20756C747269636965732E20446F6E656320766976657272612E205175697371756520766F6C757470617420657374207365642073656D2E20416C697175616D206A7573746F2E20566573746962756C756D20746F72746F72206D617373612C20706F72747469746F72207365642C2076617269757320717569732C20696163756C697320717569732C206F64696F2E20416C697175616D2065676574206E657175652E0A0A4D6175726973206E756C6C612E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566573746962756C756D206575207175616D20696E206E6571756520756C7472696365732070656C6C656E7465737175652E204372617320696E20646F6C6F722071756973207175616D207661726975732068656E6472657269742E20416C697175616D206E697369206C616375732C206C6F626F727469732065752C20636F6E76616C6C69732073697420616D65742C20666163696C697369732075742C206D692E20416C697175616D206174206E657175652E204372617320736167697474697320656C656D656E74756D206A7573746F2E20566573746962756C756D207574206C656374757320616C6971756574207075727573206D616C65737561646120766F6C75747061742E2044756973206174206C616375732061646970697363696E67206C696265726F2074696E636964756E7420766573746962756C756D2E204D6F7262692061206C696265726F2E20437261732070757275732E204D6F72626920757420617567756520657420707572757320696E74657264756D207363656C657269737175652E20496E74656765722061206475692E20496E206861632068616269746173736520706C617465612064696374756D73742E2044756973207068617265747261206D657475732065676574206D61757269732E20416C697175616D20696E74657264756D20756C6C616D636F72706572206D617373612E0A0A457469616D206F726E6172652E204E756C6C616D20657569736D6F642E2041656E65616E20636F6E7365717561742067726176696461206C6967756C612E20416C697175616D206573742E2050726F696E207669746165206C616375732E205072616573656E7420612065726F732073697420616D657420647569206C756374757320636F6D6D6F646F2E2050686173656C6C7573207665686963756C612061726375206567657420646F6C6F722E205072616573656E74206665726D656E74756D20636F6E677565206C656F2E20416C697175616D20766F6C7574706174207075727573207574206C6F72656D2E2046757363652068656E64726572697420656E696D206174206C656F2E20416C697175616D2072686F6E637573206E69736C2E20566976616D75732064696374756D2065676573746173206D692E2053757370656E64697373652070656C6C656E74657371756520626962656E64756D20646F6C6F722E2050656C6C656E7465737175652074696E636964756E742C207475727069732073656D7065722070656C6C656E74657371756520636F6E64696D656E74756D2C20697073756D206D6574757320736F64616C6573206C6967756C612C20696420766F6C7574706174206469616D2074757270697320757420656C69742E0A0A5072616573656E7420736564206C616375732E204E616D20656C656966656E64206D6F6C6573746965206D61757269732E20446F6E65632064617069627573206665726D656E74756D206D617373612E20446F6E656320766976657272612066617563696275732070757275732E2043757261626974757220636F6E6775652C206C696265726F20766974616520766976657272612070656C6C656E7465737175652C206469616D2076656C697420736F64616C657320656E696D2C20736564207375736369706974206C6563747573206E697369206E6563206E657175652E20566573746962756C756D206D616C6573756164612C206C616375732061742063757273757320636F6E6775652C2076656C6974206C65637475732074726973746971756520646F6C6F722C2073697420616D657420736F64616C6573206E6571756520697073756D2061206C696265726F2E20566573746962756C756D206574207175616D2E2043757261626974757220706C6163657261742E20437572616269747572206E756E6320617263752C20657569736D6F64206E65632C2076756C7075746174652068656E6472657269742C20616C697175657420656765742C207175616D2E204375726162697475722076656C20656E696D2E2053757370656E646973736520706F74656E74692E0A0A4E756E6320636F6E736571756174206F726369207574206C616375732E2046757363652076656C697420646F6C6F722C2064617069627573207365642C20626C616E6469742073697420616D65742C2072686F6E6375732069642C2072697375732E20447569732075726E61206E6962682C207363656C6572697371756520717569732C206461706962757320612C207363656C65726973717565207365642C206E6962682E20446F6E6563206C75637475732E205574206575206D617572697320637572737573206469616D206C6163696E69612072686F6E6375732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20416C697175616D207665686963756C61206D6F6C6573746965206A7573746F2E204D616563656E617320696D70657264696574207065646520736564206D692E2053757370656E6469737365206E756C6C6120646F6C6F722C2068656E64726572697420656765742C2068656E6472657269742069642C2064696374756D2076656C2C206C656F2E204475697320616363756D73616E2E2043757261626974757220696E2066656C69732E204E756E63206C6F72656D2E205574206C656F20646F6C6F722C206C616F72656574206E65632C2076756C7075746174652061742C20656C656966656E6420696E2C206E756C6C612E2051756973717565206E756E632070757275732C2076617269757320656765742C20616363756D73616E206E65632C20616C69717565742065742C206E6962682E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20437261732061646970697363696E67207669766572726120646F6C6F722E204D617572697320706F72747469746F7220756C7472696365732070757275732E204E756C6C6120666163696C6973692E205072616573656E7420666175636962757320616E7465207669746165206D61757269732E0A0A5072616573656E74206C6163696E6961206C656374757320736564206E69736C2E20496E2074656D70757320636F6E677565206D61757269732E20496E746567657220666163696C69736973206F726E61726520656E696D2E204E756C6C61206964206D617373612E20446F6E656320636F6D6D6F646F206469616D2061742074656C6C75732E204E616D20646170696275732076697665727261206573742E204E616D2074656C6C75732E205072616573656E742061206C696265726F2E20496E206661756369627573206573742065676574206E6962682E204E756C6C612065726F73206F7263692C20696D70657264696574206E6F6E2C20626C616E646974206E6F6E2C2074656D706F7220656765742C206D692E2050656C6C656E74657371756520636F6E76616C6C69732E0A0A517569737175652065676574206D69206163206C656F20657569736D6F642066617563696275732E2050686173656C6C75732072686F6E637573207075727573206964206475692E20566573746962756C756D206D616C65737561646120656C656966656E6420616E74652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050656C6C656E74657371756520626C616E646974206D6174746973206F64696F2E2053757370656E646973736520636F6E7365717561742C206C65637475732061632073656D70657220736F6C6C696369747564696E2C206D692076656C69742064696374756D2061756775652C2061632074656D70757320646F6C6F7220657261742073697420616D6574206475692E2050726F696E2068656E6472657269742C2066656C6973207175697320766F6C757470617420706F73756572652C206469616D206F64696F206D616C657375616461206F64696F2C206120696E74657264756D206F726369206469616D20717569732073617069656E2E2050656C6C656E746573717565206F64696F206F64696F2C20766976657272612076656C2C20677261766964612065752C206D6F6C6573746965207365642C206E756C6C612E2050686173656C6C7573206D617572697320706564652C20636F6D6D6F646F2075742C20657569736D6F642065752C2068656E6472657269742065752C206573742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C6120656C656D656E74756D206C616375732065752061756775652E2053656420657261742E2050726F696E20706F7274612E204D616563656E61732071756973206D692E2050686173656C6C757320617420656E696D206163206A7573746F206772617669646120756C7472696365732E2043726173206C656F2E0A0A496E746567657220757420617263752E20446F6E656320736564206D61676E612E2050726F696E2066656C69732E20496E20696163756C69732C206C6967756C61206964206672696E67696C6C61207072657469756D2C206E696268206469616D20616363756D73616E2074656C6C75732C206567657420616363756D73616E206D657475732064756920766172697573207475727069732E2050686173656C6C7573206F726369206D657475732C20656C656966656E64207365642C2074656D706F722061632C207363656C657269737175652061632C2075726E612E20496E74656765722076697665727261206E657175652061206D61757269732E204D617572697320706F72747469746F7220646F6C6F722065752076656C69742E20496E7465676572206F64696F20656C69742C20766573746962756C756D2075742C20766F6C75747061742069642C2072686F6E63757320636F6D6D6F646F2C2075726E612E20457469616D20706C61636572617420706861726574726120657261742E2055742074656D706F72206573742E20496E7465676572206469676E697373696D20626C616E6469742074656C6C75732E204D6F726269206E69626820646F6C6F722C207363656C657269737175652069642C20636F6D6D6F646F206D616C6573756164612C206D61747469732061742C206D692E20437261732074696E636964756E7420636F6D6D6F646F2070757275732E20496E2074696E636964756E742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D20756C6C616D636F727065722E2055742068656E6472657269742E204D6F72626920756C7472696365732E0A0A5072616573656E7420696163756C69732C2065726F73206163206567657374617320736F64616C65732C2075726E61206C656F206665726D656E74756D206C6967756C612C2073697420616D657420616C697175616D2076656C69742073656D206E6F6E2070757275732E20446F6E65632072757472756D206172637520717569732070757275732E204E616D20706F73756572652C206C6163757320617420636F6E73657175617420706C6163657261742C206E756C6C61207065646520706F7375657265206F7263692C206E6F6E20657569736D6F6420747572706973206475692071756973206E69736C2E2050726F696E20706F7274612061646970697363696E67206E6962682E20446F6E65632074726973746971756520646F6C6F722061742074656C6C75732E20446F6E6563206E65717565206D617373612C20617563746F722069642C2066617563696275732076697461652C20756C6C616D636F727065722076656C2C206E6973692E2050726F696E206D6F6C6573746965206E6571756520736564206D617373612E204E616D2074656D706F722E204D6F72626920616C697175616D2073617069656E2061742074656C6C75732E2046757363652071756973207269737573206574206D69207072657469756D2070756C76696E61722E2046757363652073697420616D6574206C6967756C612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E646973736520657520656E696D2065742066656C6973207363656C65726973717565206C6F626F727469732E205072616573656E7420626962656E64756D2E20566976616D7573207665686963756C612E20496E7465676572206174206E696268207365642076656C69742072686F6E637573206D6F6C65737469652E2043726173206C616375732E2053656420756C6C616D636F727065722065726F732076656C20657261742E20467573636520657520746F72746F722073697420616D6574206469616D20657569736D6F642073616769747469732E204E756E632071756973206C61637573206964206E69626820636F6E76616C6C6973207661726975732E2053757370656E6469737365207669746165206D692E20566573746962756C756D207472697374697175652E20446F6E6563206D616C65737561646120697073756D206964206E657175652E204E756C6C616D20736564206C616375732E204475697320656765737461732C206A7573746F20757420636F6E677565206F726E6172652C2061756775652073617069656E206C7563747573206469616D2C20617420616363756D73616E20657261742073617069656E207574206C696265726F2E2050686173656C6C75732076656C206E756C6C612E2053757370656E646973736520617263752074656C6C75732C20706F72747469746F7220612C2070686172657472612066617563696275732C20616C697175616D2073697420616D65742C206D617373612E204E756C6C6120706F72747469746F722074696E636964756E74206C6F72656D2E204E756E6320646F6C6F72206F64696F2C20736167697474697320696E2C206C6F626F727469732076656C2C20766F6C7574706174207365642C206E6962682E0A0A5175697371756520626C616E646974206C656F2075742073617069656E2074656D70757320666163696C697369732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2041656E65616E20756C7472696369657320706F72747469746F72206A7573746F2E2046757363652072757472756D2065726F732075742075726E612E2050726F696E2071756973207175616D20656765742064756920616C697175616D20616363756D73616E2E20446F6E656320737573636970697420656C656966656E6420656C69742E2050656C6C656E746573717565206D61747469732C2066656C697320736F64616C657320696163756C697320696D706572646965742C206C616375732073656D20636F6E76616C6C69732061756775652C2073697420616D657420616C69717565742061726375207075727573206672696E67696C6C612072697375732E20496E206575206F64696F206964206D61676E61207068617265747261206F726E6172652E20416C697175616D20696E74657264756D2070756C76696E617220697073756D2E20536564206E657175652E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D2073697420616D6574206E6973692E2055742061742061756775652E204D617572697320766F6C757470617420626C616E646974206C6967756C612E204E756C6C61206575206D657475732E20566573746962756C756D206567657420656C69742E205072616573656E7420706F73756572652E20566573746962756C756D2069642073656D206E6F6E206C6563747573206D6F6C6C69732074696E636964756E742E20416C697175616D2069642066656C697320617420616E7465206F726E6172652074656D706F722E204E756C6C61206C61637573207475727069732C20666575676961742076697461652C2063757273757320717569732C20636F6E736563746574756572206E6F6E2C206D61757269732E204675736365206C61637573206D617373612C20706F72747469746F722075742C206D6F6C65737469652075742C2076656E656E6174697320612C206C6F72656D2E205072616573656E742073697420616D6574206F7263692E204D61757269732072686F6E6375732066656C69732076697461652066656C69732061646970697363696E6720696D706572646965742E204D616563656E6173206D6F6C6C6973206469616D206E6563206C656F2E0A0A467573636520656E696D20697073756D2C20756C7472696365732065752C206D6F6C65737469652069642C20656C656D656E74756D2069642C2073617069656E2E20496E746567657220612075726E612E204E616D2076656C6974206C696265726F2C2076656E656E6174697320656765742C2074656D706F722073697420616D65742C20666575676961742076697461652C20616E74652E204675736365206E756E632E205365642073656D706572206E69736C206E65632072697375732E20496E20736564206C696265726F2E2050726F696E20746F72746F72206E657175652C2074696E636964756E742061632C2074656D706F722061632C20706861726574726120717569732C2076656C69742E2044756973206C65637475732061756775652C20756C747269636965732076656C2C20636F6E7365717561742069642C20696163756C69732069642C20616E74652E20566976616D757320617563746F72206D65747573206120616E74652E204375726162697475722061726375206E6973692C20666163696C697369732061742C206C616F7265657420696E2C20636F6E736563746574756572207365642C206D61757269732E205175697371756520706C616365726174206469616D20736564206475692E20566976616D7573207072657469756D20636F6E64696D656E74756D206C6F72656D2E20437572616269747572206C616F726565742E2041656E65616E206F726369206C6967756C612C2063757273757320656765742C206C6163696E6961206E6F6E2C2066617563696275732076656C2C206C6F72656D2E0A0A416C697175616D206572617420766F6C75747061742E204375726162697475722065726F7320646F6C6F722C20636F6E67756520612C20636F6E64696D656E74756D207365642C206C75637475732075742C206E6962682E204D616563656E6173206E6F6E20746F72746F72206E65632074757270697320636F6D6D6F646F2070656C6C656E7465737175652E205072616573656E7420657569736D6F6420706C616365726174206D692E2053757370656E646973736520706F74656E74692E2050686173656C6C7573207574206E65717565207669746165206F726369206D617474697320696163756C69732E20496E746567657220656765742074656C6C75732E20446F6E656320617420616E74652E204E616D206C6163696E6961206C656F206567657420657261742E204D616563656E617320657569736D6F64206D61676E6120636F6E67756520746F72746F722E204D6F726269206E6563206D6173736120657520656E696D206D616C65737561646120736F6C6C696369747564696E2E2053656420616363756D73616E2E204E756C6C616D20697073756D2E205574206F64696F2E20416C697175616D206572617420766F6C75747061742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2050656C6C656E7465737175652069642076656C69742E204E616D206F64696F2073656D2C20616C69717565742075742C2074656D7075732073697420616D65742C20657569736D6F642065742C206E756E632E0A0A50656C6C656E746573717565206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205072616573656E74206D6175726973206E756E632C207661726975732075742C20636F6E76616C6C6973206D6F6C65737469652C206C75637475732073697420616D65742C206C656F2E205365642064696374756D206C6F72656D20657420617263752E204E756E632076656E656E617469732070656C6C656E746573717565206D617373612E204E756C6C6120666163696C6973692E2050686173656C6C757320696E20746F72746F722065676574207269737573207363656C657269737175652076756C7075746174652E20536564206E69626820656C69742C2073616769747469732061632C20636F6E64696D656E74756D206E65632C20636F6E76616C6C69732065742C206A7573746F2E20467573636520766F6C7574706174206D657475732E204E756E6320617563746F722E20566573746962756C756D206C656F2065726F732C2070656C6C656E7465737175652061632C206D6F6C6C697320756C7472696365732C2072686F6E637573206E6F6E2C20646F6C6F722E204D6175726973207665686963756C6120706C616365726174206E69736C2E20566573746962756C756D20626962656E64756D2C2061726375207175697320636F6E67756520656C656D656E74756D2C2076656C6974206E756E6320656C656966656E64207475727069732C206964206C7563747573207269737573206E69736C2073697420616D65742074656C6C75732E2050686173656C6C75732070656465206E657175652C20626C616E646974206E6F6E2C20636F6D6D6F646F2076697461652C20756C7472696369657320656765742C206D61676E612E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120666163696C6973692E20416C697175616D20616320616E74652E20437261732072697375732E204D6F726269206D6175726973206C616375732C20706F73756572652065752C20626C616E6469742065742C2070686172657472612061742C206D692E2050726F696E2061632070757275732E204475697320637572737573206E69736C2072757472756D207175616D2E20416C697175616D2061206F64696F206E6F6E206D61676E612070656C6C656E74657371756520756C747269636965732E204D616563656E6173206163206D6173736120717569732073617069656E20756C6C616D636F727065722074656D7075732E2043726173206375727375732076656C6974207365642073617069656E2E2050726F696E206E756C6C612E20566976616D757320736F64616C657320616C697175616D206E6962682E20457469616D206574206572617420757420616E7465206C6163696E696120657569736D6F642E204675736365206E6973692E2050726F696E2071756973206E756C6C612E0A0A517569737175652076656E656E617469732C2065726F7320736564206C616F7265657420736F6C6C696369747564696E2C206F72636920616E74652070656C6C656E746573717565206E69736C2C2073697420616D65742076697665727261207175616D2065726174206E6F6E2072697375732E20437261732065676574206C696265726F2E2053656420656C6974206D61676E612C2073656D7065722065752C206672696E67696C6C6120696E2C206469676E697373696D20736F64616C65732C20657261742E20566976616D757320666575676961742073656D2076656C206475692E20446F6E656320636F6E76616C6C697320736F6C6C696369747564696E206469616D2E2043726173207365642070757275732E20446F6E65632066656C69732065726F732C2073656D70657220656765742C2074656D706F7220636F6E7365637465747565722C20736167697474697320717569732C206E69736C2E204475697320696E20616E74652E2043726173206E6F6E207475727069732E204E756C6C612074656D706F722076656C697420616C697175657420747572706973206D6F6C657374696520706C6163657261742E2050726F696E20656C656D656E74756D206665726D656E74756D206D61757269732E20566976616D757320736564206F726369206C6163696E69612064756920706C6163657261742076656E656E617469732E20566573746962756C756D20666575676961742C2074656C6C757320696E20766F6C75747061742072757472756D2C206D61676E61206E69736920756C6C616D636F727065722065726F732C2069642070756C76696E6172206E657175652065726174207574206C616375732E20566976616D7573207365642061756775652E204E756C6C6120666163696C6973692E204D616563656E617320616E74652061756775652C20656C656D656E74756D2075742C20736F64616C65732076697461652C20636F6E64696D656E74756D206E65632C206C6F72656D2E20447569732070656465206F7263692C206672696E67696C6C612061742C20656C656966656E64206E65632C207072657469756D20696E2C20657261742E204E616D2073616769747469732C2074757270697320766974616520636F6E76616C6C69732070686172657472612C206F64696F2073656D207363656C65726973717565206C616375732C206E6563206C6F626F7274697320647569206469616D2076656C2065726F732E20496E2073656D7065722067726176696461206E657175652E0A0A496E7465676572206E756E632E205574207072657469756D20697073756D2073697420616D657420656C69742E20496E206E656320617263752E2053656420766573746962756C756D2076756C70757461746520697073756D2E2050656C6C656E7465737175652074696E636964756E742E204E756C6C61206772617669646120646F6C6F7220696E2074656C6C75732E2043726173207665686963756C612C20646F6C6F722075742070656C6C656E74657371756520616C697175616D2C206572617420656E696D20617563746F72206D617373612C207665686963756C61206C6F626F72746973206F64696F2065726F732071756973207175616D2E2050726F696E2064617069627573206E6571756520696E20656E696D2E2050726F696E20656C69742E20496E74656765722072686F6E6375732074696E636964756E7420656C69742E204675736365206C6F72656D206D657475732C2073656D7065722061632C20766F6C75747061742076697461652C20666163696C697369732075742C2074656C6C75732E20446F6E65632076656C20747572706973207669746165206E69736920706861726574726120706F72747469746F722E204D616563656E617320746F72746F722E204675736365206D692E204E756C6C616D206E6563207475727069732E2053656420736F64616C657320766573746962756C756D206E756E632E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A50656C6C656E74657371756520646F6C6F7220646F6C6F722C206C616F726565742065752C20616C697175657420717569732C207363656C657269737175652073697420616D65742C20617263752E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C616D206375727375732075726E61206567657420656C69742E205175697371756520626C616E6469742073617069656E20616320616E74652E2050726F696E206E756C6C612065726F732C206772617669646120766F6C75747061742C20736F64616C65732076656C2C206D6F6C6C69732065752C206D617373612E204E756C6C612074726973746971756520736F6C6C696369747564696E206E69736C2E20437572616269747572207669746165206C6F72656D2076697461652076656C69742065676573746173206F726E6172652E2041656E65616E20656765742065726F732E20416C697175616D206572617420766F6C75747061742E20467573636520612075726E61206964206F64696F20616C697175657420636F6E76616C6C69732E204375726162697475722073697420616D6574206E69736C20706F7375657265206C656F20706F737565726520646170696275732E2044756973206D6574757320657261742C206C75637475732076656C2C2072686F6E6375732061742C20636F6E76616C6C69732073697420616D65742C20656E696D2E20566976616D75732068656E6472657269742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D206567657420656C69742E0A0A4E756C6C616D2061206E756E632E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206D657475732075726E612C2074696E636964756E742065742C206C6163696E69612073697420616D65742C206C6F626F727469732076697461652C206C6967756C612E2050726F696E206574206D6175726973207669746165206D6920616363756D73616E2070656C6C656E7465737175652E20457469616D207175616D2070757275732C2068656E647265726974207365642C20666575676961742076697461652C20657569736D6F6420656765742C20746F72746F722E20557420616C697175616D206D61676E61207669746165206A7573746F2E2053757370656E6469737365206E6F6E206A7573746F2076656C2076656C697420636F6E64696D656E74756D2074656D7075732E20447569732074656D70757320697073756D2076697461652074656C6C75732E2050726F696E20696E206D617373612E20457469616D20756C6C616D636F727065722064696374756D2074656C6C75732E2050726F696E20616C69717565742066656C6973206174206C656F206C616F726565742070756C76696E61722E20566573746962756C756D20617263752070757275732C206D616C6573756164612073697420616D65742C206375727375732065752C20706C6163657261742073697420616D65742C206E756E632E204E616D206D61737361206F64696F2C20736F6C6C696369747564696E20696E2C2061646970697363696E6720612C20616C697175616D206E65632C2072697375732E20416C697175616D20626C616E6469742068656E647265726974206C696265726F2E204D617572697320677261766964612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204375726162697475722061206E6962682E20557420696E74657264756D206665726D656E74756D206E657175652E2050656C6C656E74657371756520736564206E756E632E204D6175726973207665686963756C61206E697369206574206E756E632E205072616573656E74206C6F72656D2E20446F6E65632073656D7065722E20496E7465676572206575206C6163757320696E2065737420616C697175616D2068656E6472657269742E20566573746962756C756D2065676574206E657175652E205365642073656D706572206C75637475732076656C69742E20437572616269747572206E6962682061756775652C20636F6E6775652065752C2068656E6472657269742069642C20636F6E6775652065742C20656E696D2E20496E746567657220706C61636572617420616C697175616D206C65637475732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20566976616D75732076697461652065726F732E20446F6E65632076656C206E69736C2E0A0A496E20766573746962756C756D20666163696C697369732075726E612E2055742072697375732E204D61757269732070686172657472612E2050656C6C656E746573717565206D61747469732E20496E746567657220737573636970697420616C697175616D20697073756D2E204475697320626C616E6469742C2073617069656E20657420756C7472696369657320636F6E64696D656E74756D2C2066656C6973206D6920656C656D656E74756D20706564652C206E6563207361676974746973206D65747573206D61757269732071756973207175616D2E205175697371756520616363756D73616E20617263752076656C206E756C6C612E20437261732073656D2073617069656E2C20706F72747469746F722069642C20756C747269636965732073616769747469732C206C75637475732065752C206E756C6C612E20496E746567657220717569732065726F732E204D6F726269207365642075726E6120612074656C6C7573207665686963756C612076756C7075746174652E20457469616D206E656320617567756520656765742066656C69732073656D706572207472697374697175652E205175697371756520757420646F6C6F722076656C2072697375732064696374756D20636F6E7365717561742E20536564206567657420646F6C6F7220736564206E756E63206C6163696E696120616C69717565742E2053757370656E646973736520616320746F72746F7220696E20697073756D20706F73756572652076656E656E617469732E20536564206567657420657261742E204E756C6C612066617563696275732E2044756973206C616F726565742C206D6173736120706F72747469746F7220616C697175657420656765737461732C20697073756D206C65637475732072686F6E637573207175616D2C20696E2061646970697363696E672065726F732073656D2075742074656C6C75732E2050656C6C656E74657371756520666575676961742074656D707573207175616D2E20566976616D757320696420646F6C6F7220656765742073617069656E20636F6E7365637465747565722074656D706F722E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120696163756C6973206665726D656E74756D206C696265726F2E204375726162697475722066617563696275732C206D61737361206D616C657375616461206375727375732074696E636964756E742C20657261742073656D20656C656966656E64206D61757269732C20736564206672696E67696C6C61206D6920616E74652061632070757275732E204475697320656C656D656E74756D206C65637475732E204E756E63206F726E617265206172637520657520746F72746F722E20566573746962756C756D2076656C20646F6C6F72206174207075727573206C6163696E6961206672696E67696C6C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E616D20696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204D616563656E61732074696E636964756E742C2065726F73206120656765737461732070656C6C656E7465737175652C2072697375732072697375732064696374756D206C696265726F2C20696420616C6971756574206D65747573206A7573746F20696E206D617373612E2050726F696E20612074656C6C75732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205365642070757275732E20536564206E6F6E20706564652E2041656E65616E206D617373612073617069656E2C20736F64616C65732073697420616D65742C20636F6E7365717561742064696374756D2C20656C656966656E642076697461652C20746F72746F722E20446F6E656320756C747269636573206C6163696E696120656C69742E0A0A4D6F7262692061646970697363696E6720736F64616C657320646F6C6F722E20557420756C6C616D636F7270657220756C74726963696573206573742E20496E2076656E656E617469732074656D7075732061756775652E2053757370656E646973736520746F72746F7220646F6C6F722C20616363756D73616E2065742C20737573636970697420612C2074696E636964756E742075742C206C696265726F2E20416C697175616D207363656C65726973717565206D61676E61207365642066656C69732E2051756973717565207574206E756E632061206D61676E612076756C70757461746520706C6163657261742E20416C697175616D2072686F6E637573207665686963756C61206475692E2053656420746F72746F722E204E756C6C616D2073697420616D6574206469616D2E204E756E63207365642065726F732E20536564206574206F64696F2074696E636964756E7420656C6974206772617669646120636F6E76616C6C69732E20437572616269747572207175697320746F72746F722061206C616375732073656D706572207661726975732E204D6175726973206174206175677565206E6F6E206D6920736F6C6C696369747564696E20616C697175616D2E20496E746567657220756C6C616D636F727065722E2050656C6C656E746573717565207375736369706974207175616D206E6F6E2070757275732E20416C697175616D2061632065726F73206174206172637520756C6C616D636F7270657220636F6E7365637465747565722E2053757370656E6469737365207072657469756D206D6174746973206C656F2E0A0A44756973206174206E756E632E2053656420646F6C6F72206573742C207661726975732061632C20706F7274612065742C2074696E636964756E742068656E6472657269742C2072697375732E20566976616D7573207574206D61676E612E205072616573656E74207574206D61757269732E20496E207075727573206C616375732C206D6174746973207365642C20766573746962756C756D206E65632C2074656D706F722061742C206E69736C2E204372617320756C6C616D636F727065722076656E656E617469732074656C6C75732E20557420646F6C6F722E204D616563656E6173206D616C6573756164612C207065646520612070756C76696E6172206D61747469732C2061726375206469616D207665686963756C612072697375732C207175697320706F72747469746F72206175677565206D6173736120696E2076656C69742E204E756E6320636F6E6775652E204D6F7262692076656C6974206D657475732C2072686F6E6375732065742C20616C697175616D20636F6E7365637465747565722C20756C74726963696573206D616C6573756164612C206C6967756C612E205365642076656C6974206E69736C2C2073616769747469732076697461652C20706861726574726120612C20706F7375657265207365642C206D617373612E204E756C6C6120666163696C6973692E20496E207661726975732C206C6967756C61206964206C6F626F7274697320736F64616C65732C206175677565206F726369206665726D656E74756D2074656C6C75732C2065752070756C76696E6172207269737573206C6967756C6120612073617069656E2E204D6F726269206C616F7265657420697073756D206E6F6E206D692E204E616D20637572737573206C6F72656D207574206D692E20566976616D7573206D61676E6120656E696D2C20706F7375657265206E6F6E2C2073656D70657220717569732C20736F64616C65732065752C20617263752E20457469616D206D692070757275732C207072657469756D20666575676961742C20766172697573207365642C2070656C6C656E74657371756520656765742C206C6967756C612E20496E206C656F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E6563207669746165206F726369206575206F72636920736F6C6C696369747564696E20666575676961742E0A0A5072616573656E74207075727573206D617373612C20657569736D6F642076697461652C2074656D707573206E65632C20636F6E7365717561742068656E6472657269742C206D657475732E2041656E65616E2066656C6973206573742C20656765737461732076697461652C20616363756D73616E20656765742C2070656C6C656E74657371756520696E2C2073617069656E2E204475697320646170696275732070656465206E6F6E2073617069656E2E204E756E632075726E612E20496E74656765722076656C206C696265726F2E204475697320617567756520617263752C2064617069627573206E6F6E2C20666163696C697369732076697461652C20706F73756572652075742C2065726F732E20446F6E6563207669746165206E756E632073697420616D6574206172637520696D706572646965742064696374756D2E204D6F72626920656C656966656E642C206C6F72656D20657520636F6E73656374657475657220766573746962756C756D2C206469616D206E756E63206F726E61726520617263752C2061632074656D706F722066656C697320646F6C6F7220656765742065726F732E2050686173656C6C7573206D617373612073656D2C20736F6C6C696369747564696E2061632C20736F64616C657320677261766964612C206C756374757320612C207175616D2E204E616D206E65717565207175616D2C20766976657272612061742C2076656E656E6174697320717569732C207361676974746973206E6F6E2C20656E696D2E0A0A4E756C6C6120666163696C6973692E2050656C6C656E7465737175652065676573746173206C6163696E6961206573742E205365642074696E636964756E742C2070656465207365642074696E636964756E7420766573746962756C756D2C2075726E6120646F6C6F722061646970697363696E672070757275732C207669746165206672696E67696C6C612066656C697320656C697420696E206E6962682E204E756C6C6120736564206E6973692E204D6175726973207375736369706974207363656C6572697371756520617263752E20457469616D206E6F6E20656E696D2076656C2065726F7320616363756D73616E206D616C6573756164612E204E756E632074696E636964756E7420636F6D6D6F646F206D61757269732E20496E2074696E636964756E7420726973757320717569732075726E612E204E756C6C61206469616D20746F72746F722C20616C69717565742065742C2074696E636964756E7420717569732C20736F6C6C696369747564696E2061632C20746F72746F722E2043726173206E69736C206E657175652C2076756C7075746174652073757363697069742C206D6F6C657374696520717569732C2070756C76696E61722061742C206E756C6C612E204E756C6C616D206163206D65747573206E6563206F64696F20706F7375657265207661726975732E2043726173207365642070656465206E65632064756920706F737565726520626962656E64756D2E204475697320657569736D6F6420756C6C616D636F72706572206C696265726F2E20416C697175616D2066617563696275732070756C76696E6172207475727069732E0A0A496E207574206E65717565206964206E756E63206665756769617420636F6D6D6F646F2E20437572616269747572206469676E697373696D2C2066656C697320617420736F6C6C696369747564696E206C6163696E69612C20656E696D20656C6974207375736369706974206E657175652C20736564206C7563747573206C6F72656D20697073756D20696E206C656F2E204475697320646170696275732C206F64696F207175697320617563746F7220636F6D6D6F646F2C206E69736C206F64696F206D61747469732074656C6C75732C206E65632074696E636964756E7420747572706973206469616D20696E20617263752E2043757261626974757220612073656D2E204E756C6C616D20766F6C7574706174206D61676E612E2050656C6C656E7465737175652073616769747469732C206E6571756520636F6E736571756174207072657469756D206375727375732C20646F6C6F72206C6163757320636F6E73656374657475657220617263752C20736564206C616F72656574206573742075726E61206574206D657475732E2053757370656E646973736520706C6163657261742C20647569206120706F7274612074656D706F722C206C6F72656D20647569206C6F626F72746973206E657175652C207365642076656E656E61746973206469616D20656E696D2069642065726F732E20457469616D206574206E69736C206E6F6E206C656374757320666175636962757320636F6E7365637465747565722E204D6F726269207363656C657269737175652C2073656D206E65632074656D70757320756C6C616D636F727065722C20697073756D206469616D2066657567696174206C6F72656D2C2061206672696E67696C6C612073617069656E20656C69742071756973206E6962682E204E756C6C616D206469616D2075726E612C2076697665727261207365642C2070686172657472612072686F6E6375732C2074696E636964756E742076656C2C206F7263692E20496E746567657220616363756D73616E206D617474697320657261742E204E616D2064696374756D2E204D6175726973206E6563206C656F2E204E756C6C6120696163756C69732E204E756C6C61206E69736C206D692C206461706962757320717569732C207665686963756C6120612C2063757273757320656765742C206F64696F2E0A0A50686173656C6C7573206461706962757320657569736D6F64206E6962682E20566976616D757320696D7065726469657420616E746520696E206C6967756C612E2050656C6C656E74657371756520616363756D73616E2E20496E20696D706572646965742C20647569206120617563746F72206672696E67696C6C612C206D65747573206E6973692063757273757320646F6C6F722C2076656C206C7563747573206C6967756C61206C6F72656D207669746165206D61757269732E205072616573656E74206D617474697320766573746962756C756D20656C69742E20416C697175616D20656E696D206C616375732C2070756C76696E6172206E6F6E2C206C6163696E69612073697420616D65742C20656C656966656E64206E6F6E2C2076656C69742E20566573746962756C756D206163206C656F2E204D617572697320696D70657264696574206A7573746F206163206C65637475732E20536564206D6F6C6573746965206C656374757320736564206475692E20536564206665726D656E74756D2074656D707573206D61757269732E204E616D206F726E617265206F7263692061632074656C6C75732E205574206D616C6573756164612C206C61637573206964206C6163696E696120616363756D73616E2C206469616D20656C69742061646970697363696E67206D657475732C20657420626962656E64756D2073617069656E206E69626820626C616E646974206F7263692E2053757370656E646973736520697073756D2074656C6C75732C20736167697474697320717569732C20766573746962756C756D206E6F6E2C2076756C7075746174652065752C2065726F732E205072616573656E74206174206E756C6C612069642070656465207363656C6572697371756520756C747269636965732E204372617320626C616E646974207072657469756D2074656C6C75732E204D616563656E6173206461706962757320636F6E64696D656E74756D2061756775652E2050686173656C6C75732074696E636964756E74207068617265747261206C6F72656D2E204D6F726269206E6F6E2065726F732E205365642074656D706F722C206E69736C20612074696E636964756E742074696E636964756E742C2065726F73206469616D2064696374756D2073656D2C2076656C206469676E697373696D20616E7465206469616D20736564206D61676E612E205072616573656E74206E6F6E206C6967756C61206964206D65747573206D6F6C657374696520636F6E7365637465747565722E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E64697373652076656C206D692E2043757261626974757220616E7465206E756C6C612C2072757472756D20612C20636F6E76616C6C69732076656C2C207665686963756C612061632C206E756E632E204E756E632073616769747469732C20656E696D2073697420616D657420617563746F722072757472756D2C206D617572697320617263752076756C707574617465206E657175652C20657420657569736D6F64206573742066656C6973207175697320616E74652E20566573746962756C756D207475727069732074656C6C75732C2068656E64726572697420696E2C206C6163696E696120636F6D6D6F646F2C20756C6C616D636F7270657220677261766964612C2072697375732E204D61757269732072686F6E637573206C6163696E69612072697375732E204D616563656E617320736F6C6C696369747564696E2065726174207669746165206E756E632E205072616573656E74207072657469756D2070656C6C656E7465737175652061756775652E20446F6E656320696E74657264756D2E205072616573656E742061632065726F732076697461652065726174206C6F626F72746973206672696E67696C6C612E2041656E65616E20636F6E7365717561742074656C6C75732E204E756C6C6120616363756D73616E20626962656E64756D2066656C69732E204D616563656E6173207072657469756D20616E7465206964206E6973692E2041656E65616E206D6920617263752C2073656D706572207365642C206D61747469732065752C2076656E656E617469732073697420616D65742C20617263752E20446F6E656320616C697175657420657569736D6F64206C656F2E2050726F696E206D61676E61206A7573746F2C2074726973746971756520612C2073656D7065722061632C20736F6C6C696369747564696E20612C206C6967756C612E204D6F7262692076656C69742E20416C697175616D2076656C206E6973692E0A0A496E2061206C6F72656D207574206E756E63206665756769617420636F6E6775652E20446F6E6563206665726D656E74756D20626962656E64756D206475692E2050726F696E207661726975732065737420717569732076656C69742E20446F6E656320616C69717565742073656D20616363756D73616E206D692E2053656420706C6163657261742E204E756C6C616D206163206E6973692061206D61737361206C6F626F727469732073757363697069742E204E756E63206964206C656F2E20416C697175616D206574206D617373612E204E756C6C616D20766573746962756C756D20656C656D656E74756D206D657475732E20496E20636F6E736563746574756572206E6973692076656C206A7573746F2E204D616563656E6173206567657420707572757320736564206D61737361207661726975732070656C6C656E7465737175652E2050686173656C6C75732066617563696275732066656C697320717569732066656C69732E2041656E65616E206F64696F20617263752C20626C616E64697420717569732C20666163696C6973697320696E2C20696D706572646965742065752C206C6F72656D2E204E616D20706F73756572652070756C76696E6172206D692E204675736365207472697374697175652C206D617572697320657420636F6E73656374657475657220756C747269636965732C206D6175726973206C65637475732074656D706F72206A7573746F2C206174206672696E67696C6C61206573742065737420736564206E6973692E20517569737175652066617563696275732E2053656420696E20746F72746F722074696E636964756E7420657374206C6163696E696120696163756C69732E204D616563656E61732061206D617373612E2050656C6C656E7465737175652061206E69626820617420707572757320706F7274612068656E6472657269742E0A0A4E756C6C616D207475727069732E2046757363652061632073656D20736564206F64696F2070656C6C656E74657371756520696D706572646965742E2043757261626974757220696E20617263752E205072616573656E74206C61637573206C616375732C20666575676961742069642C2070756C76696E617220696E2C2074696E636964756E74207365642C206E657175652E204D616563656E61732076697665727261206F64696F206567657420746F72746F722E20496E746567657220616C697175616D2C206C6F72656D2072757472756D2076656E656E61746973206469676E697373696D2C206C6967756C61206D61676E61206D616C65737561646120617263752C2076656C2066657567696174206C6F72656D20697073756D2071756973206D617373612E204D6F72626920616E74652E20566573746962756C756D206D6175726973206C696265726F2C20756C6C616D636F7270657220717569732C20756C74726963657320717569732C20666163696C69736973206E6F6E2C206D617373612E204D616563656E617320696D706572646965742E20416C697175616D206572617420766F6C75747061742E2050656C6C656E746573717565206469676E697373696D2067726176696461206C65637475732E20496E206E696268206F64696F2C20617563746F7220656765742C206461706962757320717569732C206469676E697373696D2076656E656E617469732C20617263752E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20447569732070656C6C656E746573717565206C6967756C612071756973206D617373612E2043757261626974757220636F6E64696D656E74756D2C206A7573746F2065676574206F726E617265206C75637475732C206C6F72656D206C6967756C6120736167697474697320706564652C206120706F727461206E756E63206E756E6320696E206E657175652E20517569737175652066656C6973206D61757269732C20636F6E64696D656E74756D2076697461652C20617563746F722076697461652C2074696E636964756E7420717569732C20706564652E204E756E63206C6163696E696120616E746520696E206C656F2E2050656C6C656E746573717565206C696265726F2E2041656E65616E2061206C6967756C61206574206E756E6320766573746962756C756D20636F6E7365637465747565722E0A0A4675736365206F726E6172652E205072616573656E742069642075726E612E20496E74656765722076656E656E617469732C207175616D206E6F6E20736167697474697320616363756D73616E2C20616E7465206E6962682073616769747469732061756775652C20736F6C6C696369747564696E2061646970697363696E6720646F6C6F722076656C697420657520657261742E2050726F696E207175697320656E696D206575207075727573207665686963756C6120616C697175616D2E204E756C6C612076656C20656E696D2076656C20656C697420736F6C6C696369747564696E206672696E67696C6C612E20416C697175616D206572617420766F6C75747061742E205365642073757363697069742066656C6973207574207475727069732E20457469616D2072757472756D20726973757320696D70657264696574206573742E20416C697175616D20612074656C6C75732061742074656C6C757320636F6D6D6F646F20646170696275732E204D61757269732072757472756D206D61676E61206574206F64696F2E20496E20617420646F6C6F722E20437572616269747572207665686963756C61206C656374757320696E20746F72746F722E204675736365206A7573746F2070757275732C206C75637475732076697461652C206D6F6C6C697320696E2C2070686172657472612061632C2070757275732E204E756C6C616D20706F737565726520696E74657264756D206A7573746F2E20437572616269747572207669746165206C616375732076656C206C656F20636F6E6775652070756C76696E61722E0A0A41656E65616E20656C656966656E64206E6962682076617269757320746F72746F722E2053757370656E64697373652076656C2065726F732E2050726F696E206E6563206469616D206120746F72746F7220756C747269636573206F726E6172652E20416C697175616D207363656C657269737175652066657567696174206A7573746F2E20566976616D757320616E74652075726E612C2061646970697363696E672076697461652C20706F72747469746F722065752C20736F64616C65732065742C2066656C69732E2053757370656E646973736520706F74656E74692E20437572616269747572206163206D6173736120696E206E69736C207361676974746973206D6F6C6C69732E204E616D207175616D206C6967756C612C20636F6E73656374657475657220656765742C20696163756C69732061742C207661726975732065752C206C656F2E204475697320646F6C6F72206C6967756C612C2074696E636964756E742061742C20756C6C616D636F72706572207365642C20616363756D73616E20616C697175616D2C206C6967756C612E2050686173656C6C75732076756C7075746174652C206C6F72656D2061742074696E636964756E742070686172657472612C207269737573206C6563747573206C6163696E6961206D61676E612C20717569732072757472756D20656E696D206D61676E612061742073656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E20447569732069642073656D2061206D617572697320736F6C6C696369747564696E2074696E636964756E742E20457469616D2065752070757275732065752061726375206672696E67696C6C612061646970697363696E672E20566976616D7573206F726E6172652074656D707573206469616D2E2050726F696E20747572706973207175616D2C206C6163696E6961206E6F6E2C20656765737461732061742C20636F6D6D6F646F20656765742C20706564652E205072616573656E742076756C70757461746520726973757320696E206573742E204E756C6C6120666163696C6973692E0A0A557420656C656D656E74756D206C6163696E69612070757275732E2050726F696E2076697461652061726375206163206E756C6C6120636F6E76616C6C697320616C697175616D2E204E756C6C6120636F6E6775652C206C696265726F2069642070656C6C656E746573717565206D61747469732C207175616D206C656374757320706F72747469746F72206469616D2C2061207363656C6572697371756520647569206C696265726F20696E2073617069656E2E204E756C6C616D2066656C6973206469616D2C207665686963756C612076656C2C206D6F6C65737469652075742C20766573746962756C756D20616C697175616D2C2073617069656E2E20446F6E656320636F6E76616C6C69732C2065737420757420656C656D656E74756D20766F6C75747061742C206D617572697320697073756D20677261766964612073656D2C20636F6D6D6F646F20666163696C697369732073617069656E206C65637475732073656D706572206C65637475732E205175697371756520706F72747469746F722065726F73207574206E6962682E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20457469616D206D617474697320726973757320736564206F64696F2E20566573746962756C756D206574206F64696F2E20496E206861632068616269746173736520706C617465612064696374756D73742E204E616D20747269737469717565206D61737361207574206C6967756C612E2051756973717565206E6962682074656C6C75732C207665686963756C612073697420616D65742C2061646970697363696E672061742C20636F6E76616C6C6973206E65632C206C6967756C612E20566573746962756C756D207072657469756D2C206D69206E6563206672696E67696C6C6120626962656E64756D2C20647569206E756E6320736F64616C657320706564652C20612073656D706572206D61676E61206E696268206E6F6E206469616D2E20446F6E6563206D61737361206E756E632C20766976657272612076656C2C20636F6E73656374657475657220706F7274612C2064617069627573206E6F6E2C20697073756D2E2044756973206E69736C206D61757269732C206375727375732076656C2C2073656D706572206E6F6E2C20736F6C6C696369747564696E20626962656E64756D2C2066656C69732E20566573746962756C756D206575206E657175652E0A0A43726173206E656320646F6C6F722E20446F6E6563206C616F726565742074656D707573206C65637475732E20437261732073656420746F72746F7220696E74657264756D206C6163757320656C656966656E64206469676E697373696D2E204D616563656E61732073697420616D657420656C69742E204E756C6C616D207175697320646F6C6F722076656C20647569207068617265747261206C75637475732E20496E2073697420616D6574207175616D2073697420616D6574207065646520756C74726963657320756C7472696365732E204D616563656E6173206469616D2E20496E74656765722075726E612E204375726162697475722064696374756D2C2076656C69742073656420706C6163657261742073757363697069742C206572617420747572706973206665726D656E74756D206A7573746F2C2073656420696E74657264756D206E657175652073656D206574206E6962682E20566976616D757320636F6E73657175617420636F6E76616C6C6973206D61676E612E204E616D20616C697175616D2C2065737420616320626962656E64756D20636F6D6D6F646F2C206D61676E61206573742064696374756D206D692C207669746165206D616C65737561646120656C6974206D61676E61207669746165206F64696F2E204D616563656E61732074656D706F722076756C7075746174652074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206475692E20457469616D20616363756D73616E207065646520636F6E67756520746F72746F722E0A0A4D6F7262692074656D706F72206C696265726F206163206C6F72656D2E20496E20616C697175657420766172697573206D61676E612E20496E20617263752E2050686173656C6C7573206F64696F2E2046757363652074696E636964756E7420616C69717565742066656C69732E20517569737175652076656C69742E20536564206C75637475732E20416C697175616D2066657567696174206672696E67696C6C61206D692E20416C697175616D206D6F6C657374696520766976657272612072697375732E2050726F696E20617263752E20566573746962756C756D206C6F626F727469732074656D707573206E6973692E205072616573656E742061206172637520696E2076656C697420766976657272612072757472756D2E0A0A496E20736564206C65637475732E20446F6E656320726973757320646F6C6F722C20626C616E6469742073697420616D65742C20656C656D656E74756D20636F6E76616C6C69732C20706861726574726120717569732C20706564652E20496E7465676572206F726E6172652E2041656E65616E20656765737461732064617069627573206A7573746F2E20536564207175616D206C656F2C20706F73756572652061742C20656C656D656E74756D2076697461652C20636F6D6D6F646F20656765742C206573742E20416C697175616D206D6F6C65737469652072686F6E63757320656E696D2E2043757261626974757220696163756C697320756C74726963657320706564652E204D6F72626920616C69717565742072757472756D206C616375732E20416C697175616D207175616D2E2053656420636F6D6D6F646F2C2074757270697320696E20706861726574726120706F73756572652C206D6920726973757320696D7065726469657420657261742C206120766573746962756C756D206D617373612074656C6C7573207665686963756C612073656D2E204D6175726973206672696E67696C6C6120756C747269636573206E756E632E204E616D206E69736920656E696D2C20656C656966656E642073697420616D65742C20756C747269636573207365642C206665726D656E74756D206E6F6E2C2061756775652E2050726F696E20636F6E677565206C6F626F72746973206E6973692E204D616563656E61732068656E6472657269742E204E616D20736564206E69736C2E204E756E6320656C656D656E74756D206F64696F2065752072697375732E20496E206D657475732E2050686173656C6C75732067726176696461207072657469756D206C6967756C612E204E756C6C61207669746165206E657175652E204E616D206E69736920746F72746F722C206F726E617265206E6F6E2C20626C616E6469742061742C206375727375732065752C20746F72746F722E0A0A4475697320626962656E64756D20697073756D20696E206E756E6320637572737573206D6F6C65737469652E204E756E63206F7263692E204E756C6C616D206E656320616E7465206E6F6E20657374206469676E697373696D20766976657272612E204D617572697320626C616E6469742C2076656C69742069642066657567696174207072657469756D2C20656C6974206D61676E612070656C6C656E74657371756520646F6C6F722C206174207361676974746973206C616375732076656C69742065676573746173206D61676E612E2050656C6C656E746573717565206375727375732C206469616D20636F6E736563746574756572207361676974746973206672696E67696C6C612C20746F72746F72206E6973692061646970697363696E67206E756E632C20657520766172697573206C6163757320726973757320616320656C69742E204D6175726973206964206E6973692071756973206C656F20657569736D6F642076656E656E617469732E2050656C6C656E74657371756520616320616E74652E204D617572697320617263752073617069656E2C2074656D706F722061742C20706F72747469746F722069642C20636F6E64696D656E74756D2075742C206475692E20457469616D206665726D656E74756D20756C747269636965732061756775652E20437261732075742065726F73206174206A7573746F20756C7472696369657320696163756C69732E2044756973206469676E697373696D2C206E69736C20657420666163696C69736973206665726D656E74756D2C2065726174207075727573206D6F6C65737469652074656C6C75732C20717569732074656D70757320697073756D206C656374757320617420656C69742E204E756C6C61207669746165206C6F72656D2E0A0A41656E65616E2076656C2073656D206574206469616D2073656D70657220636F6E6775652E20496E20626962656E64756D206469616D20717569732074656C6C75732E204E756E6320666163696C6973697320756C74726963696573206E6962682E2043726173206E756E6320656E696D2C2066657567696174207365642C20756C7472696365732076697461652C2073616769747469732076697461652C20697073756D2E204675736365207669746165206E756C6C612E20446F6E65632070656C6C656E7465737175652C2076656C697420696E20706F72747469746F7220656C656966656E642C20657374206E65717565206C6F626F727469732076656C69742C2073697420616D65742072757472756D20616E746520746F72746F72206E656320646F6C6F722E20446F6E6563207665686963756C612E204E756C6C6120666163696C6973692E20536564206567657374617320756C747269636573206E6962682E20446F6E656320656C6974206C65637475732C20636F6E76616C6C697320706F72747469746F722C20616C697175657420646170696275732C206665756769617420656765742C206C6967756C612E2053656420636F6E736563746574756572206A7573746F2E204D616563656E617320612073617069656E2073697420616D6574206E6973692064617069627573206C6F626F727469732E20566976616D7573206C7563747573206C6F72656D206E6F6E206E756C6C612E2053656420656765742065726174207669746165206C696265726F20696E74657264756D20706F73756572652E20437261732070756C76696E61722E204E756C6C616D20696D706572646965742C20646F6C6F722074656D706F72206469676E697373696D20626C616E6469742C206475692073617069656E2072686F6E637573206E657175652C206964206D616C657375616461206175677565206D61676E612073697420616D65742075726E612E204475697320736564206D61757269732E0A0A4D6F72626920616363756D73616E2E20536564206D61757269732061756775652C206672696E67696C6C61206E6F6E2C20617563746F722075742C20617563746F722065742C206F7263692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320757420706564652E20446F6E6563207669766572726120656E696D2076656C206C6F72656D2E2050656C6C656E746573717565206E65717565206D61757269732C20696E74657264756D2065752C2076656E656E617469732069642C20636F6E64696D656E74756D2065752C2073617069656E2E20446F6E656320697073756D20617263752C206C6163696E69612061646970697363696E672C206C616F726565742065742C206375727375732076656C2C2076656C69742E205574207361676974746973206D617572697320717569732072697375732E20496E7465676572206575206F64696F207669746165206C61637573207669766572726120616363756D73616E2E204D6F726269206C656F20616E74652C206469676E697373696D207365642C2076617269757320717569732C20766F6C75747061742076697461652C206E6973692E204E756C6C6120706C61636572617420696E74657264756D20656C69742E20446F6E6563206E65717565206475692C2073616769747469732076697461652C20736F6C6C696369747564696E20717569732C20636F6D6D6F646F2076697461652C206E657175652E204E756C6C612071756973206C6967756C61206F726E617265206C6967756C612064696374756D206F726E6172652E204D61757269732072757472756D2072757472756D206E657175652E2041656E65616E207665686963756C612074656D707573206573742E20446F6E656320766172697573207363656C6572697371756520706564652E20446F6E656320706C6163657261742076756C707574617465206C656F2E204E756C6C616D206E756E63206E69736C2C20706F7375657265206E6F6E2C20666575676961742076697461652C2070656C6C656E74657371756520717569732C206D61757269732E20496E20647569206E657175652C2063757273757320656765742C20736167697474697320656765742C20646170696275732076697461652C206D692E2050726F696E2065676574206573742E0A0A467573636520706F727461206573742E204D6175726973206D61676E612E20416C697175616D20697073756D206C616375732C20756C747269636965732069642C20766573746962756C756D206C75637475732C20616363756D73616E2075742C20616E74652E20536564206D61757269732E205365642061646970697363696E67206C656F2073697420616D6574206D61676E612E2053757370656E646973736520706F74656E74692E204E756E63206D6173736120656C69742C206672696E67696C6C6120656765742C20656765737461732076697461652C206C75637475732076697461652C20646F6C6F722E2050686173656C6C75732071756973206E756C6C61206575206E69736920696E74657264756D20736F6C6C696369747564696E2E204E756C6C616D2069642074656C6C75732E20496E746567657220696163756C697320646F6C6F722061632070757275732E205365642076656C206D692E20437572616269747572206E6F6E206D61676E612073697420616D6574206A7573746F20636F6E64696D656E74756D2076756C7075746174652E20517569737175652074696E636964756E742070656465206575206E69736C2E20566976616D7573206C6F626F727469732E204E756E63206D65747573206D657475732C20636F6E677565207365642C2074696E636964756E74207365642C207072657469756D2061742C206F64696F2E20446F6E6563206120617263752E20496E2073656D206A7573746F2C207665686963756C61207365642C207661726975732069642C20766F6C75747061742061742C2072697375732E205072616573656E7420696163756C6973206D617373612E20496E206172637520656C69742C2068656E64726572697420656765742C20756C6C616D636F7270657220696E2C20706F7274612069642C2074656C6C75732E20446F6E65632073616769747469732068656E647265726974206469616D2E0A0A53757370656E646973736520706F74656E74692E20536564206574206469616D206574206175677565207361676974746973206C6F626F727469732E2050686173656C6C757320646F6C6F722E2055742065742061726375206567657420616E74652074656D706F7220706F73756572652E20416C697175616D206665726D656E74756D207363656C65726973717565206475692E204D61757269732061742070757275732E20446F6E656320657261742073656D2C20766573746962756C756D206E65632C2066617563696275732061632C206D617474697320612C206C656F2E2053757370656E64697373652061646970697363696E67206C6163696E69612073656D2E204E756C6C616D206F72636920617263752C2064696374756D2065742C20666175636962757320766976657272612C20646170696275732065742C206E657175652E2043726173206E756E63206469616D2C2061646970697363696E67206E6F6E2C20736F6C6C696369747564696E20696E2C20696E74657264756D2076656C2C206D617373612E204D61757269732073616769747469732C206A7573746F206174207472697374697175652074656D7075732C206D6175726973206D617572697320616C697175616D20616E74652C2073697420616D657420706F7375657265206469616D206475692065676574206C6967756C612E20496E206469676E697373696D2C206E69736C207574206C6163696E696120636F6E64696D656E74756D2C2065726174206A7573746F20706F72747469746F72206E756C6C612C206E6F6E2067726176696461206C6967756C61206D61676E612065676574206D617373612E20566573746962756C756D207669746165206C6967756C61206174206D6920766573746962756C756D2073757363697069742E2044756973206C616F726565742E204E756C6C6120636F6D6D6F646F206C696265726F2073697420616D6574206C6F72656D2E20557420656C656D656E74756D2073656D2E20496E74656765722076656C20646F6C6F722E204E616D20666163696C69736973206D6920717569732073656D20756C7472696365732073616769747469732E205365642071756973207175616D206174206D65747573206D6F6C657374696520626962656E64756D2E0A0A50726F696E2064756920656E696D2C206C6163696E696120612C20666575676961742061632C20706C6163657261742076697461652C20706564652E205175697371756520656765737461732C206C656F206567657420616C697175616D207072657469756D2C206C696265726F206A7573746F2074696E636964756E742065726F732C2075742065676573746173206175677565207065646520656C656D656E74756D206E6962682E20437572616269747572206D6F6C6C697320736F64616C657320656E696D2E20446F6E65632061756775652E2050686173656C6C757320696420697073756D20706F737565726520647569207072657469756D2066617563696275732E204D6175726973206C756374757320616E74652073656D706572206E69736920696E74657264756D2061646970697363696E672E204475697320646170696275732C206F64696F207175697320766976657272612072686F6E6375732C206A7573746F207175616D20626962656E64756D20646F6C6F722C20696420646170696275732076656C697420657261742076656C20657261742E2046757363652073697420616D6574206E69736C2076656E656E61746973207175616D20756C74726963657320636F6E64696D656E74756D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632072686F6E637573207363656C65726973717565206C6967756C612E20566573746962756C756D206D69206F64696F2C20616363756D73616E2065742C2061646970697363696E6720656765742C206F726E6172652075742C207175616D2E204E756C6C616D20626C616E646974206D6F6C6573746965206D61757269732E20437572616269747572206469676E697373696D206D6175726973206574206C6F72656D2E2053757370656E64697373652061206A7573746F2E204E616D206D617474697320666175636962757320617263752E204475697320626C616E64697420656E696D206E6F6E206D617373612E0A0A4E756C6C616D206C6F72656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E204D617572697320636F6E73656374657475657220706F7375657265206D61757269732E204D616563656E61732074696E636964756E74206D617572697320696E2065726F732E204E756C6C61206575206D65747573206575206F72636920736F6C6C696369747564696E2066617563696275732E2053757370656E646973736520616C697175616D206D6175726973206964206573742E204372617320626C616E646974206475692065742075726E612E204E756C6C6120617263752E2053656420612075726E612E204E756C6C612064617069627573207665686963756C6120746F72746F722E20446F6E65632072697375732E20536564207175616D206D657475732C20656765737461732065752C206375727375732075742C2076697665727261206E6F6E2C206F64696F2E205574206A7573746F206A7573746F2C206D616C6573756164612073697420616D65742C20626C616E6469742073757363697069742C206D6F6C657374696520696E2C206A7573746F2E20566573746962756C756D20636F6E7365717561742C207175616D20616320666575676961742074696E636964756E742C20697073756D206C696265726F20656C656966656E64206F64696F2C206E6F6E20656C656966656E64207065646520697073756D206E6F6E20616E74652E204E756C6C616D2061206D657475732E0A0A4E616D206163206E6973692061742066656C697320637572737573206D61747469732E2050656C6C656E74657371756520636F6E7365717561742073656D2071756973206F7263692E20517569737175652074656D7075732E2041656E65616E20696D70657264696574206D6F6C657374696520706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652065752074656C6C75732E204E756C6C61206469616D2065726F732C20736F64616C65732075742C20736F64616C6573206E65632C2074696E636964756E742061632C206E756E632E204E756E63206C6163696E696120666175636962757320697073756D2E20566976616D75732076656C206E6571756520696E2065726174206665726D656E74756D206C75637475732E204E756C6C612065676574206D65747573206E656320617567756520626962656E64756D20706C6163657261742E20566976616D75732074656D7075732E205072616573656E7420636F6E677565206F726E61726520697073756D2E20457469616D206D61747469732066657567696174206A7573746F2E0A0A416C697175616D206475692E2041656E65616E20636F6D6D6F646F20746F72746F72207669746165206E756C6C612E204D6F72626920657420697073756D2E204D617572697320616320697073756D2E204E616D2076656C207269737573207574206C6563747573206D6F6C6C697320766976657272612E2043757261626974757220656C656D656E74756D206D6F6C6C6973206573742E204E756C6C616D20656C69742E20566573746962756C756D207375736369706974207072657469756D20656E696D2E20566573746962756C756D207574206D617373612E2050726F696E206E65632066656C69732E204D616563656E617320677261766964612C2061726375206E656320636F6E7365717561742073616769747469732C2065726F732074656C6C7573207363656C65726973717565206D61757269732C20766974616520616363756D73616E207175616D207175616D207574206E756E632E20496E7465676572206567657420616E74652065752076656C6974206C616F72656574206D616C6573756164612E204E756E632073616769747469732C206D617572697320766974616520706861726574726120766F6C75747061742C2074656C6C75732074656C6C757320656C656966656E642065726F732C2073697420616D65742072757472756D20697073756D206E69736920612076656C69742E205072616573656E7420766172697573206C656F20657520657261742E20566976616D757320636F6E73657175617420706C6163657261742070757275732E20446F6E6563207072657469756D20656C656D656E74756D206E6962682E2050726F696E20617420656C6974206E6F6E2073656D20616C6971756574206D61747469732E2053656420756C6C616D636F7270657220697073756D2073697420616D657420656C69742E0A0A4D617572697320696E206D657475732E2053757370656E6469737365206D61676E61206C6F72656D2C2066617563696275732076656C2C2074696E636964756E7420717569732C207363656C65726973717565206E6F6E2C2074656C6C75732E2046757363652071756973206C6F72656D2E2050726F696E2061206C616375732073697420616D6574206D617572697320696163756C69732070756C76696E61722E2053757370656E64697373652072686F6E6375732065726F73206E6563206D692E205072616573656E7420657569736D6F642C207475727069732076697461652072757472756D207072657469756D2C206F64696F206D6574757320766F6C7574706174206E657175652C20656765742074656D7075732073617069656E206E657175652073656420657261742E20446F6E6563206665726D656E74756D207075727573206174206C65637475732E204E756C6C616D2073656D2E2046757363652076656C206D6920717569732065726174206C6F626F7274697320706F73756572652E2041656E65616E20656765742075726E612E2053757370656E6469737365206C6967756C612E204475697320696E206E6973692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A4375726162697475722076756C707574617465206C656374757320696420706564652E2050686173656C6C75732065752076656C69742E20457469616D2076656E656E617469732061646970697363696E67206E6962682E20416C697175616D206375727375732070756C76696E61722074656C6C75732E20566573746962756C756D206E657175652E204D6175726973206E6563206A7573746F20657420657261742073656D7065722070656C6C656E7465737175652E204675736365206D61747469732064696374756D20646F6C6F722E20457469616D2065676574207075727573206575206D617373612076617269757320656C656D656E74756D2E2050656C6C656E746573717565206D617373612E20557420756C74726963696573206469616D2073656420697073756D2E204E756C6C616D206469616D2E2050656C6C656E746573717565206964206D61676E61206964206C696265726F2074726973746971756520616C697175616D2E0A0A557420656C656966656E642C20707572757320696420706C6163657261742076656E656E617469732C2075726E6120617567756520616C6971756574206C6967756C612C20696E20756C74726963696573206C656F2072697375732065742074656C6C75732E204D6175726973206574206E756C6C612069642075726E61207472697374697175652074656D7075732E20557420666163696C697369732C2075726E6120657520766573746962756C756D2072686F6E6375732C206C616375732065726F7320636F6E736563746574756572206D657475732C2065742072757472756D20647569206C656374757320696E2070757275732E204E756E632076656C206E69736C206E6F6E20697073756D2074696E636964756E74206D6F6C6C69732E204E616D207175616D206C616375732C206F726E6172652076697461652C2072686F6E637573206E6F6E2C20636F6E677565207365642C206F64696F2E2050726F696E206E696268206475692C20706F7274612076656C2C2076656E656E61746973206E6F6E2C2070656C6C656E7465737175652075742C206E6973692E20536564207472697374697175652066656C69732061206D61676E612E2053757370656E646973736520656765742074656C6C75732E2043726173206772617669646120696D706572646965742076656C69742E20496E74656765722068656E6472657269742072697375732E2050726F696E206F7263692E20416C697175616D20756C6C616D636F72706572206D61757269732071756973206D61757269732E204E756E63206C6163696E696120766573746962756C756D206D657475732E20447569732074656C6C75732E204E756C6C616D2066617563696275732C206C656F2061632076756C70757461746520736F6C6C696369747564696E2C206C656F20646F6C6F7220666175636962757320657261742C207175697320626962656E64756D206F726369206F64696F206E6F6E20617263752E0A0A4E756C6C616D20616363756D73616E206D617474697320646F6C6F722E20446F6E6563206574206475692E205072616573656E7420612066656C6973206D6F6C6C6973206C616375732073656D706572206C6163696E69612E204375726162697475722070656C6C656E746573717565206C7563747573206573742E2050726F696E206E756C6C61206475692C20636F6E64696D656E74756D2076656C2C206661756369627573206E6F6E2C20696E74657264756D2061632C20657261742E204D616563656E6173207363656C657269737175652C206C656374757320696420766F6C757470617420616363756D73616E2C2073617069656E20746F72746F722070656C6C656E746573717565206475692C207365642073656D706572206D61676E612073656D207574206C656F2E2050726F696E206E756C6C612E204E756C6C616D206461706962757320756C6C616D636F727065722073656D2E2053757370656E6469737365207665686963756C61206D6574757320696E206E756E632E2050656C6C656E746573717565206E6F6E207175616D2076656C206172637520756C74726963657320756C6C616D636F727065722E2050686173656C6C757320717569732066656C69732073697420616D65742074656C6C757320756C6C616D636F72706572206665726D656E74756D2E20536564207665686963756C6120736F6C6C696369747564696E2075726E612E20437572616269747572207068617265747261207363656C657269737175652072697375732E2050656C6C656E746573717565206964206D617373612071756973206D6574757320616C697175616D20696D706572646965742E20496E206E756E63206C616375732C206665756769617420696E2C206772617669646120656765742C2076656E656E617469732075742C2074656C6C75732E2053757370656E646973736520706F74656E74692E204E616D20636F6E7365717561742061646970697363696E67206475692E20496E206E756C6C61206E6973692C20666575676961742075742C206665726D656E74756D2076656C2C2067726176696461206E65632C20746F72746F722E20496E207365642061756775652E0A0A457469616D20756C6C616D636F7270657220617567756520617420656E696D2E20496E7465676572206469676E697373696D2E20416C697175616D2070756C76696E617220636F6E677565206E756C6C612E204D6F72626920656E696D206D617373612C206672696E67696C6C6120612C20616363756D73616E20656765742C20636F6E64696D656E74756D206E65632C20657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2041656E65616E2070686172657472612E20457469616D20706F72747469746F722070757275732061206D657475732E20416C697175616D20696E74657264756D2073656D2065676574206A7573746F2E205175697371756520766F6C7574706174206C7563747573206573742E2041656E65616E2061756775652E2050686173656C6C757320647569206C65637475732C20756C747269636573206E65632C20636F6D6D6F646F2076656C2C20617563746F722076656C2C206E6973692E20557420756C7472696365732070656C6C656E746573717565206E6973692E20496E74656765722061632076656C69742065742073656D20696D70657264696574206C75637475732E20467573636520766974616520747572706973206964206175677565206D6F6C6C697320636F6E7365637465747565722E0A0A4D616563656E6173206E6563206C616375732E204D616563656E617320636F6E64696D656E74756D206F64696F2065752066656C69732E204D6175726973207574206E69736C207669766572726120657261742066617563696275732061646970697363696E672E20457469616D20656765737461732E204E756E6320657420646F6C6F72207669746165207269737573206469676E697373696D20636F6D6D6F646F2E204D6F726269206C65637475732076656C69742C2074696E636964756E74206E65632C20616C69717565742076656C2C206D61747469732076697461652C206C6967756C612E204D616563656E617320756C747269636965732073656D70657220646F6C6F722E2053757370656E6469737365206D616C6573756164612E20496E7465676572206D617474697320656C69742E20446F6E656320616363756D73616E2C206C6163757320666163696C69736973207661726975732074656D7075732C206E756C6C6120656C697420706F72746120657261742C2065742072757472756D20656C69742073656D2073697420616D6574206475692E0A0A4D616563656E6173206D6F6C6C6973206D69206E6F6E206E756C6C612E20566976616D7573207475727069732E2053757370656E64697373652061206D657475732E20496E2071756973206D6920696E2074757270697320636F6E67756520617563746F722E204D616563656E6173206C616375732E2053757370656E646973736520736F6C6C696369747564696E2E2050686173656C6C757320706F727461206E756E63206E6F6E206E69736C2070756C76696E617220656765737461732E20536564206E756C6C612E20566573746962756C756D206163206D692E204D617572697320756C7472696369657320636F6E64696D656E74756D206E657175652E204E756C6C612074656D707573206A7573746F2076656C206D617373612E204E756C6C6120737573636970697420636F6E67756520617263752E205072616573656E74206964207475727069732E204D6175726973206E69626820706564652C20657569736D6F642073656D7065722C206D6F6C65737469652061632C2072686F6E6375732076697461652C20616E74652E204D616563656E617320657261742066656C69732C207669766572726120736F6C6C696369747564696E2C20736167697474697320656765742C2070656C6C656E746573717565206E65632C206F7263692E20467573636520756C74726963657320636F6E736571756174206C616375732E20416C697175616D2065726174206D61676E612C20666575676961742061742C207669766572726120612C206D6F6C6C6973206E6F6E2C207475727069732E0A0A446F6E6563206D692E204E616D2064696374756D2070656C6C656E7465737175652073656D2E20446F6E6563206D6F6C6C69732072686F6E63757320656C69742E2050686173656C6C75732072686F6E63757320706564652073697420616D65742072697375732E20446F6E656320656765742061756775652E204D616563656E6173206E6F6E206C65637475732E2050686173656C6C757320736F6C6C696369747564696E206E697369206E65632066656C69732E20416C697175616D207072657469756D2C2065737420656765742073656D70657220636F6E76616C6C69732C206E696268206E756E6320736F6C6C696369747564696E2070757275732C2069642074656D706F722070656465206475692076656C206D61676E612E20566976616D7573206163206C6F72656D2E20457469616D206E69736C20746F72746F722C2061646970697363696E672064696374756D2C20656C656D656E74756D20696E2C20666163696C69736973207365642C206E6962682E2050726F696E206D61757269732E2050726F696E2072757472756D206D6173736120656765742073656D2E204375726162697475722074656D706F722061646970697363696E6720656C69742E204375726162697475722070757275732074656C6C75732C206665726D656E74756D20656765742C20616C69717565742076697461652C20636F6E76616C6C69732061632C206D61757269732E0A0A496E746567657220636F6E7365717561742076656C69742065752065726F732074696E636964756E74207665686963756C612E204E756C6C616D206C6F72656D2073617069656E2C2072686F6E637573206E6F6E2C206D617474697320717569732C20756C747269636965732073697420616D65742C20656E696D2E2043757261626974757220636F6D6D6F646F2C206C696265726F20696E20657569736D6F642073757363697069742C2073656D207075727573206672696E67696C6C6120656E696D2C206163206D6F6C657374696520746F72746F72206F7263692065742076656C69742E20446F6E656320706564652E20457469616D20706C61636572617420636F6E64696D656E74756D207475727069732E2050686173656C6C7573206567657374617320656E696D206E6563206D61676E612E20566976616D757320636F6E64696D656E74756D2C206E756C6C612076656C206C7563747573207472697374697175652C2065726F7320726973757320766573746962756C756D206E756C6C612C20696E207665686963756C61206172637520697073756D2061742066656C69732E20446F6E656320616C697175616D20656C69742061742061756775652E205175697371756520612065726F73206575206C6967756C6120616363756D73616E2064696374756D2E20457469616D207665686963756C61207475727069732071756973206C696265726F2E20416C697175616D206E6F6E206D692E20446F6E6563206574206C656F2E2050726F696E206C656F206C696265726F2C20616C697175616D2074696E636964756E742C20636F6E677565206E65632C2061646970697363696E6720706F7274612C20656E696D2E204E756C6C61206C6F626F727469732C20746F72746F722073697420616D657420696D7065726469657420756C6C616D636F727065722C20646F6C6F72206F726369206D616C65737561646120706564652C207365642067726176696461206E6962682075726E612076656C206C6F72656D2E20536564207068617265747261206D616C6573756164612065726F732E205175697371756520657569736D6F6420616C697175657420657261742E2053757370656E646973736520616C6971756574206D61747469732070757275732E0A0A4E756E63206964206E756C6C612071756973206A7573746F20636F6E67756520736F6C6C696369747564696E2E205072616573656E742065726174207475727069732C2072686F6E6375732065752C207072657469756D2065752C2070656C6C656E74657371756520612C206E6962682E20566976616D75732074656D7075732E2043726173206E65632072697375732061742074757270697320696D70657264696574206C6F626F727469732E205574206D61747469732E204D616563656E6173206573742066656C69732C2070656C6C656E746573717565206E6F6E2C20696D70657264696574207365642C20656C656966656E642074696E636964756E742C206C6F72656D2E20496E2074696E636964756E742E205365642076656C206C656F2E20446F6E65632065742075726E6120696E207475727069732068656E64726572697420626C616E6469742E20446F6E656320636F6E64696D656E74756D20616363756D73616E206573742E2055742070686172657472612C206D65747573207669746165206D617474697320636F6E7365637465747565722C206C656F207175616D2076756C707574617465206F64696F2C206E6563206C616F72656574206E6973692076656C697420657520657261742E20496E7465676572206C65637475732061756775652C206567657374617320696E2C20696E74657264756D2065752C2076656E656E617469732076656C2C2073617069656E2E2051756973717565206574206573742076697461652065726F73206C616F72656574206C6F626F727469732E204E756C6C616D207574207269737573206E6F6E206E756C6C6120706C6163657261742061646970697363696E672E205072616573656E7420646170696275732E20457469616D20612066656C69732E20557420736F64616C657320636F6E736571756174206D61757269732E2044756973206C6F72656D2066656C69732C206C756374757320612C2074726973746971756520696E2C206D6F6C65737469652061742C2072697375732E20536564207665686963756C6120626962656E64756D2074656C6C75732E204E616D20636F6E73657175617420657569736D6F64206C616375732E0A0A41656E65616E20746F72746F7220656C69742C2067726176696461206E65632C206665726D656E74756D2065752C206C6F626F727469732069642C20697073756D2E204D616563656E61732065752070757275732E204372617320616320747572706973207574206E69736920696163756C69732072686F6E6375732E204E756C6C61207075727573206D657475732C206469676E697373696D206E65632C2074696E636964756E742076697461652C20646170696275732065752C206E6962682E204675736365206C6F626F727469732C206E756E63206174207669766572726120656C656966656E642C206A7573746F20747572706973207363656C657269737175652065726F732C2061632070656C6C656E746573717565206D65747573206E69736C2061742070757275732E2053656420656C656D656E74756D2074656C6C75732073656420656E696D20696E74657264756D20626C616E6469742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E746567657220756C7472696369657320616C6971756574206F64696F2E204D61757269732065676574206E756E63206120697073756D20756C74726963657320736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2041656E65616E20616363756D73616E2E20446F6E65632073617069656E206C65637475732C20636F6E6775652061742C20706F7274612069642C2068656E6472657269742076697461652C206E69736C2E204375726162697475722076656C207175616D2076656C206E6571756520616363756D73616E206C616F726565742E204D6F7262692073617069656E206573742C207072657469756D20696E2C20636F6E7365637465747565722061632C206D6F6C6C69732075742C206C696265726F2E20446F6E65632074696E636964756E742061646970697363696E67206D657475732E204E756E6320766573746962756C756D20656765737461732061756775652E20446F6E6563207363656C65726973717565206475692075742073656D2E2053757370656E64697373652076656C206D6574757320696420657374206D6F6C657374696520696163756C69732E0A0A566976616D75732070686172657472612C20656C6974206575206D616C65737561646120626C616E6469742C206469616D20746F72746F72206D6F6C6C6973206475692C207365642070756C76696E6172206D61737361206E756E63206574206D61676E612E2053656420706C61636572617420656C697420617563746F7220746F72746F722E204E756C6C6120616320657261742E2050656C6C656E74657371756520636F6E7365637465747565722C2064756920636F6E76616C6C69732074696E636964756E7420636F6E64696D656E74756D2C2073656D206F64696F20766F6C7574706174206C696265726F2C206E6F6E20656C656D656E74756D2066656C6973206E65717565206E6563206F64696F2E204D616563656E61732068656E6472657269742065726F73206964206469616D2E204D61757269732076656C207075727573206163206F72636920636F6E76616C6C697320636F6E76616C6C69732E205365642073697420616D6574206C616375732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652064696374756D20766172697573206C616375732E204D61757269732065676574206E69736C2E2053757370656E646973736520706C6163657261742C206E756C6C61206E6F6E206F726E617265206469676E697373696D2C206E69736C206469616D2073616769747469732074656C6C75732C20696E2073656D706572206E69736920646F6C6F72206174206E6962682E204475697320756C6C616D636F7270657220766976657272612066656C69732E20496E746567657220612074656C6C75732E2053757370656E64697373652065676574206E756E632E2041656E65616E206469616D206573742C20616363756D73616E2069642C20737573636970697420696E74657264756D2C206672696E67696C6C612076697461652C206A7573746F2E2050726F696E20706564652E204D616563656E6173206174206E6571756520696E206E6571756520766573746962756C756D20656C656966656E642E0A0A566573746962756C756D206E756C6C61206C6F72656D2C20706F72747469746F7220656765742C20657569736D6F642061632C20616C697175616D2061742C206E69736C2E204D616563656E6173206574206573742065676574206D6173736120766172697573206C6F626F727469732E20496E206D692E204475697320706F72747469746F72206665726D656E74756D2070757275732E20446F6E65632063757273757320696D70657264696574206C6967756C612E204D6F726269206574206C6967756C6120657420616E7465206D6F6C6573746965207665686963756C612E204D61757269732073656420646F6C6F722E2053656420696D706572646965742066656C69732075742073656D2E20536564207669746165206E6571756520656C656D656E74756D206C656F20617563746F72206665726D656E74756D2E2044756973206665756769617420756C6C616D636F7270657220657261742E2041656E65616E2070757275732E204D6F726269206665726D656E74756D20766573746962756C756D206573742E2050656C6C656E7465737175652076656E656E61746973206D61757269732E2050686173656C6C75732070756C76696E61722E20496E746567657220697073756D206C65637475732C20696163756C697320612C206C6163696E69612069642C20616363756D73616E2069642C20617263752E2050686173656C6C7573206174206573742E204675736365206E65717565207175616D2C20756C747269636965732069642C20696163756C69732076656C2C20646170696275732076697461652C206C616375732E20496E206C6F626F7274697320636F6E76616C6C697320616E74652E204E756C6C61206E756E632070757275732C2076756C70757461746520696E2C2068656E6472657269742065742C20626C616E6469742065742C206C6967756C612E0A0A50656C6C656E746573717565206C656F206D657475732C20736167697474697320696E2C206D6F6C65737469652076697461652C2064696374756D20696E2C20706564652E204D6F726269207072657469756D2066656C6973206E6563207175616D2E2050656C6C656E746573717565206D617474697320616E746520736564207175616D20736167697474697320646170696275732E2053757370656E64697373652073617069656E2E205072616573656E7420626962656E64756D20696163756C697320746F72746F722E20447569732061206E69736C2E2041656E65616E206D692E20446F6E65632064696374756D206172637520696E206573742E204D6F72626920696E74657264756D2076756C70757461746520697073756D2E2041656E65616E2073697420616D6574206D61676E61206E6F6E206E69736C2074726973746971756520706F73756572652E2050686173656C6C75732076656C6974206D657475732C2074656D706F722061632C206665726D656E74756D20656765742C20636F6E64696D656E74756D206E6F6E2C2076656C69742E20566573746962756C756D2073697420706F73756572652E0A0A4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204372617320616C6971756574206D61737361206E6563206475692E20437261732061726375206E756E632C2068656E6472657269742061632C20656C656966656E642065752C20756C6C616D636F72706572206E65632C2074656C6C75732E205365642070686172657472612070757275732073697420616D6574207175616D2E20437572616269747572206D6F6C6C69732E204E616D20766974616520706564652E20457469616D207269737573206D617373612C207665686963756C612073697420616D65742C207068617265747261206E65632C20736F6C6C696369747564696E2075742C206475692E20446F6E65632065676573746173206A7573746F206174207175616D2E2050726F696E206E69736C2072697375732C20766573746962756C756D206E65632C207072657469756D2076697461652C207472697374697175652061632C206C6F72656D2E20416C697175616D206572617420766F6C75747061742E204372617320736564206E6962682E2050656C6C656E74657371756520736F6C6C696369747564696E20657569736D6F642061756775652E0A0A457469616D206672696E67696C6C6120736F6C6C696369747564696E206F7263692E204D61757269732063757273757320656C69742071756973206C616375732E204372617320746F72746F722E20496E2061646970697363696E672C206C656374757320696420617563746F7220766573746962756C756D2C206E65717565207065646520616363756D73616E20646F6C6F722C206E6F6E20696D70657264696574206D61676E61206469616D20616363756D73616E2076656C69742E2053757370656E6469737365206174206C696265726F207574206E69736920626C616E6469742073616769747469732E2050686173656C6C7573206E6F6E206D61757269732E20467573636520656C656D656E74756D2073616769747469732073656D2E2053757370656E646973736520616C697175616D20656C656966656E642074656C6C75732E2050726F696E206C6967756C61206C6F72656D2C20696D7065726469657420717569732C2076656E656E617469732069642C20696163756C6973206D6F6C6C69732C206E69736C2E20457469616D20636F6E76616C6C69732070656465206174206D617373612E204D6F72626920616363756D73616E20647569206574206D61757269732E0A0A53656420736564206F7263692E204E756E632070757275732E2053757370656E646973736520706F74656E74692E205574206C7563747573206672696E67696C6C61206D61757269732E20446F6E6563206E6962682E2050686173656C6C757320706F7274612E2050686173656C6C75732073697420616D6574206F64696F20736564206D61676E6120736F64616C65732070686172657472612E2043726173206C65637475732E2053757370656E6469737365206C696265726F20697073756D2C20636F6D6D6F646F206E65632C20666163696C6973697320696E2C207375736369706974206C6F626F727469732C206C6967756C612E2044756973206D61737361206E756C6C612C2073656D7065722065742C20636F6E736571756174206E65632C2070686172657472612065752C20656C69742E20566976616D757320756C7472696369657320616C697175616D206F64696F2E20566573746962756C756D2073697420616D6574206D617373612E2053656420636F6E736571756174206C61637573207365642075726E612E20457469616D2066617563696275732066656C69732076656C206F7263692E2050686173656C6C757320756C6C616D636F727065722E2041656E65616E20636F6E736563746574756572206C61637573206174206C696265726F2E0A0A436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204475697320666163696C697369732C206C6967756C6120766974616520636F6E64696D656E74756D207363656C657269737175652C2076656C6974206F72636920677261766964612066656C69732C2076656C20756C74726963696573207175616D206D69206E6F6E206469616D2E20566976616D757320617563746F72206D65747573206E6F6E206C696265726F2E205072616573656E74206C6967756C61206E6973692C20636F6D6D6F646F20636F6E64696D656E74756D2C206D6F6C65737469652065742C20766976657272612065742C206A7573746F2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320736F6C6C696369747564696E2E204E756E6320626C616E6469742063757273757320697073756D2E2041656E65616E206E6563206C6967756C612075742074656C6C757320736F64616C6573206D61747469732E20496E74656765722073656D2E20416C697175616D206964206C6967756C612E2053656420746F72746F72206D61757269732C20626C616E6469742076697461652C206375727375732076656C2C20656C656D656E74756D2065742C206E756C6C612E20416C697175616D207363656C65726973717565206D65747573206574206E69736C2E20447569732061646970697363696E67206D61676E61206174206E657175652E20517569737175652076756C70757461746520656C656966656E64206E756E632E20416C697175616D206567657420656C69742E2050686173656C6C757320647569206F64696F2C20626962656E64756D2073616769747469732C20766573746962756C756D2069642C206469676E697373696D20696D706572646965742C206F7263692E204E756C6C616D2065752066656C6973206E6F6E206E756E63206C6163696E696120736F64616C65732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A53757370656E64697373652070656C6C656E7465737175652C206C696265726F206D617474697320756C7472696369657320616363756D73616E2C20746F72746F7220746F72746F72206D616C6573756164612073656D2C20657420736F64616C6573206C696265726F206F64696F20616320697073756D2E20566976616D75732071756973206D61676E61206E656320657374207375736369706974206C6F626F727469732E20437261732074656D70757320706F7375657265206E756E632E205175697371756520757420656E696D20612066656C697320656765737461732073656D7065722E20536564207068617265747261206D6174746973206E657175652E20467573636520747572706973206E756E632C20636F6E677565207365642C20636F6E736571756174206E6F6E2C20636F6E677565207365642C206E756C6C612E2053757370656E646973736520766172697573206C6F72656D20696420726973757320706F72746120766573746962756C756D2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204675736365207365642070757275732E20496E20612066656C69732E20496E7465676572206567657374617320617563746F72206F7263692E204D617572697320756C747269636573207375736369706974206E69736C2E204E756C6C616D2070757275732E0A0A437261732074656D706F722061646970697363696E6720697073756D2E2055742071756973206D692E204D616563656E617320696E206A7573746F207574206E756C6C6120636F6E6775652070686172657472612E2050656C6C656E746573717565207574206C696265726F20657520646F6C6F722076656E656E617469732073757363697069742E205072616573656E74206665756769617420636F6E736563746574756572206E6962682E204D6F7262692066617563696275732073656D206E6F6E2066656C69732E20496E2068656E6472657269742061726375206163206D617373612E20496E20616363756D73616E20756C747269636573206D692E2050726F696E206D616C65737561646120617563746F722066656C69732E2043757261626974757220696E74657264756D2E20536564206469616D20697073756D2C20756C7472696369657320696E2C2074656D706F722073697420616D65742C207669766572726120696D706572646965742C20656C69742E204D6F726269206D6F6C6573746965206E6973692E204D617572697320697073756D2E2046757363652064696374756D206D6F6C6C6973206D61676E612E204475697320636F6D6D6F646F206469676E697373696D206E756C6C612E20566573746962756C756D20617567756520656E696D2C20756C7472696369657320717569732C20696163756C6973206E65632C2074696E636964756E742076697461652C206469616D2E204D6175726973206C6163696E69612074656D70757320697073756D2E20536564206174206D61757269732E205574206C6F72656D2E20446F6E6563206C696265726F2E0A0A4475697320696163756C6973206C6163696E6961206C65637475732E2041656E65616E20636F6E76616C6C69732065726F7320616320616E74652E205365642071756973206F726369206E656320726973757320617563746F72206672696E67696C6C612E2050686173656C6C757320666163696C6973697320656C656D656E74756D206E6973692E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E6320706F727461206C61637573206E656320616E74652E204D6F726269206D617572697320657261742C2061646970697363696E6720696E2C2070756C76696E6172206E65632C206C6F626F72746973206E65632C206F64696F2E20557420656C656966656E64206C656374757320736564207175616D2E204E756C6C616D206D6F6C6C69732E20496E206E6F6E20747572706973206574206E69736C2068656E64726572697420626C616E6469742E204475697320656C656D656E74756D2E204E756E63206E6563206C696265726F2E2053757370656E646973736520766573746962756C756D207269737573206E6F6E20706564652E204D6F72626920696D70657264696574206F64696F2073697420616D6574206C696265726F2E2053656420736564206D6173736120766974616520697073756D206D61747469732074696E636964756E742E204E756C6C61206E656320746F72746F72207669746165206C696265726F20766F6C75747061742074656D7075732E20446F6E656320616C697175616D2E0A0A4475697320736564206E756E632E2043757261626974757220747572706973206E756C6C612C207665686963756C61207365642C206C756374757320717569732C20656C656D656E74756D20656765742C2066656C69732E204D616563656E61732065742070757275732E204D616563656E6173206C656F2074656C6C75732C2074696E636964756E7420612C20666163696C697369732076697461652C206C6F626F727469732073697420616D65742C2076656C69742E20446F6E656320636F6E76616C6C69732073617069656E2E204D616563656E6173206D6F6C6C6973206F64696F206575206E6962682E20457469616D20677261766964612E20496E7465676572206D6F6C65737469652C2073617069656E206575206D6F6C6573746965206C6163696E69612C206E756E63206E69626820616C697175616D206C6967756C612C2065752073616769747469732074656C6C7573206572617420736F6C6C696369747564696E206F64696F2E20447569732065742072697375732E2050686173656C6C7573206E697369206E657175652C20706C616365726174206E65632C20636F6E64696D656E74756D206E6F6E2C20756C7472696365732065752C2073656D2E20557420706564652E20457469616D206E756C6C61206D657475732C20766F6C75747061742069642C20636F6E76616C6C6973207365642C2073757363697069742076656C2C2075726E612E20446F6E65632076656C20656C69742E205574206C656F206E657175652C2076656E656E617469732066617563696275732C206C6163696E6961206E65632C2074696E636964756E742065752C20656E696D2E2043726173206964206475692061206C696265726F207068617265747261206469676E697373696D2E20446F6E65632065726F73206C656F2C20706F72746120717569732C206C616F726565742075742C2070656C6C656E74657371756520766F6C75747061742C206C65637475732E0A0A4E756C6C616D20626C616E6469742E20416C697175616D206572617420766F6C75747061742E2046757363652061646970697363696E6720656E696D2E2053757370656E6469737365206E6F6E206475692071756973206C6967756C6120706F72746120766573746962756C756D2E20446F6E65632065752074656C6C75732076656C206C6F72656D207072657469756D20706F72747469746F722E205072616573656E74206C75637475732E20416C697175616D2061632065726F7320696E206D6173736120646170696275732074696E636964756E742E20446F6E6563207574206D61676E612E20457469616D20617563746F72206C616375732073697420616D6574206C616375732E2053656420756C7472696369657320697073756D206E656320656C69742E205175697371756520612065737420696E207075727573207375736369706974207472697374697175652E0A0A41656E65616E20736564206475692076656C20646F6C6F722070756C76696E6172206C616F726565742E20566976616D7573207665686963756C61206C6F72656D20696E20706564652E20566976616D7573206574206469616D2E20496E7465676572206163206F64696F2076656C206469616D2068656E64726572697420626962656E64756D2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E756C6C612061206E6973692E2050686173656C6C75732074696E636964756E74206475692076697461652061756775652E20447569732066617563696275732C2064756920696E74657264756D206672696E67696C6C612074696E636964756E742C206F64696F20656C697420766573746962756C756D206C696265726F2C206163206D6F6C6573746965206D61676E61206C6563747573206964206C616375732E2041656E65616E206C6967756C612E204E756C6C6120666163696C6973692E0A0A46757363652076656C2073656D2065752076656C6974206672696E67696C6C61206F726E6172652E2053656420666575676961742074696E636964756E742066656C69732E204E756C6C616D2066656C6973206D692C20657569736D6F642073697420616D65742C206D6F6C6C69732061742C20736F64616C657320656765742C2061756775652E204E616D20696D70657264696574206E6962682061742076656C69742E2053656420757420657261742E20496E206475692E204E756C6C6120666163696C6973692E204E756C6C616D206175677565206C696265726F2C2074696E636964756E74206E65632C207072657469756D2065752C2070756C76696E617220696E2C206475692E204D6F7262692076697461652066656C69732E2050656C6C656E7465737175652076656C206A7573746F2076656C2076656C6974207361676974746973206D616C6573756164612E2050726F696E207665686963756C6120626C616E646974206D617373612E20457469616D2074696E636964756E742070686172657472612075726E612E20496E206D65747573206573742C20617563746F72206E65632C20626C616E64697420612C20637572737573206E65632C207175616D2E204D6175726973206163206D657475732061206C696265726F20636F6E6775652066617563696275732E204D6175726973206D617572697320646F6C6F722C20736F64616C657320696E2C206375727375732075742C20736F64616C65732072757472756D2C2065726F732E2051756973717565206D61757269732065726F732C2073616769747469732076697461652C206C6F626F727469732075742C20656C656966656E642069642C206E6973692E0A0A41656E65616E206E657175652E20566573746962756C756D20656765737461732070656C6C656E746573717565206C6967756C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2050686173656C6C7573207361676974746973206A7573746F2076656C2072697375732E20536564207072657469756D206E657175652076697461652075726E612E2050656C6C656E74657371756520636F6E677565206C696265726F206964206C6F72656D2E204D6175726973206C656F206C6F72656D2C20626C616E6469742073697420616D65742C20636F6E76616C6C697320717569732C20636F6E736563746574756572207365642C2065726F732E204D61757269732074696E636964756E742C20656E696D2061206772617669646120657569736D6F642C206D61676E61206E756C6C61206665726D656E74756D206C696265726F2C207669766572726120656765737461732076656C6974207175616D20657420746F72746F722E20566976616D757320616C6971756574206D61737361207669746165206A7573746F2E204E756C6C6120636F6E677565206C6163757320616320656C69742E0A0A50686173656C6C757320636F6D6D6F646F207175616D2076656C206C6967756C612E2050726F696E206E6F6E206D657475732061742065726F732070756C76696E6172206C75637475732E204D6175726973206469616D206C6F72656D2C20706F737565726520717569732C20677261766964612065742C2074696E636964756E74206E65632C206C6967756C612E20536564206469616D2E20416C697175616D20656C6974206C65637475732C2068656E6472657269742075742C20696D706572646965742073697420616D65742C207072657469756D2073697420616D65742C20697073756D2E204D6175726973207665686963756C61206E69736C20696E206475692E204375726162697475722065676574207175616D207574206D61676E6120656C656D656E74756D206665726D656E74756D2E204D6175726973207363656C657269737175652E2051756973717565206C616F726565742E20457469616D2074656D707573207475727069732E2050656C6C656E746573717565206175677565207175616D2C2068656E647265726974207365642C2074696E636964756E742061742C2070686172657472612061742C206E69736C2E20416C697175616D206C616375732E2053757370656E646973736520706F74656E74692E2041656E65616E2076656C6974206C696265726F2C20756C74726963657320696E2C206C6163696E69612065752C206C75637475732076656C2C20616E74652E20457469616D2064696374756D206D6920696E2066656C69732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20467573636520677261766964612064617069627573206E69736C2E2043726173207669746165206E69736C2E0A0A4D616563656E6173206469676E697373696D2C206C6967756C61206E6F6E20706F727461206375727375732C20656E696D206E756E63206D616C6573756164612073656D2C20657520706F72747469746F72206E756C6C612075726E61206575207175616D2E2046757363652065726F732E20416C697175616D2065726F732E204E616D20617563746F722E204E756C6C61206D6F6C657374696520706F727461206573742E2053757370656E646973736520706F74656E74692E20566976616D7573206D6F6C6573746965206C6F72656D2073656420657261742E20536564206567657420697073756D2E20496E746567657220616C697175616D2070756C76696E6172206E756C6C612E204372617320616C69717565742073656D207574206E756E632E2046757363652066617563696275732074656D707573206C65637475732E204372617320736F64616C65732C206E69736920616320666163696C6973697320756C7472696365732C2065726F73206172637520646170696275732073617069656E2C20657420756C747269636573206D61757269732074656C6C7573206E6F6E20646F6C6F722E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20437261732063757273757320766172697573206D657475732E205574207475727069732E20566976616D7573206567657420746F72746F722E0A0A536564206C616F726565742C2076656C6974206E6F6E20616363756D73616E206375727375732C206E756E632075726E6120706F7375657265206A7573746F2C20696E2064696374756D206C6563747573207065646520696420616E74652E20437261732076756C7075746174652E204372617320636F6E677565206475692073656420656C69742E2050726F696E206C616375732073656D2C20756C7472696365732061742C20636F6E73657175617420696E2C2074656D706F7220717569732C206D657475732E2050726F696E2076656C20617263752E204E616D20657569736D6F642068656E64726572697420656C69742E20557420657261742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2053656420706F73756572652E204D6F7262692065726F732075726E612C2073656D7065722061742C2073656D706572206E6F6E2C20636F6E76616C6C697320717569732C2076656C69742E204D616563656E6173206F7263692E20566573746962756C756D206C6F626F7274697320747269737469717565206D657475732E20566573746962756C756D206C6F72656D206E756C6C612C20736F6C6C696369747564696E2076697461652C20636F6E64696D656E74756D20717569732C20617563746F722075742C206475692E20566976616D757320766573746962756C756D206D61676E61207574206E6973692E2043757261626974757220656C656966656E64206475692076656C206E756E632E20437572616269747572206D6175726973206C616375732C206D616C6573756164612073697420616D65742C207375736369706974207365642C2072757472756D206C75637475732C2074656C6C75732E20496E746567657220666163696C697369732075726E61207669746165206C65637475732E0A0A41656E65616E207175616D206C656F2C206C6F626F7274697320717569732C206D616C6573756164612065752C2076756C7075746174652076697461652C206E69736C2E205072616573656E7420656765742065726F732E205574206665726D656E74756D20747572706973206964207175616D2E204E616D20746F72746F722E205072616573656E74206E6563206F7263692E204E756C6C6120626962656E64756D2061646970697363696E672061756775652E20557420636F6D6D6F646F2C206D61676E61206964206D616C65737561646120677261766964612C206175677565206F64696F206D616C657375616461206D692C20706F727461206D616C65737561646120656C697420657374207669746165206469616D2E204D6175726973206E6F6E206E756C6C612E2053757370656E64697373652074696E636964756E742C206E756E6320756C7472696369657320706F7274612076656E656E617469732C206D6920706564652074696E636964756E74206C696265726F2C20656765742076617269757320616E7465206C696265726F207574206C6967756C612E20437572616269747572207072657469756D20706F72747469746F7220746F72746F722E0A0A4D616563656E617320766974616520656C69742065676574206E69736920646170696275732064696374756D2E204E756E6320696E206C696265726F2E204E756C6C612064696374756D206F726369206575206572617420617563746F72206C6F626F727469732E2050686173656C6C75732072697375732E2053757370656E646973736520706F74656E74692E2053757370656E646973736520706F74656E74692E205072616573656E742061646970697363696E6720636F6E73657175617420656C69742E20496E74656765722069642061756775652E205072616573656E7420696E206A7573746F206E6563206D61676E6120646170696275732070756C76696E61722E2044756973206E69736C2E2053757370656E6469737365206163206F64696F2E20566976616D757320696D706572646965742E20446F6E6563206E6F6E2076656C69742073697420616D6574207269737573206469676E697373696D20636F6E6775652E204E616D20616C697175657420706F73756572652076656C69742E2043726173207475727069732E204D6F726269206D616C657375616461206469676E697373696D206D692E0A0A536564206C656F206E657175652C2076617269757320717569732C2076656E656E61746973207365642C207068617265747261207365642C206573742E204D6F72626920626C616E6469742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D2073656D7065722070656C6C656E746573717565206D692E2055742076656C206C6F72656D2E204E756E63206D6920746F72746F722C206C616F726565742061742C2066617563696275732065752C2074696E636964756E742073697420616D65742C20657261742E20447569732074656D706F72206D616C65737561646120697073756D2E2050686173656C6C757320616C69717565742E20446F6E656320657420656C69742E2050656C6C656E7465737175652070757275732E20566573746962756C756D2072757472756D2073656D706572206E6962682E204E756C6C6120666163696C6973692E2050686173656C6C757320657420656E696D2073697420616D657420616E746520766573746962756C756D207665686963756C612E2050686173656C6C7573206964206E69736C2E20446F6E6563206D6F6C6C6973206C656F2061742065726F732E204D61757269732070656C6C656E746573717565206E657175652061742070757275732E204D6F726269207175697320646F6C6F7220617420697073756D207363656C6572697371756520736F64616C65732E20457469616D20766F6C7574706174207475727069732061206D657475732E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206C6F72656D206C6F72656D2C20766573746962756C756D2061632C20657569736D6F6420656765742C20756C6C616D636F72706572206469676E697373696D2C2076656C69742E0A0A43756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204372617320756C7472696365732C206E6962682076656C20616C697175616D20766573746962756C756D2C2065726F7320656E696D2076656E656E61746973206475692C20696420696163756C697320656E696D206E756E632076656C206D617373612E204D6F72626920656C656966656E64206F726369206574206D617373612E20416C697175616D206572617420766F6C75747061742E204E756C6C61206D6F6C6C69732065676573746173207475727069732E20496E20736F64616C6573206E756E63206567657420746F72746F722E2053656420697073756D2065726F732C2074656D706F7220717569732C20616C69717565742076697461652C20696D70657264696574206E6F6E2C206C6F72656D2E2050656C6C656E746573717565207175697320656C6974206964206D69206C756374757320646170696275732E20536564206E756E6320617263752C2072686F6E637573206E65632C20636F6E76616C6C697320717569732C206375727375732061742C206E657175652E204D617572697320636F6E76616C6C697320707572757320617420657261742E2050656C6C656E74657371756520766573746962756C756D2E20566976616D7573206672696E67696C6C6120656C697420617420617263752E204E756C6C616D20616C697175657420656E696D206E656320617263752E204E616D20696420746F72746F722E204E756C6C612071756973206E756E632E20557420617263752E2053757370656E646973736520706F74656E74692E2050656C6C656E74657371756520756C6C616D636F72706572206C6967756C6120696420617263752E0A0A4E616D206E6F6E206C696265726F207669746165206E69736C207363656C65726973717565206672696E67696C6C612E20517569737175652076617269757320616E7465206964206D657475732072686F6E637573206672696E67696C6C612E204E756C6C6120666163696C6973692E205072616573656E7420656C656966656E6420706F72747469746F72206C6967756C612E20457469616D207175697320646F6C6F72206E6F6E20617567756520636F6D6D6F646F20617563746F722E20446F6E65632061206D692E20566573746962756C756D2074656D706F722E20446F6E65632066656C69732075726E612C20617563746F722061742C206375727375732064696374756D2C20677261766964612069642C20617263752E2041656E65616E2064696374756D206D616C65737561646120646F6C6F722E20566976616D7573206D61747469732E2050686173656C6C757320657520706564652E2046757363652061646970697363696E67206A7573746F206672696E67696C6C61206D657475732E20457469616D20616E74652E20496E7465676572206D6F6C6C6973206D617373612071756973206E756E632E20496E74656765722064696374756D206E65717565206C756374757320656E696D2E0A0A536564206575206C696265726F2E20496E74656765722074656D706F72206C6967756C6120696E2076656C69742E2055742074696E636964756E74206C6163696E69612073656D2E204E756C6C616D2076656C2072697375732E2053656420736F64616C657320616E7465206120646F6C6F722E204375726162697475722065726F732E2053656420736F64616C65732E20536564206E6F6E206D657475732E20566573746962756C756D20656C656D656E74756D20666175636962757320616E74652E204E756C6C612076656C206E6962682E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206E6563206C6F72656D20757420697073756D206C6163696E696120696163756C69732E204475697320657261742E20416C697175616D20657261742E204372617320696163756C69732E20496E206861632068616269746173736520706C617465612064696374756D73742E0A0A4E756C6C616D20616E74652E2043726173207669746165206573742E2050656C6C656E7465737175652076656C206D657475732061206C6967756C612064617069627573206D61747469732E2044756973206665756769617420616C69717565742066656C69732E20457469616D206964206E69736C207175697320657374206469676E697373696D20636F6E64696D656E74756D2E2053757370656E646973736520706F74656E74692E204D6F7262692076656C6974206C6F72656D2C206F726E61726520717569732C2070656C6C656E7465737175652076656C2C20706C61636572617420656765742C20746F72746F722E20566573746962756C756D2074696E636964756E74206D6F6C6573746965206C696265726F2E204E756C6C61206E756C6C6120656E696D2C206D616C6573756164612069642C20756C6C616D636F727065722076697461652C2064696374756D2061742C2070757275732E20446F6E6563206469676E697373696D206F64696F20757420656E696D2E2053757370656E6469737365206174206C65637475732E0A0A5072616573656E74206C6F626F727469732061756775652076656C206C65637475732E20557420696E206C6967756C612075742066656C697320636F6E6775652073757363697069742E2051756973717565206469676E697373696D20746F72746F72207574206D692E204675736365206D61676E61206E6973692C20656C656966656E642061632C206F726E6172652076656C2C20706F72747469746F722076697461652C207175616D2E20566573746962756C756D20736F64616C6573206A7573746F2071756973207475727069732E2046757363652075726E61206E6973692C2072686F6E63757320717569732C20636F6E64696D656E74756D2076656C2C2064696374756D2065752C206E756E632E20467573636520736564206E696268207669746165206F64696F20706F73756572652061646970697363696E672E2053656420706F72746120656C6974207175697320646F6C6F722E204E616D206C696265726F206E756C6C612C20617563746F72207365642C2074696E636964756E7420717569732C2066617563696275732073697420616D65742C206D692E2051756973717565206F7263692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E756C6C616D2069642073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632076656C2065726F732E0A0A566976616D7573206C7563747573206C6F626F72746973206C656F2E2053757370656E64697373652076656C20656C6974206120656E696D20756C6C616D636F7270657220706F73756572652E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20446F6E656320717569732070656465206D6174746973206C6563747573206D6F6C6C69732061646970697363696E672E2053656420616363756D73616E20706F737565726520657261742E205072616573656E7420657569736D6F642074696E636964756E742066656C69732E20446F6E6563206D692E20557420636F6D6D6F646F2061726375206C6163696E69612074656C6C75732E20416C697175616D2061206C696265726F2071756973206C65637475732073656D70657220766976657272612E20437572616269747572206C6163696E6961206D61757269732061742074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E756E632073697420616D6574206D61676E61206D6F6C6573746965206F726369207375736369706974206672696E67696C6C612E204675736365207072657469756D206D65747573206E6F6E2073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642068656E6472657269742E204E756C6C612066656C69732E2053757370656E646973736520706F74656E74692E20416C697175616D20626C616E64697420747269737469717565206E657175652E20437572616269747572207175697320657261742076656C206E756E6320616363756D73616E206D6F6C6C69732E0A0A447569732073616769747469732C2074656C6C757320757420616C697175616D206672696E67696C6C612C20646F6C6F72206D6920756C6C616D636F72706572206E69736C2C20757420747269737469717565207065646520656C697420736564206D61757269732E204375726162697475722069642066656C69732E20446F6E65632070756C76696E6172206C61637573206574206C65637475732E20416C697175616D2076756C7075746174652076756C707574617465206D657475732E20437572616269747572206D61676E612066656C69732C2061646970697363696E672061632C20616363756D73616E2076656C2C206D6F6C657374696520717569732C207175616D2E204D617572697320656C697420617263752C207072657469756D2076697461652C206D6F6C6C69732073697420616D65742C20736F6C6C696369747564696E2075742C206D692E20446F6E656320696D70657264696574206469676E697373696D206D692E204E756C6C616D2073697420616D657420746F72746F722E20416C697175616D206E65717565206E756C6C612C2076656E656E6174697320612C20706F72746120696E2C20706C6163657261742074656D7075732C206C616375732E205175697371756520766573746962756C756D20647569206574206C616375732E2050726F696E206469676E697373696D20636F6E7365637465747565722070757275732E20457469616D206772617669646120746F72746F7220696E206E756E632E2055742074656D706F722074726973746971756520746F72746F722E20536564206C616F726565742074696E636964756E74207175616D2E20566573746962756C756D20706F7274612074757270697320757420656C69742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20446F6E6563206E696268206475692C2066657567696174206E65632C206C616F726565742069642C206D616C65737561646120656765742C206E6973692E205574206E65717565206D617373612C207665686963756C612065752C20636F6D6D6F646F206E6F6E2C20756C747269636965732076697461652C2070757275732E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204D617572697320657569736D6F642C2066656C69732076656C2074656D706F7220616C69717565742C20746F72746F72206D6175726973206D616C657375616461206E756E632C2076656C206665726D656E74756D2073656D206469616D206964206475692E204E616D2072757472756D2073617069656E2065676574206F64696F2E20416C697175616D20736564206C696265726F206E6F6E206D692066617563696275732074656D7075732E2046757363652068656E6472657269742C206469616D206E6F6E20766F6C75747061742072757472756D2C2065726174206D657475732076656E656E61746973206C6967756C612C206E6F6E207363656C657269737175652070656465206C6967756C612076656C207175616D2E204D6F7262692072686F6E6375732065726F7320616320647569206665756769617420656C656D656E74756D2E2044756973206575206C696265726F2065742074656C6C757320636F6E67756520766976657272612E204D6F726269207175616D207175616D2C20656C656D656E74756D207365642C20756C6C616D636F7270657220696D706572646965742C20636F6D6D6F646F206E6F6E2C206F64696F2E204E616D20616C697175657420656765737461732075726E612E204D6175726973206F64696F2066656C69732C207661726975732065752C206C6163696E69612065752C20636F6E64696D656E74756D20612C206C65637475732E20536564206A7573746F206D617373612C2070756C76696E61722069642C2076617269757320612C20706F72747469746F72206E65632C206C696265726F2E20457469616D207661726975732E2043757261626974757220736F64616C65732C206F64696F20617420706F73756572652073656D7065722C2065726F73206E6962682074696E636964756E74206C65637475732C2076656C2072757472756D2073617069656E206E69736920696E206C6967756C612E2053757370656E6469737365206567657420617263752E2050686173656C6C757320696D70657264696574206573742061632073617069656E2E20446F6E6563206E756C6C6120746F72746F722C20706C6163657261742076656C2C2074656D70757320612C206C6F626F727469732076656C2C206E6962682E20416C697175616D20766172697573206E6973692E204E756C6C6120657420656E696D2E20467573636520636F6E76616C6C6973206C616F72656574206C616375732E0A0A50686173656C6C757320697073756D20646F6C6F722C206D6F6C657374696520717569732C20636F6E64696D656E74756D20696E2C20636F6D6D6F646F2065752C206469616D2E205175697371756520626962656E64756D206C6163696E6961206475692E204E756C6C616D20626C616E6469742076756C707574617465206F7263692E205574206C6163696E6961206D617373612076656C2061756775652E20416C697175616D20677261766964612C207175616D207175697320696D7065726469657420696D706572646965742C2074656C6C7573206469616D20706861726574726120657261742C206174207068617265747261206C61637573206E6962682065676573746173206D61676E612E204E756C6C61207361676974746973206C6F72656D207574206C6F72656D2E204475697320636F6E64696D656E74756D2C2064756920766974616520616C697175616D20706F73756572652C206469616D207175616D20636F6E76616C6C69732076656C69742C2075742067726176696461206C656F20697073756D206E6F6E2072697375732E205574206665726D656E74756D20736F6C6C696369747564696E20657261742E20446F6E6563207361676974746973207363656C657269737175652066656C69732E204E756E6320617263752E20457469616D2074656D7075732C206D61676E612073697420616D657420737573636970697420657569736D6F642C2065726F732073656D2072757472756D206475692C207669746165207361676974746973206E696268207075727573206E6F6E206C616375732E20536564206D6F6C6C69732061726375206567657420646F6C6F722E20446F6E6563206F726E6172652C20617263752073697420616D6574206665726D656E74756D2076756C7075746174652C20726973757320656E696D206665726D656E74756D206C696265726F2C2061206C6163696E696120646F6C6F72206D69206E6F6E2076656C69742E20457469616D206C6F626F72746973207075727573206120656C69742E204E756E63206E756C6C61206475692C206D617474697320717569732C20626962656E64756D20612C20756C7472696365732061632C2061756775652E20496E20616C697175616D207665686963756C61207475727069732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A496E7465676572206964206E69736C2E20517569737175652064696374756D20656C656D656E74756D206F64696F2E2041656E65616E206C75637475732E205365642065752073656D206120706564652076756C70757461746520636F6E64696D656E74756D2E2051756973717565206D61676E612E20446F6E656320616C697175616D206D617474697320697073756D2E204375726162697475722064696374756D20736F6C6C696369747564696E2073656D2E20416C697175616D2070756C76696E61722E204E756E6320736F6C6C696369747564696E207269737573206120657261742E20566976616D757320717569732074656C6C75732073697420616D6574206E69626820766573746962756C756D20636F6E7365717561742E204E756C6C61207072657469756D20736F6C6C696369747564696E20646F6C6F722E20416C697175616D20696163756C69732074696E636964756E74207475727069732E2050686173656C6C757320697073756D206C656F2C2076656E656E6174697320696E2C20736167697474697320696E2C206F726E6172652061742C206E756E632E0A0A50656C6C656E74657371756520756C7472696365732C2064756920657520696163756C6973206C75637475732C2074656C6C757320617567756520766F6C75747061742073617069656E2C20696E206469676E697373696D2075726E612066656C6973207574206D692E205365642061726375206475692C206469676E697373696D2069642C20706F72747469746F722075742C20696D706572646965742076697461652C20616E74652E204E756C6C61206475692073656D2C20636F6D6D6F646F206E65632C2073616769747469732065742C206C6163696E69612065742C20706564652E20457469616D20656C656966656E6420647569207574206E69736C2E20446F6E656320616E7465206D61757269732C2074656D7075732073697420616D65742C207661726975732076697461652C206772617669646120717569732C206D692E20496E207363656C657269737175652C2066656C697320766974616520766976657272612073616769747469732C2076656C6974206D6574757320756C74726963696573206E657175652C207175697320696D706572646965742076656C697420656C6974206574206D61676E612E2053757370656E646973736520706F74656E74692E205365642076656C69742065726F732C20657569736D6F64207365642C20636F6E64696D656E74756D206E65632C206661756369627573207365642C2073617069656E2E204E616D20616363756D73616E206C6967756C612073697420616D6574206E657175652E20416C697175616D206572617420766F6C75747061742E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E616D20657520706564652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642065752066656C69732073656420746F72746F722074656D706F72206665726D656E74756D2E2050686173656C6C757320636F6D6D6F646F2073656D2076656C206E69736C2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050726F696E206C656374757320656C69742C2070686172657472612073697420616D65742C20616363756D73616E207365642C2074696E636964756E742065742C206D61757269732E204475697320646170696275732070686172657472612073656D2E20496E746567657220696E206A7573746F2E205072616573656E742065726F732E20566573746962756C756D20616320616E74652E20416C697175616D207363656C657269737175652073656D2070656C6C656E746573717565206E69626820636F6E73656374657475657220736F64616C65732E20416C697175616D20636F6E736563746574756572206F64696F2E2044756973206C6563747573206F64696F2C206C75637475732065752C20636F6D6D6F646F20717569732C206D6F6C6C69732076697461652C2076656C69742E2043726173206E6563206E756E63206E6F6E20656C697420696163756C6973206D61747469732E2041656E65616E206A7573746F206E657175652C20736F6C6C696369747564696E20656765742C20756C6C616D636F7270657220656765742C20656765737461732069642C2073656D2E20496E2065752072697375732E2053656420656765737461732E0A0A496E7465676572206174206E657175652E20536564207072657469756D207363656C65726973717565206E756C6C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20467573636520757420706564652E20457469616D207669746165207175616D20612075726E612076617269757320696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2044756973207665686963756C612E20467573636520756C6C616D636F72706572206E696268206E6F6E20657261742E205175697371756520696E206E657175652E205072616573656E74206573742E2050656C6C656E74657371756520617263752E0A0A50726F696E20706F73756572652E2053757370656E646973736520706F74656E74692E20496E74656765722066656C6973206C616375732C20616C697175616D207365642C2076756C70757461746520696E2C206D6F6C6C69732076656C2C2074656C6C75732E20496E7465676572207665686963756C6120626962656E64756D206573742E204E756E63206E6F6E20646F6C6F7220696E2074656C6C7573206D617474697320666163696C697369732E20496E746567657220766573746962756C756D2C20617567756520617420636F6D6D6F646F20616C697175616D2C2064756920657374206D6174746973206C6967756C612C2073697420616D65742061646970697363696E67206F7263692073656D207669746165206D61676E612E205072616573656E7420656E696D2076656C69742C206D616C6573756164612061742C20636F6E677565206E65632C206C756374757320696E2C206A7573746F2E20536564207661726975732E204D6F7262692070686172657472612E20446F6E6563206575206D61737361206E65632074656C6C75732076756C7075746174652070756C76696E61722E20557420636F6D6D6F646F20747572706973206E6F6E2073656D2E20557420636F6E76616C6C697320756C6C616D636F727065722072697375732E20457469616D20696E74657264756D2070656465206964206E6973692E2043726173206D61676E612073617069656E2C20737573636970697420612C206C616F72656574206E6F6E2C2072686F6E6375732065742C2066656C69732E20496E7465676572206F726369206C6F72656D2C20766573746962756C756D2064696374756D2C20756C6C616D636F7270657220612C20706F72747469746F722065742C206475692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A4E756E63206574206D61676E612E2053656420626962656E64756D2074656C6C757320696E206469616D2E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E616D20766974616520746F72746F722E20496E7465676572206D61676E612E20447569732076656E656E617469732C206C656F2061632074656D706F72206C616F726565742C20656C6974206E756C6C6120706861726574726120706564652C206E6F6E206665726D656E74756D206E756E63206F64696F2061206F64696F2E2050726F696E206E6F6E2076656C69742E2053656420696D706572646965742061756775652071756973206E69736C2E20496E746567657220636F6E64696D656E74756D206E69736C206E6563206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20566976616D757320706C616365726174206C696265726F2E204475697320636F6E6775652064696374756D206D61676E612E20416C697175616D206461706962757320626962656E64756D20656E696D2E204E756E6320656C656966656E6420706564652076656C20697073756D2E0A0A457469616D2076697461652076656C69742E204D61757269732065726174206E756E632C206D616C6573756164612075742C20666575676961742061632C20706C61636572617420636F6E64696D656E74756D2C2061756775652E204E616D20766F6C75747061742E20416C697175616D207665686963756C6120697073756D206964206F64696F2E20566976616D757320736F6C6C696369747564696E207475727069732069642073617069656E2E20467573636520612066656C6973207669746165206F64696F20636F6E76616C6C697320626C616E6469742E204375726162697475722076697461652065726F732069642065726F7320706F727461207072657469756D2E204E756C6C6120696E206D61676E6120656765742075726E61206C6163696E696120636F6E76616C6C69732E20416C697175616D206D61747469732076656E656E617469732070757275732E2053656420736564206D69206567657420657261742074726973746971756520706F7274612E20446F6E656320617563746F7220646F6C6F72206120657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20496E206E6563206C6967756C612E204E756E6320656C656966656E642E20566573746962756C756D2071756973206E697369206567657420656C697420706F72747469746F7220636F6E6775652E204D616563656E61732066617563696275732C206D61676E6120656765742061646970697363696E672074696E636964756E742C20646F6C6F7220616E7465206D616C65737561646120656C69742C206E6F6E20656C656D656E74756D206C616375732074757270697320696E20706564652E0A0A5574206D616C657375616461206D69206E6563206D657475732E205072616573656E7420617563746F72206175677565206163206E69736C20756C7472696369657320666163696C697369732E204E616D2070757275732073617069656E2C2070656C6C656E746573717565206469676E697373696D2C20706F73756572652065752C206375727375732069642C206469616D2E205175697371756520736F6C6C696369747564696E2C20656C697420612070656C6C656E746573717565207363656C657269737175652C206C6F72656D20726973757320617563746F72207175616D2C207175697320636F6E7365717561742074656C6C7573206E657175652069642075726E612E2053757370656E6469737365206469616D20746F72746F722C20656C656966656E64206469676E697373696D2C20656765737461732075742C206C756374757320696E2C20616E74652E204475697320616E74652E204D616563656E6173206C75637475732E20437572616269747572206375727375732070686172657472612075726E612E204D616563656E617320696D706572646965742C2065726174206E6F6E20656C656D656E74756D20657569736D6F642C20746F72746F72206F64696F20657569736D6F64206C65637475732C20616320666163696C697369732073656D206E696268207669746165206E756C6C612E204E756E6320677261766964612E204D6F72626920736F6C6C696369747564696E206F64696F2071756973206C616375732E20416C697175616D2061206E696268206E6F6E2075726E6120706F72746120696D706572646965742E20416C697175616D206572617420766F6C75747061742E20496E20696163756C6973206C6163696E69612076656C69742E20536564206C696265726F206C616375732C207472697374697175652065752C206C6163696E69612061632C20616C697175657420656765742C2075726E612E0A0A457469616D206174206E69736C2E2050686173656C6C7573206661756369627573206C7563747573206C65637475732E20557420706C6163657261742076756C70757461746520646F6C6F722E2050686173656C6C75732076656C2076656C69742E204D6F72626920766976657272612E2050686173656C6C7573206F7263692E20496E7465676572206469676E697373696D206D6174746973206D61757269732E2050656C6C656E74657371756520706F7375657265206C656F20706F7375657265207175616D2E2051756973717565206E6563206D61676E61206174206469616D20766976657272612070656C6C656E7465737175652E2053757370656E64697373652076656C697420617263752C20756C7472696369657320717569732C20636F6E67756520612C2076656E656E6174697320656765742C206C616375732E20496E74656765722073616769747469732068656E64726572697420646F6C6F722E2046757363652074696E636964756E7420616E746520612073656D2E0A0A4D616563656E617320636F6E7365637465747565722C206A7573746F207365642072686F6E6375732076656E656E617469732C206E69626820617263752072757472756D20646F6C6F722C2073656420636F6E64696D656E74756D206C696265726F206C696265726F20657420697073756D2E20566976616D7573206D6174746973206A7573746F207574206C6F72656D2074696E636964756E74206C6F626F727469732E205574206E6F6E2076656C6974206964206E6571756520616C697175657420616363756D73616E2E205365642074656D7075732076697665727261206E756C6C612E2043757261626974757220756C6C616D636F727065722C206E6571756520717569732064617069627573207363656C657269737175652C2066656C6973206469616D2067726176696461206F7263692C206E6F6E20637572737573207175616D206E6571756520766974616520656C69742E20457469616D2070686172657472612074696E636964756E74206C616375732E204475697320657569736D6F64206672696E67696C6C61206573742E20457469616D206F726E6172652074696E636964756E74206C65637475732E2050726F696E20696E207475727069732E204E756E6320626C616E64697420626C616E646974207475727069732E2041656E65616E2075742061756775652E2044756973206F726369206A7573746F2C2074696E636964756E742065752C2072757472756D207365642C2072757472756D2065742C207475727069732E2043757261626974757220666163696C69736973206F64696F20696E20616E74652E20496E206861632068616269746173736520706C617465612064696374756D73742E205365642065726F73206573742C2070656C6C656E7465737175652061742C2074696E636964756E742065752C20756C74726963657320717569732C206D657475732E204D6F7262692073697420616D6574206A7573746F2E204D616563656E617320616320617263752E204D6175726973206469676E697373696D2E0A0A50656C6C656E74657371756520756C747269636965732072757472756D206F7263692E2041656E65616E206F726E6172652E20566976616D75732065752072697375732076656C206D6175726973206C6F626F727469732064696374756D2E205365642065742074757270697320617563746F72206D692072686F6E6375732070756C76696E61722E20536564206E6563206E756E6320612070757275732074656D706F7220766976657272612E2050656C6C656E7465737175652073757363697069742E20446F6E656320747269737469717565207269737573206E6F6E206E6962682E20457469616D206E69736C206D61676E612C20736F6C6C696369747564696E2075742C20756C7472696365732073697420616D65742C20656765737461732065752C206E756C6C612E20416C697175616D206572617420766F6C75747061742E20566573746962756C756D2070686172657472612E2053656420656765737461732C206D657475732073697420616D6574206C6F626F7274697320636F6E7365717561742C206572617420656C697420696D70657264696574206C696265726F2C20657520696E74657264756D207175616D206D61737361206567657420646F6C6F722E2053757370656E6469737365207669746165206F64696F2E2050726F696E20626C616E646974206D617572697320696163756C6973206D657475732E0A0A566976616D757320766573746962756C756D2E20457469616D206574206E69736C2E20416C697175616D20696E206469616D2076656C20656C697420706C6163657261742073757363697069742E204475697320736F64616C6573207075727573206163206E6962682E204E756C6C6120696E206F64696F206567657420656E696D206C756374757320626C616E6469742E2043757261626974757220756C74726963657320697073756D206E6F6E206E65717565206567657374617320656C656966656E642E20536564207475727069732E2050726F696E20636F6E7365637465747565722E20566976616D7573206D61747469732E20496E20616C69717565742E0A0A4E756E632069642065726F732E20446F6E65632076656E656E617469732C206E756C6C61206574206D6174746973206C75637475732C20616E7465206C656F2073656D706572206A7573746F2C206E6F6E2061646970697363696E67206F64696F20726973757320736564206C616375732E205072616573656E7420766974616520726973757320636F6E677565206C696265726F20636F6E6775652074656D7075732E2050686173656C6C75732061632065726F732E204E756C6C61207665686963756C612C206C6F72656D20696E20616C69717565742073757363697069742C2061726375206572617420656765737461732073656D2C2071756973206C6F626F72746973207175616D20616E7465206575206D617373612E20437572616269747572206E6F6E206D617373612E2053656420626962656E64756D206C6163696E6961206F64696F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20566976616D757320766F6C757470617420626C616E646974206C616375732E2050726F696E20706F7274612C2074656C6C757320757420617563746F72206C616F726565742C206C65637475732065726F73206665726D656E74756D206C65637475732C2069642073616769747469732061726375206A7573746F20696E207475727069732E2050686173656C6C757320636F6E7365717561742E204E616D2070656C6C656E7465737175652C206D69206964207669766572726120636F6E76616C6C69732C206E756E63206C696265726F20706C616365726174206C656F2C20656C656966656E6420706F7274612073656D206E69736C2076697461652073617069656E2E2050656C6C656E746573717565206C6967756C61206C696265726F2C20747269737469717565206E6F6E2C20706F72747469746F722072757472756D2C20706F72747469746F72206E6F6E2C20657261742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E74656765722064696374756D2074656C6C7573206120746F72746F722E20566976616D75732066656C6973206E756E632C206D6F6C6573746965206E6F6E2C2072686F6E63757320717569732C2070686172657472612069642C206475692E20446F6E6563207269737573206D657475732C206672696E67696C6C612076656C2C20616C69717565742065752C20706C6163657261742069642C206E657175652E0A0A53757370656E646973736520697073756D2E20566976616D7573206C65637475732E2053656420766976657272612C206D61737361206567657420636F6E76616C6C6973206D61747469732C207175616D2074757270697320636F6E736563746574756572206E756E632C206567657420706F7375657265206D61676E612073656D2069642076656C69742E20496E206E6563206D61757269732E2041656E65616E206120707572757320736564207175616D206C6F626F72746973206672696E67696C6C612E2050726F696E20756C74726963696573206C6163696E696120616E74652E205365642061646970697363696E67206572617420717569732076656C69742E204E756C6C616D207669746165206E69736C206964206A7573746F20736F6C6C696369747564696E206D6F6C65737469652E204E756C6C6120666163696C6973692E20536564206E65632075726E6120736564206E69736C206672696E67696C6C6120646170696275732E204E756C6C61206174206469616D2E20416C697175616D2065676574206E6962682E204E756E63206163206E6973692073697420616D65742074656C6C757320656765737461732074656D7075732E204E616D207363656C657269737175652075726E61206574206E657175652E20446F6E656320657374206F7263692C207361676974746973206E6F6E2C2076756C70757461746520612C20636F6D6D6F646F2065742C2061756775652E205574206461706962757320746F72746F722E205574206E756E632E20446F6E65632064696374756D2064617069627573206F64696F2E204E616D20756C7472696369657320756C6C616D636F72706572206C6967756C612E2050656C6C656E74657371756520616363756D73616E20766172697573206C656F2E0A0A4D6F72626920657569736D6F64206C616F7265657420657261742E20566976616D7573207175697320697073756D2E204D6F72626920657569736D6F642E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2053757370656E64697373652076656C2070757275732E204E756C6C616D206174206D61676E612E20437572616269747572206C61637573206C6F72656D2C20696163756C697320717569732C2064617069627573206E6F6E2C20766F6C75747061742076656C2C206E756C6C612E20446F6E656320757420617263752072686F6E63757320646F6C6F72207072657469756D2064696374756D2E204E756C6C616D2076656C206D657475732E20557420617263752E2050656C6C656E746573717565206E697369206E756E632C20706C61636572617420656765742C2074696E636964756E742076656C2C207068617265747261206E6F6E2C206E756E632E20496E74656765722074696E636964756E7420756C74726963696573206C65637475732E20496E74656765722073656D7065722C2070757275732073656420756C74726963657320666575676961742C206E756C6C61207065646520736F6C6C696369747564696E20657261742C2076656C20617563746F72206E756C6C6120697073756D2076656C206C65637475732E2041656E65616E206D692E0A0A4E756C6C616D20736564206E697369206574206172637520696D70657264696574206665726D656E74756D2E204D6175726973206E6563206D657475732E20496E20616320646F6C6F722E20496E206D6920617263752C20636F6E6775652061632C207068617265747261206E65632C207363656C657269737175652073697420616D65742C206D61676E612E20437572616269747572206C616375732E2043757261626974757220657420656C69742E20416C697175616D20756C6C616D636F72706572206E756E6320657520656C69742E2053656420636F6E76616C6C697320646F6C6F722061742076656C69742E20566573746962756C756D20646170696275732C20617567756520696420636F6E73656374657475657220706C6163657261742C206E756E63206D6173736120626C616E6469742073617069656E2C20696420616C697175616D20656C6974206E697369206964206D692E2050686173656C6C75732073617069656E206573742C20677261766964612065752C20626962656E64756D2075742C2061646970697363696E6720717569732C206573742E205574206D6F6C6573746965207175616D207669746165206F64696F2E20446F6E65632071756973207269737573206964206572617420666175636962757320736F6C6C696369747564696E2E204E616D2069642066656C69732E204D61757269732073656420656E696D207669746165206C656F20616363756D73616E207072657469756D2E0A0A4E616D206A7573746F2E20446F6E656320747572706973206E69736C2C20636F6D6D6F646F2065742C20696E74657264756D2061632C20636F6E736563746574756572206E6F6E2C206D617373612E2046757363652073656D206D657475732C206C616F72656574206E65632C20706F73756572652069642C20696D7065726469657420696E2C2076656C69742E20446F6E65632076756C707574617465206A7573746F2065676574207475727069732E204E756C6C6120706564652E204D6F7262692074696E636964756E742E20467573636520616C69717565742C207175616D20657420616C697175616D206672696E67696C6C612C20616E746520616E746520696163756C6973206475692C206E656320616C697175616D20617263752070757275732073656420657261742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050686173656C6C7573207375736369706974207175616D206574206573742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B0A0A496E7465676572207365642074656C6C75732E20536564207365642076656C697420756C74726963696573206C656F2072757472756D206C616F726565742E20536564206E6F6E2065726F7320616320707572757320736167697474697320666575676961742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E205365642068656E647265726974206C6967756C612073697420616D6574206E6962682E204D616563656E6173207475727069732E204D6F72626920636F6E7365637465747565722C20646F6C6F722065742061646970697363696E6720696D706572646965742C20616E7465206E65717565206665756769617420646F6C6F722C20617420706F727461207175616D206E657175652071756973206C6967756C612E204D61757269732073656D7065722076656C69742073697420616D657420697073756D2E2050656C6C656E7465737175652074656D7075732C20707572757320696E2072757472756D20636F6E7365717561742C20656E696D2065726174207665686963756C61206D617373612C20696420616363756D73616E206C656F2073617069656E206E65632070757275732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E20646F6C6F722E20496E746567657220666163696C69736973206C696265726F2073697420616D657420706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2055742076617269757320616C697175657420656E696D2E204E756C6C6120666163696C6973692E2043757261626974757220636F6E7365637465747565722C206F64696F206575207072657469756D2074696E636964756E742C206E756E63206E69736920616C6971756574206E657175652C2076656C20696D7065726469657420656C6974206D617373612073697420616D6574207475727069732E2050656C6C656E7465737175652074656D7075732C206F72636920766F6C757470617420626C616E646974206672696E67696C6C612C206F64696F2073656D20706F737565726520616E74652C20766974616520626962656E64756D2075726E61206C6F72656D2076697461652065726F732E205072616573656E7420766976657272612072686F6E63757320617263752E2053656420617563746F722C206573742073697420616D6574206D6F6C6C6973206D6F6C6C69732C207175616D207175616D20677261766964612073617069656E2C20696E20636F6D6D6F646F206D65747573206E756C6C6120617563746F7220656E696D2E20446F6E656320666163696C697369732E0A0A50726F696E2074696E636964756E742C2073617069656E206567657420756C747269636965732061646970697363696E672C20657374206F64696F2064696374756D20617263752C207574206D6F6C6C69732065726174206475692073697420616D65742076656C69742E204D6F726269206573742073656D2C20696E74657264756D2061742C20636F6E67756520612C20656C656D656E74756D2076697461652C206D657475732E2053757370656E64697373652069642061756775652E204D617572697320656E696D2073656D2C2070756C76696E617220656765742C2074656D70757320612C2074656D7075732073697420616D65742C2073617069656E2E20467573636520766573746962756C756D20636F6E736563746574756572206475692E2050656C6C656E74657371756520657261742E20536564206469676E697373696D20706C616365726174206F64696F2E204D616563656E61732073656D7065722072686F6E637573206C65637475732E2050686173656C6C7573207072657469756D2E2044756973206C696265726F20656C69742C20656C656966656E64206E65632C20656765737461732075742C20637572737573207365642C2066656C69732E204E616D206E69736C20617263752C20616C69717565742065742C20666163696C697369732065752C206C75637475732075742C2072697375732E20457469616D20756C7472696365732C20646F6C6F722073656420766F6C7574706174206D616C6573756164612C20747572706973206172637520696D7065726469657420746F72746F722C20657569736D6F6420636F6D6D6F646F206C696265726F206D61737361207574207175616D2E20496E7465676572206D6F6C6573746965207075727573206E6F6E20656C69742E2055742076656E656E617469732073656D70657220746F72746F722E20457469616D20626962656E64756D206567657374617320697073756D2E204D617572697320736F6C6C696369747564696E2073656D206E6563206E6962682E204E756C6C61207072657469756D206D65747573206575206D657475732E2050656C6C656E7465737175652073697420616D65742073656D2E0A0A53757370656E6469737365206163206E6973692E205574206C656F2E20566573746962756C756D2068656E647265726974207072657469756D20646F6C6F722E204E756E632066657567696174206D616C6573756164612070757275732E2043726173206574206E6962682E20437572616269747572206E756E6320657261742C206D616C6573756164612076697461652C206C616F726565742061632C20756C7472696369657320696E2C2070757275732E20566976616D75732074656C6C757320617263752C20736F64616C65732065752C20666163696C6973697320612C206C6163696E6961206E65632C206E756E632E2050656C6C656E7465737175652069642076656C69742E20496E206575206E6962682E204E756E63206E656320657261742E205365642064696374756D206E65717565207574206E69736C2E0A0A4D6F726269206C65637475732074656C6C75732C2074696E636964756E742061632C20706F72747469746F722061632C2074726973746971756520696E2C2065726F732E20446F6E6563206C7563747573206C7563747573206C656F2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2046757363652075742065737420657420656E696D207363656C6572697371756520616363756D73616E2E20446F6E6563206C6967756C612066656C69732C206C6163696E696120717569732C2070656C6C656E74657371756520696E2C2073656D70657220766573746962756C756D2C20656C69742E204D61757269732065676574206F72636920612066656C697320636F6E677565207665686963756C612E20557420736F6C6C696369747564696E2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204E756C6C616D20696420646F6C6F72207574206C6F72656D206469676E697373696D2076656E656E617469732E2053757370656E64697373652076697461652073617069656E2E2050726F696E206E6F6E206D61676E612075742065726F7320766976657272612070756C76696E61722E20446F6E65632071756973206F64696F2E204E756C6C616D206E6F6E20617263752076656C206C6F72656D20737573636970697420616C697175616D2E20416C697175616D2072757472756D2074757270697320696E206C656F2E0A0A5574206C7563747573206E6962682074726973746971756520657261742E2053757370656E646973736520626962656E64756D206F64696F20766974616520746F72746F722E20446F6E6563206C6163696E69612E204372617320736F64616C65732066656C6973206C7563747573206E756C6C612E204E616D20656C656966656E64207361676974746973206C6967756C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E64697373652076656C206E657175652E204D6F72626920616C6971756574207665686963756C61206D61676E612E2041656E65616E206174206F64696F2E20447569732070656C6C656E746573717565206D61676E612E204E756C6C6120617420746F72746F72207574206469616D2064696374756D2066617563696275732E204D617572697320717569732076656C69742E20446F6E6563206E6F6E2074656C6C7573207669746165206C6F72656D206672696E67696C6C6120706F72747469746F722E2046757363652075742073617069656E207175697320746F72746F7220666575676961742073616769747469732E20446F6E656320766976657272612073656D2076697461652073617069656E2E205072616573656E7420736F64616C65732C206C6163757320696E206672696E67696C6C6120766976657272612C206F64696F2061756775652061646970697363696E672075726E612C20766974616520696E74657264756D20616E74652073656D206E6F6E206E6973692E204E756C6C616D20746F72746F72206C6F72656D2C20656C656966656E642061632C206D6F6C6C6973206E6F6E2C206C616F726565742061632C2072697375732E20496E7465676572206F726E617265206C656F20736564206A7573746F2E2051756973717565206375727375732C2073656D206E6F6E20666163696C6973697320626962656E64756D2C206E697369206D69207661726975732066656C69732C206665726D656E74756D2066657567696174206C6F72656D2065726F73206C616F726565742072697375732E0A0A517569737175652073697420616D657420657374206574206C6F72656D207665686963756C61206C6163696E69612E20446F6E6563206E656320746F72746F722E2043726173206F64696F2E204E616D207363656C657269737175652076756C7075746174652075726E612E205072616573656E74206475692E20457469616D206E6563206E69736C206C6F626F7274697320697073756D20616C69717565742074656D7075732E204D616563656E6173207072657469756D20736F6C6C696369747564696E206D61757269732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206175677565206D617373612C20636F6E67756520656765742C20636F6E76616C6C697320656765742C207472697374697175652073697420616D65742C2065726F732E2053656420636F6E736571756174206E6973692065752066656C69732E2050656C6C656E746573717565206A7573746F2E2053757370656E6469737365206E6F6E2061756775652E20496E206469676E697373696D206C6F626F72746973206D61757269732E204D61757269732073616769747469732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E0A0A5365642061646970697363696E672E20446F6E656320612074656C6C75732076697461652065737420637572737573207665686963756C612E204E616D20616E74652073656D2C20736F64616C65732069642C206672696E67696C6C612076656C2C20636F6E64696D656E74756D2076656C2C206E756C6C612E205175697371756520736F64616C65732E20457469616D20696D7065726469657420656C6974206964206F64696F2E20416C697175616D206572617420766F6C75747061742E204D616563656E617320706F7274612074656D706F7220617263752E204E756C6C612073656D2061756775652C2070656C6C656E7465737175652061632C20636F6E7365717561742075742C20636F6E64696D656E74756D20657569736D6F642C2072697375732E2053656420616C697175616D2074696E636964756E74206D692E20496E20696E74657264756D206C6F626F72746973206F7263692E0A0A536564207665686963756C612068656E6472657269742070757275732E20457469616D2061206469616D2E2043757261626974757220636F6E76616C6C69732E2053757370656E64697373652061206E6973692E20446F6E6563206964206D61676E6120696E207175616D20736F6C6C696369747564696E20756C747269636965732E20446F6E656320766976657272612E205175697371756520766F6C757470617420657374207365642073656D2E20416C697175616D206A7573746F2E20566573746962756C756D20746F72746F72206D617373612C20706F72747469746F72207365642C2076617269757320717569732C20696163756C697320717569732C206F64696F2E20416C697175616D2065676574206E657175652E0A0A4D6175726973206E756C6C612E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566573746962756C756D206575207175616D20696E206E6571756520756C7472696365732070656C6C656E7465737175652E204372617320696E20646F6C6F722071756973207175616D207661726975732068656E6472657269742E20416C697175616D206E697369206C616375732C206C6F626F727469732065752C20636F6E76616C6C69732073697420616D65742C20666163696C697369732075742C206D692E20416C697175616D206174206E657175652E204372617320736167697474697320656C656D656E74756D206A7573746F2E20566573746962756C756D207574206C656374757320616C6971756574207075727573206D616C65737561646120766F6C75747061742E2044756973206174206C616375732061646970697363696E67206C696265726F2074696E636964756E7420766573746962756C756D2E204D6F7262692061206C696265726F2E20437261732070757275732E204D6F72626920757420617567756520657420707572757320696E74657264756D207363656C657269737175652E20496E74656765722061206475692E20496E206861632068616269746173736520706C617465612064696374756D73742E2044756973207068617265747261206D657475732065676574206D61757269732E20416C697175616D20696E74657264756D20756C6C616D636F72706572206D617373612E0A0A457469616D206F726E6172652E204E756C6C616D20657569736D6F642E2041656E65616E20636F6E7365717561742067726176696461206C6967756C612E20416C697175616D206573742E2050726F696E207669746165206C616375732E205072616573656E7420612065726F732073697420616D657420647569206C756374757320636F6D6D6F646F2E2050686173656C6C7573207665686963756C612061726375206567657420646F6C6F722E205072616573656E74206665726D656E74756D20636F6E677565206C656F2E20416C697175616D20766F6C7574706174207075727573207574206C6F72656D2E2046757363652068656E64726572697420656E696D206174206C656F2E20416C697175616D2072686F6E637573206E69736C2E20566976616D75732064696374756D2065676573746173206D692E2053757370656E64697373652070656C6C656E74657371756520626962656E64756D20646F6C6F722E2050656C6C656E7465737175652074696E636964756E742C207475727069732073656D7065722070656C6C656E74657371756520636F6E64696D656E74756D2C20697073756D206D6574757320736F64616C6573206C6967756C612C20696420766F6C7574706174206469616D2074757270697320757420656C69742E0A0A5072616573656E7420736564206C616375732E204E616D20656C656966656E64206D6F6C6573746965206D61757269732E20446F6E65632064617069627573206665726D656E74756D206D617373612E20446F6E656320766976657272612066617563696275732070757275732E2043757261626974757220636F6E6775652C206C696265726F20766974616520766976657272612070656C6C656E7465737175652C206469616D2076656C697420736F64616C657320656E696D2C20736564207375736369706974206C6563747573206E697369206E6563206E657175652E20566573746962756C756D206D616C6573756164612C206C616375732061742063757273757320636F6E6775652C2076656C6974206C65637475732074726973746971756520646F6C6F722C2073697420616D657420736F64616C6573206E6571756520697073756D2061206C696265726F2E20566573746962756C756D206574207175616D2E2043757261626974757220706C6163657261742E20437572616269747572206E756E6320617263752C20657569736D6F64206E65632C2076756C7075746174652068656E6472657269742C20616C697175657420656765742C207175616D2E204375726162697475722076656C20656E696D2E2053757370656E646973736520706F74656E74692E0A0A4E756E6320636F6E736571756174206F726369207574206C616375732E2046757363652076656C697420646F6C6F722C2064617069627573207365642C20626C616E6469742073697420616D65742C2072686F6E6375732069642C2072697375732E20447569732075726E61206E6962682C207363656C6572697371756520717569732C206461706962757320612C207363656C65726973717565207365642C206E6962682E20446F6E6563206C75637475732E205574206575206D617572697320637572737573206469616D206C6163696E69612072686F6E6375732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20416C697175616D207665686963756C61206D6F6C6573746965206A7573746F2E204D616563656E617320696D70657264696574207065646520736564206D692E2053757370656E6469737365206E756C6C6120646F6C6F722C2068656E64726572697420656765742C2068656E6472657269742069642C2064696374756D2076656C2C206C656F2E204475697320616363756D73616E2E2043757261626974757220696E2066656C69732E204E756E63206C6F72656D2E205574206C656F20646F6C6F722C206C616F72656574206E65632C2076756C7075746174652061742C20656C656966656E6420696E2C206E756C6C612E2051756973717565206E756E632070757275732C2076617269757320656765742C20616363756D73616E206E65632C20616C69717565742065742C206E6962682E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20437261732061646970697363696E67207669766572726120646F6C6F722E204D617572697320706F72747469746F7220756C7472696365732070757275732E204E756C6C6120666163696C6973692E205072616573656E7420666175636962757320616E7465207669746165206D61757269732E0A0A5072616573656E74206C6163696E6961206C656374757320736564206E69736C2E20496E2074656D70757320636F6E677565206D61757269732E20496E746567657220666163696C69736973206F726E61726520656E696D2E204E756C6C61206964206D617373612E20446F6E656320636F6D6D6F646F206469616D2061742074656C6C75732E204E616D20646170696275732076697665727261206573742E204E616D2074656C6C75732E205072616573656E742061206C696265726F2E20496E206661756369627573206573742065676574206E6962682E204E756C6C612065726F73206F7263692C20696D70657264696574206E6F6E2C20626C616E646974206E6F6E2C2074656D706F7220656765742C206D692E2050656C6C656E74657371756520636F6E76616C6C69732E0A0A517569737175652065676574206D69206163206C656F20657569736D6F642066617563696275732E2050686173656C6C75732072686F6E637573207075727573206964206475692E20566573746962756C756D206D616C65737561646120656C656966656E6420616E74652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050656C6C656E74657371756520626C616E646974206D6174746973206F64696F2E2053757370656E646973736520636F6E7365717561742C206C65637475732061632073656D70657220736F6C6C696369747564696E2C206D692076656C69742064696374756D2061756775652C2061632074656D70757320646F6C6F7220657261742073697420616D6574206475692E2050726F696E2068656E6472657269742C2066656C6973207175697320766F6C757470617420706F73756572652C206469616D206F64696F206D616C657375616461206F64696F2C206120696E74657264756D206F726369206469616D20717569732073617069656E2E2050656C6C656E746573717565206F64696F206F64696F2C20766976657272612076656C2C20677261766964612065752C206D6F6C6573746965207365642C206E756C6C612E2050686173656C6C7573206D617572697320706564652C20636F6D6D6F646F2075742C20657569736D6F642065752C2068656E6472657269742065752C206573742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C6120656C656D656E74756D206C616375732065752061756775652E2053656420657261742E2050726F696E20706F7274612E204D616563656E61732071756973206D692E2050686173656C6C757320617420656E696D206163206A7573746F206772617669646120756C7472696365732E2043726173206C656F2E0A0A496E746567657220757420617263752E20446F6E656320736564206D61676E612E2050726F696E2066656C69732E20496E20696163756C69732C206C6967756C61206964206672696E67696C6C61207072657469756D2C206E696268206469616D20616363756D73616E2074656C6C75732C206567657420616363756D73616E206D657475732064756920766172697573207475727069732E2050686173656C6C7573206F726369206D657475732C20656C656966656E64207365642C2074656D706F722061632C207363656C657269737175652061632C2075726E612E20496E74656765722076697665727261206E657175652061206D61757269732E204D617572697320706F72747469746F7220646F6C6F722065752076656C69742E20496E7465676572206F64696F20656C69742C20766573746962756C756D2075742C20766F6C75747061742069642C2072686F6E63757320636F6D6D6F646F2C2075726E612E20457469616D20706C61636572617420706861726574726120657261742E2055742074656D706F72206573742E20496E7465676572206469676E697373696D20626C616E6469742074656C6C75732E204D6F726269206E69626820646F6C6F722C207363656C657269737175652069642C20636F6D6D6F646F206D616C6573756164612C206D61747469732061742C206D692E20437261732074696E636964756E7420636F6D6D6F646F2070757275732E20496E2074696E636964756E742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D20756C6C616D636F727065722E2055742068656E6472657269742E204D6F72626920756C7472696365732E0A0A5072616573656E7420696163756C69732C2065726F73206163206567657374617320736F64616C65732C2075726E61206C656F206665726D656E74756D206C6967756C612C2073697420616D657420616C697175616D2076656C69742073656D206E6F6E2070757275732E20446F6E65632072757472756D206172637520717569732070757275732E204E616D20706F73756572652C206C6163757320617420636F6E73657175617420706C6163657261742C206E756C6C61207065646520706F7375657265206F7263692C206E6F6E20657569736D6F6420747572706973206475692071756973206E69736C2E2050726F696E20706F7274612061646970697363696E67206E6962682E20446F6E65632074726973746971756520646F6C6F722061742074656C6C75732E20446F6E6563206E65717565206D617373612C20617563746F722069642C2066617563696275732076697461652C20756C6C616D636F727065722076656C2C206E6973692E2050726F696E206D6F6C6573746965206E6571756520736564206D617373612E204E616D2074656D706F722E204D6F72626920616C697175616D2073617069656E2061742074656C6C75732E2046757363652071756973207269737573206574206D69207072657469756D2070756C76696E61722E2046757363652073697420616D6574206C6967756C612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E646973736520657520656E696D2065742066656C6973207363656C65726973717565206C6F626F727469732E205072616573656E7420626962656E64756D2E20566976616D7573207665686963756C612E20496E7465676572206174206E696268207365642076656C69742072686F6E637573206D6F6C65737469652E2043726173206C616375732E2053656420756C6C616D636F727065722065726F732076656C20657261742E20467573636520657520746F72746F722073697420616D6574206469616D20657569736D6F642073616769747469732E204E756E632071756973206C61637573206964206E69626820636F6E76616C6C6973207661726975732E2053757370656E6469737365207669746165206D692E20566573746962756C756D207472697374697175652E20446F6E6563206D616C65737561646120697073756D206964206E657175652E204E756C6C616D20736564206C616375732E204475697320656765737461732C206A7573746F20757420636F6E677565206F726E6172652C2061756775652073617069656E206C7563747573206469616D2C20617420616363756D73616E20657261742073617069656E207574206C696265726F2E2050686173656C6C75732076656C206E756C6C612E2053757370656E646973736520617263752074656C6C75732C20706F72747469746F7220612C2070686172657472612066617563696275732C20616C697175616D2073697420616D65742C206D617373612E204E756C6C6120706F72747469746F722074696E636964756E74206C6F72656D2E204E756E6320646F6C6F72206F64696F2C20736167697474697320696E2C206C6F626F727469732076656C2C20766F6C7574706174207365642C206E6962682E0A0A5175697371756520626C616E646974206C656F2075742073617069656E2074656D70757320666163696C697369732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2041656E65616E20756C7472696369657320706F72747469746F72206A7573746F2E2046757363652072757472756D2065726F732075742075726E612E2050726F696E2071756973207175616D20656765742064756920616C697175616D20616363756D73616E2E20446F6E656320737573636970697420656C656966656E6420656C69742E2050656C6C656E746573717565206D61747469732C2066656C697320736F64616C657320696163756C697320696D706572646965742C206C616375732073656D20636F6E76616C6C69732061756775652C2073697420616D657420616C69717565742061726375207075727573206672696E67696C6C612072697375732E20496E206575206F64696F206964206D61676E61207068617265747261206F726E6172652E20416C697175616D20696E74657264756D2070756C76696E617220697073756D2E20536564206E657175652E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D2073697420616D6574206E6973692E2055742061742061756775652E204D617572697320766F6C757470617420626C616E646974206C6967756C612E204E756C6C61206575206D657475732E20566573746962756C756D206567657420656C69742E205072616573656E7420706F73756572652E20566573746962756C756D2069642073656D206E6F6E206C6563747573206D6F6C6C69732074696E636964756E742E20416C697175616D2069642066656C697320617420616E7465206F726E6172652074656D706F722E204E756C6C61206C61637573207475727069732C20666575676961742076697461652C2063757273757320717569732C20636F6E736563746574756572206E6F6E2C206D61757269732E204675736365206C61637573206D617373612C20706F72747469746F722075742C206D6F6C65737469652075742C2076656E656E6174697320612C206C6F72656D2E205072616573656E742073697420616D6574206F7263692E204D61757269732072686F6E6375732066656C69732076697461652066656C69732061646970697363696E6720696D706572646965742E204D616563656E6173206D6F6C6C6973206469616D206E6563206C656F2E0A0A467573636520656E696D20697073756D2C20756C7472696365732065752C206D6F6C65737469652069642C20656C656D656E74756D2069642C2073617069656E2E20496E746567657220612075726E612E204E616D2076656C6974206C696265726F2C2076656E656E6174697320656765742C2074656D706F722073697420616D65742C20666575676961742076697461652C20616E74652E204675736365206E756E632E205365642073656D706572206E69736C206E65632072697375732E20496E20736564206C696265726F2E2050726F696E20746F72746F72206E657175652C2074696E636964756E742061632C2074656D706F722061632C20706861726574726120717569732C2076656C69742E2044756973206C65637475732061756775652C20756C747269636965732076656C2C20636F6E7365717561742069642C20696163756C69732069642C20616E74652E20566976616D757320617563746F72206D65747573206120616E74652E204375726162697475722061726375206E6973692C20666163696C697369732061742C206C616F7265657420696E2C20636F6E736563746574756572207365642C206D61757269732E205175697371756520706C616365726174206469616D20736564206475692E20566976616D7573207072657469756D20636F6E64696D656E74756D206C6F72656D2E20437572616269747572206C616F726565742E2041656E65616E206F726369206C6967756C612C2063757273757320656765742C206C6163696E6961206E6F6E2C2066617563696275732076656C2C206C6F72656D2E0A0A416C697175616D206572617420766F6C75747061742E204375726162697475722065726F7320646F6C6F722C20636F6E67756520612C20636F6E64696D656E74756D207365642C206C75637475732075742C206E6962682E204D616563656E6173206E6F6E20746F72746F72206E65632074757270697320636F6D6D6F646F2070656C6C656E7465737175652E205072616573656E7420657569736D6F6420706C616365726174206D692E2053757370656E646973736520706F74656E74692E2050686173656C6C7573207574206E65717565207669746165206F726369206D617474697320696163756C69732E20496E746567657220656765742074656C6C75732E20446F6E656320617420616E74652E204E616D206C6163696E6961206C656F206567657420657261742E204D616563656E617320657569736D6F64206D61676E6120636F6E67756520746F72746F722E204D6F726269206E6563206D6173736120657520656E696D206D616C65737561646120736F6C6C696369747564696E2E2053656420616363756D73616E2E204E756C6C616D20697073756D2E205574206F64696F2E20416C697175616D206572617420766F6C75747061742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2050656C6C656E7465737175652069642076656C69742E204E616D206F64696F2073656D2C20616C69717565742075742C2074656D7075732073697420616D65742C20657569736D6F642065742C206E756E632E0A0A50656C6C656E746573717565206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205072616573656E74206D6175726973206E756E632C207661726975732075742C20636F6E76616C6C6973206D6F6C65737469652C206C75637475732073697420616D65742C206C656F2E205365642064696374756D206C6F72656D20657420617263752E204E756E632076656E656E617469732070656C6C656E746573717565206D617373612E204E756C6C6120666163696C6973692E2050686173656C6C757320696E20746F72746F722065676574207269737573207363656C657269737175652076756C7075746174652E20536564206E69626820656C69742C2073616769747469732061632C20636F6E64696D656E74756D206E65632C20636F6E76616C6C69732065742C206A7573746F2E20467573636520766F6C7574706174206D657475732E204E756E6320617563746F722E20566573746962756C756D206C656F2065726F732C2070656C6C656E7465737175652061632C206D6F6C6C697320756C7472696365732C2072686F6E637573206E6F6E2C20646F6C6F722E204D6175726973207665686963756C6120706C616365726174206E69736C2E20566573746962756C756D20626962656E64756D2C2061726375207175697320636F6E67756520656C656D656E74756D2C2076656C6974206E756E6320656C656966656E64207475727069732C206964206C7563747573207269737573206E69736C2073697420616D65742074656C6C75732E2050686173656C6C75732070656465206E657175652C20626C616E646974206E6F6E2C20636F6D6D6F646F2076697461652C20756C7472696369657320656765742C206D61676E612E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120666163696C6973692E20416C697175616D20616320616E74652E20437261732072697375732E204D6F726269206D6175726973206C616375732C20706F73756572652065752C20626C616E6469742065742C2070686172657472612061742C206D692E2050726F696E2061632070757275732E204475697320637572737573206E69736C2072757472756D207175616D2E20416C697175616D2061206F64696F206E6F6E206D61676E612070656C6C656E74657371756520756C747269636965732E204D616563656E6173206163206D6173736120717569732073617069656E20756C6C616D636F727065722074656D7075732E2043726173206375727375732076656C6974207365642073617069656E2E2050726F696E206E756C6C612E20566976616D757320736F64616C657320616C697175616D206E6962682E20457469616D206574206572617420757420616E7465206C6163696E696120657569736D6F642E204675736365206E6973692E2050726F696E2071756973206E756C6C612E0A0A517569737175652076656E656E617469732C2065726F7320736564206C616F7265657420736F6C6C696369747564696E2C206F72636920616E74652070656C6C656E746573717565206E69736C2C2073697420616D65742076697665727261207175616D2065726174206E6F6E2072697375732E20437261732065676574206C696265726F2E2053656420656C6974206D61676E612C2073656D7065722065752C206672696E67696C6C6120696E2C206469676E697373696D20736F64616C65732C20657261742E20566976616D757320666575676961742073656D2076656C206475692E20446F6E656320636F6E76616C6C697320736F6C6C696369747564696E206469616D2E2043726173207365642070757275732E20446F6E65632066656C69732065726F732C2073656D70657220656765742C2074656D706F7220636F6E7365637465747565722C20736167697474697320717569732C206E69736C2E204475697320696E20616E74652E2043726173206E6F6E207475727069732E204E756C6C612074656D706F722076656C697420616C697175657420747572706973206D6F6C657374696520706C6163657261742E2050726F696E20656C656D656E74756D206665726D656E74756D206D61757269732E20566976616D757320736564206F726369206C6163696E69612064756920706C6163657261742076656E656E617469732E20566573746962756C756D20666575676961742C2074656C6C757320696E20766F6C75747061742072757472756D2C206D61676E61206E69736920756C6C616D636F727065722065726F732C2069642070756C76696E6172206E657175652065726174207574206C616375732E20566976616D7573207365642061756775652E204E756C6C6120666163696C6973692E204D616563656E617320616E74652061756775652C20656C656D656E74756D2075742C20736F64616C65732076697461652C20636F6E64696D656E74756D206E65632C206C6F72656D2E20447569732070656465206F7263692C206672696E67696C6C612061742C20656C656966656E64206E65632C207072657469756D20696E2C20657261742E204E616D2073616769747469732C2074757270697320766974616520636F6E76616C6C69732070686172657472612C206F64696F2073656D207363656C65726973717565206C616375732C206E6563206C6F626F7274697320647569206469616D2076656C2065726F732E20496E2073656D7065722067726176696461206E657175652E0A0A496E7465676572206E756E632E205574207072657469756D20697073756D2073697420616D657420656C69742E20496E206E656320617263752E2053656420766573746962756C756D2076756C70757461746520697073756D2E2050656C6C656E7465737175652074696E636964756E742E204E756C6C61206772617669646120646F6C6F7220696E2074656C6C75732E2043726173207665686963756C612C20646F6C6F722075742070656C6C656E74657371756520616C697175616D2C206572617420656E696D20617563746F72206D617373612C207665686963756C61206C6F626F72746973206F64696F2065726F732071756973207175616D2E2050726F696E2064617069627573206E6571756520696E20656E696D2E2050726F696E20656C69742E20496E74656765722072686F6E6375732074696E636964756E7420656C69742E204675736365206C6F72656D206D657475732C2073656D7065722061632C20766F6C75747061742076697461652C20666163696C697369732075742C2074656C6C75732E20446F6E65632076656C20747572706973207669746165206E69736920706861726574726120706F72747469746F722E204D616563656E617320746F72746F722E204675736365206D692E204E756C6C616D206E6563207475727069732E2053656420736F64616C657320766573746962756C756D206E756E632E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A50656C6C656E74657371756520646F6C6F7220646F6C6F722C206C616F726565742065752C20616C697175657420717569732C207363656C657269737175652073697420616D65742C20617263752E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C616D206375727375732075726E61206567657420656C69742E205175697371756520626C616E6469742073617069656E20616320616E74652E2050726F696E206E756C6C612065726F732C206772617669646120766F6C75747061742C20736F64616C65732076656C2C206D6F6C6C69732065752C206D617373612E204E756C6C612074726973746971756520736F6C6C696369747564696E206E69736C2E20437572616269747572207669746165206C6F72656D2076697461652076656C69742065676573746173206F726E6172652E2041656E65616E20656765742065726F732E20416C697175616D206572617420766F6C75747061742E20467573636520612075726E61206964206F64696F20616C697175657420636F6E76616C6C69732E204375726162697475722073697420616D6574206E69736C20706F7375657265206C656F20706F737565726520646170696275732E2044756973206D6574757320657261742C206C75637475732076656C2C2072686F6E6375732061742C20636F6E76616C6C69732073697420616D65742C20656E696D2E20566976616D75732068656E6472657269742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D206567657420656C69742E0A0A4E756C6C616D2061206E756E632E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206D657475732075726E612C2074696E636964756E742065742C206C6163696E69612073697420616D65742C206C6F626F727469732076697461652C206C6967756C612E2050726F696E206574206D6175726973207669746165206D6920616363756D73616E2070656C6C656E7465737175652E20457469616D207175616D2070757275732C2068656E647265726974207365642C20666575676961742076697461652C20657569736D6F6420656765742C20746F72746F722E20557420616C697175616D206D61676E61207669746165206A7573746F2E2053757370656E6469737365206E6F6E206A7573746F2076656C2076656C697420636F6E64696D656E74756D2074656D7075732E20447569732074656D70757320697073756D2076697461652074656C6C75732E2050726F696E20696E206D617373612E20457469616D20756C6C616D636F727065722064696374756D2074656C6C75732E2050726F696E20616C69717565742066656C6973206174206C656F206C616F726565742070756C76696E61722E20566573746962756C756D20617263752070757275732C206D616C6573756164612073697420616D65742C206375727375732065752C20706C6163657261742073697420616D65742C206E756E632E204E616D206D61737361206F64696F2C20736F6C6C696369747564696E20696E2C2061646970697363696E6720612C20616C697175616D206E65632C2072697375732E20416C697175616D20626C616E6469742068656E647265726974206C696265726F2E204D617572697320677261766964612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204375726162697475722061206E6962682E20557420696E74657264756D206665726D656E74756D206E657175652E2050656C6C656E74657371756520736564206E756E632E204D6175726973207665686963756C61206E697369206574206E756E632E205072616573656E74206C6F72656D2E20446F6E65632073656D7065722E20496E7465676572206575206C6163757320696E2065737420616C697175616D2068656E6472657269742E20566573746962756C756D2065676574206E657175652E205365642073656D706572206C75637475732076656C69742E20437572616269747572206E6962682061756775652C20636F6E6775652065752C2068656E6472657269742069642C20636F6E6775652065742C20656E696D2E20496E746567657220706C61636572617420616C697175616D206C65637475732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20566976616D75732076697461652065726F732E20446F6E65632076656C206E69736C2E0A0A496E20766573746962756C756D20666163696C697369732075726E612E2055742072697375732E204D61757269732070686172657472612E2050656C6C656E746573717565206D61747469732E20496E746567657220737573636970697420616C697175616D20697073756D2E204475697320626C616E6469742C2073617069656E20657420756C7472696369657320636F6E64696D656E74756D2C2066656C6973206D6920656C656D656E74756D20706564652C206E6563207361676974746973206D65747573206D61757269732071756973207175616D2E205175697371756520616363756D73616E20617263752076656C206E756C6C612E20437261732073656D2073617069656E2C20706F72747469746F722069642C20756C747269636965732073616769747469732C206C75637475732065752C206E756C6C612E20496E746567657220717569732065726F732E204D6F726269207365642075726E6120612074656C6C7573207665686963756C612076756C7075746174652E20457469616D206E656320617567756520656765742066656C69732073656D706572207472697374697175652E205175697371756520757420646F6C6F722076656C2072697375732064696374756D20636F6E7365717561742E20536564206567657420646F6C6F7220736564206E756E63206C6163696E696120616C69717565742E2053757370656E646973736520616320746F72746F7220696E20697073756D20706F73756572652076656E656E617469732E20536564206567657420657261742E204E756C6C612066617563696275732E2044756973206C616F726565742C206D6173736120706F72747469746F7220616C697175657420656765737461732C20697073756D206C65637475732072686F6E637573207175616D2C20696E2061646970697363696E672065726F732073656D2075742074656C6C75732E2050656C6C656E74657371756520666575676961742074656D707573207175616D2E20566976616D757320696420646F6C6F7220656765742073617069656E20636F6E7365637465747565722074656D706F722E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120696163756C6973206665726D656E74756D206C696265726F2E204375726162697475722066617563696275732C206D61737361206D616C657375616461206375727375732074696E636964756E742C20657261742073656D20656C656966656E64206D61757269732C20736564206672696E67696C6C61206D6920616E74652061632070757275732E204475697320656C656D656E74756D206C65637475732E204E756E63206F726E617265206172637520657520746F72746F722E20566573746962756C756D2076656C20646F6C6F72206174207075727573206C6163696E6961206672696E67696C6C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E616D20696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204D616563656E61732074696E636964756E742C2065726F73206120656765737461732070656C6C656E7465737175652C2072697375732072697375732064696374756D206C696265726F2C20696420616C6971756574206D65747573206A7573746F20696E206D617373612E2050726F696E20612074656C6C75732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205365642070757275732E20536564206E6F6E20706564652E2041656E65616E206D617373612073617069656E2C20736F64616C65732073697420616D65742C20636F6E7365717561742064696374756D2C20656C656966656E642076697461652C20746F72746F722E20446F6E656320756C747269636573206C6163696E696120656C69742E0A0A4D6F7262692061646970697363696E6720736F64616C657320646F6C6F722E20557420756C6C616D636F7270657220756C74726963696573206573742E20496E2076656E656E617469732074656D7075732061756775652E2053757370656E646973736520746F72746F7220646F6C6F722C20616363756D73616E2065742C20737573636970697420612C2074696E636964756E742075742C206C696265726F2E20416C697175616D207363656C65726973717565206D61676E61207365642066656C69732E2051756973717565207574206E756E632061206D61676E612076756C70757461746520706C6163657261742E20416C697175616D2072686F6E637573207665686963756C61206475692E2053656420746F72746F722E204E756C6C616D2073697420616D6574206469616D2E204E756E63207365642065726F732E20536564206574206F64696F2074696E636964756E7420656C6974206772617669646120636F6E76616C6C69732E20437572616269747572207175697320746F72746F722061206C616375732073656D706572207661726975732E204D6175726973206174206175677565206E6F6E206D6920736F6C6C696369747564696E20616C697175616D2E20496E746567657220756C6C616D636F727065722E2050656C6C656E746573717565207375736369706974207175616D206E6F6E2070757275732E20416C697175616D2061632065726F73206174206172637520756C6C616D636F7270657220636F6E7365637465747565722E2053757370656E6469737365207072657469756D206D6174746973206C656F2E0A0A44756973206174206E756E632E2053656420646F6C6F72206573742C207661726975732061632C20706F7274612065742C2074696E636964756E742068656E6472657269742C2072697375732E20566976616D7573207574206D61676E612E205072616573656E74207574206D61757269732E20496E207075727573206C616375732C206D6174746973207365642C20766573746962756C756D206E65632C2074656D706F722061742C206E69736C2E204372617320756C6C616D636F727065722076656E656E617469732074656C6C75732E20557420646F6C6F722E204D616563656E6173206D616C6573756164612C207065646520612070756C76696E6172206D61747469732C2061726375206469616D207665686963756C612072697375732C207175697320706F72747469746F72206175677565206D6173736120696E2076656C69742E204E756E6320636F6E6775652E204D6F7262692076656C6974206D657475732C2072686F6E6375732065742C20616C697175616D20636F6E7365637465747565722C20756C74726963696573206D616C6573756164612C206C6967756C612E205365642076656C6974206E69736C2C2073616769747469732076697461652C20706861726574726120612C20706F7375657265207365642C206D617373612E204E756C6C6120666163696C6973692E20496E207661726975732C206C6967756C61206964206C6F626F7274697320736F64616C65732C206175677565206F726369206665726D656E74756D2074656C6C75732C2065752070756C76696E6172207269737573206C6967756C6120612073617069656E2E204D6F726269206C616F7265657420697073756D206E6F6E206D692E204E616D20637572737573206C6F72656D207574206D692E20566976616D7573206D61676E6120656E696D2C20706F7375657265206E6F6E2C2073656D70657220717569732C20736F64616C65732065752C20617263752E20457469616D206D692070757275732C207072657469756D20666575676961742C20766172697573207365642C2070656C6C656E74657371756520656765742C206C6967756C612E20496E206C656F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E6563207669746165206F726369206575206F72636920736F6C6C696369747564696E20666575676961742E0A0A5072616573656E74207075727573206D617373612C20657569736D6F642076697461652C2074656D707573206E65632C20636F6E7365717561742068656E6472657269742C206D657475732E2041656E65616E2066656C6973206573742C20656765737461732076697461652C20616363756D73616E20656765742C2070656C6C656E74657371756520696E2C2073617069656E2E204475697320646170696275732070656465206E6F6E2073617069656E2E204E756E632075726E612E20496E74656765722076656C206C696265726F2E204475697320617567756520617263752C2064617069627573206E6F6E2C20666163696C697369732076697461652C20706F73756572652075742C2065726F732E20446F6E6563207669746165206E756E632073697420616D6574206172637520696D706572646965742064696374756D2E204D6F72626920656C656966656E642C206C6F72656D20657520636F6E73656374657475657220766573746962756C756D2C206469616D206E756E63206F726E61726520617263752C2061632074656D706F722066656C697320646F6C6F7220656765742065726F732E2050686173656C6C7573206D617373612073656D2C20736F6C6C696369747564696E2061632C20736F64616C657320677261766964612C206C756374757320612C207175616D2E204E616D206E65717565207175616D2C20766976657272612061742C2076656E656E6174697320717569732C207361676974746973206E6F6E2C20656E696D2E0A0A4E756C6C6120666163696C6973692E2050656C6C656E7465737175652065676573746173206C6163696E6961206573742E205365642074696E636964756E742C2070656465207365642074696E636964756E7420766573746962756C756D2C2075726E6120646F6C6F722061646970697363696E672070757275732C207669746165206672696E67696C6C612066656C697320656C697420696E206E6962682E204E756C6C6120736564206E6973692E204D6175726973207375736369706974207363656C6572697371756520617263752E20457469616D206E6F6E20656E696D2076656C2065726F7320616363756D73616E206D616C6573756164612E204E756E632074696E636964756E7420636F6D6D6F646F206D61757269732E20496E2074696E636964756E7420726973757320717569732075726E612E204E756C6C61206469616D20746F72746F722C20616C69717565742065742C2074696E636964756E7420717569732C20736F6C6C696369747564696E2061632C20746F72746F722E2043726173206E69736C206E657175652C2076756C7075746174652073757363697069742C206D6F6C657374696520717569732C2070756C76696E61722061742C206E756C6C612E204E756C6C616D206163206D65747573206E6563206F64696F20706F7375657265207661726975732E2043726173207365642070656465206E65632064756920706F737565726520626962656E64756D2E204475697320657569736D6F6420756C6C616D636F72706572206C696265726F2E20416C697175616D2066617563696275732070756C76696E6172207475727069732E0A0A496E207574206E65717565206964206E756E63206665756769617420636F6D6D6F646F2E20437572616269747572206469676E697373696D2C2066656C697320617420736F6C6C696369747564696E206C6163696E69612C20656E696D20656C6974207375736369706974206E657175652C20736564206C7563747573206C6F72656D20697073756D20696E206C656F2E204475697320646170696275732C206F64696F207175697320617563746F7220636F6D6D6F646F2C206E69736C206F64696F206D61747469732074656C6C75732C206E65632074696E636964756E7420747572706973206469616D20696E20617263752E2043757261626974757220612073656D2E204E756C6C616D20766F6C7574706174206D61676E612E2050656C6C656E7465737175652073616769747469732C206E6571756520636F6E736571756174207072657469756D206375727375732C20646F6C6F72206C6163757320636F6E73656374657475657220617263752C20736564206C616F72656574206573742075726E61206574206D657475732E2053757370656E646973736520706C6163657261742C20647569206120706F7274612074656D706F722C206C6F72656D20647569206C6F626F72746973206E657175652C207365642076656E656E61746973206469616D20656E696D2069642065726F732E20457469616D206574206E69736C206E6F6E206C656374757320666175636962757320636F6E7365637465747565722E204D6F726269207363656C657269737175652C2073656D206E65632074656D70757320756C6C616D636F727065722C20697073756D206469616D2066657567696174206C6F72656D2C2061206672696E67696C6C612073617069656E20656C69742071756973206E6962682E204E756C6C616D206469616D2075726E612C2076697665727261207365642C2070686172657472612072686F6E6375732C2074696E636964756E742076656C2C206F7263692E20496E746567657220616363756D73616E206D617474697320657261742E204E616D2064696374756D2E204D6175726973206E6563206C656F2E204E756C6C6120696163756C69732E204E756C6C61206E69736C206D692C206461706962757320717569732C207665686963756C6120612C2063757273757320656765742C206F64696F2E0A0A50686173656C6C7573206461706962757320657569736D6F64206E6962682E20566976616D757320696D7065726469657420616E746520696E206C6967756C612E2050656C6C656E74657371756520616363756D73616E2E20496E20696D706572646965742C20647569206120617563746F72206672696E67696C6C612C206D65747573206E6973692063757273757320646F6C6F722C2076656C206C7563747573206C6967756C61206C6F72656D207669746165206D61757269732E205072616573656E74206D617474697320766573746962756C756D20656C69742E20416C697175616D20656E696D206C616375732C2070756C76696E6172206E6F6E2C206C6163696E69612073697420616D65742C20656C656966656E64206E6F6E2C2076656C69742E20566573746962756C756D206163206C656F2E204D617572697320696D70657264696574206A7573746F206163206C65637475732E20536564206D6F6C6573746965206C656374757320736564206475692E20536564206665726D656E74756D2074656D707573206D61757269732E204E616D206F726E617265206F7263692061632074656C6C75732E205574206D616C6573756164612C206C61637573206964206C6163696E696120616363756D73616E2C206469616D20656C69742061646970697363696E67206D657475732C20657420626962656E64756D2073617069656E206E69626820626C616E646974206F7263692E2053757370656E646973736520697073756D2074656C6C75732C20736167697474697320717569732C20766573746962756C756D206E6F6E2C2076756C7075746174652065752C2065726F732E205072616573656E74206174206E756C6C612069642070656465207363656C6572697371756520756C747269636965732E204372617320626C616E646974207072657469756D2074656C6C75732E204D616563656E6173206461706962757320636F6E64696D656E74756D2061756775652E2050686173656C6C75732074696E636964756E74207068617265747261206C6F72656D2E204D6F726269206E6F6E2065726F732E205365642074656D706F722C206E69736C20612074696E636964756E742074696E636964756E742C2065726F73206469616D2064696374756D2073656D2C2076656C206469676E697373696D20616E7465206469616D20736564206D61676E612E205072616573656E74206E6F6E206C6967756C61206964206D65747573206D6F6C657374696520636F6E7365637465747565722E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E64697373652076656C206D692E2043757261626974757220616E7465206E756C6C612C2072757472756D20612C20636F6E76616C6C69732076656C2C207665686963756C612061632C206E756E632E204E756E632073616769747469732C20656E696D2073697420616D657420617563746F722072757472756D2C206D617572697320617263752076756C707574617465206E657175652C20657420657569736D6F64206573742066656C6973207175697320616E74652E20566573746962756C756D207475727069732074656C6C75732C2068656E64726572697420696E2C206C6163696E696120636F6D6D6F646F2C20756C6C616D636F7270657220677261766964612C2072697375732E204D61757269732072686F6E637573206C6163696E69612072697375732E204D616563656E617320736F6C6C696369747564696E2065726174207669746165206E756E632E205072616573656E74207072657469756D2070656C6C656E7465737175652061756775652E20446F6E656320696E74657264756D2E205072616573656E742061632065726F732076697461652065726174206C6F626F72746973206672696E67696C6C612E2041656E65616E20636F6E7365717561742074656C6C75732E204E756C6C6120616363756D73616E20626962656E64756D2066656C69732E204D616563656E6173207072657469756D20616E7465206964206E6973692E2041656E65616E206D6920617263752C2073656D706572207365642C206D61747469732065752C2076656E656E617469732073697420616D65742C20617263752E20446F6E656320616C697175657420657569736D6F64206C656F2E2050726F696E206D61676E61206A7573746F2C2074726973746971756520612C2073656D7065722061632C20736F6C6C696369747564696E20612C206C6967756C612E204D6F7262692076656C69742E20416C697175616D2076656C206E6973692E0A0A496E2061206C6F72656D207574206E756E63206665756769617420636F6E6775652E20446F6E6563206665726D656E74756D20626962656E64756D206475692E2050726F696E207661726975732065737420717569732076656C69742E20446F6E656320616C69717565742073656D20616363756D73616E206D692E2053656420706C6163657261742E204E756C6C616D206163206E6973692061206D61737361206C6F626F727469732073757363697069742E204E756E63206964206C656F2E20416C697175616D206574206D617373612E204E756C6C616D20766573746962756C756D20656C656D656E74756D206D657475732E20496E20636F6E736563746574756572206E6973692076656C206A7573746F2E204D616563656E6173206567657420707572757320736564206D61737361207661726975732070656C6C656E7465737175652E2050686173656C6C75732066617563696275732066656C697320717569732066656C69732E2041656E65616E206F64696F20617263752C20626C616E64697420717569732C20666163696C6973697320696E2C20696D706572646965742065752C206C6F72656D2E204E616D20706F73756572652070756C76696E6172206D692E204675736365207472697374697175652C206D617572697320657420636F6E73656374657475657220756C747269636965732C206D6175726973206C65637475732074656D706F72206A7573746F2C206174206672696E67696C6C61206573742065737420736564206E6973692E20517569737175652066617563696275732E2053656420696E20746F72746F722074696E636964756E7420657374206C6163696E696120696163756C69732E204D616563656E61732061206D617373612E2050656C6C656E7465737175652061206E69626820617420707572757320706F7274612068656E6472657269742E0A0A4E756C6C616D207475727069732E2046757363652061632073656D20736564206F64696F2070656C6C656E74657371756520696D706572646965742E2043757261626974757220696E20617263752E205072616573656E74206C61637573206C616375732C20666575676961742069642C2070756C76696E617220696E2C2074696E636964756E74207365642C206E657175652E204D616563656E61732076697665727261206F64696F206567657420746F72746F722E20496E746567657220616C697175616D2C206C6F72656D2072757472756D2076656E656E61746973206469676E697373696D2C206C6967756C61206D61676E61206D616C65737561646120617263752C2076656C2066657567696174206C6F72656D20697073756D2071756973206D617373612E204D6F72626920616E74652E20566573746962756C756D206D6175726973206C696265726F2C20756C6C616D636F7270657220717569732C20756C74726963657320717569732C20666163696C69736973206E6F6E2C206D617373612E204D616563656E617320696D706572646965742E20416C697175616D206572617420766F6C75747061742E2050656C6C656E746573717565206469676E697373696D2067726176696461206C65637475732E20496E206E696268206F64696F2C20617563746F7220656765742C206461706962757320717569732C206469676E697373696D2076656E656E617469732C20617263752E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20447569732070656C6C656E746573717565206C6967756C612071756973206D617373612E2043757261626974757220636F6E64696D656E74756D2C206A7573746F2065676574206F726E617265206C75637475732C206C6F72656D206C6967756C6120736167697474697320706564652C206120706F727461206E756E63206E756E6320696E206E657175652E20517569737175652066656C6973206D61757269732C20636F6E64696D656E74756D2076697461652C20617563746F722076697461652C2074696E636964756E7420717569732C20706564652E204E756E63206C6163696E696120616E746520696E206C656F2E2050656C6C656E746573717565206C696265726F2E2041656E65616E2061206C6967756C61206574206E756E6320766573746962756C756D20636F6E7365637465747565722E0A0A4675736365206F726E6172652E205072616573656E742069642075726E612E20496E74656765722076656E656E617469732C207175616D206E6F6E20736167697474697320616363756D73616E2C20616E7465206E6962682073616769747469732061756775652C20736F6C6C696369747564696E2061646970697363696E6720646F6C6F722076656C697420657520657261742E2050726F696E207175697320656E696D206575207075727573207665686963756C6120616C697175616D2E204E756C6C612076656C20656E696D2076656C20656C697420736F6C6C696369747564696E206672696E67696C6C612E20416C697175616D206572617420766F6C75747061742E205365642073757363697069742066656C6973207574207475727069732E20457469616D2072757472756D20726973757320696D70657264696574206573742E20416C697175616D20612074656C6C75732061742074656C6C757320636F6D6D6F646F20646170696275732E204D61757269732072757472756D206D61676E61206574206F64696F2E20496E20617420646F6C6F722E20437572616269747572207665686963756C61206C656374757320696E20746F72746F722E204675736365206A7573746F2070757275732C206C75637475732076697461652C206D6F6C6C697320696E2C2070686172657472612061632C2070757275732E204E756C6C616D20706F737565726520696E74657264756D206A7573746F2E20437572616269747572207669746165206C616375732076656C206C656F20636F6E6775652070756C76696E61722E0A0A41656E65616E20656C656966656E64206E6962682076617269757320746F72746F722E2053757370656E64697373652076656C2065726F732E2050726F696E206E6563206469616D206120746F72746F7220756C747269636573206F726E6172652E20416C697175616D207363656C657269737175652066657567696174206A7573746F2E20566976616D757320616E74652075726E612C2061646970697363696E672076697461652C20706F72747469746F722065752C20736F64616C65732065742C2066656C69732E2053757370656E646973736520706F74656E74692E20437572616269747572206163206D6173736120696E206E69736C207361676974746973206D6F6C6C69732E204E616D207175616D206C6967756C612C20636F6E73656374657475657220656765742C20696163756C69732061742C207661726975732065752C206C656F2E204475697320646F6C6F72206C6967756C612C2074696E636964756E742061742C20756C6C616D636F72706572207365642C20616363756D73616E20616C697175616D2C206C6967756C612E2050686173656C6C75732076756C7075746174652C206C6F72656D2061742074696E636964756E742070686172657472612C207269737573206C6563747573206C6163696E6961206D61676E612C20717569732072757472756D20656E696D206D61676E612061742073656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E20447569732069642073656D2061206D617572697320736F6C6C696369747564696E2074696E636964756E742E20457469616D2065752070757275732065752061726375206672696E67696C6C612061646970697363696E672E20566976616D7573206F726E6172652074656D707573206469616D2E2050726F696E20747572706973207175616D2C206C6163696E6961206E6F6E2C20656765737461732061742C20636F6D6D6F646F20656765742C20706564652E205072616573656E742076756C70757461746520726973757320696E206573742E204E756C6C6120666163696C6973692E0A0A557420656C656D656E74756D206C6163696E69612070757275732E2050726F696E2076697461652061726375206163206E756C6C6120636F6E76616C6C697320616C697175616D2E204E756C6C6120636F6E6775652C206C696265726F2069642070656C6C656E746573717565206D61747469732C207175616D206C656374757320706F72747469746F72206469616D2C2061207363656C6572697371756520647569206C696265726F20696E2073617069656E2E204E756C6C616D2066656C6973206469616D2C207665686963756C612076656C2C206D6F6C65737469652075742C20766573746962756C756D20616C697175616D2C2073617069656E2E20446F6E656320636F6E76616C6C69732C2065737420757420656C656D656E74756D20766F6C75747061742C206D617572697320697073756D20677261766964612073656D2C20636F6D6D6F646F20666163696C697369732073617069656E206C65637475732073656D706572206C65637475732E205175697371756520706F72747469746F722065726F73207574206E6962682E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20457469616D206D617474697320726973757320736564206F64696F2E20566573746962756C756D206574206F64696F2E20496E206861632068616269746173736520706C617465612064696374756D73742E204E616D20747269737469717565206D61737361207574206C6967756C612E2051756973717565206E6962682074656C6C75732C207665686963756C612073697420616D65742C2061646970697363696E672061742C20636F6E76616C6C6973206E65632C206C6967756C612E20566573746962756C756D207072657469756D2C206D69206E6563206672696E67696C6C6120626962656E64756D2C20647569206E756E6320736F64616C657320706564652C20612073656D706572206D61676E61206E696268206E6F6E206469616D2E20446F6E6563206D61737361206E756E632C20766976657272612076656C2C20636F6E73656374657475657220706F7274612C2064617069627573206E6F6E2C20697073756D2E2044756973206E69736C206D61757269732C206375727375732076656C2C2073656D706572206E6F6E2C20736F6C6C696369747564696E20626962656E64756D2C2066656C69732E20566573746962756C756D206575206E657175652E0A0A43726173206E656320646F6C6F722E20446F6E6563206C616F726565742074656D707573206C65637475732E20437261732073656420746F72746F7220696E74657264756D206C6163757320656C656966656E64206469676E697373696D2E204D616563656E61732073697420616D657420656C69742E204E756C6C616D207175697320646F6C6F722076656C20647569207068617265747261206C75637475732E20496E2073697420616D6574207175616D2073697420616D6574207065646520756C74726963657320756C7472696365732E204D616563656E6173206469616D2E20496E74656765722075726E612E204375726162697475722064696374756D2C2076656C69742073656420706C6163657261742073757363697069742C206572617420747572706973206665726D656E74756D206A7573746F2C2073656420696E74657264756D206E657175652073656D206574206E6962682E20566976616D757320636F6E73657175617420636F6E76616C6C6973206D61676E612E204E616D20616C697175616D2C2065737420616320626962656E64756D20636F6D6D6F646F2C206D61676E61206573742064696374756D206D692C207669746165206D616C65737561646120656C6974206D61676E61207669746165206F64696F2E204D616563656E61732074656D706F722076756C7075746174652074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206475692E20457469616D20616363756D73616E207065646520636F6E67756520746F72746F722E0A0A4D6F7262692074656D706F72206C696265726F206163206C6F72656D2E20496E20616C697175657420766172697573206D61676E612E20496E20617263752E2050686173656C6C7573206F64696F2E2046757363652074696E636964756E7420616C69717565742066656C69732E20517569737175652076656C69742E20536564206C75637475732E20416C697175616D2066657567696174206672696E67696C6C61206D692E20416C697175616D206D6F6C657374696520766976657272612072697375732E2050726F696E20617263752E20566573746962756C756D206C6F626F727469732074656D707573206E6973692E205072616573656E742061206172637520696E2076656C697420766976657272612072757472756D2E0A0A496E20736564206C65637475732E20446F6E656320726973757320646F6C6F722C20626C616E6469742073697420616D65742C20656C656D656E74756D20636F6E76616C6C69732C20706861726574726120717569732C20706564652E20496E7465676572206F726E6172652E2041656E65616E20656765737461732064617069627573206A7573746F2E20536564207175616D206C656F2C20706F73756572652061742C20656C656D656E74756D2076697461652C20636F6D6D6F646F20656765742C206573742E20416C697175616D206D6F6C65737469652072686F6E63757320656E696D2E2043757261626974757220696163756C697320756C74726963657320706564652E204D6F72626920616C69717565742072757472756D206C616375732E20416C697175616D207175616D2E2053656420636F6D6D6F646F2C2074757270697320696E20706861726574726120706F73756572652C206D6920726973757320696D7065726469657420657261742C206120766573746962756C756D206D617373612074656C6C7573207665686963756C612073656D2E204D6175726973206672696E67696C6C6120756C747269636573206E756E632E204E616D206E69736920656E696D2C20656C656966656E642073697420616D65742C20756C747269636573207365642C206665726D656E74756D206E6F6E2C2061756775652E2050726F696E20636F6E677565206C6F626F72746973206E6973692E204D616563656E61732068656E6472657269742E204E616D20736564206E69736C2E204E756E6320656C656D656E74756D206F64696F2065752072697375732E20496E206D657475732E2050686173656C6C75732067726176696461207072657469756D206C6967756C612E204E756C6C61207669746165206E657175652E204E616D206E69736920746F72746F722C206F726E617265206E6F6E2C20626C616E6469742061742C206375727375732065752C20746F72746F722E0A0A4475697320626962656E64756D20697073756D20696E206E756E6320637572737573206D6F6C65737469652E204E756E63206F7263692E204E756C6C616D206E656320616E7465206E6F6E20657374206469676E697373696D20766976657272612E204D617572697320626C616E6469742C2076656C69742069642066657567696174207072657469756D2C20656C6974206D61676E612070656C6C656E74657371756520646F6C6F722C206174207361676974746973206C616375732076656C69742065676573746173206D61676E612E2050656C6C656E746573717565206375727375732C206469616D20636F6E736563746574756572207361676974746973206672696E67696C6C612C20746F72746F72206E6973692061646970697363696E67206E756E632C20657520766172697573206C6163757320726973757320616320656C69742E204D6175726973206964206E6973692071756973206C656F20657569736D6F642076656E656E617469732E2050656C6C656E74657371756520616320616E74652E204D617572697320617263752073617069656E2C2074656D706F722061742C20706F72747469746F722069642C20636F6E64696D656E74756D2075742C206475692E20457469616D206665726D656E74756D20756C747269636965732061756775652E20437261732075742065726F73206174206A7573746F20756C7472696369657320696163756C69732E2044756973206469676E697373696D2C206E69736C20657420666163696C69736973206665726D656E74756D2C2065726174207075727573206D6F6C65737469652074656C6C75732C20717569732074656D70757320697073756D206C656374757320617420656C69742E204E756C6C61207669746165206C6F72656D2E0A0A41656E65616E2076656C2073656D206574206469616D2073656D70657220636F6E6775652E20496E20626962656E64756D206469616D20717569732074656C6C75732E204E756E6320666163696C6973697320756C74726963696573206E6962682E2043726173206E756E6320656E696D2C2066657567696174207365642C20756C7472696365732076697461652C2073616769747469732076697461652C20697073756D2E204675736365207669746165206E756C6C612E20446F6E65632070656C6C656E7465737175652C2076656C697420696E20706F72747469746F7220656C656966656E642C20657374206E65717565206C6F626F727469732076656C69742C2073697420616D65742072757472756D20616E746520746F72746F72206E656320646F6C6F722E20446F6E6563207665686963756C612E204E756C6C6120666163696C6973692E20536564206567657374617320756C747269636573206E6962682E20446F6E656320656C6974206C65637475732C20636F6E76616C6C697320706F72747469746F722C20616C697175657420646170696275732C206665756769617420656765742C206C6967756C612E2053656420636F6E736563746574756572206A7573746F2E204D616563656E617320612073617069656E2073697420616D6574206E6973692064617069627573206C6F626F727469732E20566976616D7573206C7563747573206C6F72656D206E6F6E206E756C6C612E2053656420656765742065726174207669746165206C696265726F20696E74657264756D20706F73756572652E20437261732070756C76696E61722E204E756C6C616D20696D706572646965742C20646F6C6F722074656D706F72206469676E697373696D20626C616E6469742C206475692073617069656E2072686F6E637573206E657175652C206964206D616C657375616461206175677565206D61676E612073697420616D65742075726E612E204475697320736564206D61757269732E0A0A4D6F72626920616363756D73616E2E20536564206D61757269732061756775652C206672696E67696C6C61206E6F6E2C20617563746F722075742C20617563746F722065742C206F7263692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320757420706564652E20446F6E6563207669766572726120656E696D2076656C206C6F72656D2E2050656C6C656E746573717565206E65717565206D61757269732C20696E74657264756D2065752C2076656E656E617469732069642C20636F6E64696D656E74756D2065752C2073617069656E2E20446F6E656320697073756D20617263752C206C6163696E69612061646970697363696E672C206C616F726565742065742C206375727375732076656C2C2076656C69742E205574207361676974746973206D617572697320717569732072697375732E20496E7465676572206575206F64696F207669746165206C61637573207669766572726120616363756D73616E2E204D6F726269206C656F20616E74652C206469676E697373696D207365642C2076617269757320717569732C20766F6C75747061742076697461652C206E6973692E204E756C6C6120706C61636572617420696E74657264756D20656C69742E20446F6E6563206E65717565206475692C2073616769747469732076697461652C20736F6C6C696369747564696E20717569732C20636F6D6D6F646F2076697461652C206E657175652E204E756C6C612071756973206C6967756C61206F726E617265206C6967756C612064696374756D206F726E6172652E204D61757269732072757472756D2072757472756D206E657175652E2041656E65616E207665686963756C612074656D707573206573742E20446F6E656320766172697573207363656C6572697371756520706564652E20446F6E656320706C6163657261742076756C707574617465206C656F2E204E756C6C616D206E756E63206E69736C2C20706F7375657265206E6F6E2C20666575676961742076697461652C2070656C6C656E74657371756520717569732C206D61757269732E20496E20647569206E657175652C2063757273757320656765742C20736167697474697320656765742C20646170696275732076697461652C206D692E2050726F696E2065676574206573742E0A0A467573636520706F727461206573742E204D6175726973206D61676E612E20416C697175616D20697073756D206C616375732C20756C747269636965732069642C20766573746962756C756D206C75637475732C20616363756D73616E2075742C20616E74652E20536564206D61757269732E205365642061646970697363696E67206C656F2073697420616D6574206D61676E612E2053757370656E646973736520706F74656E74692E204E756E63206D6173736120656C69742C206672696E67696C6C6120656765742C20656765737461732076697461652C206C75637475732076697461652C20646F6C6F722E2050686173656C6C75732071756973206E756C6C61206575206E69736920696E74657264756D20736F6C6C696369747564696E2E204E756C6C616D2069642074656C6C75732E20496E746567657220696163756C697320646F6C6F722061632070757275732E205365642076656C206D692E20437572616269747572206E6F6E206D61676E612073697420616D6574206A7573746F20636F6E64696D656E74756D2076756C7075746174652E20517569737175652074696E636964756E742070656465206575206E69736C2E20566976616D7573206C6F626F727469732E204E756E63206D65747573206D657475732C20636F6E677565207365642C2074696E636964756E74207365642C207072657469756D2061742C206F64696F2E20446F6E6563206120617263752E20496E2073656D206A7573746F2C207665686963756C61207365642C207661726975732069642C20766F6C75747061742061742C2072697375732E205072616573656E7420696163756C6973206D617373612E20496E206172637520656C69742C2068656E64726572697420656765742C20756C6C616D636F7270657220696E2C20706F7274612069642C2074656C6C75732E20446F6E65632073616769747469732068656E647265726974206469616D2E0A0A53757370656E646973736520706F74656E74692E20536564206574206469616D206574206175677565207361676974746973206C6F626F727469732E2050686173656C6C757320646F6C6F722E2055742065742061726375206567657420616E74652074656D706F7220706F73756572652E20416C697175616D206665726D656E74756D207363656C65726973717565206475692E204D61757269732061742070757275732E20446F6E656320657261742073656D2C20766573746962756C756D206E65632C2066617563696275732061632C206D617474697320612C206C656F2E2053757370656E64697373652061646970697363696E67206C6163696E69612073656D2E204E756C6C616D206F72636920617263752C2064696374756D2065742C20666175636962757320766976657272612C20646170696275732065742C206E657175652E2043726173206E756E63206469616D2C2061646970697363696E67206E6F6E2C20736F6C6C696369747564696E20696E2C20696E74657264756D2076656C2C206D617373612E204D61757269732073616769747469732C206A7573746F206174207472697374697175652074656D7075732C206D6175726973206D617572697320616C697175616D20616E74652C2073697420616D657420706F7375657265206469616D206475692065676574206C6967756C612E20496E206469676E697373696D2C206E69736C207574206C6163696E696120636F6E64696D656E74756D2C2065726174206A7573746F20706F72747469746F72206E756C6C612C206E6F6E2067726176696461206C6967756C61206D61676E612065676574206D617373612E20566573746962756C756D207669746165206C6967756C61206174206D6920766573746962756C756D2073757363697069742E2044756973206C616F726565742E204E756C6C6120636F6D6D6F646F206C696265726F2073697420616D6574206C6F72656D2E20557420656C656D656E74756D2073656D2E20496E74656765722076656C20646F6C6F722E204E616D20666163696C69736973206D6920717569732073656D20756C7472696365732073616769747469732E205365642071756973207175616D206174206D65747573206D6F6C657374696520626962656E64756D2E0A0A50726F696E2064756920656E696D2C206C6163696E696120612C20666575676961742061632C20706C6163657261742076697461652C20706564652E205175697371756520656765737461732C206C656F206567657420616C697175616D207072657469756D2C206C696265726F206A7573746F2074696E636964756E742065726F732C2075742065676573746173206175677565207065646520656C656D656E74756D206E6962682E20437572616269747572206D6F6C6C697320736F64616C657320656E696D2E20446F6E65632061756775652E2050686173656C6C757320696420697073756D20706F737565726520647569207072657469756D2066617563696275732E204D6175726973206C756374757320616E74652073656D706572206E69736920696E74657264756D2061646970697363696E672E204475697320646170696275732C206F64696F207175697320766976657272612072686F6E6375732C206A7573746F207175616D20626962656E64756D20646F6C6F722C20696420646170696275732076656C697420657261742076656C20657261742E2046757363652073697420616D6574206E69736C2076656E656E61746973207175616D20756C74726963657320636F6E64696D656E74756D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632072686F6E637573207363656C65726973717565206C6967756C612E20566573746962756C756D206D69206F64696F2C20616363756D73616E2065742C2061646970697363696E6720656765742C206F726E6172652075742C207175616D2E204E756C6C616D20626C616E646974206D6F6C6573746965206D61757269732E20437572616269747572206469676E697373696D206D6175726973206574206C6F72656D2E2053757370656E64697373652061206A7573746F2E204E616D206D617474697320666175636962757320617263752E204475697320626C616E64697420656E696D206E6F6E206D617373612E0A0A4E756C6C616D206C6F72656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E204D617572697320636F6E73656374657475657220706F7375657265206D61757269732E204D616563656E61732074696E636964756E74206D617572697320696E2065726F732E204E756C6C61206575206D65747573206575206F72636920736F6C6C696369747564696E2066617563696275732E2053757370656E646973736520616C697175616D206D6175726973206964206573742E204372617320626C616E646974206475692065742075726E612E204E756C6C6120617263752E2053656420612075726E612E204E756C6C612064617069627573207665686963756C6120746F72746F722E20446F6E65632072697375732E20536564207175616D206D657475732C20656765737461732065752C206375727375732075742C2076697665727261206E6F6E2C206F64696F2E205574206A7573746F206A7573746F2C206D616C6573756164612073697420616D65742C20626C616E6469742073757363697069742C206D6F6C657374696520696E2C206A7573746F2E20566573746962756C756D20636F6E7365717561742C207175616D20616320666575676961742074696E636964756E742C20697073756D206C696265726F20656C656966656E64206F64696F2C206E6F6E20656C656966656E64207065646520697073756D206E6F6E20616E74652E204E756C6C616D2061206D657475732E0A0A4E616D206163206E6973692061742066656C697320637572737573206D61747469732E2050656C6C656E74657371756520636F6E7365717561742073656D2071756973206F7263692E20517569737175652074656D7075732E2041656E65616E20696D70657264696574206D6F6C657374696520706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652065752074656C6C75732E204E756C6C61206469616D2065726F732C20736F64616C65732075742C20736F64616C6573206E65632C2074696E636964756E742061632C206E756E632E204E756E63206C6163696E696120666175636962757320697073756D2E20566976616D75732076656C206E6571756520696E2065726174206665726D656E74756D206C75637475732E204E756C6C612065676574206D65747573206E656320617567756520626962656E64756D20706C6163657261742E20566976616D75732074656D7075732E205072616573656E7420636F6E677565206F726E61726520697073756D2E20457469616D206D61747469732066657567696174206A7573746F2E0A0A416C697175616D206475692E2041656E65616E20636F6D6D6F646F20746F72746F72207669746165206E756C6C612E204D6F72626920657420697073756D2E204D617572697320616320697073756D2E204E616D2076656C207269737573207574206C6563747573206D6F6C6C697320766976657272612E2043757261626974757220656C656D656E74756D206D6F6C6C6973206573742E204E756C6C616D20656C69742E20566573746962756C756D207375736369706974207072657469756D20656E696D2E20566573746962756C756D207574206D617373612E2050726F696E206E65632066656C69732E204D616563656E617320677261766964612C2061726375206E656320636F6E7365717561742073616769747469732C2065726F732074656C6C7573207363656C65726973717565206D61757269732C20766974616520616363756D73616E207175616D207175616D207574206E756E632E20496E7465676572206567657420616E74652065752076656C6974206C616F72656574206D616C6573756164612E204E756E632073616769747469732C206D617572697320766974616520706861726574726120766F6C75747061742C2074656C6C75732074656C6C757320656C656966656E642065726F732C2073697420616D65742072757472756D20697073756D206E69736920612076656C69742E205072616573656E7420766172697573206C656F20657520657261742E20566976616D757320636F6E73657175617420706C6163657261742070757275732E20446F6E6563207072657469756D20656C656D656E74756D206E6962682E2050726F696E20617420656C6974206E6F6E2073656D20616C6971756574206D61747469732E2053656420756C6C616D636F7270657220697073756D2073697420616D657420656C69742E0A0A4D617572697320696E206D657475732E2053757370656E6469737365206D61676E61206C6F72656D2C2066617563696275732076656C2C2074696E636964756E7420717569732C207363656C65726973717565206E6F6E2C2074656C6C75732E2046757363652071756973206C6F72656D2E2050726F696E2061206C616375732073697420616D6574206D617572697320696163756C69732070756C76696E61722E2053757370656E64697373652072686F6E6375732065726F73206E6563206D692E205072616573656E7420657569736D6F642C207475727069732076697461652072757472756D207072657469756D2C206F64696F206D6574757320766F6C7574706174206E657175652C20656765742074656D7075732073617069656E206E657175652073656420657261742E20446F6E6563206665726D656E74756D207075727573206174206C65637475732E204E756C6C616D2073656D2E2046757363652076656C206D6920717569732065726174206C6F626F7274697320706F73756572652E2041656E65616E20656765742075726E612E2053757370656E6469737365206C6967756C612E204475697320696E206E6973692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A4375726162697475722076756C707574617465206C656374757320696420706564652E2050686173656C6C75732065752076656C69742E20457469616D2076656E656E617469732061646970697363696E67206E6962682E20416C697175616D206375727375732070756C76696E61722074656C6C75732E20566573746962756C756D206E657175652E204D6175726973206E6563206A7573746F20657420657261742073656D7065722070656C6C656E7465737175652E204675736365206D61747469732064696374756D20646F6C6F722E20457469616D2065676574207075727573206575206D617373612076617269757320656C656D656E74756D2E2050656C6C656E746573717565206D617373612E20557420756C74726963696573206469616D2073656420697073756D2E204E756C6C616D206469616D2E2050656C6C656E746573717565206964206D61676E61206964206C696265726F2074726973746971756520616C697175616D2E0A0A557420656C656966656E642C20707572757320696420706C6163657261742076656E656E617469732C2075726E6120617567756520616C6971756574206C6967756C612C20696E20756C74726963696573206C656F2072697375732065742074656C6C75732E204D6175726973206574206E756C6C612069642075726E61207472697374697175652074656D7075732E20557420666163696C697369732C2075726E6120657520766573746962756C756D2072686F6E6375732C206C616375732065726F7320636F6E736563746574756572206D657475732C2065742072757472756D20647569206C656374757320696E2070757275732E204E756E632076656C206E69736C206E6F6E20697073756D2074696E636964756E74206D6F6C6C69732E204E616D207175616D206C616375732C206F726E6172652076697461652C2072686F6E637573206E6F6E2C20636F6E677565207365642C206F64696F2E2050726F696E206E696268206475692C20706F7274612076656C2C2076656E656E61746973206E6F6E2C2070656C6C656E7465737175652075742C206E6973692E20536564207472697374697175652066656C69732061206D61676E612E2053757370656E646973736520656765742074656C6C75732E2043726173206772617669646120696D706572646965742076656C69742E20496E74656765722068656E6472657269742072697375732E2050726F696E206F7263692E20416C697175616D20756C6C616D636F72706572206D61757269732071756973206D61757269732E204E756E63206C6163696E696120766573746962756C756D206D657475732E20447569732074656C6C75732E204E756C6C616D2066617563696275732C206C656F2061632076756C70757461746520736F6C6C696369747564696E2C206C656F20646F6C6F7220666175636962757320657261742C207175697320626962656E64756D206F726369206F64696F206E6F6E20617263752E0A0A4E756C6C616D20616363756D73616E206D617474697320646F6C6F722E20446F6E6563206574206475692E205072616573656E7420612066656C6973206D6F6C6C6973206C616375732073656D706572206C6163696E69612E204375726162697475722070656C6C656E746573717565206C7563747573206573742E2050726F696E206E756C6C61206475692C20636F6E64696D656E74756D2076656C2C206661756369627573206E6F6E2C20696E74657264756D2061632C20657261742E204D616563656E6173207363656C657269737175652C206C656374757320696420766F6C757470617420616363756D73616E2C2073617069656E20746F72746F722070656C6C656E746573717565206475692C207365642073656D706572206D61676E612073656D207574206C656F2E2050726F696E206E756C6C612E204E756C6C616D206461706962757320756C6C616D636F727065722073656D2E2053757370656E6469737365207665686963756C61206D6574757320696E206E756E632E2050656C6C656E746573717565206E6F6E207175616D2076656C206172637520756C74726963657320756C6C616D636F727065722E2050686173656C6C757320717569732066656C69732073697420616D65742074656C6C757320756C6C616D636F72706572206665726D656E74756D2E20536564207665686963756C6120736F6C6C696369747564696E2075726E612E20437572616269747572207068617265747261207363656C657269737175652072697375732E2050656C6C656E746573717565206964206D617373612071756973206D6574757320616C697175616D20696D706572646965742E20496E206E756E63206C616375732C206665756769617420696E2C206772617669646120656765742C2076656E656E617469732075742C2074656C6C75732E2053757370656E646973736520706F74656E74692E204E616D20636F6E7365717561742061646970697363696E67206475692E20496E206E756C6C61206E6973692C20666575676961742075742C206665726D656E74756D2076656C2C2067726176696461206E65632C20746F72746F722E20496E207365642061756775652E0A0A457469616D20756C6C616D636F7270657220617567756520617420656E696D2E20496E7465676572206469676E697373696D2E20416C697175616D2070756C76696E617220636F6E677565206E756C6C612E204D6F72626920656E696D206D617373612C206672696E67696C6C6120612C20616363756D73616E20656765742C20636F6E64696D656E74756D206E65632C20657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2041656E65616E2070686172657472612E20457469616D20706F72747469746F722070757275732061206D657475732E20416C697175616D20696E74657264756D2073656D2065676574206A7573746F2E205175697371756520766F6C7574706174206C7563747573206573742E2041656E65616E2061756775652E2050686173656C6C757320647569206C65637475732C20756C747269636573206E65632C20636F6D6D6F646F2076656C2C20617563746F722076656C2C206E6973692E20557420756C7472696365732070656C6C656E746573717565206E6973692E20496E74656765722061632076656C69742065742073656D20696D70657264696574206C75637475732E20467573636520766974616520747572706973206964206175677565206D6F6C6C697320636F6E7365637465747565722E0A0A4D616563656E6173206E6563206C616375732E204D616563656E617320636F6E64696D656E74756D206F64696F2065752066656C69732E204D6175726973207574206E69736C207669766572726120657261742066617563696275732061646970697363696E672E20457469616D20656765737461732E204E756E6320657420646F6C6F72207669746165207269737573206469676E697373696D20636F6D6D6F646F2E204D6F726269206C65637475732076656C69742C2074696E636964756E74206E65632C20616C69717565742076656C2C206D61747469732076697461652C206C6967756C612E204D616563656E617320756C747269636965732073656D70657220646F6C6F722E2053757370656E6469737365206D616C6573756164612E20496E7465676572206D617474697320656C69742E20446F6E656320616363756D73616E2C206C6163757320666163696C69736973207661726975732074656D7075732C206E756C6C6120656C697420706F72746120657261742C2065742072757472756D20656C69742073656D2073697420616D6574206475692E0A0A4D616563656E6173206D6F6C6C6973206D69206E6F6E206E756C6C612E20566976616D7573207475727069732E2053757370656E64697373652061206D657475732E20496E2071756973206D6920696E2074757270697320636F6E67756520617563746F722E204D616563656E6173206C616375732E2053757370656E646973736520736F6C6C696369747564696E2E2050686173656C6C757320706F727461206E756E63206E6F6E206E69736C2070756C76696E617220656765737461732E20536564206E756C6C612E20566573746962756C756D206163206D692E204D617572697320756C7472696369657320636F6E64696D656E74756D206E657175652E204E756C6C612074656D707573206A7573746F2076656C206D617373612E204E756C6C6120737573636970697420636F6E67756520617263752E205072616573656E74206964207475727069732E204D6175726973206E69626820706564652C20657569736D6F642073656D7065722C206D6F6C65737469652061632C2072686F6E6375732076697461652C20616E74652E204D616563656E617320657261742066656C69732C207669766572726120736F6C6C696369747564696E2C20736167697474697320656765742C2070656C6C656E746573717565206E65632C206F7263692E20467573636520756C74726963657320636F6E736571756174206C616375732E20416C697175616D2065726174206D61676E612C20666575676961742061742C207669766572726120612C206D6F6C6C6973206E6F6E2C207475727069732E0A0A446F6E6563206D692E204E616D2064696374756D2070656C6C656E7465737175652073656D2E20446F6E6563206D6F6C6C69732072686F6E63757320656C69742E2050686173656C6C75732072686F6E63757320706564652073697420616D65742072697375732E20446F6E656320656765742061756775652E204D616563656E6173206E6F6E206C65637475732E2050686173656C6C757320736F6C6C696369747564696E206E697369206E65632066656C69732E20416C697175616D207072657469756D2C2065737420656765742073656D70657220636F6E76616C6C69732C206E696268206E756E6320736F6C6C696369747564696E2070757275732C2069642074656D706F722070656465206475692076656C206D61676E612E20566976616D7573206163206C6F72656D2E20457469616D206E69736C20746F72746F722C2061646970697363696E672064696374756D2C20656C656D656E74756D20696E2C20666163696C69736973207365642C206E6962682E2050726F696E206D61757269732E2050726F696E2072757472756D206D6173736120656765742073656D2E204375726162697475722074656D706F722061646970697363696E6720656C69742E204375726162697475722070757275732074656C6C75732C206665726D656E74756D20656765742C20616C69717565742076697461652C20636F6E76616C6C69732061632C206D61757269732E0A0A496E746567657220636F6E7365717561742076656C69742065752065726F732074696E636964756E74207665686963756C612E204E756C6C616D206C6F72656D2073617069656E2C2072686F6E637573206E6F6E2C206D617474697320717569732C20756C747269636965732073697420616D65742C20656E696D2E2043757261626974757220636F6D6D6F646F2C206C696265726F20696E20657569736D6F642073757363697069742C2073656D207075727573206672696E67696C6C6120656E696D2C206163206D6F6C657374696520746F72746F72206F7263692065742076656C69742E20446F6E656320706564652E20457469616D20706C61636572617420636F6E64696D656E74756D207475727069732E2050686173656C6C7573206567657374617320656E696D206E6563206D61676E612E20566976616D757320636F6E64696D656E74756D2C206E756C6C612076656C206C7563747573207472697374697175652C2065726F7320726973757320766573746962756C756D206E756C6C612C20696E207665686963756C61206172637520697073756D2061742066656C69732E20446F6E656320616C697175616D20656C69742061742061756775652E205175697371756520612065726F73206575206C6967756C6120616363756D73616E2064696374756D2E20457469616D207665686963756C61207475727069732071756973206C696265726F2E20416C697175616D206E6F6E206D692E20446F6E6563206574206C656F2E2050726F696E206C656F206C696265726F2C20616C697175616D2074696E636964756E742C20636F6E677565206E65632C2061646970697363696E6720706F7274612C20656E696D2E204E756C6C61206C6F626F727469732C20746F72746F722073697420616D657420696D7065726469657420756C6C616D636F727065722C20646F6C6F72206F726369206D616C65737561646120706564652C207365642067726176696461206E6962682075726E612076656C206C6F72656D2E20536564207068617265747261206D616C6573756164612065726F732E205175697371756520657569736D6F6420616C697175657420657261742E2053757370656E646973736520616C6971756574206D61747469732070757275732E0A0A4E756E63206964206E756C6C612071756973206A7573746F20636F6E67756520736F6C6C696369747564696E2E205072616573656E742065726174207475727069732C2072686F6E6375732065752C207072657469756D2065752C2070656C6C656E74657371756520612C206E6962682E20566976616D75732074656D7075732E2043726173206E65632072697375732061742074757270697320696D70657264696574206C6F626F727469732E205574206D61747469732E204D616563656E6173206573742066656C69732C2070656C6C656E746573717565206E6F6E2C20696D70657264696574207365642C20656C656966656E642074696E636964756E742C206C6F72656D2E20496E2074696E636964756E742E205365642076656C206C656F2E20446F6E65632065742075726E6120696E207475727069732068656E64726572697420626C616E6469742E20446F6E656320636F6E64696D656E74756D20616363756D73616E206573742E2055742070686172657472612C206D65747573207669746165206D617474697320636F6E7365637465747565722C206C656F207175616D2076756C707574617465206F64696F2C206E6563206C616F72656574206E6973692076656C697420657520657261742E20496E7465676572206C65637475732061756775652C206567657374617320696E2C20696E74657264756D2065752C2076656E656E617469732076656C2C2073617069656E2E2051756973717565206574206573742076697461652065726F73206C616F72656574206C6F626F727469732E204E756C6C616D207574207269737573206E6F6E206E756C6C6120706C6163657261742061646970697363696E672E205072616573656E7420646170696275732E20457469616D20612066656C69732E20557420736F64616C657320636F6E736571756174206D61757269732E2044756973206C6F72656D2066656C69732C206C756374757320612C2074726973746971756520696E2C206D6F6C65737469652061742C2072697375732E20536564207665686963756C6120626962656E64756D2074656C6C75732E204E616D20636F6E73657175617420657569736D6F64206C616375732E0A0A41656E65616E20746F72746F7220656C69742C2067726176696461206E65632C206665726D656E74756D2065752C206C6F626F727469732069642C20697073756D2E204D616563656E61732065752070757275732E204372617320616320747572706973207574206E69736920696163756C69732072686F6E6375732E204E756C6C61207075727573206D657475732C206469676E697373696D206E65632C2074696E636964756E742076697461652C20646170696275732065752C206E6962682E204675736365206C6F626F727469732C206E756E63206174207669766572726120656C656966656E642C206A7573746F20747572706973207363656C657269737175652065726F732C2061632070656C6C656E746573717565206D65747573206E69736C2061742070757275732E2053656420656C656D656E74756D2074656C6C75732073656420656E696D20696E74657264756D20626C616E6469742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E746567657220756C7472696369657320616C6971756574206F64696F2E204D61757269732065676574206E756E63206120697073756D20756C74726963657320736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2041656E65616E20616363756D73616E2E20446F6E65632073617069656E206C65637475732C20636F6E6775652061742C20706F7274612069642C2068656E6472657269742076697461652C206E69736C2E204375726162697475722076656C207175616D2076656C206E6571756520616363756D73616E206C616F726565742E204D6F7262692073617069656E206573742C207072657469756D20696E2C20636F6E7365637465747565722061632C206D6F6C6C69732075742C206C696265726F2E20446F6E65632074696E636964756E742061646970697363696E67206D657475732E204E756E6320766573746962756C756D20656765737461732061756775652E20446F6E6563207363656C65726973717565206475692075742073656D2E2053757370656E64697373652076656C206D6574757320696420657374206D6F6C657374696520696163756C69732E0A0A566976616D75732070686172657472612C20656C6974206575206D616C65737561646120626C616E6469742C206469616D20746F72746F72206D6F6C6C6973206475692C207365642070756C76696E6172206D61737361206E756E63206574206D61676E612E2053656420706C61636572617420656C697420617563746F7220746F72746F722E204E756C6C6120616320657261742E2050656C6C656E74657371756520636F6E7365637465747565722C2064756920636F6E76616C6C69732074696E636964756E7420636F6E64696D656E74756D2C2073656D206F64696F20766F6C7574706174206C696265726F2C206E6F6E20656C656D656E74756D2066656C6973206E65717565206E6563206F64696F2E204D616563656E61732068656E6472657269742065726F73206964206469616D2E204D61757269732076656C207075727573206163206F72636920636F6E76616C6C697320636F6E76616C6C69732E205365642073697420616D6574206C616375732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652064696374756D20766172697573206C616375732E204D61757269732065676574206E69736C2E2053757370656E646973736520706C6163657261742C206E756C6C61206E6F6E206F726E617265206469676E697373696D2C206E69736C206469616D2073616769747469732074656C6C75732C20696E2073656D706572206E69736920646F6C6F72206174206E6962682E204475697320756C6C616D636F7270657220766976657272612066656C69732E20496E746567657220612074656C6C75732E2053757370656E64697373652065676574206E756E632E2041656E65616E206469616D206573742C20616363756D73616E2069642C20737573636970697420696E74657264756D2C206672696E67696C6C612076697461652C206A7573746F2E2050726F696E20706564652E204D616563656E6173206174206E6571756520696E206E6571756520766573746962756C756D20656C656966656E642E0A0A566573746962756C756D206E756C6C61206C6F72656D2C20706F72747469746F7220656765742C20657569736D6F642061632C20616C697175616D2061742C206E69736C2E204D616563656E6173206574206573742065676574206D6173736120766172697573206C6F626F727469732E20496E206D692E204475697320706F72747469746F72206665726D656E74756D2070757275732E20446F6E65632063757273757320696D70657264696574206C6967756C612E204D6F726269206574206C6967756C6120657420616E7465206D6F6C6573746965207665686963756C612E204D61757269732073656420646F6C6F722E2053656420696D706572646965742066656C69732075742073656D2E20536564207669746165206E6571756520656C656D656E74756D206C656F20617563746F72206665726D656E74756D2E2044756973206665756769617420756C6C616D636F7270657220657261742E2041656E65616E2070757275732E204D6F726269206665726D656E74756D20766573746962756C756D206573742E2050656C6C656E7465737175652076656E656E61746973206D61757269732E2050686173656C6C75732070756C76696E61722E20496E746567657220697073756D206C65637475732C20696163756C697320612C206C6163696E69612069642C20616363756D73616E2069642C20617263752E2050686173656C6C7573206174206573742E204675736365206E65717565207175616D2C20756C747269636965732069642C20696163756C69732076656C2C20646170696275732076697461652C206C616375732E20496E206C6F626F7274697320636F6E76616C6C697320616E74652E204E756C6C61206E756E632070757275732C2076756C70757461746520696E2C2068656E6472657269742065742C20626C616E6469742065742C206C6967756C612E0A0A50656C6C656E746573717565206C656F206D657475732C20736167697474697320696E2C206D6F6C65737469652076697461652C2064696374756D20696E2C20706564652E204D6F726269207072657469756D2066656C6973206E6563207175616D2E2050656C6C656E746573717565206D617474697320616E746520736564207175616D20736167697474697320646170696275732E2053757370656E64697373652073617069656E2E205072616573656E7420626962656E64756D20696163756C697320746F72746F722E20447569732061206E69736C2E2041656E65616E206D692E20446F6E65632064696374756D206172637520696E206573742E204D6F72626920696E74657264756D2076756C70757461746520697073756D2E2041656E65616E2073697420616D6574206D61676E61206E6F6E206E69736C2074726973746971756520706F73756572652E2050686173656C6C75732076656C6974206D657475732C2074656D706F722061632C206665726D656E74756D20656765742C20636F6E64696D656E74756D206E6F6E2C2076656C69742E20566573746962756C756D2073697420706F73756572652E0A0A4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204372617320616C6971756574206D61737361206E6563206475692E20437261732061726375206E756E632C2068656E6472657269742061632C20656C656966656E642065752C20756C6C616D636F72706572206E65632C2074656C6C75732E205365642070686172657472612070757275732073697420616D6574207175616D2E20437572616269747572206D6F6C6C69732E204E616D20766974616520706564652E20457469616D207269737573206D617373612C207665686963756C612073697420616D65742C207068617265747261206E65632C20736F6C6C696369747564696E2075742C206475692E20446F6E65632065676573746173206A7573746F206174207175616D2E2050726F696E206E69736C2072697375732C20766573746962756C756D206E65632C207072657469756D2076697461652C207472697374697175652061632C206C6F72656D2E20416C697175616D206572617420766F6C75747061742E204372617320736564206E6962682E2050656C6C656E74657371756520736F6C6C696369747564696E20657569736D6F642061756775652E0A0A457469616D206672696E67696C6C6120736F6C6C696369747564696E206F7263692E204D61757269732063757273757320656C69742071756973206C616375732E204372617320746F72746F722E20496E2061646970697363696E672C206C656374757320696420617563746F7220766573746962756C756D2C206E65717565207065646520616363756D73616E20646F6C6F722C206E6F6E20696D70657264696574206D61676E61206469616D20616363756D73616E2076656C69742E2053757370656E6469737365206174206C696265726F207574206E69736920626C616E6469742073616769747469732E2050686173656C6C7573206E6F6E206D61757269732E20467573636520656C656D656E74756D2073616769747469732073656D2E2053757370656E646973736520616C697175616D20656C656966656E642074656C6C75732E2050726F696E206C6967756C61206C6F72656D2C20696D7065726469657420717569732C2076656E656E617469732069642C20696163756C6973206D6F6C6C69732C206E69736C2E20457469616D20636F6E76616C6C69732070656465206174206D617373612E204D6F72626920616363756D73616E20647569206574206D61757269732E0A0A53656420736564206F7263692E204E756E632070757275732E2053757370656E646973736520706F74656E74692E205574206C7563747573206672696E67696C6C61206D61757269732E20446F6E6563206E6962682E2050686173656C6C757320706F7274612E2050686173656C6C75732073697420616D6574206F64696F20736564206D61676E6120736F64616C65732070686172657472612E2043726173206C65637475732E2053757370656E6469737365206C696265726F20697073756D2C20636F6D6D6F646F206E65632C20666163696C6973697320696E2C207375736369706974206C6F626F727469732C206C6967756C612E2044756973206D61737361206E756C6C612C2073656D7065722065742C20636F6E736571756174206E65632C2070686172657472612065752C20656C69742E20566976616D757320756C7472696369657320616C697175616D206F64696F2E20566573746962756C756D2073697420616D6574206D617373612E2053656420636F6E736571756174206C61637573207365642075726E612E20457469616D2066617563696275732066656C69732076656C206F7263692E2050686173656C6C757320756C6C616D636F727065722E2041656E65616E20636F6E736563746574756572206C61637573206174206C696265726F2E0A0A436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204475697320666163696C697369732C206C6967756C6120766974616520636F6E64696D656E74756D207363656C657269737175652C2076656C6974206F72636920677261766964612066656C69732C2076656C20756C74726963696573207175616D206D69206E6F6E206469616D2E20566976616D757320617563746F72206D65747573206E6F6E206C696265726F2E205072616573656E74206C6967756C61206E6973692C20636F6D6D6F646F20636F6E64696D656E74756D2C206D6F6C65737469652065742C20766976657272612065742C206A7573746F2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320736F6C6C696369747564696E2E204E756E6320626C616E6469742063757273757320697073756D2E2041656E65616E206E6563206C6967756C612075742074656C6C757320736F64616C6573206D61747469732E20496E74656765722073656D2E20416C697175616D206964206C6967756C612E2053656420746F72746F72206D61757269732C20626C616E6469742076697461652C206375727375732076656C2C20656C656D656E74756D2065742C206E756C6C612E20416C697175616D207363656C65726973717565206D65747573206574206E69736C2E20447569732061646970697363696E67206D61676E61206174206E657175652E20517569737175652076756C70757461746520656C656966656E64206E756E632E20416C697175616D206567657420656C69742E2050686173656C6C757320647569206F64696F2C20626962656E64756D2073616769747469732C20766573746962756C756D2069642C206469676E697373696D20696D706572646965742C206F7263692E204E756C6C616D2065752066656C6973206E6F6E206E756E63206C6163696E696120736F64616C65732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A53757370656E64697373652070656C6C656E7465737175652C206C696265726F206D617474697320756C7472696369657320616363756D73616E2C20746F72746F7220746F72746F72206D616C6573756164612073656D2C20657420736F64616C6573206C696265726F206F64696F20616320697073756D2E20566976616D75732071756973206D61676E61206E656320657374207375736369706974206C6F626F727469732E20437261732074656D70757320706F7375657265206E756E632E205175697371756520757420656E696D20612066656C697320656765737461732073656D7065722E20536564207068617265747261206D6174746973206E657175652E20467573636520747572706973206E756E632C20636F6E677565207365642C20636F6E736571756174206E6F6E2C20636F6E677565207365642C206E756C6C612E2053757370656E646973736520766172697573206C6F72656D20696420726973757320706F72746120766573746962756C756D2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204675736365207365642070757275732E20496E20612066656C69732E20496E7465676572206567657374617320617563746F72206F7263692E204D617572697320756C747269636573207375736369706974206E69736C2E204E756C6C616D2070757275732E0A0A437261732074656D706F722061646970697363696E6720697073756D2E2055742071756973206D692E204D616563656E617320696E206A7573746F207574206E756C6C6120636F6E6775652070686172657472612E2050656C6C656E746573717565207574206C696265726F20657520646F6C6F722076656E656E617469732073757363697069742E205072616573656E74206665756769617420636F6E736563746574756572206E6962682E204D6F7262692066617563696275732073656D206E6F6E2066656C69732E20496E2068656E6472657269742061726375206163206D617373612E20496E20616363756D73616E20756C747269636573206D692E2050726F696E206D616C65737561646120617563746F722066656C69732E2043757261626974757220696E74657264756D2E20536564206469616D20697073756D2C20756C7472696369657320696E2C2074656D706F722073697420616D65742C207669766572726120696D706572646965742C20656C69742E204D6F726269206D6F6C6573746965206E6973692E204D617572697320697073756D2E2046757363652064696374756D206D6F6C6C6973206D61676E612E204475697320636F6D6D6F646F206469676E697373696D206E756C6C612E20566573746962756C756D20617567756520656E696D2C20756C7472696369657320717569732C20696163756C6973206E65632C2074696E636964756E742076697461652C206469616D2E204D6175726973206C6163696E69612074656D70757320697073756D2E20536564206174206D61757269732E205574206C6F72656D2E20446F6E6563206C696265726F2E0A0A4475697320696163756C6973206C6163696E6961206C65637475732E2041656E65616E20636F6E76616C6C69732065726F7320616320616E74652E205365642071756973206F726369206E656320726973757320617563746F72206672696E67696C6C612E2050686173656C6C757320666163696C6973697320656C656D656E74756D206E6973692E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E6320706F727461206C61637573206E656320616E74652E204D6F726269206D617572697320657261742C2061646970697363696E6720696E2C2070756C76696E6172206E65632C206C6F626F72746973206E65632C206F64696F2E20557420656C656966656E64206C656374757320736564207175616D2E204E756C6C616D206D6F6C6C69732E20496E206E6F6E20747572706973206574206E69736C2068656E64726572697420626C616E6469742E204475697320656C656D656E74756D2E204E756E63206E6563206C696265726F2E2053757370656E646973736520766573746962756C756D207269737573206E6F6E20706564652E204D6F72626920696D70657264696574206F64696F2073697420616D6574206C696265726F2E2053656420736564206D6173736120766974616520697073756D206D61747469732074696E636964756E742E204E756C6C61206E656320746F72746F72207669746165206C696265726F20766F6C75747061742074656D7075732E20446F6E656320616C697175616D2E0A0A4475697320736564206E756E632E2043757261626974757220747572706973206E756C6C612C207665686963756C61207365642C206C756374757320717569732C20656C656D656E74756D20656765742C2066656C69732E204D616563656E61732065742070757275732E204D616563656E6173206C656F2074656C6C75732C2074696E636964756E7420612C20666163696C697369732076697461652C206C6F626F727469732073697420616D65742C2076656C69742E20446F6E656320636F6E76616C6C69732073617069656E2E204D616563656E6173206D6F6C6C6973206F64696F206575206E6962682E20457469616D20677261766964612E20496E7465676572206D6F6C65737469652C2073617069656E206575206D6F6C6573746965206C6163696E69612C206E756E63206E69626820616C697175616D206C6967756C612C2065752073616769747469732074656C6C7573206572617420736F6C6C696369747564696E206F64696F2E20447569732065742072697375732E2050686173656C6C7573206E697369206E657175652C20706C616365726174206E65632C20636F6E64696D656E74756D206E6F6E2C20756C7472696365732065752C2073656D2E20557420706564652E20457469616D206E756C6C61206D657475732C20766F6C75747061742069642C20636F6E76616C6C6973207365642C2073757363697069742076656C2C2075726E612E20446F6E65632076656C20656C69742E205574206C656F206E657175652C2076656E656E617469732066617563696275732C206C6163696E6961206E65632C2074696E636964756E742065752C20656E696D2E2043726173206964206475692061206C696265726F207068617265747261206469676E697373696D2E20446F6E65632065726F73206C656F2C20706F72746120717569732C206C616F726565742075742C2070656C6C656E74657371756520766F6C75747061742C206C65637475732E0A0A4E756C6C616D20626C616E6469742E20416C697175616D206572617420766F6C75747061742E2046757363652061646970697363696E6720656E696D2E2053757370656E6469737365206E6F6E206475692071756973206C6967756C6120706F72746120766573746962756C756D2E20446F6E65632065752074656C6C75732076656C206C6F72656D207072657469756D20706F72747469746F722E205072616573656E74206C75637475732E20416C697175616D2061632065726F7320696E206D6173736120646170696275732074696E636964756E742E20446F6E6563207574206D61676E612E20457469616D20617563746F72206C616375732073697420616D6574206C616375732E2053656420756C7472696369657320697073756D206E656320656C69742E205175697371756520612065737420696E207075727573207375736369706974207472697374697175652E0A0A41656E65616E20736564206475692076656C20646F6C6F722070756C76696E6172206C616F726565742E20566976616D7573207665686963756C61206C6F72656D20696E20706564652E20566976616D7573206574206469616D2E20496E7465676572206163206F64696F2076656C206469616D2068656E64726572697420626962656E64756D2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E756C6C612061206E6973692E2050686173656C6C75732074696E636964756E74206475692076697461652061756775652E20447569732066617563696275732C2064756920696E74657264756D206672696E67696C6C612074696E636964756E742C206F64696F20656C697420766573746962756C756D206C696265726F2C206163206D6F6C6573746965206D61676E61206C6563747573206964206C616375732E2041656E65616E206C6967756C612E204E756C6C6120666163696C6973692E0A0A46757363652076656C2073656D2065752076656C6974206672696E67696C6C61206F726E6172652E2053656420666575676961742074696E636964756E742066656C69732E204E756C6C616D2066656C6973206D692C20657569736D6F642073697420616D65742C206D6F6C6C69732061742C20736F64616C657320656765742C2061756775652E204E616D20696D70657264696574206E6962682061742076656C69742E2053656420757420657261742E20496E206475692E204E756C6C6120666163696C6973692E204E756C6C616D206175677565206C696265726F2C2074696E636964756E74206E65632C207072657469756D2065752C2070756C76696E617220696E2C206475692E204D6F7262692076697461652066656C69732E2050656C6C656E7465737175652076656C206A7573746F2076656C2076656C6974207361676974746973206D616C6573756164612E2050726F696E207665686963756C6120626C616E646974206D617373612E20457469616D2074696E636964756E742070686172657472612075726E612E20496E206D65747573206573742C20617563746F72206E65632C20626C616E64697420612C20637572737573206E65632C207175616D2E204D6175726973206163206D657475732061206C696265726F20636F6E6775652066617563696275732E204D6175726973206D617572697320646F6C6F722C20736F64616C657320696E2C206375727375732075742C20736F64616C65732072757472756D2C2065726F732E2051756973717565206D61757269732065726F732C2073616769747469732076697461652C206C6F626F727469732075742C20656C656966656E642069642C206E6973692E0A0A41656E65616E206E657175652E20566573746962756C756D20656765737461732070656C6C656E746573717565206C6967756C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2050686173656C6C7573207361676974746973206A7573746F2076656C2072697375732E20536564207072657469756D206E657175652076697461652075726E612E2050656C6C656E74657371756520636F6E677565206C696265726F206964206C6F72656D2E204D6175726973206C656F206C6F72656D2C20626C616E6469742073697420616D65742C20636F6E76616C6C697320717569732C20636F6E736563746574756572207365642C2065726F732E204D61757269732074696E636964756E742C20656E696D2061206772617669646120657569736D6F642C206D61676E61206E756C6C61206665726D656E74756D206C696265726F2C207669766572726120656765737461732076656C6974207175616D20657420746F72746F722E20566976616D757320616C6971756574206D61737361207669746165206A7573746F2E204E756C6C6120636F6E677565206C6163757320616320656C69742E0A0A50686173656C6C757320636F6D6D6F646F207175616D2076656C206C6967756C612E2050726F696E206E6F6E206D657475732061742065726F732070756C76696E6172206C75637475732E204D6175726973206469616D206C6F72656D2C20706F737565726520717569732C20677261766964612065742C2074696E636964756E74206E65632C206C6967756C612E20536564206469616D2E20416C697175616D20656C6974206C65637475732C2068656E6472657269742075742C20696D706572646965742073697420616D65742C207072657469756D2073697420616D65742C20697073756D2E204D6175726973207665686963756C61206E69736C20696E206475692E204375726162697475722065676574207175616D207574206D61676E6120656C656D656E74756D206665726D656E74756D2E204D6175726973207363656C657269737175652E2051756973717565206C616F726565742E20457469616D2074656D707573207475727069732E2050656C6C656E746573717565206175677565207175616D2C2068656E647265726974207365642C2074696E636964756E742061742C2070686172657472612061742C206E69736C2E20416C697175616D206C616375732E2053757370656E646973736520706F74656E74692E2041656E65616E2076656C6974206C696265726F2C20756C74726963657320696E2C206C6163696E69612065752C206C75637475732076656C2C20616E74652E20457469616D2064696374756D206D6920696E2066656C69732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20467573636520677261766964612064617069627573206E69736C2E2043726173207669746165206E69736C2E0A0A4D616563656E6173206469676E697373696D2C206C6967756C61206E6F6E20706F727461206375727375732C20656E696D206E756E63206D616C6573756164612073656D2C20657520706F72747469746F72206E756C6C612075726E61206575207175616D2E2046757363652065726F732E20416C697175616D2065726F732E204E616D20617563746F722E204E756C6C61206D6F6C657374696520706F727461206573742E2053757370656E646973736520706F74656E74692E20566976616D7573206D6F6C6573746965206C6F72656D2073656420657261742E20536564206567657420697073756D2E20496E746567657220616C697175616D2070756C76696E6172206E756C6C612E204372617320616C69717565742073656D207574206E756E632E2046757363652066617563696275732074656D707573206C65637475732E204372617320736F64616C65732C206E69736920616320666163696C6973697320756C7472696365732C2065726F73206172637520646170696275732073617069656E2C20657420756C747269636573206D61757269732074656C6C7573206E6F6E20646F6C6F722E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20437261732063757273757320766172697573206D657475732E205574207475727069732E20566976616D7573206567657420746F72746F722E0A0A536564206C616F726565742C2076656C6974206E6F6E20616363756D73616E206375727375732C206E756E632075726E6120706F7375657265206A7573746F2C20696E2064696374756D206C6563747573207065646520696420616E74652E20437261732076756C7075746174652E204372617320636F6E677565206475692073656420656C69742E2050726F696E206C616375732073656D2C20756C7472696365732061742C20636F6E73657175617420696E2C2074656D706F7220717569732C206D657475732E2050726F696E2076656C20617263752E204E616D20657569736D6F642068656E64726572697420656C69742E20557420657261742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2053656420706F73756572652E204D6F7262692065726F732075726E612C2073656D7065722061742C2073656D706572206E6F6E2C20636F6E76616C6C697320717569732C2076656C69742E204D616563656E6173206F7263692E20566573746962756C756D206C6F626F7274697320747269737469717565206D657475732E20566573746962756C756D206C6F72656D206E756C6C612C20736F6C6C696369747564696E2076697461652C20636F6E64696D656E74756D20717569732C20617563746F722075742C206475692E20566976616D757320766573746962756C756D206D61676E61207574206E6973692E2043757261626974757220656C656966656E64206475692076656C206E756E632E20437572616269747572206D6175726973206C616375732C206D616C6573756164612073697420616D65742C207375736369706974207365642C2072757472756D206C75637475732C2074656C6C75732E20496E746567657220666163696C697369732075726E61207669746165206C65637475732E0A0A41656E65616E207175616D206C656F2C206C6F626F7274697320717569732C206D616C6573756164612065752C2076756C7075746174652076697461652C206E69736C2E205072616573656E7420656765742065726F732E205574206665726D656E74756D20747572706973206964207175616D2E204E616D20746F72746F722E205072616573656E74206E6563206F7263692E204E756C6C6120626962656E64756D2061646970697363696E672061756775652E20557420636F6D6D6F646F2C206D61676E61206964206D616C65737561646120677261766964612C206175677565206F64696F206D616C657375616461206D692C20706F727461206D616C65737561646120656C697420657374207669746165206469616D2E204D6175726973206E6F6E206E756C6C612E2053757370656E64697373652074696E636964756E742C206E756E6320756C7472696369657320706F7274612076656E656E617469732C206D6920706564652074696E636964756E74206C696265726F2C20656765742076617269757320616E7465206C696265726F207574206C6967756C612E20437572616269747572207072657469756D20706F72747469746F7220746F72746F722E0A0A4D616563656E617320766974616520656C69742065676574206E69736920646170696275732064696374756D2E204E756E6320696E206C696265726F2E204E756C6C612064696374756D206F726369206575206572617420617563746F72206C6F626F727469732E2050686173656C6C75732072697375732E2053757370656E646973736520706F74656E74692E2053757370656E646973736520706F74656E74692E205072616573656E742061646970697363696E6720636F6E73657175617420656C69742E20496E74656765722069642061756775652E205072616573656E7420696E206A7573746F206E6563206D61676E6120646170696275732070756C76696E61722E2044756973206E69736C2E2053757370656E6469737365206163206F64696F2E20566976616D757320696D706572646965742E20446F6E6563206E6F6E2076656C69742073697420616D6574207269737573206469676E697373696D20636F6E6775652E204E616D20616C697175657420706F73756572652076656C69742E2043726173207475727069732E204D6F726269206D616C657375616461206469676E697373696D206D692E0A0A536564206C656F206E657175652C2076617269757320717569732C2076656E656E61746973207365642C207068617265747261207365642C206573742E204D6F72626920626C616E6469742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D2073656D7065722070656C6C656E746573717565206D692E2055742076656C206C6F72656D2E204E756E63206D6920746F72746F722C206C616F726565742061742C2066617563696275732065752C2074696E636964756E742073697420616D65742C20657261742E20447569732074656D706F72206D616C65737561646120697073756D2E2050686173656C6C757320616C69717565742E20446F6E656320657420656C69742E2050656C6C656E7465737175652070757275732E20566573746962756C756D2072757472756D2073656D706572206E6962682E204E756C6C6120666163696C6973692E2050686173656C6C757320657420656E696D2073697420616D657420616E746520766573746962756C756D207665686963756C612E2050686173656C6C7573206964206E69736C2E20446F6E6563206D6F6C6C6973206C656F2061742065726F732E204D61757269732070656C6C656E746573717565206E657175652061742070757275732E204D6F726269207175697320646F6C6F7220617420697073756D207363656C6572697371756520736F64616C65732E20457469616D20766F6C7574706174207475727069732061206D657475732E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206C6F72656D206C6F72656D2C20766573746962756C756D2061632C20657569736D6F6420656765742C20756C6C616D636F72706572206469676E697373696D2C2076656C69742E0A0A43756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204372617320756C7472696365732C206E6962682076656C20616C697175616D20766573746962756C756D2C2065726F7320656E696D2076656E656E61746973206475692C20696420696163756C697320656E696D206E756E632076656C206D617373612E204D6F72626920656C656966656E64206F726369206574206D617373612E20416C697175616D206572617420766F6C75747061742E204E756C6C61206D6F6C6C69732065676573746173207475727069732E20496E20736F64616C6573206E756E63206567657420746F72746F722E2053656420697073756D2065726F732C2074656D706F7220717569732C20616C69717565742076697461652C20696D70657264696574206E6F6E2C206C6F72656D2E2050656C6C656E746573717565207175697320656C6974206964206D69206C756374757320646170696275732E20536564206E756E6320617263752C2072686F6E637573206E65632C20636F6E76616C6C697320717569732C206375727375732061742C206E657175652E204D617572697320636F6E76616C6C697320707572757320617420657261742E2050656C6C656E74657371756520766573746962756C756D2E20566976616D7573206672696E67696C6C6120656C697420617420617263752E204E756C6C616D20616C697175657420656E696D206E656320617263752E204E616D20696420746F72746F722E204E756C6C612071756973206E756E632E20557420617263752E2053757370656E646973736520706F74656E74692E2050656C6C656E74657371756520756C6C616D636F72706572206C6967756C6120696420617263752E0A0A4E616D206E6F6E206C696265726F207669746165206E69736C207363656C65726973717565206672696E67696C6C612E20517569737175652076617269757320616E7465206964206D657475732072686F6E637573206672696E67696C6C612E204E756C6C6120666163696C6973692E205072616573656E7420656C656966656E6420706F72747469746F72206C6967756C612E20457469616D207175697320646F6C6F72206E6F6E20617567756520636F6D6D6F646F20617563746F722E20446F6E65632061206D692E20566573746962756C756D2074656D706F722E20446F6E65632066656C69732075726E612C20617563746F722061742C206375727375732064696374756D2C20677261766964612069642C20617263752E2041656E65616E2064696374756D206D616C65737561646120646F6C6F722E20566976616D7573206D61747469732E2050686173656C6C757320657520706564652E2046757363652061646970697363696E67206A7573746F206672696E67696C6C61206D657475732E20457469616D20616E74652E20496E7465676572206D6F6C6C6973206D617373612071756973206E756E632E20496E74656765722064696374756D206E65717565206C756374757320656E696D2E0A0A536564206575206C696265726F2E20496E74656765722074656D706F72206C6967756C6120696E2076656C69742E2055742074696E636964756E74206C6163696E69612073656D2E204E756C6C616D2076656C2072697375732E2053656420736F64616C657320616E7465206120646F6C6F722E204375726162697475722065726F732E2053656420736F64616C65732E20536564206E6F6E206D657475732E20566573746962756C756D20656C656D656E74756D20666175636962757320616E74652E204E756C6C612076656C206E6962682E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206E6563206C6F72656D20757420697073756D206C6163696E696120696163756C69732E204475697320657261742E20416C697175616D20657261742E204372617320696163756C69732E20496E206861632068616269746173736520706C617465612064696374756D73742E0A0A4E756C6C616D20616E74652E2043726173207669746165206573742E2050656C6C656E7465737175652076656C206D657475732061206C6967756C612064617069627573206D61747469732E2044756973206665756769617420616C69717565742066656C69732E20457469616D206964206E69736C207175697320657374206469676E697373696D20636F6E64696D656E74756D2E2053757370656E646973736520706F74656E74692E204D6F7262692076656C6974206C6F72656D2C206F726E61726520717569732C2070656C6C656E7465737175652076656C2C20706C61636572617420656765742C20746F72746F722E20566573746962756C756D2074696E636964756E74206D6F6C6573746965206C696265726F2E204E756C6C61206E756C6C6120656E696D2C206D616C6573756164612069642C20756C6C616D636F727065722076697461652C2064696374756D2061742C2070757275732E20446F6E6563206469676E697373696D206F64696F20757420656E696D2E2053757370656E6469737365206174206C65637475732E0A0A5072616573656E74206C6F626F727469732061756775652076656C206C65637475732E20557420696E206C6967756C612075742066656C697320636F6E6775652073757363697069742E2051756973717565206469676E697373696D20746F72746F72207574206D692E204675736365206D61676E61206E6973692C20656C656966656E642061632C206F726E6172652076656C2C20706F72747469746F722076697461652C207175616D2E20566573746962756C756D20736F64616C6573206A7573746F2071756973207475727069732E2046757363652075726E61206E6973692C2072686F6E63757320717569732C20636F6E64696D656E74756D2076656C2C2064696374756D2065752C206E756E632E20467573636520736564206E696268207669746165206F64696F20706F73756572652061646970697363696E672E2053656420706F72746120656C6974207175697320646F6C6F722E204E616D206C696265726F206E756C6C612C20617563746F72207365642C2074696E636964756E7420717569732C2066617563696275732073697420616D65742C206D692E2051756973717565206F7263692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E756C6C616D2069642073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632076656C2065726F732E0A0A566976616D7573206C7563747573206C6F626F72746973206C656F2E2053757370656E64697373652076656C20656C6974206120656E696D20756C6C616D636F7270657220706F73756572652E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20446F6E656320717569732070656465206D6174746973206C6563747573206D6F6C6C69732061646970697363696E672E2053656420616363756D73616E20706F737565726520657261742E205072616573656E7420657569736D6F642074696E636964756E742066656C69732E20446F6E6563206D692E20557420636F6D6D6F646F2061726375206C6163696E69612074656C6C75732E20416C697175616D2061206C696265726F2071756973206C65637475732073656D70657220766976657272612E20437572616269747572206C6163696E6961206D61757269732061742074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E756E632073697420616D6574206D61676E61206D6F6C6573746965206F726369207375736369706974206672696E67696C6C612E204675736365207072657469756D206D65747573206E6F6E2073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642068656E6472657269742E204E756C6C612066656C69732E2053757370656E646973736520706F74656E74692E20416C697175616D20626C616E64697420747269737469717565206E657175652E20437572616269747572207175697320657261742076656C206E756E6320616363756D73616E206D6F6C6C69732E0A0A447569732073616769747469732C2074656C6C757320757420616C697175616D206672696E67696C6C612C20646F6C6F72206D6920756C6C616D636F72706572206E69736C2C20757420747269737469717565207065646520656C697420736564206D61757269732E204375726162697475722069642066656C69732E20446F6E65632070756C76696E6172206C61637573206574206C65637475732E20416C697175616D2076756C7075746174652076756C707574617465206D657475732E20437572616269747572206D61676E612066656C69732C2061646970697363696E672061632C20616363756D73616E2076656C2C206D6F6C657374696520717569732C207175616D2E204D617572697320656C697420617263752C207072657469756D2076697461652C206D6F6C6C69732073697420616D65742C20736F6C6C696369747564696E2075742C206D692E20446F6E656320696D70657264696574206469676E697373696D206D692E204E756C6C616D2073697420616D657420746F72746F722E20416C697175616D206E65717565206E756C6C612C2076656E656E6174697320612C20706F72746120696E2C20706C6163657261742074656D7075732C206C616375732E205175697371756520766573746962756C756D20647569206574206C616375732E2050726F696E206469676E697373696D20636F6E7365637465747565722070757275732E20457469616D206772617669646120746F72746F7220696E206E756E632E2055742074656D706F722074726973746971756520746F72746F722E20536564206C616F726565742074696E636964756E74207175616D2E20566573746962756C756D20706F7274612074757270697320757420656C69742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20446F6E6563206E696268206475692C2066657567696174206E65632C206C616F726565742069642C206D616C65737561646120656765742C206E6973692E205574206E65717565206D617373612C207665686963756C612065752C20636F6D6D6F646F206E6F6E2C20756C747269636965732076697461652C2070757275732E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204D617572697320657569736D6F642C2066656C69732076656C2074656D706F7220616C69717565742C20746F72746F72206D6175726973206D616C657375616461206E756E632C2076656C206665726D656E74756D2073656D206469616D206964206475692E204E616D2072757472756D2073617069656E2065676574206F64696F2E20416C697175616D20736564206C696265726F206E6F6E206D692066617563696275732074656D7075732E2046757363652068656E6472657269742C206469616D206E6F6E20766F6C75747061742072757472756D2C2065726174206D657475732076656E656E61746973206C6967756C612C206E6F6E207363656C657269737175652070656465206C6967756C612076656C207175616D2E204D6F7262692072686F6E6375732065726F7320616320647569206665756769617420656C656D656E74756D2E2044756973206575206C696265726F2065742074656C6C757320636F6E67756520766976657272612E204D6F726269207175616D207175616D2C20656C656D656E74756D207365642C20756C6C616D636F7270657220696D706572646965742C20636F6D6D6F646F206E6F6E2C206F64696F2E204E616D20616C697175657420656765737461732075726E612E204D6175726973206F64696F2066656C69732C207661726975732065752C206C6163696E69612065752C20636F6E64696D656E74756D20612C206C65637475732E20536564206A7573746F206D617373612C2070756C76696E61722069642C2076617269757320612C20706F72747469746F72206E65632C206C696265726F2E20457469616D207661726975732E2043757261626974757220736F64616C65732C206F64696F20617420706F73756572652073656D7065722C2065726F73206E6962682074696E636964756E74206C65637475732C2076656C2072757472756D2073617069656E206E69736920696E206C6967756C612E2053757370656E6469737365206567657420617263752E2050686173656C6C757320696D70657264696574206573742061632073617069656E2E20446F6E6563206E756C6C6120746F72746F722C20706C6163657261742076656C2C2074656D70757320612C206C6F626F727469732076656C2C206E6962682E20416C697175616D20766172697573206E6973692E204E756C6C6120657420656E696D2E20467573636520636F6E76616C6C6973206C616F72656574206C616375732E0A0A50686173656C6C757320697073756D20646F6C6F722C206D6F6C657374696520717569732C20636F6E64696D656E74756D20696E2C20636F6D6D6F646F2065752C206469616D2E205175697371756520626962656E64756D206C6163696E6961206475692E204E756C6C616D20626C616E6469742076756C707574617465206F7263692E205574206C6163696E6961206D617373612076656C2061756775652E20416C697175616D20677261766964612C207175616D207175697320696D7065726469657420696D706572646965742C2074656C6C7573206469616D20706861726574726120657261742C206174207068617265747261206C61637573206E6962682065676573746173206D61676E612E204E756C6C61207361676974746973206C6F72656D207574206C6F72656D2E204475697320636F6E64696D656E74756D2C2064756920766974616520616C697175616D20706F73756572652C206469616D207175616D20636F6E76616C6C69732076656C69742C2075742067726176696461206C656F20697073756D206E6F6E2072697375732E205574206665726D656E74756D20736F6C6C696369747564696E20657261742E20446F6E6563207361676974746973207363656C657269737175652066656C69732E204E756E6320617263752E20457469616D2074656D7075732C206D61676E612073697420616D657420737573636970697420657569736D6F642C2065726F732073656D2072757472756D206475692C207669746165207361676974746973206E696268207075727573206E6F6E206C616375732E20536564206D6F6C6C69732061726375206567657420646F6C6F722E20446F6E6563206F726E6172652C20617263752073697420616D6574206665726D656E74756D2076756C7075746174652C20726973757320656E696D206665726D656E74756D206C696265726F2C2061206C6163696E696120646F6C6F72206D69206E6F6E2076656C69742E20457469616D206C6F626F72746973207075727573206120656C69742E204E756E63206E756C6C61206475692C206D617474697320717569732C20626962656E64756D20612C20756C7472696365732061632C2061756775652E20496E20616C697175616D207665686963756C61207475727069732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A496E7465676572206964206E69736C2E20517569737175652064696374756D20656C656D656E74756D206F64696F2E2041656E65616E206C75637475732E205365642065752073656D206120706564652076756C70757461746520636F6E64696D656E74756D2E2051756973717565206D61676E612E20446F6E656320616C697175616D206D617474697320697073756D2E204375726162697475722064696374756D20736F6C6C696369747564696E2073656D2E20416C697175616D2070756C76696E61722E204E756E6320736F6C6C696369747564696E207269737573206120657261742E20566976616D757320717569732074656C6C75732073697420616D6574206E69626820766573746962756C756D20636F6E7365717561742E204E756C6C61207072657469756D20736F6C6C696369747564696E20646F6C6F722E20416C697175616D20696163756C69732074696E636964756E74207475727069732E2050686173656C6C757320697073756D206C656F2C2076656E656E6174697320696E2C20736167697474697320696E2C206F726E6172652061742C206E756E632E0A0A50656C6C656E74657371756520756C7472696365732C2064756920657520696163756C6973206C75637475732C2074656C6C757320617567756520766F6C75747061742073617069656E2C20696E206469676E697373696D2075726E612066656C6973207574206D692E205365642061726375206475692C206469676E697373696D2069642C20706F72747469746F722075742C20696D706572646965742076697461652C20616E74652E204E756C6C61206475692073656D2C20636F6D6D6F646F206E65632C2073616769747469732065742C206C6163696E69612065742C20706564652E20457469616D20656C656966656E6420647569207574206E69736C2E20446F6E656320616E7465206D61757269732C2074656D7075732073697420616D65742C207661726975732076697461652C206772617669646120717569732C206D692E20496E207363656C657269737175652C2066656C697320766974616520766976657272612073616769747469732C2076656C6974206D6574757320756C74726963696573206E657175652C207175697320696D706572646965742076656C697420656C6974206574206D61676E612E2053757370656E646973736520706F74656E74692E205365642076656C69742065726F732C20657569736D6F64207365642C20636F6E64696D656E74756D206E65632C206661756369627573207365642C2073617069656E2E204E616D20616363756D73616E206C6967756C612073697420616D6574206E657175652E20416C697175616D206572617420766F6C75747061742E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E616D20657520706564652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642065752066656C69732073656420746F72746F722074656D706F72206665726D656E74756D2E2050686173656C6C757320636F6D6D6F646F2073656D2076656C206E69736C2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050726F696E206C656374757320656C69742C2070686172657472612073697420616D65742C20616363756D73616E207365642C2074696E636964756E742065742C206D61757269732E204475697320646170696275732070686172657472612073656D2E20496E746567657220696E206A7573746F2E205072616573656E742065726F732E20566573746962756C756D20616320616E74652E20416C697175616D207363656C657269737175652073656D2070656C6C656E746573717565206E69626820636F6E73656374657475657220736F64616C65732E20416C697175616D20636F6E736563746574756572206F64696F2E2044756973206C6563747573206F64696F2C206C75637475732065752C20636F6D6D6F646F20717569732C206D6F6C6C69732076697461652C2076656C69742E2043726173206E6563206E756E63206E6F6E20656C697420696163756C6973206D61747469732E2041656E65616E206A7573746F206E657175652C20736F6C6C696369747564696E20656765742C20756C6C616D636F7270657220656765742C20656765737461732069642C2073656D2E20496E2065752072697375732E2053656420656765737461732E0A0A496E7465676572206174206E657175652E20536564207072657469756D207363656C65726973717565206E756C6C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20467573636520757420706564652E20457469616D207669746165207175616D20612075726E612076617269757320696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2044756973207665686963756C612E20467573636520756C6C616D636F72706572206E696268206E6F6E20657261742E205175697371756520696E206E657175652E205072616573656E74206573742E2050656C6C656E74657371756520617263752E0A0A50726F696E20706F73756572652E2053757370656E646973736520706F74656E74692E20496E74656765722066656C6973206C616375732C20616C697175616D207365642C2076756C70757461746520696E2C206D6F6C6C69732076656C2C2074656C6C75732E20496E7465676572207665686963756C6120626962656E64756D206573742E204E756E63206E6F6E20646F6C6F7220696E2074656C6C7573206D617474697320666163696C697369732E20496E746567657220766573746962756C756D2C20617567756520617420636F6D6D6F646F20616C697175616D2C2064756920657374206D6174746973206C6967756C612C2073697420616D65742061646970697363696E67206F7263692073656D207669746165206D61676E612E205072616573656E7420656E696D2076656C69742C206D616C6573756164612061742C20636F6E677565206E65632C206C756374757320696E2C206A7573746F2E20536564207661726975732E204D6F7262692070686172657472612E20446F6E6563206575206D61737361206E65632074656C6C75732076756C7075746174652070756C76696E61722E20557420636F6D6D6F646F20747572706973206E6F6E2073656D2E20557420636F6E76616C6C697320756C6C616D636F727065722072697375732E20457469616D20696E74657264756D2070656465206964206E6973692E2043726173206D61676E612073617069656E2C20737573636970697420612C206C616F72656574206E6F6E2C2072686F6E6375732065742C2066656C69732E20496E7465676572206F726369206C6F72656D2C20766573746962756C756D2064696374756D2C20756C6C616D636F7270657220612C20706F72747469746F722065742C206475692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A4E756E63206574206D61676E612E2053656420626962656E64756D2074656C6C757320696E206469616D2E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E616D20766974616520746F72746F722E20496E7465676572206D61676E612E20447569732076656E656E617469732C206C656F2061632074656D706F72206C616F726565742C20656C6974206E756C6C6120706861726574726120706564652C206E6F6E206665726D656E74756D206E756E63206F64696F2061206F64696F2E2050726F696E206E6F6E2076656C69742E2053656420696D706572646965742061756775652071756973206E69736C2E20496E746567657220636F6E64696D656E74756D206E69736C206E6563206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20566976616D757320706C616365726174206C696265726F2E204475697320636F6E6775652064696374756D206D61676E612E20416C697175616D206461706962757320626962656E64756D20656E696D2E204E756E6320656C656966656E6420706564652076656C20697073756D2E0A0A457469616D2076697461652076656C69742E204D61757269732065726174206E756E632C206D616C6573756164612075742C20666575676961742061632C20706C61636572617420636F6E64696D656E74756D2C2061756775652E204E616D20766F6C75747061742E20416C697175616D207665686963756C6120697073756D206964206F64696F2E20566976616D757320736F6C6C696369747564696E207475727069732069642073617069656E2E20467573636520612066656C6973207669746165206F64696F20636F6E76616C6C697320626C616E6469742E204375726162697475722076697461652065726F732069642065726F7320706F727461207072657469756D2E204E756C6C6120696E206D61676E6120656765742075726E61206C6163696E696120636F6E76616C6C69732E20416C697175616D206D61747469732076656E656E617469732070757275732E2053656420736564206D69206567657420657261742074726973746971756520706F7274612E20446F6E656320617563746F7220646F6C6F72206120657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20496E206E6563206C6967756C612E204E756E6320656C656966656E642E20566573746962756C756D2071756973206E697369206567657420656C697420706F72747469746F7220636F6E6775652E204D616563656E61732066617563696275732C206D61676E6120656765742061646970697363696E672074696E636964756E742C20646F6C6F7220616E7465206D616C65737561646120656C69742C206E6F6E20656C656D656E74756D206C616375732074757270697320696E20706564652E0A0A5574206D616C657375616461206D69206E6563206D657475732E205072616573656E7420617563746F72206175677565206163206E69736C20756C7472696369657320666163696C697369732E204E616D2070757275732073617069656E2C2070656C6C656E746573717565206469676E697373696D2C20706F73756572652065752C206375727375732069642C206469616D2E205175697371756520736F6C6C696369747564696E2C20656C697420612070656C6C656E746573717565207363656C657269737175652C206C6F72656D20726973757320617563746F72207175616D2C207175697320636F6E7365717561742074656C6C7573206E657175652069642075726E612E2053757370656E6469737365206469616D20746F72746F722C20656C656966656E64206469676E697373696D2C20656765737461732075742C206C756374757320696E2C20616E74652E204475697320616E74652E204D616563656E6173206C75637475732E20437572616269747572206375727375732070686172657472612075726E612E204D616563656E617320696D706572646965742C2065726174206E6F6E20656C656D656E74756D20657569736D6F642C20746F72746F72206F64696F20657569736D6F64206C65637475732C20616320666163696C697369732073656D206E696268207669746165206E756C6C612E204E756E6320677261766964612E204D6F72626920736F6C6C696369747564696E206F64696F2071756973206C616375732E20416C697175616D2061206E696268206E6F6E2075726E6120706F72746120696D706572646965742E20416C697175616D206572617420766F6C75747061742E20496E20696163756C6973206C6163696E69612076656C69742E20536564206C696265726F206C616375732C207472697374697175652065752C206C6163696E69612061632C20616C697175657420656765742C2075726E612E0A0A457469616D206174206E69736C2E2050686173656C6C7573206661756369627573206C7563747573206C65637475732E20557420706C6163657261742076756C70757461746520646F6C6F722E2050686173656C6C75732076656C2076656C69742E204D6F72626920766976657272612E2050686173656C6C7573206F7263692E20496E7465676572206469676E697373696D206D6174746973206D61757269732E2050656C6C656E74657371756520706F7375657265206C656F20706F7375657265207175616D2E2051756973717565206E6563206D61676E61206174206469616D20766976657272612070656C6C656E7465737175652E2053757370656E64697373652076656C697420617263752C20756C7472696369657320717569732C20636F6E67756520612C2076656E656E6174697320656765742C206C616375732E20496E74656765722073616769747469732068656E64726572697420646F6C6F722E2046757363652074696E636964756E7420616E746520612073656D2E0A0A4D616563656E617320636F6E7365637465747565722C206A7573746F207365642072686F6E6375732076656E656E617469732C206E69626820617263752072757472756D20646F6C6F722C2073656420636F6E64696D656E74756D206C696265726F206C696265726F20657420697073756D2E20566976616D7573206D6174746973206A7573746F207574206C6F72656D2074696E636964756E74206C6F626F727469732E205574206E6F6E2076656C6974206964206E6571756520616C697175657420616363756D73616E2E205365642074656D7075732076697665727261206E756C6C612E2043757261626974757220756C6C616D636F727065722C206E6571756520717569732064617069627573207363656C657269737175652C2066656C6973206469616D2067726176696461206F7263692C206E6F6E20637572737573207175616D206E6571756520766974616520656C69742E20457469616D2070686172657472612074696E636964756E74206C616375732E204475697320657569736D6F64206672696E67696C6C61206573742E20457469616D206F726E6172652074696E636964756E74206C65637475732E2050726F696E20696E207475727069732E204E756E6320626C616E64697420626C616E646974207475727069732E2041656E65616E2075742061756775652E2044756973206F726369206A7573746F2C2074696E636964756E742065752C2072757472756D207365642C2072757472756D2065742C207475727069732E2043757261626974757220666163696C69736973206F64696F20696E20616E74652E20496E206861632068616269746173736520706C617465612064696374756D73742E205365642065726F73206573742C2070656C6C656E7465737175652061742C2074696E636964756E742065752C20756C74726963657320717569732C206D657475732E204D6F7262692073697420616D6574206A7573746F2E204D616563656E617320616320617263752E204D6175726973206469676E697373696D2E0A0A50656C6C656E74657371756520756C747269636965732072757472756D206F7263692E2041656E65616E206F726E6172652E20566976616D75732065752072697375732076656C206D6175726973206C6F626F727469732064696374756D2E205365642065742074757270697320617563746F72206D692072686F6E6375732070756C76696E61722E20536564206E6563206E756E6320612070757275732074656D706F7220766976657272612E2050656C6C656E7465737175652073757363697069742E20446F6E656320747269737469717565207269737573206E6F6E206E6962682E20457469616D206E69736C206D61676E612C20736F6C6C696369747564696E2075742C20756C7472696365732073697420616D65742C20656765737461732065752C206E756C6C612E20416C697175616D206572617420766F6C75747061742E20566573746962756C756D2070686172657472612E2053656420656765737461732C206D657475732073697420616D6574206C6F626F7274697320636F6E7365717561742C206572617420656C697420696D70657264696574206C696265726F2C20657520696E74657264756D207175616D206D61737361206567657420646F6C6F722E2053757370656E6469737365207669746165206F64696F2E2050726F696E20626C616E646974206D617572697320696163756C6973206D657475732E0A0A566976616D757320766573746962756C756D2E20457469616D206574206E69736C2E20416C697175616D20696E206469616D2076656C20656C697420706C6163657261742073757363697069742E204475697320736F64616C6573207075727573206163206E6962682E204E756C6C6120696E206F64696F206567657420656E696D206C756374757320626C616E6469742E2043757261626974757220756C74726963657320697073756D206E6F6E206E65717565206567657374617320656C656966656E642E20536564207475727069732E2050726F696E20636F6E7365637465747565722E20566976616D7573206D61747469732E20496E20616C69717565742E0A0A4E756E632069642065726F732E20446F6E65632076656E656E617469732C206E756C6C61206574206D6174746973206C75637475732C20616E7465206C656F2073656D706572206A7573746F2C206E6F6E2061646970697363696E67206F64696F20726973757320736564206C616375732E205072616573656E7420766974616520726973757320636F6E677565206C696265726F20636F6E6775652074656D7075732E2050686173656C6C75732061632065726F732E204E756C6C61207665686963756C612C206C6F72656D20696E20616C69717565742073757363697069742C2061726375206572617420656765737461732073656D2C2071756973206C6F626F72746973207175616D20616E7465206575206D617373612E20437572616269747572206E6F6E206D617373612E2053656420626962656E64756D206C6163696E6961206F64696F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20566976616D757320766F6C757470617420626C616E646974206C616375732E2050726F696E20706F7274612C2074656C6C757320757420617563746F72206C616F726565742C206C65637475732065726F73206665726D656E74756D206C65637475732C2069642073616769747469732061726375206A7573746F20696E207475727069732E2050686173656C6C757320636F6E7365717561742E204E616D2070656C6C656E7465737175652C206D69206964207669766572726120636F6E76616C6C69732C206E756E63206C696265726F20706C616365726174206C656F2C20656C656966656E6420706F7274612073656D206E69736C2076697461652073617069656E2E2050656C6C656E746573717565206C6967756C61206C696265726F2C20747269737469717565206E6F6E2C20706F72747469746F722072757472756D2C20706F72747469746F72206E6F6E2C20657261742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E74656765722064696374756D2074656C6C7573206120746F72746F722E20566976616D75732066656C6973206E756E632C206D6F6C6573746965206E6F6E2C2072686F6E63757320717569732C2070686172657472612069642C206475692E20446F6E6563207269737573206D657475732C206672696E67696C6C612076656C2C20616C69717565742065752C20706C6163657261742069642C206E657175652E0A0A53757370656E646973736520697073756D2E20566976616D7573206C65637475732E2053656420766976657272612C206D61737361206567657420636F6E76616C6C6973206D61747469732C207175616D2074757270697320636F6E736563746574756572206E756E632C206567657420706F7375657265206D61676E612073656D2069642076656C69742E20496E206E6563206D61757269732E2041656E65616E206120707572757320736564207175616D206C6F626F72746973206672696E67696C6C612E2050726F696E20756C74726963696573206C6163696E696120616E74652E205365642061646970697363696E67206572617420717569732076656C69742E204E756C6C616D207669746165206E69736C206964206A7573746F20736F6C6C696369747564696E206D6F6C65737469652E204E756C6C6120666163696C6973692E20536564206E65632075726E6120736564206E69736C206672696E67696C6C6120646170696275732E204E756C6C61206174206469616D2E20416C697175616D2065676574206E6962682E204E756E63206163206E6973692073697420616D65742074656C6C757320656765737461732074656D7075732E204E616D207363656C657269737175652075726E61206574206E657175652E20446F6E656320657374206F7263692C207361676974746973206E6F6E2C2076756C70757461746520612C20636F6D6D6F646F2065742C2061756775652E205574206461706962757320746F72746F722E205574206E756E632E20446F6E65632064696374756D2064617069627573206F64696F2E204E616D20756C7472696369657320756C6C616D636F72706572206C6967756C612E2050656C6C656E74657371756520616363756D73616E20766172697573206C656F2E0A0A4D6F72626920657569736D6F64206C616F7265657420657261742E20566976616D7573207175697320697073756D2E204D6F72626920657569736D6F642E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2053757370656E64697373652076656C2070757275732E204E756C6C616D206174206D61676E612E20437572616269747572206C61637573206C6F72656D2C20696163756C697320717569732C2064617069627573206E6F6E2C20766F6C75747061742076656C2C206E756C6C612E20446F6E656320757420617263752072686F6E63757320646F6C6F72207072657469756D2064696374756D2E204E756C6C616D2076656C206D657475732E20557420617263752E2050656C6C656E746573717565206E697369206E756E632C20706C61636572617420656765742C2074696E636964756E742076656C2C207068617265747261206E6F6E2C206E756E632E20496E74656765722074696E636964756E7420756C74726963696573206C65637475732E20496E74656765722073656D7065722C2070757275732073656420756C74726963657320666575676961742C206E756C6C61207065646520736F6C6C696369747564696E20657261742C2076656C20617563746F72206E756C6C6120697073756D2076656C206C65637475732E2041656E65616E206D692E0A0A4E756C6C616D20736564206E697369206574206172637520696D70657264696574206665726D656E74756D2E204D6175726973206E6563206D657475732E20496E20616320646F6C6F722E20496E206D6920617263752C20636F6E6775652061632C207068617265747261206E65632C207363656C657269737175652073697420616D65742C206D61676E612E20437572616269747572206C616375732E2043757261626974757220657420656C69742E20416C697175616D20756C6C616D636F72706572206E756E6320657520656C69742E2053656420636F6E76616C6C697320646F6C6F722061742076656C69742E20566573746962756C756D20646170696275732C20617567756520696420636F6E73656374657475657220706C6163657261742C206E756E63206D6173736120626C616E6469742073617069656E2C20696420616C697175616D20656C6974206E697369206964206D692E2050686173656C6C75732073617069656E206573742C20677261766964612065752C20626962656E64756D2075742C2061646970697363696E6720717569732C206573742E205574206D6F6C6573746965207175616D207669746165206F64696F2E20446F6E65632071756973207269737573206964206572617420666175636962757320736F6C6C696369747564696E2E204E616D2069642066656C69732E204D61757269732073656420656E696D207669746165206C656F20616363756D73616E207072657469756D2E0A0A4E616D206A7573746F2E20446F6E656320747572706973206E69736C2C20636F6D6D6F646F2065742C20696E74657264756D2061632C20636F6E736563746574756572206E6F6E2C206D617373612E2046757363652073656D206D657475732C206C616F72656574206E65632C20706F73756572652069642C20696D7065726469657420696E2C2076656C69742E20446F6E65632076756C707574617465206A7573746F2065676574207475727069732E204E756C6C6120706564652E204D6F7262692074696E636964756E742E20467573636520616C69717565742C207175616D20657420616C697175616D206672696E67696C6C612C20616E746520616E746520696163756C6973206475692C206E656320616C697175616D20617263752070757275732073656420657261742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050686173656C6C7573207375736369706974207175616D206574206573742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B0A0A496E7465676572207365642074656C6C75732E20536564207365642076656C697420756C74726963696573206C656F2072757472756D206C616F726565742E20536564206E6F6E2065726F7320616320707572757320736167697474697320666575676961742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E205365642068656E647265726974206C6967756C612073697420616D6574206E6962682E204D616563656E6173207475727069732E204D6F72626920636F6E7365637465747565722C20646F6C6F722065742061646970697363696E6720696D706572646965742C20616E7465206E65717565206665756769617420646F6C6F722C20617420706F727461207175616D206E657175652071756973206C6967756C612E204D61757269732073656D7065722076656C69742073697420616D657420697073756D2E2050656C6C656E7465737175652074656D7075732C20707572757320696E2072757472756D20636F6E7365717561742C20656E696D2065726174207665686963756C61206D617373612C20696420616363756D73616E206C656F2073617069656E206E65632070757275732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E20646F6C6F722E20496E746567657220666163696C69736973206C696265726F2073697420616D657420706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2055742076617269757320616C697175657420656E696D2E204E756C6C6120666163696C6973692E2043757261626974757220636F6E7365637465747565722C206F64696F206575207072657469756D2074696E636964756E742C206E756E63206E69736920616C6971756574206E657175652C2076656C20696D7065726469657420656C6974206D617373612073697420616D6574207475727069732E2050656C6C656E7465737175652074656D7075732C206F72636920766F6C757470617420626C616E646974206672696E67696C6C612C206F64696F2073656D20706F737565726520616E74652C20766974616520626962656E64756D2075726E61206C6F72656D2076697461652065726F732E205072616573656E7420766976657272612072686F6E63757320617263752E2053656420617563746F722C206573742073697420616D6574206D6F6C6C6973206D6F6C6C69732C207175616D207175616D20677261766964612073617069656E2C20696E20636F6D6D6F646F206D65747573206E756C6C6120617563746F7220656E696D2E20446F6E656320666163696C697369732E0A0A50726F696E2074696E636964756E742C2073617069656E206567657420756C747269636965732061646970697363696E672C20657374206F64696F2064696374756D20617263752C207574206D6F6C6C69732065726174206475692073697420616D65742076656C69742E204D6F726269206573742073656D2C20696E74657264756D2061742C20636F6E67756520612C20656C656D656E74756D2076697461652C206D657475732E2053757370656E64697373652069642061756775652E204D617572697320656E696D2073656D2C2070756C76696E617220656765742C2074656D70757320612C2074656D7075732073697420616D65742C2073617069656E2E20467573636520766573746962756C756D20636F6E736563746574756572206475692E2050656C6C656E74657371756520657261742E20536564206469676E697373696D20706C616365726174206F64696F2E204D616563656E61732073656D7065722072686F6E637573206C65637475732E2050686173656C6C7573207072657469756D2E2044756973206C696265726F20656C69742C20656C656966656E64206E65632C20656765737461732075742C20637572737573207365642C2066656C69732E204E616D206E69736C20617263752C20616C69717565742065742C20666163696C697369732065752C206C75637475732075742C2072697375732E20457469616D20756C7472696365732C20646F6C6F722073656420766F6C7574706174206D616C6573756164612C20747572706973206172637520696D7065726469657420746F72746F722C20657569736D6F6420636F6D6D6F646F206C696265726F206D61737361207574207175616D2E20496E7465676572206D6F6C6573746965207075727573206E6F6E20656C69742E2055742076656E656E617469732073656D70657220746F72746F722E20457469616D20626962656E64756D206567657374617320697073756D2E204D617572697320736F6C6C696369747564696E2073656D206E6563206E6962682E204E756C6C61207072657469756D206D65747573206575206D657475732E2050656C6C656E7465737175652073697420616D65742073656D2E0A0A53757370656E6469737365206163206E6973692E205574206C656F2E20566573746962756C756D2068656E647265726974207072657469756D20646F6C6F722E204E756E632066657567696174206D616C6573756164612070757275732E2043726173206574206E6962682E20437572616269747572206E756E6320657261742C206D616C6573756164612076697461652C206C616F726565742061632C20756C7472696369657320696E2C2070757275732E20566976616D75732074656C6C757320617263752C20736F64616C65732065752C20666163696C6973697320612C206C6163696E6961206E65632C206E756E632E2050656C6C656E7465737175652069642076656C69742E20496E206575206E6962682E204E756E63206E656320657261742E205365642064696374756D206E65717565207574206E69736C2E0A0A4D6F726269206C65637475732074656C6C75732C2074696E636964756E742061632C20706F72747469746F722061632C2074726973746971756520696E2C2065726F732E20446F6E6563206C7563747573206C7563747573206C656F2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2046757363652075742065737420657420656E696D207363656C6572697371756520616363756D73616E2E20446F6E6563206C6967756C612066656C69732C206C6163696E696120717569732C2070656C6C656E74657371756520696E2C2073656D70657220766573746962756C756D2C20656C69742E204D61757269732065676574206F72636920612066656C697320636F6E677565207665686963756C612E20557420736F6C6C696369747564696E2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204E756C6C616D20696420646F6C6F72207574206C6F72656D206469676E697373696D2076656E656E617469732E2053757370656E64697373652076697461652073617069656E2E2050726F696E206E6F6E206D61676E612075742065726F7320766976657272612070756C76696E61722E20446F6E65632071756973206F64696F2E204E756C6C616D206E6F6E20617263752076656C206C6F72656D20737573636970697420616C697175616D2E20416C697175616D2072757472756D2074757270697320696E206C656F2E0A0A5574206C7563747573206E6962682074726973746971756520657261742E2053757370656E646973736520626962656E64756D206F64696F20766974616520746F72746F722E20446F6E6563206C6163696E69612E204372617320736F64616C65732066656C6973206C7563747573206E756C6C612E204E616D20656C656966656E64207361676974746973206C6967756C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E64697373652076656C206E657175652E204D6F72626920616C6971756574207665686963756C61206D61676E612E2041656E65616E206174206F64696F2E20447569732070656C6C656E746573717565206D61676E612E204E756C6C6120617420746F72746F72207574206469616D2064696374756D2066617563696275732E204D617572697320717569732076656C69742E20446F6E6563206E6F6E2074656C6C7573207669746165206C6F72656D206672696E67696C6C6120706F72747469746F722E2046757363652075742073617069656E207175697320746F72746F7220666575676961742073616769747469732E20446F6E656320766976657272612073656D2076697461652073617069656E2E205072616573656E7420736F64616C65732C206C6163757320696E206672696E67696C6C6120766976657272612C206F64696F2061756775652061646970697363696E672075726E612C20766974616520696E74657264756D20616E74652073656D206E6F6E206E6973692E204E756C6C616D20746F72746F72206C6F72656D2C20656C656966656E642061632C206D6F6C6C6973206E6F6E2C206C616F726565742061632C2072697375732E20496E7465676572206F726E617265206C656F20736564206A7573746F2E2051756973717565206375727375732C2073656D206E6F6E20666163696C6973697320626962656E64756D2C206E697369206D69207661726975732066656C69732C206665726D656E74756D2066657567696174206C6F72656D2065726F73206C616F726565742072697375732E0A0A517569737175652073697420616D657420657374206574206C6F72656D207665686963756C61206C6163696E69612E20446F6E6563206E656320746F72746F722E2043726173206F64696F2E204E616D207363656C657269737175652076756C7075746174652075726E612E205072616573656E74206475692E20457469616D206E6563206E69736C206C6F626F7274697320697073756D20616C69717565742074656D7075732E204D616563656E6173207072657469756D20736F6C6C696369747564696E206D61757269732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206175677565206D617373612C20636F6E67756520656765742C20636F6E76616C6C697320656765742C207472697374697175652073697420616D65742C2065726F732E2053656420636F6E736571756174206E6973692065752066656C69732E2050656C6C656E746573717565206A7573746F2E2053757370656E6469737365206E6F6E2061756775652E20496E206469676E697373696D206C6F626F72746973206D61757269732E204D61757269732073616769747469732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E0A0A5365642061646970697363696E672E20446F6E656320612074656C6C75732076697461652065737420637572737573207665686963756C612E204E616D20616E74652073656D2C20736F64616C65732069642C206672696E67696C6C612076656C2C20636F6E64696D656E74756D2076656C2C206E756C6C612E205175697371756520736F64616C65732E20457469616D20696D7065726469657420656C6974206964206F64696F2E20416C697175616D206572617420766F6C75747061742E204D616563656E617320706F7274612074656D706F7220617263752E204E756C6C612073656D2061756775652C2070656C6C656E7465737175652061632C20636F6E7365717561742075742C20636F6E64696D656E74756D20657569736D6F642C2072697375732E2053656420616C697175616D2074696E636964756E74206D692E20496E20696E74657264756D206C6F626F72746973206F7263692E0A0A536564207665686963756C612068656E6472657269742070757275732E20457469616D2061206469616D2E2043757261626974757220636F6E76616C6C69732E2053757370656E64697373652061206E6973692E20446F6E6563206964206D61676E6120696E207175616D20736F6C6C696369747564696E20756C747269636965732E20446F6E656320766976657272612E205175697371756520766F6C757470617420657374207365642073656D2E20416C697175616D206A7573746F2E20566573746962756C756D20746F72746F72206D617373612C20706F72747469746F72207365642C2076617269757320717569732C20696163756C697320717569732C206F64696F2E20416C697175616D2065676574206E657175652E0A0A4D6175726973206E756C6C612E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566573746962756C756D206575207175616D20696E206E6571756520756C7472696365732070656C6C656E7465737175652E204372617320696E20646F6C6F722071756973207175616D207661726975732068656E6472657269742E20416C697175616D206E697369206C616375732C206C6F626F727469732065752C20636F6E76616C6C69732073697420616D65742C20666163696C697369732075742C206D692E20416C697175616D206174206E657175652E204372617320736167697474697320656C656D656E74756D206A7573746F2E20566573746962756C756D207574206C656374757320616C6971756574207075727573206D616C65737561646120766F6C75747061742E2044756973206174206C616375732061646970697363696E67206C696265726F2074696E636964756E7420766573746962756C756D2E204D6F7262692061206C696265726F2E20437261732070757275732E204D6F72626920757420617567756520657420707572757320696E74657264756D207363656C657269737175652E20496E74656765722061206475692E20496E206861632068616269746173736520706C617465612064696374756D73742E2044756973207068617265747261206D657475732065676574206D61757269732E20416C697175616D20696E74657264756D20756C6C616D636F72706572206D617373612E0A0A457469616D206F726E6172652E204E756C6C616D20657569736D6F642E2041656E65616E20636F6E7365717561742067726176696461206C6967756C612E20416C697175616D206573742E2050726F696E207669746165206C616375732E205072616573656E7420612065726F732073697420616D657420647569206C756374757320636F6D6D6F646F2E2050686173656C6C7573207665686963756C612061726375206567657420646F6C6F722E205072616573656E74206665726D656E74756D20636F6E677565206C656F2E20416C697175616D20766F6C7574706174207075727573207574206C6F72656D2E2046757363652068656E64726572697420656E696D206174206C656F2E20416C697175616D2072686F6E637573206E69736C2E20566976616D75732064696374756D2065676573746173206D692E2053757370656E64697373652070656C6C656E74657371756520626962656E64756D20646F6C6F722E2050656C6C656E7465737175652074696E636964756E742C207475727069732073656D7065722070656C6C656E74657371756520636F6E64696D656E74756D2C20697073756D206D6574757320736F64616C6573206C6967756C612C20696420766F6C7574706174206469616D2074757270697320757420656C69742E0A0A5072616573656E7420736564206C616375732E204E616D20656C656966656E64206D6F6C6573746965206D61757269732E20446F6E65632064617069627573206665726D656E74756D206D617373612E20446F6E656320766976657272612066617563696275732070757275732E2043757261626974757220636F6E6775652C206C696265726F20766974616520766976657272612070656C6C656E7465737175652C206469616D2076656C697420736F64616C657320656E696D2C20736564207375736369706974206C6563747573206E697369206E6563206E657175652E20566573746962756C756D206D616C6573756164612C206C616375732061742063757273757320636F6E6775652C2076656C6974206C65637475732074726973746971756520646F6C6F722C2073697420616D657420736F64616C6573206E6571756520697073756D2061206C696265726F2E20566573746962756C756D206574207175616D2E2043757261626974757220706C6163657261742E20437572616269747572206E756E6320617263752C20657569736D6F64206E65632C2076756C7075746174652068656E6472657269742C20616C697175657420656765742C207175616D2E204375726162697475722076656C20656E696D2E2053757370656E646973736520706F74656E74692E0A0A4E756E6320636F6E736571756174206F726369207574206C616375732E2046757363652076656C697420646F6C6F722C2064617069627573207365642C20626C616E6469742073697420616D65742C2072686F6E6375732069642C2072697375732E20447569732075726E61206E6962682C207363656C6572697371756520717569732C206461706962757320612C207363656C65726973717565207365642C206E6962682E20446F6E6563206C75637475732E205574206575206D617572697320637572737573206469616D206C6163696E69612072686F6E6375732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20416C697175616D207665686963756C61206D6F6C6573746965206A7573746F2E204D616563656E617320696D70657264696574207065646520736564206D692E2053757370656E6469737365206E756C6C6120646F6C6F722C2068656E64726572697420656765742C2068656E6472657269742069642C2064696374756D2076656C2C206C656F2E204475697320616363756D73616E2E2043757261626974757220696E2066656C69732E204E756E63206C6F72656D2E205574206C656F20646F6C6F722C206C616F72656574206E65632C2076756C7075746174652061742C20656C656966656E6420696E2C206E756C6C612E2051756973717565206E756E632070757275732C2076617269757320656765742C20616363756D73616E206E65632C20616C69717565742065742C206E6962682E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20437261732061646970697363696E67207669766572726120646F6C6F722E204D617572697320706F72747469746F7220756C7472696365732070757275732E204E756C6C6120666163696C6973692E205072616573656E7420666175636962757320616E7465207669746165206D61757269732E0A0A5072616573656E74206C6163696E6961206C656374757320736564206E69736C2E20496E2074656D70757320636F6E677565206D61757269732E20496E746567657220666163696C69736973206F726E61726520656E696D2E204E756C6C61206964206D617373612E20446F6E656320636F6D6D6F646F206469616D2061742074656C6C75732E204E616D20646170696275732076697665727261206573742E204E616D2074656C6C75732E205072616573656E742061206C696265726F2E20496E206661756369627573206573742065676574206E6962682E204E756C6C612065726F73206F7263692C20696D70657264696574206E6F6E2C20626C616E646974206E6F6E2C2074656D706F7220656765742C206D692E2050656C6C656E74657371756520636F6E76616C6C69732E0A0A517569737175652065676574206D69206163206C656F20657569736D6F642066617563696275732E2050686173656C6C75732072686F6E637573207075727573206964206475692E20566573746962756C756D206D616C65737561646120656C656966656E6420616E74652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050656C6C656E74657371756520626C616E646974206D6174746973206F64696F2E2053757370656E646973736520636F6E7365717561742C206C65637475732061632073656D70657220736F6C6C696369747564696E2C206D692076656C69742064696374756D2061756775652C2061632074656D70757320646F6C6F7220657261742073697420616D6574206475692E2050726F696E2068656E6472657269742C2066656C6973207175697320766F6C757470617420706F73756572652C206469616D206F64696F206D616C657375616461206F64696F2C206120696E74657264756D206F726369206469616D20717569732073617069656E2E2050656C6C656E746573717565206F64696F206F64696F2C20766976657272612076656C2C20677261766964612065752C206D6F6C6573746965207365642C206E756C6C612E2050686173656C6C7573206D617572697320706564652C20636F6D6D6F646F2075742C20657569736D6F642065752C2068656E6472657269742065752C206573742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C6120656C656D656E74756D206C616375732065752061756775652E2053656420657261742E2050726F696E20706F7274612E204D616563656E61732071756973206D692E2050686173656C6C757320617420656E696D206163206A7573746F206772617669646120756C7472696365732E2043726173206C656F2E0A0A496E746567657220757420617263752E20446F6E656320736564206D61676E612E2050726F696E2066656C69732E20496E20696163756C69732C206C6967756C61206964206672696E67696C6C61207072657469756D2C206E696268206469616D20616363756D73616E2074656C6C75732C206567657420616363756D73616E206D657475732064756920766172697573207475727069732E2050686173656C6C7573206F726369206D657475732C20656C656966656E64207365642C2074656D706F722061632C207363656C657269737175652061632C2075726E612E20496E74656765722076697665727261206E657175652061206D61757269732E204D617572697320706F72747469746F7220646F6C6F722065752076656C69742E20496E7465676572206F64696F20656C69742C20766573746962756C756D2075742C20766F6C75747061742069642C2072686F6E63757320636F6D6D6F646F2C2075726E612E20457469616D20706C61636572617420706861726574726120657261742E2055742074656D706F72206573742E20496E7465676572206469676E697373696D20626C616E6469742074656C6C75732E204D6F726269206E69626820646F6C6F722C207363656C657269737175652069642C20636F6D6D6F646F206D616C6573756164612C206D61747469732061742C206D692E20437261732074696E636964756E7420636F6D6D6F646F2070757275732E20496E2074696E636964756E742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D20756C6C616D636F727065722E2055742068656E6472657269742E204D6F72626920756C7472696365732E0A0A5072616573656E7420696163756C69732C2065726F73206163206567657374617320736F64616C65732C2075726E61206C656F206665726D656E74756D206C6967756C612C2073697420616D657420616C697175616D2076656C69742073656D206E6F6E2070757275732E20446F6E65632072757472756D206172637520717569732070757275732E204E616D20706F73756572652C206C6163757320617420636F6E73657175617420706C6163657261742C206E756C6C61207065646520706F7375657265206F7263692C206E6F6E20657569736D6F6420747572706973206475692071756973206E69736C2E2050726F696E20706F7274612061646970697363696E67206E6962682E20446F6E65632074726973746971756520646F6C6F722061742074656C6C75732E20446F6E6563206E65717565206D617373612C20617563746F722069642C2066617563696275732076697461652C20756C6C616D636F727065722076656C2C206E6973692E2050726F696E206D6F6C6573746965206E6571756520736564206D617373612E204E616D2074656D706F722E204D6F72626920616C697175616D2073617069656E2061742074656C6C75732E2046757363652071756973207269737573206574206D69207072657469756D2070756C76696E61722E2046757363652073697420616D6574206C6967756C612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E646973736520657520656E696D2065742066656C6973207363656C65726973717565206C6F626F727469732E205072616573656E7420626962656E64756D2E20566976616D7573207665686963756C612E20496E7465676572206174206E696268207365642076656C69742072686F6E637573206D6F6C65737469652E2043726173206C616375732E2053656420756C6C616D636F727065722065726F732076656C20657261742E20467573636520657520746F72746F722073697420616D6574206469616D20657569736D6F642073616769747469732E204E756E632071756973206C61637573206964206E69626820636F6E76616C6C6973207661726975732E2053757370656E6469737365207669746165206D692E20566573746962756C756D207472697374697175652E20446F6E6563206D616C65737561646120697073756D206964206E657175652E204E756C6C616D20736564206C616375732E204475697320656765737461732C206A7573746F20757420636F6E677565206F726E6172652C2061756775652073617069656E206C7563747573206469616D2C20617420616363756D73616E20657261742073617069656E207574206C696265726F2E2050686173656C6C75732076656C206E756C6C612E2053757370656E646973736520617263752074656C6C75732C20706F72747469746F7220612C2070686172657472612066617563696275732C20616C697175616D2073697420616D65742C206D617373612E204E756C6C6120706F72747469746F722074696E636964756E74206C6F72656D2E204E756E6320646F6C6F72206F64696F2C20736167697474697320696E2C206C6F626F727469732076656C2C20766F6C7574706174207365642C206E6962682E0A0A5175697371756520626C616E646974206C656F2075742073617069656E2074656D70757320666163696C697369732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2041656E65616E20756C7472696369657320706F72747469746F72206A7573746F2E2046757363652072757472756D2065726F732075742075726E612E2050726F696E2071756973207175616D20656765742064756920616C697175616D20616363756D73616E2E20446F6E656320737573636970697420656C656966656E6420656C69742E2050656C6C656E746573717565206D61747469732C2066656C697320736F64616C657320696163756C697320696D706572646965742C206C616375732073656D20636F6E76616C6C69732061756775652C2073697420616D657420616C69717565742061726375207075727573206672696E67696C6C612072697375732E20496E206575206F64696F206964206D61676E61207068617265747261206F726E6172652E20416C697175616D20696E74657264756D2070756C76696E617220697073756D2E20536564206E657175652E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D2073697420616D6574206E6973692E2055742061742061756775652E204D617572697320766F6C757470617420626C616E646974206C6967756C612E204E756C6C61206575206D657475732E20566573746962756C756D206567657420656C69742E205072616573656E7420706F73756572652E20566573746962756C756D2069642073656D206E6F6E206C6563747573206D6F6C6C69732074696E636964756E742E20416C697175616D2069642066656C697320617420616E7465206F726E6172652074656D706F722E204E756C6C61206C61637573207475727069732C20666575676961742076697461652C2063757273757320717569732C20636F6E736563746574756572206E6F6E2C206D61757269732E204675736365206C61637573206D617373612C20706F72747469746F722075742C206D6F6C65737469652075742C2076656E656E6174697320612C206C6F72656D2E205072616573656E742073697420616D6574206F7263692E204D61757269732072686F6E6375732066656C69732076697461652066656C69732061646970697363696E6720696D706572646965742E204D616563656E6173206D6F6C6C6973206469616D206E6563206C656F2E0A0A467573636520656E696D20697073756D2C20756C7472696365732065752C206D6F6C65737469652069642C20656C656D656E74756D2069642C2073617069656E2E20496E746567657220612075726E612E204E616D2076656C6974206C696265726F2C2076656E656E6174697320656765742C2074656D706F722073697420616D65742C20666575676961742076697461652C20616E74652E204675736365206E756E632E205365642073656D706572206E69736C206E65632072697375732E20496E20736564206C696265726F2E2050726F696E20746F72746F72206E657175652C2074696E636964756E742061632C2074656D706F722061632C20706861726574726120717569732C2076656C69742E2044756973206C65637475732061756775652C20756C747269636965732076656C2C20636F6E7365717561742069642C20696163756C69732069642C20616E74652E20566976616D757320617563746F72206D65747573206120616E74652E204375726162697475722061726375206E6973692C20666163696C697369732061742C206C616F7265657420696E2C20636F6E736563746574756572207365642C206D61757269732E205175697371756520706C616365726174206469616D20736564206475692E20566976616D7573207072657469756D20636F6E64696D656E74756D206C6F72656D2E20437572616269747572206C616F726565742E2041656E65616E206F726369206C6967756C612C2063757273757320656765742C206C6163696E6961206E6F6E2C2066617563696275732076656C2C206C6F72656D2E0A0A416C697175616D206572617420766F6C75747061742E204375726162697475722065726F7320646F6C6F722C20636F6E67756520612C20636F6E64696D656E74756D207365642C206C75637475732075742C206E6962682E204D616563656E6173206E6F6E20746F72746F72206E65632074757270697320636F6D6D6F646F2070656C6C656E7465737175652E205072616573656E7420657569736D6F6420706C616365726174206D692E2053757370656E646973736520706F74656E74692E2050686173656C6C7573207574206E65717565207669746165206F726369206D617474697320696163756C69732E20496E746567657220656765742074656C6C75732E20446F6E656320617420616E74652E204E616D206C6163696E6961206C656F206567657420657261742E204D616563656E617320657569736D6F64206D61676E6120636F6E67756520746F72746F722E204D6F726269206E6563206D6173736120657520656E696D206D616C65737561646120736F6C6C696369747564696E2E2053656420616363756D73616E2E204E756C6C616D20697073756D2E205574206F64696F2E20416C697175616D206572617420766F6C75747061742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2050656C6C656E7465737175652069642076656C69742E204E616D206F64696F2073656D2C20616C69717565742075742C2074656D7075732073697420616D65742C20657569736D6F642065742C206E756E632E0A0A50656C6C656E746573717565206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205072616573656E74206D6175726973206E756E632C207661726975732075742C20636F6E76616C6C6973206D6F6C65737469652C206C75637475732073697420616D65742C206C656F2E205365642064696374756D206C6F72656D20657420617263752E204E756E632076656E656E617469732070656C6C656E746573717565206D617373612E204E756C6C6120666163696C6973692E2050686173656C6C757320696E20746F72746F722065676574207269737573207363656C657269737175652076756C7075746174652E20536564206E69626820656C69742C2073616769747469732061632C20636F6E64696D656E74756D206E65632C20636F6E76616C6C69732065742C206A7573746F2E20467573636520766F6C7574706174206D657475732E204E756E6320617563746F722E20566573746962756C756D206C656F2065726F732C2070656C6C656E7465737175652061632C206D6F6C6C697320756C7472696365732C2072686F6E637573206E6F6E2C20646F6C6F722E204D6175726973207665686963756C6120706C616365726174206E69736C2E20566573746962756C756D20626962656E64756D2C2061726375207175697320636F6E67756520656C656D656E74756D2C2076656C6974206E756E6320656C656966656E64207475727069732C206964206C7563747573207269737573206E69736C2073697420616D65742074656C6C75732E2050686173656C6C75732070656465206E657175652C20626C616E646974206E6F6E2C20636F6D6D6F646F2076697461652C20756C7472696369657320656765742C206D61676E612E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120666163696C6973692E20416C697175616D20616320616E74652E20437261732072697375732E204D6F726269206D6175726973206C616375732C20706F73756572652065752C20626C616E6469742065742C2070686172657472612061742C206D692E2050726F696E2061632070757275732E204475697320637572737573206E69736C2072757472756D207175616D2E20416C697175616D2061206F64696F206E6F6E206D61676E612070656C6C656E74657371756520756C747269636965732E204D616563656E6173206163206D6173736120717569732073617069656E20756C6C616D636F727065722074656D7075732E2043726173206375727375732076656C6974207365642073617069656E2E2050726F696E206E756C6C612E20566976616D757320736F64616C657320616C697175616D206E6962682E20457469616D206574206572617420757420616E7465206C6163696E696120657569736D6F642E204675736365206E6973692E2050726F696E2071756973206E756C6C612E0A0A517569737175652076656E656E617469732C2065726F7320736564206C616F7265657420736F6C6C696369747564696E2C206F72636920616E74652070656C6C656E746573717565206E69736C2C2073697420616D65742076697665727261207175616D2065726174206E6F6E2072697375732E20437261732065676574206C696265726F2E2053656420656C6974206D61676E612C2073656D7065722065752C206672696E67696C6C6120696E2C206469676E697373696D20736F64616C65732C20657261742E20566976616D757320666575676961742073656D2076656C206475692E20446F6E656320636F6E76616C6C697320736F6C6C696369747564696E206469616D2E2043726173207365642070757275732E20446F6E65632066656C69732065726F732C2073656D70657220656765742C2074656D706F7220636F6E7365637465747565722C20736167697474697320717569732C206E69736C2E204475697320696E20616E74652E2043726173206E6F6E207475727069732E204E756C6C612074656D706F722076656C697420616C697175657420747572706973206D6F6C657374696520706C6163657261742E2050726F696E20656C656D656E74756D206665726D656E74756D206D61757269732E20566976616D757320736564206F726369206C6163696E69612064756920706C6163657261742076656E656E617469732E20566573746962756C756D20666575676961742C2074656C6C757320696E20766F6C75747061742072757472756D2C206D61676E61206E69736920756C6C616D636F727065722065726F732C2069642070756C76696E6172206E657175652065726174207574206C616375732E20566976616D7573207365642061756775652E204E756C6C6120666163696C6973692E204D616563656E617320616E74652061756775652C20656C656D656E74756D2075742C20736F64616C65732076697461652C20636F6E64696D656E74756D206E65632C206C6F72656D2E20447569732070656465206F7263692C206672696E67696C6C612061742C20656C656966656E64206E65632C207072657469756D20696E2C20657261742E204E616D2073616769747469732C2074757270697320766974616520636F6E76616C6C69732070686172657472612C206F64696F2073656D207363656C65726973717565206C616375732C206E6563206C6F626F7274697320647569206469616D2076656C2065726F732E20496E2073656D7065722067726176696461206E657175652E0A0A496E7465676572206E756E632E205574207072657469756D20697073756D2073697420616D657420656C69742E20496E206E656320617263752E2053656420766573746962756C756D2076756C70757461746520697073756D2E2050656C6C656E7465737175652074696E636964756E742E204E756C6C61206772617669646120646F6C6F7220696E2074656C6C75732E2043726173207665686963756C612C20646F6C6F722075742070656C6C656E74657371756520616C697175616D2C206572617420656E696D20617563746F72206D617373612C207665686963756C61206C6F626F72746973206F64696F2065726F732071756973207175616D2E2050726F696E2064617069627573206E6571756520696E20656E696D2E2050726F696E20656C69742E20496E74656765722072686F6E6375732074696E636964756E7420656C69742E204675736365206C6F72656D206D657475732C2073656D7065722061632C20766F6C75747061742076697461652C20666163696C697369732075742C2074656C6C75732E20446F6E65632076656C20747572706973207669746165206E69736920706861726574726120706F72747469746F722E204D616563656E617320746F72746F722E204675736365206D692E204E756C6C616D206E6563207475727069732E2053656420736F64616C657320766573746962756C756D206E756E632E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A50656C6C656E74657371756520646F6C6F7220646F6C6F722C206C616F726565742065752C20616C697175657420717569732C207363656C657269737175652073697420616D65742C20617263752E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C616D206375727375732075726E61206567657420656C69742E205175697371756520626C616E6469742073617069656E20616320616E74652E2050726F696E206E756C6C612065726F732C206772617669646120766F6C75747061742C20736F64616C65732076656C2C206D6F6C6C69732065752C206D617373612E204E756C6C612074726973746971756520736F6C6C696369747564696E206E69736C2E20437572616269747572207669746165206C6F72656D2076697461652076656C69742065676573746173206F726E6172652E2041656E65616E20656765742065726F732E20416C697175616D206572617420766F6C75747061742E20467573636520612075726E61206964206F64696F20616C697175657420636F6E76616C6C69732E204375726162697475722073697420616D6574206E69736C20706F7375657265206C656F20706F737565726520646170696275732E2044756973206D6574757320657261742C206C75637475732076656C2C2072686F6E6375732061742C20636F6E76616C6C69732073697420616D65742C20656E696D2E20566976616D75732068656E6472657269742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D206567657420656C69742E0A0A4E756C6C616D2061206E756E632E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206D657475732075726E612C2074696E636964756E742065742C206C6163696E69612073697420616D65742C206C6F626F727469732076697461652C206C6967756C612E2050726F696E206574206D6175726973207669746165206D6920616363756D73616E2070656C6C656E7465737175652E20457469616D207175616D2070757275732C2068656E647265726974207365642C20666575676961742076697461652C20657569736D6F6420656765742C20746F72746F722E20557420616C697175616D206D61676E61207669746165206A7573746F2E2053757370656E6469737365206E6F6E206A7573746F2076656C2076656C697420636F6E64696D656E74756D2074656D7075732E20447569732074656D70757320697073756D2076697461652074656C6C75732E2050726F696E20696E206D617373612E20457469616D20756C6C616D636F727065722064696374756D2074656C6C75732E2050726F696E20616C69717565742066656C6973206174206C656F206C616F726565742070756C76696E61722E20566573746962756C756D20617263752070757275732C206D616C6573756164612073697420616D65742C206375727375732065752C20706C6163657261742073697420616D65742C206E756E632E204E616D206D61737361206F64696F2C20736F6C6C696369747564696E20696E2C2061646970697363696E6720612C20616C697175616D206E65632C2072697375732E20416C697175616D20626C616E6469742068656E647265726974206C696265726F2E204D617572697320677261766964612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204375726162697475722061206E6962682E20557420696E74657264756D206665726D656E74756D206E657175652E2050656C6C656E74657371756520736564206E756E632E204D6175726973207665686963756C61206E697369206574206E756E632E205072616573656E74206C6F72656D2E20446F6E65632073656D7065722E20496E7465676572206575206C6163757320696E2065737420616C697175616D2068656E6472657269742E20566573746962756C756D2065676574206E657175652E205365642073656D706572206C75637475732076656C69742E20437572616269747572206E6962682061756775652C20636F6E6775652065752C2068656E6472657269742069642C20636F6E6775652065742C20656E696D2E20496E746567657220706C61636572617420616C697175616D206C65637475732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20566976616D75732076697461652065726F732E20446F6E65632076656C206E69736C2E0A0A496E20766573746962756C756D20666163696C697369732075726E612E2055742072697375732E204D61757269732070686172657472612E2050656C6C656E746573717565206D61747469732E20496E746567657220737573636970697420616C697175616D20697073756D2E204475697320626C616E6469742C2073617069656E20657420756C7472696369657320636F6E64696D656E74756D2C2066656C6973206D6920656C656D656E74756D20706564652C206E6563207361676974746973206D65747573206D61757269732071756973207175616D2E205175697371756520616363756D73616E20617263752076656C206E756C6C612E20437261732073656D2073617069656E2C20706F72747469746F722069642C20756C747269636965732073616769747469732C206C75637475732065752C206E756C6C612E20496E746567657220717569732065726F732E204D6F726269207365642075726E6120612074656C6C7573207665686963756C612076756C7075746174652E20457469616D206E656320617567756520656765742066656C69732073656D706572207472697374697175652E205175697371756520757420646F6C6F722076656C2072697375732064696374756D20636F6E7365717561742E20536564206567657420646F6C6F7220736564206E756E63206C6163696E696120616C69717565742E2053757370656E646973736520616320746F72746F7220696E20697073756D20706F73756572652076656E656E617469732E20536564206567657420657261742E204E756C6C612066617563696275732E2044756973206C616F726565742C206D6173736120706F72747469746F7220616C697175657420656765737461732C20697073756D206C65637475732072686F6E637573207175616D2C20696E2061646970697363696E672065726F732073656D2075742074656C6C75732E2050656C6C656E74657371756520666575676961742074656D707573207175616D2E20566976616D757320696420646F6C6F7220656765742073617069656E20636F6E7365637465747565722074656D706F722E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120696163756C6973206665726D656E74756D206C696265726F2E204375726162697475722066617563696275732C206D61737361206D616C657375616461206375727375732074696E636964756E742C20657261742073656D20656C656966656E64206D61757269732C20736564206672696E67696C6C61206D6920616E74652061632070757275732E204475697320656C656D656E74756D206C65637475732E204E756E63206F726E617265206172637520657520746F72746F722E20566573746962756C756D2076656C20646F6C6F72206174207075727573206C6163696E6961206672696E67696C6C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E616D20696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204D616563656E61732074696E636964756E742C2065726F73206120656765737461732070656C6C656E7465737175652C2072697375732072697375732064696374756D206C696265726F2C20696420616C6971756574206D65747573206A7573746F20696E206D617373612E2050726F696E20612074656C6C75732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205365642070757275732E20536564206E6F6E20706564652E2041656E65616E206D617373612073617069656E2C20736F64616C65732073697420616D65742C20636F6E7365717561742064696374756D2C20656C656966656E642076697461652C20746F72746F722E20446F6E656320756C747269636573206C6163696E696120656C69742E0A0A4D6F7262692061646970697363696E6720736F64616C657320646F6C6F722E20557420756C6C616D636F7270657220756C74726963696573206573742E20496E2076656E656E617469732074656D7075732061756775652E2053757370656E646973736520746F72746F7220646F6C6F722C20616363756D73616E2065742C20737573636970697420612C2074696E636964756E742075742C206C696265726F2E20416C697175616D207363656C65726973717565206D61676E61207365642066656C69732E2051756973717565207574206E756E632061206D61676E612076756C70757461746520706C6163657261742E20416C697175616D2072686F6E637573207665686963756C61206475692E2053656420746F72746F722E204E756C6C616D2073697420616D6574206469616D2E204E756E63207365642065726F732E20536564206574206F64696F2074696E636964756E7420656C6974206772617669646120636F6E76616C6C69732E20437572616269747572207175697320746F72746F722061206C616375732073656D706572207661726975732E204D6175726973206174206175677565206E6F6E206D6920736F6C6C696369747564696E20616C697175616D2E20496E746567657220756C6C616D636F727065722E2050656C6C656E746573717565207375736369706974207175616D206E6F6E2070757275732E20416C697175616D2061632065726F73206174206172637520756C6C616D636F7270657220636F6E7365637465747565722E2053757370656E6469737365207072657469756D206D6174746973206C656F2E0A0A44756973206174206E756E632E2053656420646F6C6F72206573742C207661726975732061632C20706F7274612065742C2074696E636964756E742068656E6472657269742C2072697375732E20566976616D7573207574206D61676E612E205072616573656E74207574206D61757269732E20496E207075727573206C616375732C206D6174746973207365642C20766573746962756C756D206E65632C2074656D706F722061742C206E69736C2E204372617320756C6C616D636F727065722076656E656E617469732074656C6C75732E20557420646F6C6F722E204D616563656E6173206D616C6573756164612C207065646520612070756C76696E6172206D61747469732C2061726375206469616D207665686963756C612072697375732C207175697320706F72747469746F72206175677565206D6173736120696E2076656C69742E204E756E6320636F6E6775652E204D6F7262692076656C6974206D657475732C2072686F6E6375732065742C20616C697175616D20636F6E7365637465747565722C20756C74726963696573206D616C6573756164612C206C6967756C612E205365642076656C6974206E69736C2C2073616769747469732076697461652C20706861726574726120612C20706F7375657265207365642C206D617373612E204E756C6C6120666163696C6973692E20496E207661726975732C206C6967756C61206964206C6F626F7274697320736F64616C65732C206175677565206F726369206665726D656E74756D2074656C6C75732C2065752070756C76696E6172207269737573206C6967756C6120612073617069656E2E204D6F726269206C616F7265657420697073756D206E6F6E206D692E204E616D20637572737573206C6F72656D207574206D692E20566976616D7573206D61676E6120656E696D2C20706F7375657265206E6F6E2C2073656D70657220717569732C20736F64616C65732065752C20617263752E20457469616D206D692070757275732C207072657469756D20666575676961742C20766172697573207365642C2070656C6C656E74657371756520656765742C206C6967756C612E20496E206C656F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E6563207669746165206F726369206575206F72636920736F6C6C696369747564696E20666575676961742E0A0A5072616573656E74207075727573206D617373612C20657569736D6F642076697461652C2074656D707573206E65632C20636F6E7365717561742068656E6472657269742C206D657475732E2041656E65616E2066656C6973206573742C20656765737461732076697461652C20616363756D73616E20656765742C2070656C6C656E74657371756520696E2C2073617069656E2E204475697320646170696275732070656465206E6F6E2073617069656E2E204E756E632075726E612E20496E74656765722076656C206C696265726F2E204475697320617567756520617263752C2064617069627573206E6F6E2C20666163696C697369732076697461652C20706F73756572652075742C2065726F732E20446F6E6563207669746165206E756E632073697420616D6574206172637520696D706572646965742064696374756D2E204D6F72626920656C656966656E642C206C6F72656D20657520636F6E73656374657475657220766573746962756C756D2C206469616D206E756E63206F726E61726520617263752C2061632074656D706F722066656C697320646F6C6F7220656765742065726F732E2050686173656C6C7573206D617373612073656D2C20736F6C6C696369747564696E2061632C20736F64616C657320677261766964612C206C756374757320612C207175616D2E204E616D206E65717565207175616D2C20766976657272612061742C2076656E656E6174697320717569732C207361676974746973206E6F6E2C20656E696D2E0A0A4E756C6C6120666163696C6973692E2050656C6C656E7465737175652065676573746173206C6163696E6961206573742E205365642074696E636964756E742C2070656465207365642074696E636964756E7420766573746962756C756D2C2075726E6120646F6C6F722061646970697363696E672070757275732C207669746165206672696E67696C6C612066656C697320656C697420696E206E6962682E204E756C6C6120736564206E6973692E204D6175726973207375736369706974207363656C6572697371756520617263752E20457469616D206E6F6E20656E696D2076656C2065726F7320616363756D73616E206D616C6573756164612E204E756E632074696E636964756E7420636F6D6D6F646F206D61757269732E20496E2074696E636964756E7420726973757320717569732075726E612E204E756C6C61206469616D20746F72746F722C20616C69717565742065742C2074696E636964756E7420717569732C20736F6C6C696369747564696E2061632C20746F72746F722E2043726173206E69736C206E657175652C2076756C7075746174652073757363697069742C206D6F6C657374696520717569732C2070756C76696E61722061742C206E756C6C612E204E756C6C616D206163206D65747573206E6563206F64696F20706F7375657265207661726975732E2043726173207365642070656465206E65632064756920706F737565726520626962656E64756D2E204475697320657569736D6F6420756C6C616D636F72706572206C696265726F2E20416C697175616D2066617563696275732070756C76696E6172207475727069732E0A0A496E207574206E65717565206964206E756E63206665756769617420636F6D6D6F646F2E20437572616269747572206469676E697373696D2C2066656C697320617420736F6C6C696369747564696E206C6163696E69612C20656E696D20656C6974207375736369706974206E657175652C20736564206C7563747573206C6F72656D20697073756D20696E206C656F2E204475697320646170696275732C206F64696F207175697320617563746F7220636F6D6D6F646F2C206E69736C206F64696F206D61747469732074656C6C75732C206E65632074696E636964756E7420747572706973206469616D20696E20617263752E2043757261626974757220612073656D2E204E756C6C616D20766F6C7574706174206D61676E612E2050656C6C656E7465737175652073616769747469732C206E6571756520636F6E736571756174207072657469756D206375727375732C20646F6C6F72206C6163757320636F6E73656374657475657220617263752C20736564206C616F72656574206573742075726E61206574206D657475732E2053757370656E646973736520706C6163657261742C20647569206120706F7274612074656D706F722C206C6F72656D20647569206C6F626F72746973206E657175652C207365642076656E656E61746973206469616D20656E696D2069642065726F732E20457469616D206574206E69736C206E6F6E206C656374757320666175636962757320636F6E7365637465747565722E204D6F726269207363656C657269737175652C2073656D206E65632074656D70757320756C6C616D636F727065722C20697073756D206469616D2066657567696174206C6F72656D2C2061206672696E67696C6C612073617069656E20656C69742071756973206E6962682E204E756C6C616D206469616D2075726E612C2076697665727261207365642C2070686172657472612072686F6E6375732C2074696E636964756E742076656C2C206F7263692E20496E746567657220616363756D73616E206D617474697320657261742E204E616D2064696374756D2E204D6175726973206E6563206C656F2E204E756C6C6120696163756C69732E204E756C6C61206E69736C206D692C206461706962757320717569732C207665686963756C6120612C2063757273757320656765742C206F64696F2E0A0A50686173656C6C7573206461706962757320657569736D6F64206E6962682E20566976616D757320696D7065726469657420616E746520696E206C6967756C612E2050656C6C656E74657371756520616363756D73616E2E20496E20696D706572646965742C20647569206120617563746F72206672696E67696C6C612C206D65747573206E6973692063757273757320646F6C6F722C2076656C206C7563747573206C6967756C61206C6F72656D207669746165206D61757269732E205072616573656E74206D617474697320766573746962756C756D20656C69742E20416C697175616D20656E696D206C616375732C2070756C76696E6172206E6F6E2C206C6163696E69612073697420616D65742C20656C656966656E64206E6F6E2C2076656C69742E20566573746962756C756D206163206C656F2E204D617572697320696D70657264696574206A7573746F206163206C65637475732E20536564206D6F6C6573746965206C656374757320736564206475692E20536564206665726D656E74756D2074656D707573206D61757269732E204E616D206F726E617265206F7263692061632074656C6C75732E205574206D616C6573756164612C206C61637573206964206C6163696E696120616363756D73616E2C206469616D20656C69742061646970697363696E67206D657475732C20657420626962656E64756D2073617069656E206E69626820626C616E646974206F7263692E2053757370656E646973736520697073756D2074656C6C75732C20736167697474697320717569732C20766573746962756C756D206E6F6E2C2076756C7075746174652065752C2065726F732E205072616573656E74206174206E756C6C612069642070656465207363656C6572697371756520756C747269636965732E204372617320626C616E646974207072657469756D2074656C6C75732E204D616563656E6173206461706962757320636F6E64696D656E74756D2061756775652E2050686173656C6C75732074696E636964756E74207068617265747261206C6F72656D2E204D6F726269206E6F6E2065726F732E205365642074656D706F722C206E69736C20612074696E636964756E742074696E636964756E742C2065726F73206469616D2064696374756D2073656D2C2076656C206469676E697373696D20616E7465206469616D20736564206D61676E612E205072616573656E74206E6F6E206C6967756C61206964206D65747573206D6F6C657374696520636F6E7365637465747565722E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E64697373652076656C206D692E2043757261626974757220616E7465206E756C6C612C2072757472756D20612C20636F6E76616C6C69732076656C2C207665686963756C612061632C206E756E632E204E756E632073616769747469732C20656E696D2073697420616D657420617563746F722072757472756D2C206D617572697320617263752076756C707574617465206E657175652C20657420657569736D6F64206573742066656C6973207175697320616E74652E20566573746962756C756D207475727069732074656C6C75732C2068656E64726572697420696E2C206C6163696E696120636F6D6D6F646F2C20756C6C616D636F7270657220677261766964612C2072697375732E204D61757269732072686F6E637573206C6163696E69612072697375732E204D616563656E617320736F6C6C696369747564696E2065726174207669746165206E756E632E205072616573656E74207072657469756D2070656C6C656E7465737175652061756775652E20446F6E656320696E74657264756D2E205072616573656E742061632065726F732076697461652065726174206C6F626F72746973206672696E67696C6C612E2041656E65616E20636F6E7365717561742074656C6C75732E204E756C6C6120616363756D73616E20626962656E64756D2066656C69732E204D616563656E6173207072657469756D20616E7465206964206E6973692E2041656E65616E206D6920617263752C2073656D706572207365642C206D61747469732065752C2076656E656E617469732073697420616D65742C20617263752E20446F6E656320616C697175657420657569736D6F64206C656F2E2050726F696E206D61676E61206A7573746F2C2074726973746971756520612C2073656D7065722061632C20736F6C6C696369747564696E20612C206C6967756C612E204D6F7262692076656C69742E20416C697175616D2076656C206E6973692E0A0A496E2061206C6F72656D207574206E756E63206665756769617420636F6E6775652E20446F6E6563206665726D656E74756D20626962656E64756D206475692E2050726F696E207661726975732065737420717569732076656C69742E20446F6E656320616C69717565742073656D20616363756D73616E206D692E2053656420706C6163657261742E204E756C6C616D206163206E6973692061206D61737361206C6F626F727469732073757363697069742E204E756E63206964206C656F2E20416C697175616D206574206D617373612E204E756C6C616D20766573746962756C756D20656C656D656E74756D206D657475732E20496E20636F6E736563746574756572206E6973692076656C206A7573746F2E204D616563656E6173206567657420707572757320736564206D61737361207661726975732070656C6C656E7465737175652E2050686173656C6C75732066617563696275732066656C697320717569732066656C69732E2041656E65616E206F64696F20617263752C20626C616E64697420717569732C20666163696C6973697320696E2C20696D706572646965742065752C206C6F72656D2E204E616D20706F73756572652070756C76696E6172206D692E204675736365207472697374697175652C206D617572697320657420636F6E73656374657475657220756C747269636965732C206D6175726973206C65637475732074656D706F72206A7573746F2C206174206672696E67696C6C61206573742065737420736564206E6973692E20517569737175652066617563696275732E2053656420696E20746F72746F722074696E636964756E7420657374206C6163696E696120696163756C69732E204D616563656E61732061206D617373612E2050656C6C656E7465737175652061206E69626820617420707572757320706F7274612068656E6472657269742E0A0A4E756C6C616D207475727069732E2046757363652061632073656D20736564206F64696F2070656C6C656E74657371756520696D706572646965742E2043757261626974757220696E20617263752E205072616573656E74206C61637573206C616375732C20666575676961742069642C2070756C76696E617220696E2C2074696E636964756E74207365642C206E657175652E204D616563656E61732076697665727261206F64696F206567657420746F72746F722E20496E746567657220616C697175616D2C206C6F72656D2072757472756D2076656E656E61746973206469676E697373696D2C206C6967756C61206D61676E61206D616C65737561646120617263752C2076656C2066657567696174206C6F72656D20697073756D2071756973206D617373612E204D6F72626920616E74652E20566573746962756C756D206D6175726973206C696265726F2C20756C6C616D636F7270657220717569732C20756C74726963657320717569732C20666163696C69736973206E6F6E2C206D617373612E204D616563656E617320696D706572646965742E20416C697175616D206572617420766F6C75747061742E2050656C6C656E746573717565206469676E697373696D2067726176696461206C65637475732E20496E206E696268206F64696F2C20617563746F7220656765742C206461706962757320717569732C206469676E697373696D2076656E656E617469732C20617263752E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20447569732070656C6C656E746573717565206C6967756C612071756973206D617373612E2043757261626974757220636F6E64696D656E74756D2C206A7573746F2065676574206F726E617265206C75637475732C206C6F72656D206C6967756C6120736167697474697320706564652C206120706F727461206E756E63206E756E6320696E206E657175652E20517569737175652066656C6973206D61757269732C20636F6E64696D656E74756D2076697461652C20617563746F722076697461652C2074696E636964756E7420717569732C20706564652E204E756E63206C6163696E696120616E746520696E206C656F2E2050656C6C656E746573717565206C696265726F2E2041656E65616E2061206C6967756C61206574206E756E6320766573746962756C756D20636F6E7365637465747565722E0A0A4675736365206F726E6172652E205072616573656E742069642075726E612E20496E74656765722076656E656E617469732C207175616D206E6F6E20736167697474697320616363756D73616E2C20616E7465206E6962682073616769747469732061756775652C20736F6C6C696369747564696E2061646970697363696E6720646F6C6F722076656C697420657520657261742E2050726F696E207175697320656E696D206575207075727573207665686963756C6120616C697175616D2E204E756C6C612076656C20656E696D2076656C20656C697420736F6C6C696369747564696E206672696E67696C6C612E20416C697175616D206572617420766F6C75747061742E205365642073757363697069742066656C6973207574207475727069732E20457469616D2072757472756D20726973757320696D70657264696574206573742E20416C697175616D20612074656C6C75732061742074656C6C757320636F6D6D6F646F20646170696275732E204D61757269732072757472756D206D61676E61206574206F64696F2E20496E20617420646F6C6F722E20437572616269747572207665686963756C61206C656374757320696E20746F72746F722E204675736365206A7573746F2070757275732C206C75637475732076697461652C206D6F6C6C697320696E2C2070686172657472612061632C2070757275732E204E756C6C616D20706F737565726520696E74657264756D206A7573746F2E20437572616269747572207669746165206C616375732076656C206C656F20636F6E6775652070756C76696E61722E0A0A41656E65616E20656C656966656E64206E6962682076617269757320746F72746F722E2053757370656E64697373652076656C2065726F732E2050726F696E206E6563206469616D206120746F72746F7220756C747269636573206F726E6172652E20416C697175616D207363656C657269737175652066657567696174206A7573746F2E20566976616D757320616E74652075726E612C2061646970697363696E672076697461652C20706F72747469746F722065752C20736F64616C65732065742C2066656C69732E2053757370656E646973736520706F74656E74692E20437572616269747572206163206D6173736120696E206E69736C207361676974746973206D6F6C6C69732E204E616D207175616D206C6967756C612C20636F6E73656374657475657220656765742C20696163756C69732061742C207661726975732065752C206C656F2E204475697320646F6C6F72206C6967756C612C2074696E636964756E742061742C20756C6C616D636F72706572207365642C20616363756D73616E20616C697175616D2C206C6967756C612E2050686173656C6C75732076756C7075746174652C206C6F72656D2061742074696E636964756E742070686172657472612C207269737573206C6563747573206C6163696E6961206D61676E612C20717569732072757472756D20656E696D206D61676E612061742073656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E20447569732069642073656D2061206D617572697320736F6C6C696369747564696E2074696E636964756E742E20457469616D2065752070757275732065752061726375206672696E67696C6C612061646970697363696E672E20566976616D7573206F726E6172652074656D707573206469616D2E2050726F696E20747572706973207175616D2C206C6163696E6961206E6F6E2C20656765737461732061742C20636F6D6D6F646F20656765742C20706564652E205072616573656E742076756C70757461746520726973757320696E206573742E204E756C6C6120666163696C6973692E0A0A557420656C656D656E74756D206C6163696E69612070757275732E2050726F696E2076697461652061726375206163206E756C6C6120636F6E76616C6C697320616C697175616D2E204E756C6C6120636F6E6775652C206C696265726F2069642070656C6C656E746573717565206D61747469732C207175616D206C656374757320706F72747469746F72206469616D2C2061207363656C6572697371756520647569206C696265726F20696E2073617069656E2E204E756C6C616D2066656C6973206469616D2C207665686963756C612076656C2C206D6F6C65737469652075742C20766573746962756C756D20616C697175616D2C2073617069656E2E20446F6E656320636F6E76616C6C69732C2065737420757420656C656D656E74756D20766F6C75747061742C206D617572697320697073756D20677261766964612073656D2C20636F6D6D6F646F20666163696C697369732073617069656E206C65637475732073656D706572206C65637475732E205175697371756520706F72747469746F722065726F73207574206E6962682E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20457469616D206D617474697320726973757320736564206F64696F2E20566573746962756C756D206574206F64696F2E20496E206861632068616269746173736520706C617465612064696374756D73742E204E616D20747269737469717565206D61737361207574206C6967756C612E2051756973717565206E6962682074656C6C75732C207665686963756C612073697420616D65742C2061646970697363696E672061742C20636F6E76616C6C6973206E65632C206C6967756C612E20566573746962756C756D207072657469756D2C206D69206E6563206672696E67696C6C6120626962656E64756D2C20647569206E756E6320736F64616C657320706564652C20612073656D706572206D61676E61206E696268206E6F6E206469616D2E20446F6E6563206D61737361206E756E632C20766976657272612076656C2C20636F6E73656374657475657220706F7274612C2064617069627573206E6F6E2C20697073756D2E2044756973206E69736C206D61757269732C206375727375732076656C2C2073656D706572206E6F6E2C20736F6C6C696369747564696E20626962656E64756D2C2066656C69732E20566573746962756C756D206575206E657175652E0A0A43726173206E656320646F6C6F722E20446F6E6563206C616F726565742074656D707573206C65637475732E20437261732073656420746F72746F7220696E74657264756D206C6163757320656C656966656E64206469676E697373696D2E204D616563656E61732073697420616D657420656C69742E204E756C6C616D207175697320646F6C6F722076656C20647569207068617265747261206C75637475732E20496E2073697420616D6574207175616D2073697420616D6574207065646520756C74726963657320756C7472696365732E204D616563656E6173206469616D2E20496E74656765722075726E612E204375726162697475722064696374756D2C2076656C69742073656420706C6163657261742073757363697069742C206572617420747572706973206665726D656E74756D206A7573746F2C2073656420696E74657264756D206E657175652073656D206574206E6962682E20566976616D757320636F6E73657175617420636F6E76616C6C6973206D61676E612E204E616D20616C697175616D2C2065737420616320626962656E64756D20636F6D6D6F646F2C206D61676E61206573742064696374756D206D692C207669746165206D616C65737561646120656C6974206D61676E61207669746165206F64696F2E204D616563656E61732074656D706F722076756C7075746174652074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206475692E20457469616D20616363756D73616E207065646520636F6E67756520746F72746F722E0A0A4D6F7262692074656D706F72206C696265726F206163206C6F72656D2E20496E20616C697175657420766172697573206D61676E612E20496E20617263752E2050686173656C6C7573206F64696F2E2046757363652074696E636964756E7420616C69717565742066656C69732E20517569737175652076656C69742E20536564206C75637475732E20416C697175616D2066657567696174206672696E67696C6C61206D692E20416C697175616D206D6F6C657374696520766976657272612072697375732E2050726F696E20617263752E20566573746962756C756D206C6F626F727469732074656D707573206E6973692E205072616573656E742061206172637520696E2076656C697420766976657272612072757472756D2E0A0A496E20736564206C65637475732E20446F6E656320726973757320646F6C6F722C20626C616E6469742073697420616D65742C20656C656D656E74756D20636F6E76616C6C69732C20706861726574726120717569732C20706564652E20496E7465676572206F726E6172652E2041656E65616E20656765737461732064617069627573206A7573746F2E20536564207175616D206C656F2C20706F73756572652061742C20656C656D656E74756D2076697461652C20636F6D6D6F646F20656765742C206573742E20416C697175616D206D6F6C65737469652072686F6E63757320656E696D2E2043757261626974757220696163756C697320756C74726963657320706564652E204D6F72626920616C69717565742072757472756D206C616375732E20416C697175616D207175616D2E2053656420636F6D6D6F646F2C2074757270697320696E20706861726574726120706F73756572652C206D6920726973757320696D7065726469657420657261742C206120766573746962756C756D206D617373612074656C6C7573207665686963756C612073656D2E204D6175726973206672696E67696C6C6120756C747269636573206E756E632E204E616D206E69736920656E696D2C20656C656966656E642073697420616D65742C20756C747269636573207365642C206665726D656E74756D206E6F6E2C2061756775652E2050726F696E20636F6E677565206C6F626F72746973206E6973692E204D616563656E61732068656E6472657269742E204E616D20736564206E69736C2E204E756E6320656C656D656E74756D206F64696F2065752072697375732E20496E206D657475732E2050686173656C6C75732067726176696461207072657469756D206C6967756C612E204E756C6C61207669746165206E657175652E204E616D206E69736920746F72746F722C206F726E617265206E6F6E2C20626C616E6469742061742C206375727375732065752C20746F72746F722E0A0A4475697320626962656E64756D20697073756D20696E206E756E6320637572737573206D6F6C65737469652E204E756E63206F7263692E204E756C6C616D206E656320616E7465206E6F6E20657374206469676E697373696D20766976657272612E204D617572697320626C616E6469742C2076656C69742069642066657567696174207072657469756D2C20656C6974206D61676E612070656C6C656E74657371756520646F6C6F722C206174207361676974746973206C616375732076656C69742065676573746173206D61676E612E2050656C6C656E746573717565206375727375732C206469616D20636F6E736563746574756572207361676974746973206672696E67696C6C612C20746F72746F72206E6973692061646970697363696E67206E756E632C20657520766172697573206C6163757320726973757320616320656C69742E204D6175726973206964206E6973692071756973206C656F20657569736D6F642076656E656E617469732E2050656C6C656E74657371756520616320616E74652E204D617572697320617263752073617069656E2C2074656D706F722061742C20706F72747469746F722069642C20636F6E64696D656E74756D2075742C206475692E20457469616D206665726D656E74756D20756C747269636965732061756775652E20437261732075742065726F73206174206A7573746F20756C7472696369657320696163756C69732E2044756973206469676E697373696D2C206E69736C20657420666163696C69736973206665726D656E74756D2C2065726174207075727573206D6F6C65737469652074656C6C75732C20717569732074656D70757320697073756D206C656374757320617420656C69742E204E756C6C61207669746165206C6F72656D2E0A0A41656E65616E2076656C2073656D206574206469616D2073656D70657220636F6E6775652E20496E20626962656E64756D206469616D20717569732074656C6C75732E204E756E6320666163696C6973697320756C74726963696573206E6962682E2043726173206E756E6320656E696D2C2066657567696174207365642C20756C7472696365732076697461652C2073616769747469732076697461652C20697073756D2E204675736365207669746165206E756C6C612E20446F6E65632070656C6C656E7465737175652C2076656C697420696E20706F72747469746F7220656C656966656E642C20657374206E65717565206C6F626F727469732076656C69742C2073697420616D65742072757472756D20616E746520746F72746F72206E656320646F6C6F722E20446F6E6563207665686963756C612E204E756C6C6120666163696C6973692E20536564206567657374617320756C747269636573206E6962682E20446F6E656320656C6974206C65637475732C20636F6E76616C6C697320706F72747469746F722C20616C697175657420646170696275732C206665756769617420656765742C206C6967756C612E2053656420636F6E736563746574756572206A7573746F2E204D616563656E617320612073617069656E2073697420616D6574206E6973692064617069627573206C6F626F727469732E20566976616D7573206C7563747573206C6F72656D206E6F6E206E756C6C612E2053656420656765742065726174207669746165206C696265726F20696E74657264756D20706F73756572652E20437261732070756C76696E61722E204E756C6C616D20696D706572646965742C20646F6C6F722074656D706F72206469676E697373696D20626C616E6469742C206475692073617069656E2072686F6E637573206E657175652C206964206D616C657375616461206175677565206D61676E612073697420616D65742075726E612E204475697320736564206D61757269732E0A0A4D6F72626920616363756D73616E2E20536564206D61757269732061756775652C206672696E67696C6C61206E6F6E2C20617563746F722075742C20617563746F722065742C206F7263692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320757420706564652E20446F6E6563207669766572726120656E696D2076656C206C6F72656D2E2050656C6C656E746573717565206E65717565206D61757269732C20696E74657264756D2065752C2076656E656E617469732069642C20636F6E64696D656E74756D2065752C2073617069656E2E20446F6E656320697073756D20617263752C206C6163696E69612061646970697363696E672C206C616F726565742065742C206375727375732076656C2C2076656C69742E205574207361676974746973206D617572697320717569732072697375732E20496E7465676572206575206F64696F207669746165206C61637573207669766572726120616363756D73616E2E204D6F726269206C656F20616E74652C206469676E697373696D207365642C2076617269757320717569732C20766F6C75747061742076697461652C206E6973692E204E756C6C6120706C61636572617420696E74657264756D20656C69742E20446F6E6563206E65717565206475692C2073616769747469732076697461652C20736F6C6C696369747564696E20717569732C20636F6D6D6F646F2076697461652C206E657175652E204E756C6C612071756973206C6967756C61206F726E617265206C6967756C612064696374756D206F726E6172652E204D61757269732072757472756D2072757472756D206E657175652E2041656E65616E207665686963756C612074656D707573206573742E20446F6E656320766172697573207363656C6572697371756520706564652E20446F6E656320706C6163657261742076756C707574617465206C656F2E204E756C6C616D206E756E63206E69736C2C20706F7375657265206E6F6E2C20666575676961742076697461652C2070656C6C656E74657371756520717569732C206D61757269732E20496E20647569206E657175652C2063757273757320656765742C20736167697474697320656765742C20646170696275732076697461652C206D692E2050726F696E2065676574206573742E0A0A467573636520706F727461206573742E204D6175726973206D61676E612E20416C697175616D20697073756D206C616375732C20756C747269636965732069642C20766573746962756C756D206C75637475732C20616363756D73616E2075742C20616E74652E20536564206D61757269732E205365642061646970697363696E67206C656F2073697420616D6574206D61676E612E2053757370656E646973736520706F74656E74692E204E756E63206D6173736120656C69742C206672696E67696C6C6120656765742C20656765737461732076697461652C206C75637475732076697461652C20646F6C6F722E2050686173656C6C75732071756973206E756C6C61206575206E69736920696E74657264756D20736F6C6C696369747564696E2E204E756C6C616D2069642074656C6C75732E20496E746567657220696163756C697320646F6C6F722061632070757275732E205365642076656C206D692E20437572616269747572206E6F6E206D61676E612073697420616D6574206A7573746F20636F6E64696D656E74756D2076756C7075746174652E20517569737175652074696E636964756E742070656465206575206E69736C2E20566976616D7573206C6F626F727469732E204E756E63206D65747573206D657475732C20636F6E677565207365642C2074696E636964756E74207365642C207072657469756D2061742C206F64696F2E20446F6E6563206120617263752E20496E2073656D206A7573746F2C207665686963756C61207365642C207661726975732069642C20766F6C75747061742061742C2072697375732E205072616573656E7420696163756C6973206D617373612E20496E206172637520656C69742C2068656E64726572697420656765742C20756C6C616D636F7270657220696E2C20706F7274612069642C2074656C6C75732E20446F6E65632073616769747469732068656E647265726974206469616D2E0A0A53757370656E646973736520706F74656E74692E20536564206574206469616D206574206175677565207361676974746973206C6F626F727469732E2050686173656C6C757320646F6C6F722E2055742065742061726375206567657420616E74652074656D706F7220706F73756572652E20416C697175616D206665726D656E74756D207363656C65726973717565206475692E204D61757269732061742070757275732E20446F6E656320657261742073656D2C20766573746962756C756D206E65632C2066617563696275732061632C206D617474697320612C206C656F2E2053757370656E64697373652061646970697363696E67206C6163696E69612073656D2E204E756C6C616D206F72636920617263752C2064696374756D2065742C20666175636962757320766976657272612C20646170696275732065742C206E657175652E2043726173206E756E63206469616D2C2061646970697363696E67206E6F6E2C20736F6C6C696369747564696E20696E2C20696E74657264756D2076656C2C206D617373612E204D61757269732073616769747469732C206A7573746F206174207472697374697175652074656D7075732C206D6175726973206D617572697320616C697175616D20616E74652C2073697420616D657420706F7375657265206469616D206475692065676574206C6967756C612E20496E206469676E697373696D2C206E69736C207574206C6163696E696120636F6E64696D656E74756D2C2065726174206A7573746F20706F72747469746F72206E756C6C612C206E6F6E2067726176696461206C6967756C61206D61676E612065676574206D617373612E20566573746962756C756D207669746165206C6967756C61206174206D6920766573746962756C756D2073757363697069742E2044756973206C616F726565742E204E756C6C6120636F6D6D6F646F206C696265726F2073697420616D6574206C6F72656D2E20557420656C656D656E74756D2073656D2E20496E74656765722076656C20646F6C6F722E204E616D20666163696C69736973206D6920717569732073656D20756C7472696365732073616769747469732E205365642071756973207175616D206174206D65747573206D6F6C657374696520626962656E64756D2E0A0A50726F696E2064756920656E696D2C206C6163696E696120612C20666575676961742061632C20706C6163657261742076697461652C20706564652E205175697371756520656765737461732C206C656F206567657420616C697175616D207072657469756D2C206C696265726F206A7573746F2074696E636964756E742065726F732C2075742065676573746173206175677565207065646520656C656D656E74756D206E6962682E20437572616269747572206D6F6C6C697320736F64616C657320656E696D2E20446F6E65632061756775652E2050686173656C6C757320696420697073756D20706F737565726520647569207072657469756D2066617563696275732E204D6175726973206C756374757320616E74652073656D706572206E69736920696E74657264756D2061646970697363696E672E204475697320646170696275732C206F64696F207175697320766976657272612072686F6E6375732C206A7573746F207175616D20626962656E64756D20646F6C6F722C20696420646170696275732076656C697420657261742076656C20657261742E2046757363652073697420616D6574206E69736C2076656E656E61746973207175616D20756C74726963657320636F6E64696D656E74756D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632072686F6E637573207363656C65726973717565206C6967756C612E20566573746962756C756D206D69206F64696F2C20616363756D73616E2065742C2061646970697363696E6720656765742C206F726E6172652075742C207175616D2E204E756C6C616D20626C616E646974206D6F6C6573746965206D61757269732E20437572616269747572206469676E697373696D206D6175726973206574206C6F72656D2E2053757370656E64697373652061206A7573746F2E204E616D206D617474697320666175636962757320617263752E204475697320626C616E64697420656E696D206E6F6E206D617373612E0A0A4E756C6C616D206C6F72656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E204D617572697320636F6E73656374657475657220706F7375657265206D61757269732E204D616563656E61732074696E636964756E74206D617572697320696E2065726F732E204E756C6C61206575206D65747573206575206F72636920736F6C6C696369747564696E2066617563696275732E2053757370656E646973736520616C697175616D206D6175726973206964206573742E204372617320626C616E646974206475692065742075726E612E204E756C6C6120617263752E2053656420612075726E612E204E756C6C612064617069627573207665686963756C6120746F72746F722E20446F6E65632072697375732E20536564207175616D206D657475732C20656765737461732065752C206375727375732075742C2076697665727261206E6F6E2C206F64696F2E205574206A7573746F206A7573746F2C206D616C6573756164612073697420616D65742C20626C616E6469742073757363697069742C206D6F6C657374696520696E2C206A7573746F2E20566573746962756C756D20636F6E7365717561742C207175616D20616320666575676961742074696E636964756E742C20697073756D206C696265726F20656C656966656E64206F64696F2C206E6F6E20656C656966656E64207065646520697073756D206E6F6E20616E74652E204E756C6C616D2061206D657475732E0A0A4E616D206163206E6973692061742066656C697320637572737573206D61747469732E2050656C6C656E74657371756520636F6E7365717561742073656D2071756973206F7263692E20517569737175652074656D7075732E2041656E65616E20696D70657264696574206D6F6C657374696520706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652065752074656C6C75732E204E756C6C61206469616D2065726F732C20736F64616C65732075742C20736F64616C6573206E65632C2074696E636964756E742061632C206E756E632E204E756E63206C6163696E696120666175636962757320697073756D2E20566976616D75732076656C206E6571756520696E2065726174206665726D656E74756D206C75637475732E204E756C6C612065676574206D65747573206E656320617567756520626962656E64756D20706C6163657261742E20566976616D75732074656D7075732E205072616573656E7420636F6E677565206F726E61726520697073756D2E20457469616D206D61747469732066657567696174206A7573746F2E0A0A416C697175616D206475692E2041656E65616E20636F6D6D6F646F20746F72746F72207669746165206E756C6C612E204D6F72626920657420697073756D2E204D617572697320616320697073756D2E204E616D2076656C207269737573207574206C6563747573206D6F6C6C697320766976657272612E2043757261626974757220656C656D656E74756D206D6F6C6C6973206573742E204E756C6C616D20656C69742E20566573746962756C756D207375736369706974207072657469756D20656E696D2E20566573746962756C756D207574206D617373612E2050726F696E206E65632066656C69732E204D616563656E617320677261766964612C2061726375206E656320636F6E7365717561742073616769747469732C2065726F732074656C6C7573207363656C65726973717565206D61757269732C20766974616520616363756D73616E207175616D207175616D207574206E756E632E20496E7465676572206567657420616E74652065752076656C6974206C616F72656574206D616C6573756164612E204E756E632073616769747469732C206D617572697320766974616520706861726574726120766F6C75747061742C2074656C6C75732074656C6C757320656C656966656E642065726F732C2073697420616D65742072757472756D20697073756D206E69736920612076656C69742E205072616573656E7420766172697573206C656F20657520657261742E20566976616D757320636F6E73657175617420706C6163657261742070757275732E20446F6E6563207072657469756D20656C656D656E74756D206E6962682E2050726F696E20617420656C6974206E6F6E2073656D20616C6971756574206D61747469732E2053656420756C6C616D636F7270657220697073756D2073697420616D657420656C69742E0A0A4D617572697320696E206D657475732E2053757370656E6469737365206D61676E61206C6F72656D2C2066617563696275732076656C2C2074696E636964756E7420717569732C207363656C65726973717565206E6F6E2C2074656C6C75732E2046757363652071756973206C6F72656D2E2050726F696E2061206C616375732073697420616D6574206D617572697320696163756C69732070756C76696E61722E2053757370656E64697373652072686F6E6375732065726F73206E6563206D692E205072616573656E7420657569736D6F642C207475727069732076697461652072757472756D207072657469756D2C206F64696F206D6574757320766F6C7574706174206E657175652C20656765742074656D7075732073617069656E206E657175652073656420657261742E20446F6E6563206665726D656E74756D207075727573206174206C65637475732E204E756C6C616D2073656D2E2046757363652076656C206D6920717569732065726174206C6F626F7274697320706F73756572652E2041656E65616E20656765742075726E612E2053757370656E6469737365206C6967756C612E204475697320696E206E6973692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A4375726162697475722076756C707574617465206C656374757320696420706564652E2050686173656C6C75732065752076656C69742E20457469616D2076656E656E617469732061646970697363696E67206E6962682E20416C697175616D206375727375732070756C76696E61722074656C6C75732E20566573746962756C756D206E657175652E204D6175726973206E6563206A7573746F20657420657261742073656D7065722070656C6C656E7465737175652E204675736365206D61747469732064696374756D20646F6C6F722E20457469616D2065676574207075727573206575206D617373612076617269757320656C656D656E74756D2E2050656C6C656E746573717565206D617373612E20557420756C74726963696573206469616D2073656420697073756D2E204E756C6C616D206469616D2E2050656C6C656E746573717565206964206D61676E61206964206C696265726F2074726973746971756520616C697175616D2E0A0A557420656C656966656E642C20707572757320696420706C6163657261742076656E656E617469732C2075726E6120617567756520616C6971756574206C6967756C612C20696E20756C74726963696573206C656F2072697375732065742074656C6C75732E204D6175726973206574206E756C6C612069642075726E61207472697374697175652074656D7075732E20557420666163696C697369732C2075726E6120657520766573746962756C756D2072686F6E6375732C206C616375732065726F7320636F6E736563746574756572206D657475732C2065742072757472756D20647569206C656374757320696E2070757275732E204E756E632076656C206E69736C206E6F6E20697073756D2074696E636964756E74206D6F6C6C69732E204E616D207175616D206C616375732C206F726E6172652076697461652C2072686F6E637573206E6F6E2C20636F6E677565207365642C206F64696F2E2050726F696E206E696268206475692C20706F7274612076656C2C2076656E656E61746973206E6F6E2C2070656C6C656E7465737175652075742C206E6973692E20536564207472697374697175652066656C69732061206D61676E612E2053757370656E646973736520656765742074656C6C75732E2043726173206772617669646120696D706572646965742076656C69742E20496E74656765722068656E6472657269742072697375732E2050726F696E206F7263692E20416C697175616D20756C6C616D636F72706572206D61757269732071756973206D61757269732E204E756E63206C6163696E696120766573746962756C756D206D657475732E20447569732074656C6C75732E204E756C6C616D2066617563696275732C206C656F2061632076756C70757461746520736F6C6C696369747564696E2C206C656F20646F6C6F7220666175636962757320657261742C207175697320626962656E64756D206F726369206F64696F206E6F6E20617263752E0A0A4E756C6C616D20616363756D73616E206D617474697320646F6C6F722E20446F6E6563206574206475692E205072616573656E7420612066656C6973206D6F6C6C6973206C616375732073656D706572206C6163696E69612E204375726162697475722070656C6C656E746573717565206C7563747573206573742E2050726F696E206E756C6C61206475692C20636F6E64696D656E74756D2076656C2C206661756369627573206E6F6E2C20696E74657264756D2061632C20657261742E204D616563656E6173207363656C657269737175652C206C656374757320696420766F6C757470617420616363756D73616E2C2073617069656E20746F72746F722070656C6C656E746573717565206475692C207365642073656D706572206D61676E612073656D207574206C656F2E2050726F696E206E756C6C612E204E756C6C616D206461706962757320756C6C616D636F727065722073656D2E2053757370656E6469737365207665686963756C61206D6574757320696E206E756E632E2050656C6C656E746573717565206E6F6E207175616D2076656C206172637520756C74726963657320756C6C616D636F727065722E2050686173656C6C757320717569732066656C69732073697420616D65742074656C6C757320756C6C616D636F72706572206665726D656E74756D2E20536564207665686963756C6120736F6C6C696369747564696E2075726E612E20437572616269747572207068617265747261207363656C657269737175652072697375732E2050656C6C656E746573717565206964206D617373612071756973206D6574757320616C697175616D20696D706572646965742E20496E206E756E63206C616375732C206665756769617420696E2C206772617669646120656765742C2076656E656E617469732075742C2074656C6C75732E2053757370656E646973736520706F74656E74692E204E616D20636F6E7365717561742061646970697363696E67206475692E20496E206E756C6C61206E6973692C20666575676961742075742C206665726D656E74756D2076656C2C2067726176696461206E65632C20746F72746F722E20496E207365642061756775652E0A0A457469616D20756C6C616D636F7270657220617567756520617420656E696D2E20496E7465676572206469676E697373696D2E20416C697175616D2070756C76696E617220636F6E677565206E756C6C612E204D6F72626920656E696D206D617373612C206672696E67696C6C6120612C20616363756D73616E20656765742C20636F6E64696D656E74756D206E65632C20657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2041656E65616E2070686172657472612E20457469616D20706F72747469746F722070757275732061206D657475732E20416C697175616D20696E74657264756D2073656D2065676574206A7573746F2E205175697371756520766F6C7574706174206C7563747573206573742E2041656E65616E2061756775652E2050686173656C6C757320647569206C65637475732C20756C747269636573206E65632C20636F6D6D6F646F2076656C2C20617563746F722076656C2C206E6973692E20557420756C7472696365732070656C6C656E746573717565206E6973692E20496E74656765722061632076656C69742065742073656D20696D70657264696574206C75637475732E20467573636520766974616520747572706973206964206175677565206D6F6C6C697320636F6E7365637465747565722E0A0A4D616563656E6173206E6563206C616375732E204D616563656E617320636F6E64696D656E74756D206F64696F2065752066656C69732E204D6175726973207574206E69736C207669766572726120657261742066617563696275732061646970697363696E672E20457469616D20656765737461732E204E756E6320657420646F6C6F72207669746165207269737573206469676E697373696D20636F6D6D6F646F2E204D6F726269206C65637475732076656C69742C2074696E636964756E74206E65632C20616C69717565742076656C2C206D61747469732076697461652C206C6967756C612E204D616563656E617320756C747269636965732073656D70657220646F6C6F722E2053757370656E6469737365206D616C6573756164612E20496E7465676572206D617474697320656C69742E20446F6E656320616363756D73616E2C206C6163757320666163696C69736973207661726975732074656D7075732C206E756C6C6120656C697420706F72746120657261742C2065742072757472756D20656C69742073656D2073697420616D6574206475692E0A0A4D616563656E6173206D6F6C6C6973206D69206E6F6E206E756C6C612E20566976616D7573207475727069732E2053757370656E64697373652061206D657475732E20496E2071756973206D6920696E2074757270697320636F6E67756520617563746F722E204D616563656E6173206C616375732E2053757370656E646973736520736F6C6C696369747564696E2E2050686173656C6C757320706F727461206E756E63206E6F6E206E69736C2070756C76696E617220656765737461732E20536564206E756C6C612E20566573746962756C756D206163206D692E204D617572697320756C7472696369657320636F6E64696D656E74756D206E657175652E204E756C6C612074656D707573206A7573746F2076656C206D617373612E204E756C6C6120737573636970697420636F6E67756520617263752E205072616573656E74206964207475727069732E204D6175726973206E69626820706564652C20657569736D6F642073656D7065722C206D6F6C65737469652061632C2072686F6E6375732076697461652C20616E74652E204D616563656E617320657261742066656C69732C207669766572726120736F6C6C696369747564696E2C20736167697474697320656765742C2070656C6C656E746573717565206E65632C206F7263692E20467573636520756C74726963657320636F6E736571756174206C616375732E20416C697175616D2065726174206D61676E612C20666575676961742061742C207669766572726120612C206D6F6C6C6973206E6F6E2C207475727069732E0A0A446F6E6563206D692E204E616D2064696374756D2070656C6C656E7465737175652073656D2E20446F6E6563206D6F6C6C69732072686F6E63757320656C69742E2050686173656C6C75732072686F6E63757320706564652073697420616D65742072697375732E20446F6E656320656765742061756775652E204D616563656E6173206E6F6E206C65637475732E2050686173656C6C757320736F6C6C696369747564696E206E697369206E65632066656C69732E20416C697175616D207072657469756D2C2065737420656765742073656D70657220636F6E76616C6C69732C206E696268206E756E6320736F6C6C696369747564696E2070757275732C2069642074656D706F722070656465206475692076656C206D61676E612E20566976616D7573206163206C6F72656D2E20457469616D206E69736C20746F72746F722C2061646970697363696E672064696374756D2C20656C656D656E74756D20696E2C20666163696C69736973207365642C206E6962682E2050726F696E206D61757269732E2050726F696E2072757472756D206D6173736120656765742073656D2E204375726162697475722074656D706F722061646970697363696E6720656C69742E204375726162697475722070757275732074656C6C75732C206665726D656E74756D20656765742C20616C69717565742076697461652C20636F6E76616C6C69732061632C206D61757269732E0A0A496E746567657220636F6E7365717561742076656C69742065752065726F732074696E636964756E74207665686963756C612E204E756C6C616D206C6F72656D2073617069656E2C2072686F6E637573206E6F6E2C206D617474697320717569732C20756C747269636965732073697420616D65742C20656E696D2E2043757261626974757220636F6D6D6F646F2C206C696265726F20696E20657569736D6F642073757363697069742C2073656D207075727573206672696E67696C6C6120656E696D2C206163206D6F6C657374696520746F72746F72206F7263692065742076656C69742E20446F6E656320706564652E20457469616D20706C61636572617420636F6E64696D656E74756D207475727069732E2050686173656C6C7573206567657374617320656E696D206E6563206D61676E612E20566976616D757320636F6E64696D656E74756D2C206E756C6C612076656C206C7563747573207472697374697175652C2065726F7320726973757320766573746962756C756D206E756C6C612C20696E207665686963756C61206172637520697073756D2061742066656C69732E20446F6E656320616C697175616D20656C69742061742061756775652E205175697371756520612065726F73206575206C6967756C6120616363756D73616E2064696374756D2E20457469616D207665686963756C61207475727069732071756973206C696265726F2E20416C697175616D206E6F6E206D692E20446F6E6563206574206C656F2E2050726F696E206C656F206C696265726F2C20616C697175616D2074696E636964756E742C20636F6E677565206E65632C2061646970697363696E6720706F7274612C20656E696D2E204E756C6C61206C6F626F727469732C20746F72746F722073697420616D657420696D7065726469657420756C6C616D636F727065722C20646F6C6F72206F726369206D616C65737561646120706564652C207365642067726176696461206E6962682075726E612076656C206C6F72656D2E20536564207068617265747261206D616C6573756164612065726F732E205175697371756520657569736D6F6420616C697175657420657261742E2053757370656E646973736520616C6971756574206D61747469732070757275732E0A0A4E756E63206964206E756C6C612071756973206A7573746F20636F6E67756520736F6C6C696369747564696E2E205072616573656E742065726174207475727069732C2072686F6E6375732065752C207072657469756D2065752C2070656C6C656E74657371756520612C206E6962682E20566976616D75732074656D7075732E2043726173206E65632072697375732061742074757270697320696D70657264696574206C6F626F727469732E205574206D61747469732E204D616563656E6173206573742066656C69732C2070656C6C656E746573717565206E6F6E2C20696D70657264696574207365642C20656C656966656E642074696E636964756E742C206C6F72656D2E20496E2074696E636964756E742E205365642076656C206C656F2E20446F6E65632065742075726E6120696E207475727069732068656E64726572697420626C616E6469742E20446F6E656320636F6E64696D656E74756D20616363756D73616E206573742E2055742070686172657472612C206D65747573207669746165206D617474697320636F6E7365637465747565722C206C656F207175616D2076756C707574617465206F64696F2C206E6563206C616F72656574206E6973692076656C697420657520657261742E20496E7465676572206C65637475732061756775652C206567657374617320696E2C20696E74657264756D2065752C2076656E656E617469732076656C2C2073617069656E2E2051756973717565206574206573742076697461652065726F73206C616F72656574206C6F626F727469732E204E756C6C616D207574207269737573206E6F6E206E756C6C6120706C6163657261742061646970697363696E672E205072616573656E7420646170696275732E20457469616D20612066656C69732E20557420736F64616C657320636F6E736571756174206D61757269732E2044756973206C6F72656D2066656C69732C206C756374757320612C2074726973746971756520696E2C206D6F6C65737469652061742C2072697375732E20536564207665686963756C6120626962656E64756D2074656C6C75732E204E616D20636F6E73657175617420657569736D6F64206C616375732E0A0A41656E65616E20746F72746F7220656C69742C2067726176696461206E65632C206665726D656E74756D2065752C206C6F626F727469732069642C20697073756D2E204D616563656E61732065752070757275732E204372617320616320747572706973207574206E69736920696163756C69732072686F6E6375732E204E756C6C61207075727573206D657475732C206469676E697373696D206E65632C2074696E636964756E742076697461652C20646170696275732065752C206E6962682E204675736365206C6F626F727469732C206E756E63206174207669766572726120656C656966656E642C206A7573746F20747572706973207363656C657269737175652065726F732C2061632070656C6C656E746573717565206D65747573206E69736C2061742070757275732E2053656420656C656D656E74756D2074656C6C75732073656420656E696D20696E74657264756D20626C616E6469742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E746567657220756C7472696369657320616C6971756574206F64696F2E204D61757269732065676574206E756E63206120697073756D20756C74726963657320736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2041656E65616E20616363756D73616E2E20446F6E65632073617069656E206C65637475732C20636F6E6775652061742C20706F7274612069642C2068656E6472657269742076697461652C206E69736C2E204375726162697475722076656C207175616D2076656C206E6571756520616363756D73616E206C616F726565742E204D6F7262692073617069656E206573742C207072657469756D20696E2C20636F6E7365637465747565722061632C206D6F6C6C69732075742C206C696265726F2E20446F6E65632074696E636964756E742061646970697363696E67206D657475732E204E756E6320766573746962756C756D20656765737461732061756775652E20446F6E6563207363656C65726973717565206475692075742073656D2E2053757370656E64697373652076656C206D6574757320696420657374206D6F6C657374696520696163756C69732E0A0A566976616D75732070686172657472612C20656C6974206575206D616C65737561646120626C616E6469742C206469616D20746F72746F72206D6F6C6C6973206475692C207365642070756C76696E6172206D61737361206E756E63206574206D61676E612E2053656420706C61636572617420656C697420617563746F7220746F72746F722E204E756C6C6120616320657261742E2050656C6C656E74657371756520636F6E7365637465747565722C2064756920636F6E76616C6C69732074696E636964756E7420636F6E64696D656E74756D2C2073656D206F64696F20766F6C7574706174206C696265726F2C206E6F6E20656C656D656E74756D2066656C6973206E65717565206E6563206F64696F2E204D616563656E61732068656E6472657269742065726F73206964206469616D2E204D61757269732076656C207075727573206163206F72636920636F6E76616C6C697320636F6E76616C6C69732E205365642073697420616D6574206C616375732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652064696374756D20766172697573206C616375732E204D61757269732065676574206E69736C2E2053757370656E646973736520706C6163657261742C206E756C6C61206E6F6E206F726E617265206469676E697373696D2C206E69736C206469616D2073616769747469732074656C6C75732C20696E2073656D706572206E69736920646F6C6F72206174206E6962682E204475697320756C6C616D636F7270657220766976657272612066656C69732E20496E746567657220612074656C6C75732E2053757370656E64697373652065676574206E756E632E2041656E65616E206469616D206573742C20616363756D73616E2069642C20737573636970697420696E74657264756D2C206672696E67696C6C612076697461652C206A7573746F2E2050726F696E20706564652E204D616563656E6173206174206E6571756520696E206E6571756520766573746962756C756D20656C656966656E642E0A0A566573746962756C756D206E756C6C61206C6F72656D2C20706F72747469746F7220656765742C20657569736D6F642061632C20616C697175616D2061742C206E69736C2E204D616563656E6173206574206573742065676574206D6173736120766172697573206C6F626F727469732E20496E206D692E204475697320706F72747469746F72206665726D656E74756D2070757275732E20446F6E65632063757273757320696D70657264696574206C6967756C612E204D6F726269206574206C6967756C6120657420616E7465206D6F6C6573746965207665686963756C612E204D61757269732073656420646F6C6F722E2053656420696D706572646965742066656C69732075742073656D2E20536564207669746165206E6571756520656C656D656E74756D206C656F20617563746F72206665726D656E74756D2E2044756973206665756769617420756C6C616D636F7270657220657261742E2041656E65616E2070757275732E204D6F726269206665726D656E74756D20766573746962756C756D206573742E2050656C6C656E7465737175652076656E656E61746973206D61757269732E2050686173656C6C75732070756C76696E61722E20496E746567657220697073756D206C65637475732C20696163756C697320612C206C6163696E69612069642C20616363756D73616E2069642C20617263752E2050686173656C6C7573206174206573742E204675736365206E65717565207175616D2C20756C747269636965732069642C20696163756C69732076656C2C20646170696275732076697461652C206C616375732E20496E206C6F626F7274697320636F6E76616C6C697320616E74652E204E756C6C61206E756E632070757275732C2076756C70757461746520696E2C2068656E6472657269742065742C20626C616E6469742065742C206C6967756C612E0A0A50656C6C656E746573717565206C656F206D657475732C20736167697474697320696E2C206D6F6C65737469652076697461652C2064696374756D20696E2C20706564652E204D6F726269207072657469756D2066656C6973206E6563207175616D2E2050656C6C656E746573717565206D617474697320616E746520736564207175616D20736167697474697320646170696275732E2053757370656E64697373652073617069656E2E205072616573656E7420626962656E64756D20696163756C697320746F72746F722E20447569732061206E69736C2E2041656E65616E206D692E20446F6E65632064696374756D206172637520696E206573742E204D6F72626920696E74657264756D2076756C70757461746520697073756D2E2041656E65616E2073697420616D6574206D61676E61206E6F6E206E69736C2074726973746971756520706F73756572652E2050686173656C6C75732076656C6974206D657475732C2074656D706F722061632C206665726D656E74756D20656765742C20636F6E64696D656E74756D206E6F6E2C2076656C69742E20566573746962756C756D2073697420706F73756572652E0A0A4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204372617320616C6971756574206D61737361206E6563206475692E20437261732061726375206E756E632C2068656E6472657269742061632C20656C656966656E642065752C20756C6C616D636F72706572206E65632C2074656C6C75732E205365642070686172657472612070757275732073697420616D6574207175616D2E20437572616269747572206D6F6C6C69732E204E616D20766974616520706564652E20457469616D207269737573206D617373612C207665686963756C612073697420616D65742C207068617265747261206E65632C20736F6C6C696369747564696E2075742C206475692E20446F6E65632065676573746173206A7573746F206174207175616D2E2050726F696E206E69736C2072697375732C20766573746962756C756D206E65632C207072657469756D2076697461652C207472697374697175652061632C206C6F72656D2E20416C697175616D206572617420766F6C75747061742E204372617320736564206E6962682E2050656C6C656E74657371756520736F6C6C696369747564696E20657569736D6F642061756775652E0A0A457469616D206672696E67696C6C6120736F6C6C696369747564696E206F7263692E204D61757269732063757273757320656C69742071756973206C616375732E204372617320746F72746F722E20496E2061646970697363696E672C206C656374757320696420617563746F7220766573746962756C756D2C206E65717565207065646520616363756D73616E20646F6C6F722C206E6F6E20696D70657264696574206D61676E61206469616D20616363756D73616E2076656C69742E2053757370656E6469737365206174206C696265726F207574206E69736920626C616E6469742073616769747469732E2050686173656C6C7573206E6F6E206D61757269732E20467573636520656C656D656E74756D2073616769747469732073656D2E2053757370656E646973736520616C697175616D20656C656966656E642074656C6C75732E2050726F696E206C6967756C61206C6F72656D2C20696D7065726469657420717569732C2076656E656E617469732069642C20696163756C6973206D6F6C6C69732C206E69736C2E20457469616D20636F6E76616C6C69732070656465206174206D617373612E204D6F72626920616363756D73616E20647569206574206D61757269732E0A0A53656420736564206F7263692E204E756E632070757275732E2053757370656E646973736520706F74656E74692E205574206C7563747573206672696E67696C6C61206D61757269732E20446F6E6563206E6962682E2050686173656C6C757320706F7274612E2050686173656C6C75732073697420616D6574206F64696F20736564206D61676E6120736F64616C65732070686172657472612E2043726173206C65637475732E2053757370656E6469737365206C696265726F20697073756D2C20636F6D6D6F646F206E65632C20666163696C6973697320696E2C207375736369706974206C6F626F727469732C206C6967756C612E2044756973206D61737361206E756C6C612C2073656D7065722065742C20636F6E736571756174206E65632C2070686172657472612065752C20656C69742E20566976616D757320756C7472696369657320616C697175616D206F64696F2E20566573746962756C756D2073697420616D6574206D617373612E2053656420636F6E736571756174206C61637573207365642075726E612E20457469616D2066617563696275732066656C69732076656C206F7263692E2050686173656C6C757320756C6C616D636F727065722E2041656E65616E20636F6E736563746574756572206C61637573206174206C696265726F2E0A0A436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204475697320666163696C697369732C206C6967756C6120766974616520636F6E64696D656E74756D207363656C657269737175652C2076656C6974206F72636920677261766964612066656C69732C2076656C20756C74726963696573207175616D206D69206E6F6E206469616D2E20566976616D757320617563746F72206D65747573206E6F6E206C696265726F2E205072616573656E74206C6967756C61206E6973692C20636F6D6D6F646F20636F6E64696D656E74756D2C206D6F6C65737469652065742C20766976657272612065742C206A7573746F2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320736F6C6C696369747564696E2E204E756E6320626C616E6469742063757273757320697073756D2E2041656E65616E206E6563206C6967756C612075742074656C6C757320736F64616C6573206D61747469732E20496E74656765722073656D2E20416C697175616D206964206C6967756C612E2053656420746F72746F72206D61757269732C20626C616E6469742076697461652C206375727375732076656C2C20656C656D656E74756D2065742C206E756C6C612E20416C697175616D207363656C65726973717565206D65747573206574206E69736C2E20447569732061646970697363696E67206D61676E61206174206E657175652E20517569737175652076756C70757461746520656C656966656E64206E756E632E20416C697175616D206567657420656C69742E2050686173656C6C757320647569206F64696F2C20626962656E64756D2073616769747469732C20766573746962756C756D2069642C206469676E697373696D20696D706572646965742C206F7263692E204E756C6C616D2065752066656C6973206E6F6E206E756E63206C6163696E696120736F64616C65732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A53757370656E64697373652070656C6C656E7465737175652C206C696265726F206D617474697320756C7472696369657320616363756D73616E2C20746F72746F7220746F72746F72206D616C6573756164612073656D2C20657420736F64616C6573206C696265726F206F64696F20616320697073756D2E20566976616D75732071756973206D61676E61206E656320657374207375736369706974206C6F626F727469732E20437261732074656D70757320706F7375657265206E756E632E205175697371756520757420656E696D20612066656C697320656765737461732073656D7065722E20536564207068617265747261206D6174746973206E657175652E20467573636520747572706973206E756E632C20636F6E677565207365642C20636F6E736571756174206E6F6E2C20636F6E677565207365642C206E756C6C612E2053757370656E646973736520766172697573206C6F72656D20696420726973757320706F72746120766573746962756C756D2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204675736365207365642070757275732E20496E20612066656C69732E20496E7465676572206567657374617320617563746F72206F7263692E204D617572697320756C747269636573207375736369706974206E69736C2E204E756C6C616D2070757275732E0A0A437261732074656D706F722061646970697363696E6720697073756D2E2055742071756973206D692E204D616563656E617320696E206A7573746F207574206E756C6C6120636F6E6775652070686172657472612E2050656C6C656E746573717565207574206C696265726F20657520646F6C6F722076656E656E617469732073757363697069742E205072616573656E74206665756769617420636F6E736563746574756572206E6962682E204D6F7262692066617563696275732073656D206E6F6E2066656C69732E20496E2068656E6472657269742061726375206163206D617373612E20496E20616363756D73616E20756C747269636573206D692E2050726F696E206D616C65737561646120617563746F722066656C69732E2043757261626974757220696E74657264756D2E20536564206469616D20697073756D2C20756C7472696369657320696E2C2074656D706F722073697420616D65742C207669766572726120696D706572646965742C20656C69742E204D6F726269206D6F6C6573746965206E6973692E204D617572697320697073756D2E2046757363652064696374756D206D6F6C6C6973206D61676E612E204475697320636F6D6D6F646F206469676E697373696D206E756C6C612E20566573746962756C756D20617567756520656E696D2C20756C7472696369657320717569732C20696163756C6973206E65632C2074696E636964756E742076697461652C206469616D2E204D6175726973206C6163696E69612074656D70757320697073756D2E20536564206174206D61757269732E205574206C6F72656D2E20446F6E6563206C696265726F2E0A0A4475697320696163756C6973206C6163696E6961206C65637475732E2041656E65616E20636F6E76616C6C69732065726F7320616320616E74652E205365642071756973206F726369206E656320726973757320617563746F72206672696E67696C6C612E2050686173656C6C757320666163696C6973697320656C656D656E74756D206E6973692E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E6320706F727461206C61637573206E656320616E74652E204D6F726269206D617572697320657261742C2061646970697363696E6720696E2C2070756C76696E6172206E65632C206C6F626F72746973206E65632C206F64696F2E20557420656C656966656E64206C656374757320736564207175616D2E204E756C6C616D206D6F6C6C69732E20496E206E6F6E20747572706973206574206E69736C2068656E64726572697420626C616E6469742E204475697320656C656D656E74756D2E204E756E63206E6563206C696265726F2E2053757370656E646973736520766573746962756C756D207269737573206E6F6E20706564652E204D6F72626920696D70657264696574206F64696F2073697420616D6574206C696265726F2E2053656420736564206D6173736120766974616520697073756D206D61747469732074696E636964756E742E204E756C6C61206E656320746F72746F72207669746165206C696265726F20766F6C75747061742074656D7075732E20446F6E656320616C697175616D2E0A0A4475697320736564206E756E632E2043757261626974757220747572706973206E756C6C612C207665686963756C61207365642C206C756374757320717569732C20656C656D656E74756D20656765742C2066656C69732E204D616563656E61732065742070757275732E204D616563656E6173206C656F2074656C6C75732C2074696E636964756E7420612C20666163696C697369732076697461652C206C6F626F727469732073697420616D65742C2076656C69742E20446F6E656320636F6E76616C6C69732073617069656E2E204D616563656E6173206D6F6C6C6973206F64696F206575206E6962682E20457469616D20677261766964612E20496E7465676572206D6F6C65737469652C2073617069656E206575206D6F6C6573746965206C6163696E69612C206E756E63206E69626820616C697175616D206C6967756C612C2065752073616769747469732074656C6C7573206572617420736F6C6C696369747564696E206F64696F2E20447569732065742072697375732E2050686173656C6C7573206E697369206E657175652C20706C616365726174206E65632C20636F6E64696D656E74756D206E6F6E2C20756C7472696365732065752C2073656D2E20557420706564652E20457469616D206E756C6C61206D657475732C20766F6C75747061742069642C20636F6E76616C6C6973207365642C2073757363697069742076656C2C2075726E612E20446F6E65632076656C20656C69742E205574206C656F206E657175652C2076656E656E617469732066617563696275732C206C6163696E6961206E65632C2074696E636964756E742065752C20656E696D2E2043726173206964206475692061206C696265726F207068617265747261206469676E697373696D2E20446F6E65632065726F73206C656F2C20706F72746120717569732C206C616F726565742075742C2070656C6C656E74657371756520766F6C75747061742C206C65637475732E0A0A4E756C6C616D20626C616E6469742E20416C697175616D206572617420766F6C75747061742E2046757363652061646970697363696E6720656E696D2E2053757370656E6469737365206E6F6E206475692071756973206C6967756C6120706F72746120766573746962756C756D2E20446F6E65632065752074656C6C75732076656C206C6F72656D207072657469756D20706F72747469746F722E205072616573656E74206C75637475732E20416C697175616D2061632065726F7320696E206D6173736120646170696275732074696E636964756E742E20446F6E6563207574206D61676E612E20457469616D20617563746F72206C616375732073697420616D6574206C616375732E2053656420756C7472696369657320697073756D206E656320656C69742E205175697371756520612065737420696E207075727573207375736369706974207472697374697175652E0A0A41656E65616E20736564206475692076656C20646F6C6F722070756C76696E6172206C616F726565742E20566976616D7573207665686963756C61206C6F72656D20696E20706564652E20566976616D7573206574206469616D2E20496E7465676572206163206F64696F2076656C206469616D2068656E64726572697420626962656E64756D2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E756C6C612061206E6973692E2050686173656C6C75732074696E636964756E74206475692076697461652061756775652E20447569732066617563696275732C2064756920696E74657264756D206672696E67696C6C612074696E636964756E742C206F64696F20656C697420766573746962756C756D206C696265726F2C206163206D6F6C6573746965206D61676E61206C6563747573206964206C616375732E2041656E65616E206C6967756C612E204E756C6C6120666163696C6973692E0A0A46757363652076656C2073656D2065752076656C6974206672696E67696C6C61206F726E6172652E2053656420666575676961742074696E636964756E742066656C69732E204E756C6C616D2066656C6973206D692C20657569736D6F642073697420616D65742C206D6F6C6C69732061742C20736F64616C657320656765742C2061756775652E204E616D20696D70657264696574206E6962682061742076656C69742E2053656420757420657261742E20496E206475692E204E756C6C6120666163696C6973692E204E756C6C616D206175677565206C696265726F2C2074696E636964756E74206E65632C207072657469756D2065752C2070756C76696E617220696E2C206475692E204D6F7262692076697461652066656C69732E2050656C6C656E7465737175652076656C206A7573746F2076656C2076656C6974207361676974746973206D616C6573756164612E2050726F696E207665686963756C6120626C616E646974206D617373612E20457469616D2074696E636964756E742070686172657472612075726E612E20496E206D65747573206573742C20617563746F72206E65632C20626C616E64697420612C20637572737573206E65632C207175616D2E204D6175726973206163206D657475732061206C696265726F20636F6E6775652066617563696275732E204D6175726973206D617572697320646F6C6F722C20736F64616C657320696E2C206375727375732075742C20736F64616C65732072757472756D2C2065726F732E2051756973717565206D61757269732065726F732C2073616769747469732076697461652C206C6F626F727469732075742C20656C656966656E642069642C206E6973692E0A0A41656E65616E206E657175652E20566573746962756C756D20656765737461732070656C6C656E746573717565206C6967756C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2050686173656C6C7573207361676974746973206A7573746F2076656C2072697375732E20536564207072657469756D206E657175652076697461652075726E612E2050656C6C656E74657371756520636F6E677565206C696265726F206964206C6F72656D2E204D6175726973206C656F206C6F72656D2C20626C616E6469742073697420616D65742C20636F6E76616C6C697320717569732C20636F6E736563746574756572207365642C2065726F732E204D61757269732074696E636964756E742C20656E696D2061206772617669646120657569736D6F642C206D61676E61206E756C6C61206665726D656E74756D206C696265726F2C207669766572726120656765737461732076656C6974207175616D20657420746F72746F722E20566976616D757320616C6971756574206D61737361207669746165206A7573746F2E204E756C6C6120636F6E677565206C6163757320616320656C69742E0A0A50686173656C6C757320636F6D6D6F646F207175616D2076656C206C6967756C612E2050726F696E206E6F6E206D657475732061742065726F732070756C76696E6172206C75637475732E204D6175726973206469616D206C6F72656D2C20706F737565726520717569732C20677261766964612065742C2074696E636964756E74206E65632C206C6967756C612E20536564206469616D2E20416C697175616D20656C6974206C65637475732C2068656E6472657269742075742C20696D706572646965742073697420616D65742C207072657469756D2073697420616D65742C20697073756D2E204D6175726973207665686963756C61206E69736C20696E206475692E204375726162697475722065676574207175616D207574206D61676E6120656C656D656E74756D206665726D656E74756D2E204D6175726973207363656C657269737175652E2051756973717565206C616F726565742E20457469616D2074656D707573207475727069732E2050656C6C656E746573717565206175677565207175616D2C2068656E647265726974207365642C2074696E636964756E742061742C2070686172657472612061742C206E69736C2E20416C697175616D206C616375732E2053757370656E646973736520706F74656E74692E2041656E65616E2076656C6974206C696265726F2C20756C74726963657320696E2C206C6163696E69612065752C206C75637475732076656C2C20616E74652E20457469616D2064696374756D206D6920696E2066656C69732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20467573636520677261766964612064617069627573206E69736C2E2043726173207669746165206E69736C2E0A0A4D616563656E6173206469676E697373696D2C206C6967756C61206E6F6E20706F727461206375727375732C20656E696D206E756E63206D616C6573756164612073656D2C20657520706F72747469746F72206E756C6C612075726E61206575207175616D2E2046757363652065726F732E20416C697175616D2065726F732E204E616D20617563746F722E204E756C6C61206D6F6C657374696520706F727461206573742E2053757370656E646973736520706F74656E74692E20566976616D7573206D6F6C6573746965206C6F72656D2073656420657261742E20536564206567657420697073756D2E20496E746567657220616C697175616D2070756C76696E6172206E756C6C612E204372617320616C69717565742073656D207574206E756E632E2046757363652066617563696275732074656D707573206C65637475732E204372617320736F64616C65732C206E69736920616320666163696C6973697320756C7472696365732C2065726F73206172637520646170696275732073617069656E2C20657420756C747269636573206D61757269732074656C6C7573206E6F6E20646F6C6F722E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20437261732063757273757320766172697573206D657475732E205574207475727069732E20566976616D7573206567657420746F72746F722E0A0A536564206C616F726565742C2076656C6974206E6F6E20616363756D73616E206375727375732C206E756E632075726E6120706F7375657265206A7573746F2C20696E2064696374756D206C6563747573207065646520696420616E74652E20437261732076756C7075746174652E204372617320636F6E677565206475692073656420656C69742E2050726F696E206C616375732073656D2C20756C7472696365732061742C20636F6E73657175617420696E2C2074656D706F7220717569732C206D657475732E2050726F696E2076656C20617263752E204E616D20657569736D6F642068656E64726572697420656C69742E20557420657261742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2053656420706F73756572652E204D6F7262692065726F732075726E612C2073656D7065722061742C2073656D706572206E6F6E2C20636F6E76616C6C697320717569732C2076656C69742E204D616563656E6173206F7263692E20566573746962756C756D206C6F626F7274697320747269737469717565206D657475732E20566573746962756C756D206C6F72656D206E756C6C612C20736F6C6C696369747564696E2076697461652C20636F6E64696D656E74756D20717569732C20617563746F722075742C206475692E20566976616D757320766573746962756C756D206D61676E61207574206E6973692E2043757261626974757220656C656966656E64206475692076656C206E756E632E20437572616269747572206D6175726973206C616375732C206D616C6573756164612073697420616D65742C207375736369706974207365642C2072757472756D206C75637475732C2074656C6C75732E20496E746567657220666163696C697369732075726E61207669746165206C65637475732E0A0A41656E65616E207175616D206C656F2C206C6F626F7274697320717569732C206D616C6573756164612065752C2076756C7075746174652076697461652C206E69736C2E205072616573656E7420656765742065726F732E205574206665726D656E74756D20747572706973206964207175616D2E204E616D20746F72746F722E205072616573656E74206E6563206F7263692E204E756C6C6120626962656E64756D2061646970697363696E672061756775652E20557420636F6D6D6F646F2C206D61676E61206964206D616C65737561646120677261766964612C206175677565206F64696F206D616C657375616461206D692C20706F727461206D616C65737561646120656C697420657374207669746165206469616D2E204D6175726973206E6F6E206E756C6C612E2053757370656E64697373652074696E636964756E742C206E756E6320756C7472696369657320706F7274612076656E656E617469732C206D6920706564652074696E636964756E74206C696265726F2C20656765742076617269757320616E7465206C696265726F207574206C6967756C612E20437572616269747572207072657469756D20706F72747469746F7220746F72746F722E0A0A4D616563656E617320766974616520656C69742065676574206E69736920646170696275732064696374756D2E204E756E6320696E206C696265726F2E204E756C6C612064696374756D206F726369206575206572617420617563746F72206C6F626F727469732E2050686173656C6C75732072697375732E2053757370656E646973736520706F74656E74692E2053757370656E646973736520706F74656E74692E205072616573656E742061646970697363696E6720636F6E73657175617420656C69742E20496E74656765722069642061756775652E205072616573656E7420696E206A7573746F206E6563206D61676E6120646170696275732070756C76696E61722E2044756973206E69736C2E2053757370656E6469737365206163206F64696F2E20566976616D757320696D706572646965742E20446F6E6563206E6F6E2076656C69742073697420616D6574207269737573206469676E697373696D20636F6E6775652E204E616D20616C697175657420706F73756572652076656C69742E2043726173207475727069732E204D6F726269206D616C657375616461206469676E697373696D206D692E0A0A536564206C656F206E657175652C2076617269757320717569732C2076656E656E61746973207365642C207068617265747261207365642C206573742E204D6F72626920626C616E6469742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D2073656D7065722070656C6C656E746573717565206D692E2055742076656C206C6F72656D2E204E756E63206D6920746F72746F722C206C616F726565742061742C2066617563696275732065752C2074696E636964756E742073697420616D65742C20657261742E20447569732074656D706F72206D616C65737561646120697073756D2E2050686173656C6C757320616C69717565742E20446F6E656320657420656C69742E2050656C6C656E7465737175652070757275732E20566573746962756C756D2072757472756D2073656D706572206E6962682E204E756C6C6120666163696C6973692E2050686173656C6C757320657420656E696D2073697420616D657420616E746520766573746962756C756D207665686963756C612E2050686173656C6C7573206964206E69736C2E20446F6E6563206D6F6C6C6973206C656F2061742065726F732E204D61757269732070656C6C656E746573717565206E657175652061742070757275732E204D6F726269207175697320646F6C6F7220617420697073756D207363656C6572697371756520736F64616C65732E20457469616D20766F6C7574706174207475727069732061206D657475732E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206C6F72656D206C6F72656D2C20766573746962756C756D2061632C20657569736D6F6420656765742C20756C6C616D636F72706572206469676E697373696D2C2076656C69742E0A0A43756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204372617320756C7472696365732C206E6962682076656C20616C697175616D20766573746962756C756D2C2065726F7320656E696D2076656E656E61746973206475692C20696420696163756C697320656E696D206E756E632076656C206D617373612E204D6F72626920656C656966656E64206F726369206574206D617373612E20416C697175616D206572617420766F6C75747061742E204E756C6C61206D6F6C6C69732065676573746173207475727069732E20496E20736F64616C6573206E756E63206567657420746F72746F722E2053656420697073756D2065726F732C2074656D706F7220717569732C20616C69717565742076697461652C20696D70657264696574206E6F6E2C206C6F72656D2E2050656C6C656E746573717565207175697320656C6974206964206D69206C756374757320646170696275732E20536564206E756E6320617263752C2072686F6E637573206E65632C20636F6E76616C6C697320717569732C206375727375732061742C206E657175652E204D617572697320636F6E76616C6C697320707572757320617420657261742E2050656C6C656E74657371756520766573746962756C756D2E20566976616D7573206672696E67696C6C6120656C697420617420617263752E204E756C6C616D20616C697175657420656E696D206E656320617263752E204E616D20696420746F72746F722E204E756C6C612071756973206E756E632E20557420617263752E2053757370656E646973736520706F74656E74692E2050656C6C656E74657371756520756C6C616D636F72706572206C6967756C6120696420617263752E0A0A4E616D206E6F6E206C696265726F207669746165206E69736C207363656C65726973717565206672696E67696C6C612E20517569737175652076617269757320616E7465206964206D657475732072686F6E637573206672696E67696C6C612E204E756C6C6120666163696C6973692E205072616573656E7420656C656966656E6420706F72747469746F72206C6967756C612E20457469616D207175697320646F6C6F72206E6F6E20617567756520636F6D6D6F646F20617563746F722E20446F6E65632061206D692E20566573746962756C756D2074656D706F722E20446F6E65632066656C69732075726E612C20617563746F722061742C206375727375732064696374756D2C20677261766964612069642C20617263752E2041656E65616E2064696374756D206D616C65737561646120646F6C6F722E20566976616D7573206D61747469732E2050686173656C6C757320657520706564652E2046757363652061646970697363696E67206A7573746F206672696E67696C6C61206D657475732E20457469616D20616E74652E20496E7465676572206D6F6C6C6973206D617373612071756973206E756E632E20496E74656765722064696374756D206E65717565206C756374757320656E696D2E0A0A536564206575206C696265726F2E20496E74656765722074656D706F72206C6967756C6120696E2076656C69742E2055742074696E636964756E74206C6163696E69612073656D2E204E756C6C616D2076656C2072697375732E2053656420736F64616C657320616E7465206120646F6C6F722E204375726162697475722065726F732E2053656420736F64616C65732E20536564206E6F6E206D657475732E20566573746962756C756D20656C656D656E74756D20666175636962757320616E74652E204E756C6C612076656C206E6962682E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206E6563206C6F72656D20757420697073756D206C6163696E696120696163756C69732E204475697320657261742E20416C697175616D20657261742E204372617320696163756C69732E20496E206861632068616269746173736520706C617465612064696374756D73742E0A0A4E756C6C616D20616E74652E2043726173207669746165206573742E2050656C6C656E7465737175652076656C206D657475732061206C6967756C612064617069627573206D61747469732E2044756973206665756769617420616C69717565742066656C69732E20457469616D206964206E69736C207175697320657374206469676E697373696D20636F6E64696D656E74756D2E2053757370656E646973736520706F74656E74692E204D6F7262692076656C6974206C6F72656D2C206F726E61726520717569732C2070656C6C656E7465737175652076656C2C20706C61636572617420656765742C20746F72746F722E20566573746962756C756D2074696E636964756E74206D6F6C6573746965206C696265726F2E204E756C6C61206E756C6C6120656E696D2C206D616C6573756164612069642C20756C6C616D636F727065722076697461652C2064696374756D2061742C2070757275732E20446F6E6563206469676E697373696D206F64696F20757420656E696D2E2053757370656E6469737365206174206C65637475732E0A0A5072616573656E74206C6F626F727469732061756775652076656C206C65637475732E20557420696E206C6967756C612075742066656C697320636F6E6775652073757363697069742E2051756973717565206469676E697373696D20746F72746F72207574206D692E204675736365206D61676E61206E6973692C20656C656966656E642061632C206F726E6172652076656C2C20706F72747469746F722076697461652C207175616D2E20566573746962756C756D20736F64616C6573206A7573746F2071756973207475727069732E2046757363652075726E61206E6973692C2072686F6E63757320717569732C20636F6E64696D656E74756D2076656C2C2064696374756D2065752C206E756E632E20467573636520736564206E696268207669746165206F64696F20706F73756572652061646970697363696E672E2053656420706F72746120656C6974207175697320646F6C6F722E204E616D206C696265726F206E756C6C612C20617563746F72207365642C2074696E636964756E7420717569732C2066617563696275732073697420616D65742C206D692E2051756973717565206F7263692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E756C6C616D2069642073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632076656C2065726F732E0A0A566976616D7573206C7563747573206C6F626F72746973206C656F2E2053757370656E64697373652076656C20656C6974206120656E696D20756C6C616D636F7270657220706F73756572652E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20446F6E656320717569732070656465206D6174746973206C6563747573206D6F6C6C69732061646970697363696E672E2053656420616363756D73616E20706F737565726520657261742E205072616573656E7420657569736D6F642074696E636964756E742066656C69732E20446F6E6563206D692E20557420636F6D6D6F646F2061726375206C6163696E69612074656C6C75732E20416C697175616D2061206C696265726F2071756973206C65637475732073656D70657220766976657272612E20437572616269747572206C6163696E6961206D61757269732061742074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E756E632073697420616D6574206D61676E61206D6F6C6573746965206F726369207375736369706974206672696E67696C6C612E204675736365207072657469756D206D65747573206E6F6E2073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642068656E6472657269742E204E756C6C612066656C69732E2053757370656E646973736520706F74656E74692E20416C697175616D20626C616E64697420747269737469717565206E657175652E20437572616269747572207175697320657261742076656C206E756E6320616363756D73616E206D6F6C6C69732E0A0A447569732073616769747469732C2074656C6C757320757420616C697175616D206672696E67696C6C612C20646F6C6F72206D6920756C6C616D636F72706572206E69736C2C20757420747269737469717565207065646520656C697420736564206D61757269732E204375726162697475722069642066656C69732E20446F6E65632070756C76696E6172206C61637573206574206C65637475732E20416C697175616D2076756C7075746174652076756C707574617465206D657475732E20437572616269747572206D61676E612066656C69732C2061646970697363696E672061632C20616363756D73616E2076656C2C206D6F6C657374696520717569732C207175616D2E204D617572697320656C697420617263752C207072657469756D2076697461652C206D6F6C6C69732073697420616D65742C20736F6C6C696369747564696E2075742C206D692E20446F6E656320696D70657264696574206469676E697373696D206D692E204E756C6C616D2073697420616D657420746F72746F722E20416C697175616D206E65717565206E756C6C612C2076656E656E6174697320612C20706F72746120696E2C20706C6163657261742074656D7075732C206C616375732E205175697371756520766573746962756C756D20647569206574206C616375732E2050726F696E206469676E697373696D20636F6E7365637465747565722070757275732E20457469616D206772617669646120746F72746F7220696E206E756E632E2055742074656D706F722074726973746971756520746F72746F722E20536564206C616F726565742074696E636964756E74207175616D2E20566573746962756C756D20706F7274612074757270697320757420656C69742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20446F6E6563206E696268206475692C2066657567696174206E65632C206C616F726565742069642C206D616C65737561646120656765742C206E6973692E205574206E65717565206D617373612C207665686963756C612065752C20636F6D6D6F646F206E6F6E2C20756C747269636965732076697461652C2070757275732E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204D617572697320657569736D6F642C2066656C69732076656C2074656D706F7220616C69717565742C20746F72746F72206D6175726973206D616C657375616461206E756E632C2076656C206665726D656E74756D2073656D206469616D206964206475692E204E616D2072757472756D2073617069656E2065676574206F64696F2E20416C697175616D20736564206C696265726F206E6F6E206D692066617563696275732074656D7075732E2046757363652068656E6472657269742C206469616D206E6F6E20766F6C75747061742072757472756D2C2065726174206D657475732076656E656E61746973206C6967756C612C206E6F6E207363656C657269737175652070656465206C6967756C612076656C207175616D2E204D6F7262692072686F6E6375732065726F7320616320647569206665756769617420656C656D656E74756D2E2044756973206575206C696265726F2065742074656C6C757320636F6E67756520766976657272612E204D6F726269207175616D207175616D2C20656C656D656E74756D207365642C20756C6C616D636F7270657220696D706572646965742C20636F6D6D6F646F206E6F6E2C206F64696F2E204E616D20616C697175657420656765737461732075726E612E204D6175726973206F64696F2066656C69732C207661726975732065752C206C6163696E69612065752C20636F6E64696D656E74756D20612C206C65637475732E20536564206A7573746F206D617373612C2070756C76696E61722069642C2076617269757320612C20706F72747469746F72206E65632C206C696265726F2E20457469616D207661726975732E2043757261626974757220736F64616C65732C206F64696F20617420706F73756572652073656D7065722C2065726F73206E6962682074696E636964756E74206C65637475732C2076656C2072757472756D2073617069656E206E69736920696E206C6967756C612E2053757370656E6469737365206567657420617263752E2050686173656C6C757320696D70657264696574206573742061632073617069656E2E20446F6E6563206E756C6C6120746F72746F722C20706C6163657261742076656C2C2074656D70757320612C206C6F626F727469732076656C2C206E6962682E20416C697175616D20766172697573206E6973692E204E756C6C6120657420656E696D2E20467573636520636F6E76616C6C6973206C616F72656574206C616375732E0A0A50686173656C6C757320697073756D20646F6C6F722C206D6F6C657374696520717569732C20636F6E64696D656E74756D20696E2C20636F6D6D6F646F2065752C206469616D2E205175697371756520626962656E64756D206C6163696E6961206475692E204E756C6C616D20626C616E6469742076756C707574617465206F7263692E205574206C6163696E6961206D617373612076656C2061756775652E20416C697175616D20677261766964612C207175616D207175697320696D7065726469657420696D706572646965742C2074656C6C7573206469616D20706861726574726120657261742C206174207068617265747261206C61637573206E6962682065676573746173206D61676E612E204E756C6C61207361676974746973206C6F72656D207574206C6F72656D2E204475697320636F6E64696D656E74756D2C2064756920766974616520616C697175616D20706F73756572652C206469616D207175616D20636F6E76616C6C69732076656C69742C2075742067726176696461206C656F20697073756D206E6F6E2072697375732E205574206665726D656E74756D20736F6C6C696369747564696E20657261742E20446F6E6563207361676974746973207363656C657269737175652066656C69732E204E756E6320617263752E20457469616D2074656D7075732C206D61676E612073697420616D657420737573636970697420657569736D6F642C2065726F732073656D2072757472756D206475692C207669746165207361676974746973206E696268207075727573206E6F6E206C616375732E20536564206D6F6C6C69732061726375206567657420646F6C6F722E20446F6E6563206F726E6172652C20617263752073697420616D6574206665726D656E74756D2076756C7075746174652C20726973757320656E696D206665726D656E74756D206C696265726F2C2061206C6163696E696120646F6C6F72206D69206E6F6E2076656C69742E20457469616D206C6F626F72746973207075727573206120656C69742E204E756E63206E756C6C61206475692C206D617474697320717569732C20626962656E64756D20612C20756C7472696365732061632C2061756775652E20496E20616C697175616D207665686963756C61207475727069732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A496E7465676572206964206E69736C2E20517569737175652064696374756D20656C656D656E74756D206F64696F2E2041656E65616E206C75637475732E205365642065752073656D206120706564652076756C70757461746520636F6E64696D656E74756D2E2051756973717565206D61676E612E20446F6E656320616C697175616D206D617474697320697073756D2E204375726162697475722064696374756D20736F6C6C696369747564696E2073656D2E20416C697175616D2070756C76696E61722E204E756E6320736F6C6C696369747564696E207269737573206120657261742E20566976616D757320717569732074656C6C75732073697420616D6574206E69626820766573746962756C756D20636F6E7365717561742E204E756C6C61207072657469756D20736F6C6C696369747564696E20646F6C6F722E20416C697175616D20696163756C69732074696E636964756E74207475727069732E2050686173656C6C757320697073756D206C656F2C2076656E656E6174697320696E2C20736167697474697320696E2C206F726E6172652061742C206E756E632E0A0A50656C6C656E74657371756520756C7472696365732C2064756920657520696163756C6973206C75637475732C2074656C6C757320617567756520766F6C75747061742073617069656E2C20696E206469676E697373696D2075726E612066656C6973207574206D692E205365642061726375206475692C206469676E697373696D2069642C20706F72747469746F722075742C20696D706572646965742076697461652C20616E74652E204E756C6C61206475692073656D2C20636F6D6D6F646F206E65632C2073616769747469732065742C206C6163696E69612065742C20706564652E20457469616D20656C656966656E6420647569207574206E69736C2E20446F6E656320616E7465206D61757269732C2074656D7075732073697420616D65742C207661726975732076697461652C206772617669646120717569732C206D692E20496E207363656C657269737175652C2066656C697320766974616520766976657272612073616769747469732C2076656C6974206D6574757320756C74726963696573206E657175652C207175697320696D706572646965742076656C697420656C6974206574206D61676E612E2053757370656E646973736520706F74656E74692E205365642076656C69742065726F732C20657569736D6F64207365642C20636F6E64696D656E74756D206E65632C206661756369627573207365642C2073617069656E2E204E616D20616363756D73616E206C6967756C612073697420616D6574206E657175652E20416C697175616D206572617420766F6C75747061742E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E616D20657520706564652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642065752066656C69732073656420746F72746F722074656D706F72206665726D656E74756D2E2050686173656C6C757320636F6D6D6F646F2073656D2076656C206E69736C2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050726F696E206C656374757320656C69742C2070686172657472612073697420616D65742C20616363756D73616E207365642C2074696E636964756E742065742C206D61757269732E204475697320646170696275732070686172657472612073656D2E20496E746567657220696E206A7573746F2E205072616573656E742065726F732E20566573746962756C756D20616320616E74652E20416C697175616D207363656C657269737175652073656D2070656C6C656E746573717565206E69626820636F6E73656374657475657220736F64616C65732E20416C697175616D20636F6E736563746574756572206F64696F2E2044756973206C6563747573206F64696F2C206C75637475732065752C20636F6D6D6F646F20717569732C206D6F6C6C69732076697461652C2076656C69742E2043726173206E6563206E756E63206E6F6E20656C697420696163756C6973206D61747469732E2041656E65616E206A7573746F206E657175652C20736F6C6C696369747564696E20656765742C20756C6C616D636F7270657220656765742C20656765737461732069642C2073656D2E20496E2065752072697375732E2053656420656765737461732E0A0A496E7465676572206174206E657175652E20536564207072657469756D207363656C65726973717565206E756C6C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20467573636520757420706564652E20457469616D207669746165207175616D20612075726E612076617269757320696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2044756973207665686963756C612E20467573636520756C6C616D636F72706572206E696268206E6F6E20657261742E205175697371756520696E206E657175652E205072616573656E74206573742E2050656C6C656E74657371756520617263752E0A0A50726F696E20706F73756572652E2053757370656E646973736520706F74656E74692E20496E74656765722066656C6973206C616375732C20616C697175616D207365642C2076756C70757461746520696E2C206D6F6C6C69732076656C2C2074656C6C75732E20496E7465676572207665686963756C6120626962656E64756D206573742E204E756E63206E6F6E20646F6C6F7220696E2074656C6C7573206D617474697320666163696C697369732E20496E746567657220766573746962756C756D2C20617567756520617420636F6D6D6F646F20616C697175616D2C2064756920657374206D6174746973206C6967756C612C2073697420616D65742061646970697363696E67206F7263692073656D207669746165206D61676E612E205072616573656E7420656E696D2076656C69742C206D616C6573756164612061742C20636F6E677565206E65632C206C756374757320696E2C206A7573746F2E20536564207661726975732E204D6F7262692070686172657472612E20446F6E6563206575206D61737361206E65632074656C6C75732076756C7075746174652070756C76696E61722E20557420636F6D6D6F646F20747572706973206E6F6E2073656D2E20557420636F6E76616C6C697320756C6C616D636F727065722072697375732E20457469616D20696E74657264756D2070656465206964206E6973692E2043726173206D61676E612073617069656E2C20737573636970697420612C206C616F72656574206E6F6E2C2072686F6E6375732065742C2066656C69732E20496E7465676572206F726369206C6F72656D2C20766573746962756C756D2064696374756D2C20756C6C616D636F7270657220612C20706F72747469746F722065742C206475692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A4E756E63206574206D61676E612E2053656420626962656E64756D2074656C6C757320696E206469616D2E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E616D20766974616520746F72746F722E20496E7465676572206D61676E612E20447569732076656E656E617469732C206C656F2061632074656D706F72206C616F726565742C20656C6974206E756C6C6120706861726574726120706564652C206E6F6E206665726D656E74756D206E756E63206F64696F2061206F64696F2E2050726F696E206E6F6E2076656C69742E2053656420696D706572646965742061756775652071756973206E69736C2E20496E746567657220636F6E64696D656E74756D206E69736C206E6563206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20566976616D757320706C616365726174206C696265726F2E204475697320636F6E6775652064696374756D206D61676E612E20416C697175616D206461706962757320626962656E64756D20656E696D2E204E756E6320656C656966656E6420706564652076656C20697073756D2E0A0A457469616D2076697461652076656C69742E204D61757269732065726174206E756E632C206D616C6573756164612075742C20666575676961742061632C20706C61636572617420636F6E64696D656E74756D2C2061756775652E204E616D20766F6C75747061742E20416C697175616D207665686963756C6120697073756D206964206F64696F2E20566976616D757320736F6C6C696369747564696E207475727069732069642073617069656E2E20467573636520612066656C6973207669746165206F64696F20636F6E76616C6C697320626C616E6469742E204375726162697475722076697461652065726F732069642065726F7320706F727461207072657469756D2E204E756C6C6120696E206D61676E6120656765742075726E61206C6163696E696120636F6E76616C6C69732E20416C697175616D206D61747469732076656E656E617469732070757275732E2053656420736564206D69206567657420657261742074726973746971756520706F7274612E20446F6E656320617563746F7220646F6C6F72206120657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20496E206E6563206C6967756C612E204E756E6320656C656966656E642E20566573746962756C756D2071756973206E697369206567657420656C697420706F72747469746F7220636F6E6775652E204D616563656E61732066617563696275732C206D61676E6120656765742061646970697363696E672074696E636964756E742C20646F6C6F7220616E7465206D616C65737561646120656C69742C206E6F6E20656C656D656E74756D206C616375732074757270697320696E20706564652E0A0A5574206D616C657375616461206D69206E6563206D657475732E205072616573656E7420617563746F72206175677565206163206E69736C20756C7472696369657320666163696C697369732E204E616D2070757275732073617069656E2C2070656C6C656E746573717565206469676E697373696D2C20706F73756572652065752C206375727375732069642C206469616D2E205175697371756520736F6C6C696369747564696E2C20656C697420612070656C6C656E746573717565207363656C657269737175652C206C6F72656D20726973757320617563746F72207175616D2C207175697320636F6E7365717561742074656C6C7573206E657175652069642075726E612E2053757370656E6469737365206469616D20746F72746F722C20656C656966656E64206469676E697373696D2C20656765737461732075742C206C756374757320696E2C20616E74652E204475697320616E74652E204D616563656E6173206C75637475732E20437572616269747572206375727375732070686172657472612075726E612E204D616563656E617320696D706572646965742C2065726174206E6F6E20656C656D656E74756D20657569736D6F642C20746F72746F72206F64696F20657569736D6F64206C65637475732C20616320666163696C697369732073656D206E696268207669746165206E756C6C612E204E756E6320677261766964612E204D6F72626920736F6C6C696369747564696E206F64696F2071756973206C616375732E20416C697175616D2061206E696268206E6F6E2075726E6120706F72746120696D706572646965742E20416C697175616D206572617420766F6C75747061742E20496E20696163756C6973206C6163696E69612076656C69742E20536564206C696265726F206C616375732C207472697374697175652065752C206C6163696E69612061632C20616C697175657420656765742C2075726E612E0A0A457469616D206174206E69736C2E2050686173656C6C7573206661756369627573206C7563747573206C65637475732E20557420706C6163657261742076756C70757461746520646F6C6F722E2050686173656C6C75732076656C2076656C69742E204D6F72626920766976657272612E2050686173656C6C7573206F7263692E20496E7465676572206469676E697373696D206D6174746973206D61757269732E2050656C6C656E74657371756520706F7375657265206C656F20706F7375657265207175616D2E2051756973717565206E6563206D61676E61206174206469616D20766976657272612070656C6C656E7465737175652E2053757370656E64697373652076656C697420617263752C20756C7472696369657320717569732C20636F6E67756520612C2076656E656E6174697320656765742C206C616375732E20496E74656765722073616769747469732068656E64726572697420646F6C6F722E2046757363652074696E636964756E7420616E746520612073656D2E0A0A4D616563656E617320636F6E7365637465747565722C206A7573746F207365642072686F6E6375732076656E656E617469732C206E69626820617263752072757472756D20646F6C6F722C2073656420636F6E64696D656E74756D206C696265726F206C696265726F20657420697073756D2E20566976616D7573206D6174746973206A7573746F207574206C6F72656D2074696E636964756E74206C6F626F727469732E205574206E6F6E2076656C6974206964206E6571756520616C697175657420616363756D73616E2E205365642074656D7075732076697665727261206E756C6C612E2043757261626974757220756C6C616D636F727065722C206E6571756520717569732064617069627573207363656C657269737175652C2066656C6973206469616D2067726176696461206F7263692C206E6F6E20637572737573207175616D206E6571756520766974616520656C69742E20457469616D2070686172657472612074696E636964756E74206C616375732E204475697320657569736D6F64206672696E67696C6C61206573742E20457469616D206F726E6172652074696E636964756E74206C65637475732E2050726F696E20696E207475727069732E204E756E6320626C616E64697420626C616E646974207475727069732E2041656E65616E2075742061756775652E2044756973206F726369206A7573746F2C2074696E636964756E742065752C2072757472756D207365642C2072757472756D2065742C207475727069732E2043757261626974757220666163696C69736973206F64696F20696E20616E74652E20496E206861632068616269746173736520706C617465612064696374756D73742E205365642065726F73206573742C2070656C6C656E7465737175652061742C2074696E636964756E742065752C20756C74726963657320717569732C206D657475732E204D6F7262692073697420616D6574206A7573746F2E204D616563656E617320616320617263752E204D6175726973206469676E697373696D2E0A0A50656C6C656E74657371756520756C747269636965732072757472756D206F7263692E2041656E65616E206F726E6172652E20566976616D75732065752072697375732076656C206D6175726973206C6F626F727469732064696374756D2E205365642065742074757270697320617563746F72206D692072686F6E6375732070756C76696E61722E20536564206E6563206E756E6320612070757275732074656D706F7220766976657272612E2050656C6C656E7465737175652073757363697069742E20446F6E656320747269737469717565207269737573206E6F6E206E6962682E20457469616D206E69736C206D61676E612C20736F6C6C696369747564696E2075742C20756C7472696365732073697420616D65742C20656765737461732065752C206E756C6C612E20416C697175616D206572617420766F6C75747061742E20566573746962756C756D2070686172657472612E2053656420656765737461732C206D657475732073697420616D6574206C6F626F7274697320636F6E7365717561742C206572617420656C697420696D70657264696574206C696265726F2C20657520696E74657264756D207175616D206D61737361206567657420646F6C6F722E2053757370656E6469737365207669746165206F64696F2E2050726F696E20626C616E646974206D617572697320696163756C6973206D657475732E0A0A566976616D757320766573746962756C756D2E20457469616D206574206E69736C2E20416C697175616D20696E206469616D2076656C20656C697420706C6163657261742073757363697069742E204475697320736F64616C6573207075727573206163206E6962682E204E756C6C6120696E206F64696F206567657420656E696D206C756374757320626C616E6469742E2043757261626974757220756C74726963657320697073756D206E6F6E206E65717565206567657374617320656C656966656E642E20536564207475727069732E2050726F696E20636F6E7365637465747565722E20566976616D7573206D61747469732E20496E20616C69717565742E0A0A4E756E632069642065726F732E20446F6E65632076656E656E617469732C206E756C6C61206574206D6174746973206C75637475732C20616E7465206C656F2073656D706572206A7573746F2C206E6F6E2061646970697363696E67206F64696F20726973757320736564206C616375732E205072616573656E7420766974616520726973757320636F6E677565206C696265726F20636F6E6775652074656D7075732E2050686173656C6C75732061632065726F732E204E756C6C61207665686963756C612C206C6F72656D20696E20616C69717565742073757363697069742C2061726375206572617420656765737461732073656D2C2071756973206C6F626F72746973207175616D20616E7465206575206D617373612E20437572616269747572206E6F6E206D617373612E2053656420626962656E64756D206C6163696E6961206F64696F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20566976616D757320766F6C757470617420626C616E646974206C616375732E2050726F696E20706F7274612C2074656C6C757320757420617563746F72206C616F726565742C206C65637475732065726F73206665726D656E74756D206C65637475732C2069642073616769747469732061726375206A7573746F20696E207475727069732E2050686173656C6C757320636F6E7365717561742E204E616D2070656C6C656E7465737175652C206D69206964207669766572726120636F6E76616C6C69732C206E756E63206C696265726F20706C616365726174206C656F2C20656C656966656E6420706F7274612073656D206E69736C2076697461652073617069656E2E2050656C6C656E746573717565206C6967756C61206C696265726F2C20747269737469717565206E6F6E2C20706F72747469746F722072757472756D2C20706F72747469746F72206E6F6E2C20657261742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E74656765722064696374756D2074656C6C7573206120746F72746F722E20566976616D75732066656C6973206E756E632C206D6F6C6573746965206E6F6E2C2072686F6E63757320717569732C2070686172657472612069642C206475692E20446F6E6563207269737573206D657475732C206672696E67696C6C612076656C2C20616C69717565742065752C20706C6163657261742069642C206E657175652E0A0A53757370656E646973736520697073756D2E20566976616D7573206C65637475732E2053656420766976657272612C206D61737361206567657420636F6E76616C6C6973206D61747469732C207175616D2074757270697320636F6E736563746574756572206E756E632C206567657420706F7375657265206D61676E612073656D2069642076656C69742E20496E206E6563206D61757269732E2041656E65616E206120707572757320736564207175616D206C6F626F72746973206672696E67696C6C612E2050726F696E20756C74726963696573206C6163696E696120616E74652E205365642061646970697363696E67206572617420717569732076656C69742E204E756C6C616D207669746165206E69736C206964206A7573746F20736F6C6C696369747564696E206D6F6C65737469652E204E756C6C6120666163696C6973692E20536564206E65632075726E6120736564206E69736C206672696E67696C6C6120646170696275732E204E756C6C61206174206469616D2E20416C697175616D2065676574206E6962682E204E756E63206163206E6973692073697420616D65742074656C6C757320656765737461732074656D7075732E204E616D207363656C657269737175652075726E61206574206E657175652E20446F6E656320657374206F7263692C207361676974746973206E6F6E2C2076756C70757461746520612C20636F6D6D6F646F2065742C2061756775652E205574206461706962757320746F72746F722E205574206E756E632E20446F6E65632064696374756D2064617069627573206F64696F2E204E616D20756C7472696369657320756C6C616D636F72706572206C6967756C612E2050656C6C656E74657371756520616363756D73616E20766172697573206C656F2E0A0A4D6F72626920657569736D6F64206C616F7265657420657261742E20566976616D7573207175697320697073756D2E204D6F72626920657569736D6F642E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2053757370656E64697373652076656C2070757275732E204E756C6C616D206174206D61676E612E20437572616269747572206C61637573206C6F72656D2C20696163756C697320717569732C2064617069627573206E6F6E2C20766F6C75747061742076656C2C206E756C6C612E20446F6E656320757420617263752072686F6E63757320646F6C6F72207072657469756D2064696374756D2E204E756C6C616D2076656C206D657475732E20557420617263752E2050656C6C656E746573717565206E697369206E756E632C20706C61636572617420656765742C2074696E636964756E742076656C2C207068617265747261206E6F6E2C206E756E632E20496E74656765722074696E636964756E7420756C74726963696573206C65637475732E20496E74656765722073656D7065722C2070757275732073656420756C74726963657320666575676961742C206E756C6C61207065646520736F6C6C696369747564696E20657261742C2076656C20617563746F72206E756C6C6120697073756D2076656C206C65637475732E2041656E65616E206D692E0A0A4E756C6C616D20736564206E697369206574206172637520696D70657264696574206665726D656E74756D2E204D6175726973206E6563206D657475732E20496E20616320646F6C6F722E20496E206D6920617263752C20636F6E6775652061632C207068617265747261206E65632C207363656C657269737175652073697420616D65742C206D61676E612E20437572616269747572206C616375732E2043757261626974757220657420656C69742E20416C697175616D20756C6C616D636F72706572206E756E6320657520656C69742E2053656420636F6E76616C6C697320646F6C6F722061742076656C69742E20566573746962756C756D20646170696275732C20617567756520696420636F6E73656374657475657220706C6163657261742C206E756E63206D6173736120626C616E6469742073617069656E2C20696420616C697175616D20656C6974206E697369206964206D692E2050686173656C6C75732073617069656E206573742C20677261766964612065752C20626962656E64756D2075742C2061646970697363696E6720717569732C206573742E205574206D6F6C6573746965207175616D207669746165206F64696F2E20446F6E65632071756973207269737573206964206572617420666175636962757320736F6C6C696369747564696E2E204E616D2069642066656C69732E204D61757269732073656420656E696D207669746165206C656F20616363756D73616E207072657469756D2E0A0A4E616D206A7573746F2E20446F6E656320747572706973206E69736C2C20636F6D6D6F646F2065742C20696E74657264756D2061632C20636F6E736563746574756572206E6F6E2C206D617373612E2046757363652073656D206D657475732C206C616F72656574206E65632C20706F73756572652069642C20696D7065726469657420696E2C2076656C69742E20446F6E65632076756C707574617465206A7573746F2065676574207475727069732E204E756C6C6120706564652E204D6F7262692074696E636964756E742E20467573636520616C69717565742C207175616D20657420616C697175616D206672696E67696C6C612C20616E746520616E746520696163756C6973206475692C206E656320616C697175616D20617263752070757275732073656420657261742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050686173656C6C7573207375736369706974207175616D206574206573742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B0A0A496E7465676572207365642074656C6C75732E20536564207365642076656C697420756C74726963696573206C656F2072757472756D206C616F726565742E20536564206E6F6E2065726F7320616320707572757320736167697474697320666575676961742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E205365642068656E647265726974206C6967756C612073697420616D6574206E6962682E204D616563656E6173207475727069732E204D6F72626920636F6E7365637465747565722C20646F6C6F722065742061646970697363696E6720696D706572646965742C20616E7465206E65717565206665756769617420646F6C6F722C20617420706F727461207175616D206E657175652071756973206C6967756C612E204D61757269732073656D7065722076656C69742073697420616D657420697073756D2E2050656C6C656E7465737175652074656D7075732C20707572757320696E2072757472756D20636F6E7365717561742C20656E696D2065726174207665686963756C61206D617373612C20696420616363756D73616E206C656F2073617069656E206E65632070757275732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E20646F6C6F722E20496E746567657220666163696C69736973206C696265726F2073697420616D657420706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2055742076617269757320616C697175657420656E696D2E204E756C6C6120666163696C6973692E2043757261626974757220636F6E7365637465747565722C206F64696F206575207072657469756D2074696E636964756E742C206E756E63206E69736920616C6971756574206E657175652C2076656C20696D7065726469657420656C6974206D617373612073697420616D6574207475727069732E2050656C6C656E7465737175652074656D7075732C206F72636920766F6C757470617420626C616E646974206672696E67696C6C612C206F64696F2073656D20706F737565726520616E74652C20766974616520626962656E64756D2075726E61206C6F72656D2076697461652065726F732E205072616573656E7420766976657272612072686F6E63757320617263752E2053656420617563746F722C206573742073697420616D6574206D6F6C6C6973206D6F6C6C69732C207175616D207175616D20677261766964612073617069656E2C20696E20636F6D6D6F646F206D65747573206E756C6C6120617563746F7220656E696D2E20446F6E656320666163696C697369732E0A0A50726F696E2074696E636964756E742C2073617069656E206567657420756C747269636965732061646970697363696E672C20657374206F64696F2064696374756D20617263752C207574206D6F6C6C69732065726174206475692073697420616D65742076656C69742E204D6F726269206573742073656D2C20696E74657264756D2061742C20636F6E67756520612C20656C656D656E74756D2076697461652C206D657475732E2053757370656E64697373652069642061756775652E204D617572697320656E696D2073656D2C2070756C76696E617220656765742C2074656D70757320612C2074656D7075732073697420616D65742C2073617069656E2E20467573636520766573746962756C756D20636F6E736563746574756572206475692E2050656C6C656E74657371756520657261742E20536564206469676E697373696D20706C616365726174206F64696F2E204D616563656E61732073656D7065722072686F6E637573206C65637475732E2050686173656C6C7573207072657469756D2E2044756973206C696265726F20656C69742C20656C656966656E64206E65632C20656765737461732075742C20637572737573207365642C2066656C69732E204E616D206E69736C20617263752C20616C69717565742065742C20666163696C697369732065752C206C75637475732075742C2072697375732E20457469616D20756C7472696365732C20646F6C6F722073656420766F6C7574706174206D616C6573756164612C20747572706973206172637520696D7065726469657420746F72746F722C20657569736D6F6420636F6D6D6F646F206C696265726F206D61737361207574207175616D2E20496E7465676572206D6F6C6573746965207075727573206E6F6E20656C69742E2055742076656E656E617469732073656D70657220746F72746F722E20457469616D20626962656E64756D206567657374617320697073756D2E204D617572697320736F6C6C696369747564696E2073656D206E6563206E6962682E204E756C6C61207072657469756D206D65747573206575206D657475732E2050656C6C656E7465737175652073697420616D65742073656D2E0A0A53757370656E6469737365206163206E6973692E205574206C656F2E20566573746962756C756D2068656E647265726974207072657469756D20646F6C6F722E204E756E632066657567696174206D616C6573756164612070757275732E2043726173206574206E6962682E20437572616269747572206E756E6320657261742C206D616C6573756164612076697461652C206C616F726565742061632C20756C7472696369657320696E2C2070757275732E20566976616D75732074656C6C757320617263752C20736F64616C65732065752C20666163696C6973697320612C206C6163696E6961206E65632C206E756E632E2050656C6C656E7465737175652069642076656C69742E20496E206575206E6962682E204E756E63206E656320657261742E205365642064696374756D206E65717565207574206E69736C2E0A0A4D6F726269206C65637475732074656C6C75732C2074696E636964756E742061632C20706F72747469746F722061632C2074726973746971756520696E2C2065726F732E20446F6E6563206C7563747573206C7563747573206C656F2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2046757363652075742065737420657420656E696D207363656C6572697371756520616363756D73616E2E20446F6E6563206C6967756C612066656C69732C206C6163696E696120717569732C2070656C6C656E74657371756520696E2C2073656D70657220766573746962756C756D2C20656C69742E204D61757269732065676574206F72636920612066656C697320636F6E677565207665686963756C612E20557420736F6C6C696369747564696E2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204E756C6C616D20696420646F6C6F72207574206C6F72656D206469676E697373696D2076656E656E617469732E2053757370656E64697373652076697461652073617069656E2E2050726F696E206E6F6E206D61676E612075742065726F7320766976657272612070756C76696E61722E20446F6E65632071756973206F64696F2E204E756C6C616D206E6F6E20617263752076656C206C6F72656D20737573636970697420616C697175616D2E20416C697175616D2072757472756D2074757270697320696E206C656F2E0A0A5574206C7563747573206E6962682074726973746971756520657261742E2053757370656E646973736520626962656E64756D206F64696F20766974616520746F72746F722E20446F6E6563206C6163696E69612E204372617320736F64616C65732066656C6973206C7563747573206E756C6C612E204E616D20656C656966656E64207361676974746973206C6967756C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E64697373652076656C206E657175652E204D6F72626920616C6971756574207665686963756C61206D61676E612E2041656E65616E206174206F64696F2E20447569732070656C6C656E746573717565206D61676E612E204E756C6C6120617420746F72746F72207574206469616D2064696374756D2066617563696275732E204D617572697320717569732076656C69742E20446F6E6563206E6F6E2074656C6C7573207669746165206C6F72656D206672696E67696C6C6120706F72747469746F722E2046757363652075742073617069656E207175697320746F72746F7220666575676961742073616769747469732E20446F6E656320766976657272612073656D2076697461652073617069656E2E205072616573656E7420736F64616C65732C206C6163757320696E206672696E67696C6C6120766976657272612C206F64696F2061756775652061646970697363696E672075726E612C20766974616520696E74657264756D20616E74652073656D206E6F6E206E6973692E204E756C6C616D20746F72746F72206C6F72656D2C20656C656966656E642061632C206D6F6C6C6973206E6F6E2C206C616F726565742061632C2072697375732E20496E7465676572206F726E617265206C656F20736564206A7573746F2E2051756973717565206375727375732C2073656D206E6F6E20666163696C6973697320626962656E64756D2C206E697369206D69207661726975732066656C69732C206665726D656E74756D2066657567696174206C6F72656D2065726F73206C616F726565742072697375732E0A0A517569737175652073697420616D657420657374206574206C6F72656D207665686963756C61206C6163696E69612E20446F6E6563206E656320746F72746F722E2043726173206F64696F2E204E616D207363656C657269737175652076756C7075746174652075726E612E205072616573656E74206475692E20457469616D206E6563206E69736C206C6F626F7274697320697073756D20616C69717565742074656D7075732E204D616563656E6173207072657469756D20736F6C6C696369747564696E206D61757269732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206175677565206D617373612C20636F6E67756520656765742C20636F6E76616C6C697320656765742C207472697374697175652073697420616D65742C2065726F732E2053656420636F6E736571756174206E6973692065752066656C69732E2050656C6C656E746573717565206A7573746F2E2053757370656E6469737365206E6F6E2061756775652E20496E206469676E697373696D206C6F626F72746973206D61757269732E204D61757269732073616769747469732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E0A0A5365642061646970697363696E672E20446F6E656320612074656C6C75732076697461652065737420637572737573207665686963756C612E204E616D20616E74652073656D2C20736F64616C65732069642C206672696E67696C6C612076656C2C20636F6E64696D656E74756D2076656C2C206E756C6C612E205175697371756520736F64616C65732E20457469616D20696D7065726469657420656C6974206964206F64696F2E20416C697175616D206572617420766F6C75747061742E204D616563656E617320706F7274612074656D706F7220617263752E204E756C6C612073656D2061756775652C2070656C6C656E7465737175652061632C20636F6E7365717561742075742C20636F6E64696D656E74756D20657569736D6F642C2072697375732E2053656420616C697175616D2074696E636964756E74206D692E20496E20696E74657264756D206C6F626F72746973206F7263692E0A0A536564207665686963756C612068656E6472657269742070757275732E20457469616D2061206469616D2E2043757261626974757220636F6E76616C6C69732E2053757370656E64697373652061206E6973692E20446F6E6563206964206D61676E6120696E207175616D20736F6C6C696369747564696E20756C747269636965732E20446F6E656320766976657272612E205175697371756520766F6C757470617420657374207365642073656D2E20416C697175616D206A7573746F2E20566573746962756C756D20746F72746F72206D617373612C20706F72747469746F72207365642C2076617269757320717569732C20696163756C697320717569732C206F64696F2E20416C697175616D2065676574206E657175652E0A0A4D6175726973206E756C6C612E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566573746962756C756D206575207175616D20696E206E6571756520756C7472696365732070656C6C656E7465737175652E204372617320696E20646F6C6F722071756973207175616D207661726975732068656E6472657269742E20416C697175616D206E697369206C616375732C206C6F626F727469732065752C20636F6E76616C6C69732073697420616D65742C20666163696C697369732075742C206D692E20416C697175616D206174206E657175652E204372617320736167697474697320656C656D656E74756D206A7573746F2E20566573746962756C756D207574206C656374757320616C6971756574207075727573206D616C65737561646120766F6C75747061742E2044756973206174206C616375732061646970697363696E67206C696265726F2074696E636964756E7420766573746962756C756D2E204D6F7262692061206C696265726F2E20437261732070757275732E204D6F72626920757420617567756520657420707572757320696E74657264756D207363656C657269737175652E20496E74656765722061206475692E20496E206861632068616269746173736520706C617465612064696374756D73742E2044756973207068617265747261206D657475732065676574206D61757269732E20416C697175616D20696E74657264756D20756C6C616D636F72706572206D617373612E0A0A457469616D206F726E6172652E204E756C6C616D20657569736D6F642E2041656E65616E20636F6E7365717561742067726176696461206C6967756C612E20416C697175616D206573742E2050726F696E207669746165206C616375732E205072616573656E7420612065726F732073697420616D657420647569206C756374757320636F6D6D6F646F2E2050686173656C6C7573207665686963756C612061726375206567657420646F6C6F722E205072616573656E74206665726D656E74756D20636F6E677565206C656F2E20416C697175616D20766F6C7574706174207075727573207574206C6F72656D2E2046757363652068656E64726572697420656E696D206174206C656F2E20416C697175616D2072686F6E637573206E69736C2E20566976616D75732064696374756D2065676573746173206D692E2053757370656E64697373652070656C6C656E74657371756520626962656E64756D20646F6C6F722E2050656C6C656E7465737175652074696E636964756E742C207475727069732073656D7065722070656C6C656E74657371756520636F6E64696D656E74756D2C20697073756D206D6574757320736F64616C6573206C6967756C612C20696420766F6C7574706174206469616D2074757270697320757420656C69742E0A0A5072616573656E7420736564206C616375732E204E616D20656C656966656E64206D6F6C6573746965206D61757269732E20446F6E65632064617069627573206665726D656E74756D206D617373612E20446F6E656320766976657272612066617563696275732070757275732E2043757261626974757220636F6E6775652C206C696265726F20766974616520766976657272612070656C6C656E7465737175652C206469616D2076656C697420736F64616C657320656E696D2C20736564207375736369706974206C6563747573206E697369206E6563206E657175652E20566573746962756C756D206D616C6573756164612C206C616375732061742063757273757320636F6E6775652C2076656C6974206C65637475732074726973746971756520646F6C6F722C2073697420616D657420736F64616C6573206E6571756520697073756D2061206C696265726F2E20566573746962756C756D206574207175616D2E2043757261626974757220706C6163657261742E20437572616269747572206E756E6320617263752C20657569736D6F64206E65632C2076756C7075746174652068656E6472657269742C20616C697175657420656765742C207175616D2E204375726162697475722076656C20656E696D2E2053757370656E646973736520706F74656E74692E0A0A4E756E6320636F6E736571756174206F726369207574206C616375732E2046757363652076656C697420646F6C6F722C2064617069627573207365642C20626C616E6469742073697420616D65742C2072686F6E6375732069642C2072697375732E20447569732075726E61206E6962682C207363656C6572697371756520717569732C206461706962757320612C207363656C65726973717565207365642C206E6962682E20446F6E6563206C75637475732E205574206575206D617572697320637572737573206469616D206C6163696E69612072686F6E6375732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20416C697175616D207665686963756C61206D6F6C6573746965206A7573746F2E204D616563656E617320696D70657264696574207065646520736564206D692E2053757370656E6469737365206E756C6C6120646F6C6F722C2068656E64726572697420656765742C2068656E6472657269742069642C2064696374756D2076656C2C206C656F2E204475697320616363756D73616E2E2043757261626974757220696E2066656C69732E204E756E63206C6F72656D2E205574206C656F20646F6C6F722C206C616F72656574206E65632C2076756C7075746174652061742C20656C656966656E6420696E2C206E756C6C612E2051756973717565206E756E632070757275732C2076617269757320656765742C20616363756D73616E206E65632C20616C69717565742065742C206E6962682E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20437261732061646970697363696E67207669766572726120646F6C6F722E204D617572697320706F72747469746F7220756C7472696365732070757275732E204E756C6C6120666163696C6973692E205072616573656E7420666175636962757320616E7465207669746165206D61757269732E0A0A5072616573656E74206C6163696E6961206C656374757320736564206E69736C2E20496E2074656D70757320636F6E677565206D61757269732E20496E746567657220666163696C69736973206F726E61726520656E696D2E204E756C6C61206964206D617373612E20446F6E656320636F6D6D6F646F206469616D2061742074656C6C75732E204E616D20646170696275732076697665727261206573742E204E616D2074656C6C75732E205072616573656E742061206C696265726F2E20496E206661756369627573206573742065676574206E6962682E204E756C6C612065726F73206F7263692C20696D70657264696574206E6F6E2C20626C616E646974206E6F6E2C2074656D706F7220656765742C206D692E2050656C6C656E74657371756520636F6E76616C6C69732E0A0A517569737175652065676574206D69206163206C656F20657569736D6F642066617563696275732E2050686173656C6C75732072686F6E637573207075727573206964206475692E20566573746962756C756D206D616C65737561646120656C656966656E6420616E74652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050656C6C656E74657371756520626C616E646974206D6174746973206F64696F2E2053757370656E646973736520636F6E7365717561742C206C65637475732061632073656D70657220736F6C6C696369747564696E2C206D692076656C69742064696374756D2061756775652C2061632074656D70757320646F6C6F7220657261742073697420616D6574206475692E2050726F696E2068656E6472657269742C2066656C6973207175697320766F6C757470617420706F73756572652C206469616D206F64696F206D616C657375616461206F64696F2C206120696E74657264756D206F726369206469616D20717569732073617069656E2E2050656C6C656E746573717565206F64696F206F64696F2C20766976657272612076656C2C20677261766964612065752C206D6F6C6573746965207365642C206E756C6C612E2050686173656C6C7573206D617572697320706564652C20636F6D6D6F646F2075742C20657569736D6F642065752C2068656E6472657269742065752C206573742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C6120656C656D656E74756D206C616375732065752061756775652E2053656420657261742E2050726F696E20706F7274612E204D616563656E61732071756973206D692E2050686173656C6C757320617420656E696D206163206A7573746F206772617669646120756C7472696365732E2043726173206C656F2E0A0A496E746567657220757420617263752E20446F6E656320736564206D61676E612E2050726F696E2066656C69732E20496E20696163756C69732C206C6967756C61206964206672696E67696C6C61207072657469756D2C206E696268206469616D20616363756D73616E2074656C6C75732C206567657420616363756D73616E206D657475732064756920766172697573207475727069732E2050686173656C6C7573206F726369206D657475732C20656C656966656E64207365642C2074656D706F722061632C207363656C657269737175652061632C2075726E612E20496E74656765722076697665727261206E657175652061206D61757269732E204D617572697320706F72747469746F7220646F6C6F722065752076656C69742E20496E7465676572206F64696F20656C69742C20766573746962756C756D2075742C20766F6C75747061742069642C2072686F6E63757320636F6D6D6F646F2C2075726E612E20457469616D20706C61636572617420706861726574726120657261742E2055742074656D706F72206573742E20496E7465676572206469676E697373696D20626C616E6469742074656C6C75732E204D6F726269206E69626820646F6C6F722C207363656C657269737175652069642C20636F6D6D6F646F206D616C6573756164612C206D61747469732061742C206D692E20437261732074696E636964756E7420636F6D6D6F646F2070757275732E20496E2074696E636964756E742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D20756C6C616D636F727065722E2055742068656E6472657269742E204D6F72626920756C7472696365732E0A0A5072616573656E7420696163756C69732C2065726F73206163206567657374617320736F64616C65732C2075726E61206C656F206665726D656E74756D206C6967756C612C2073697420616D657420616C697175616D2076656C69742073656D206E6F6E2070757275732E20446F6E65632072757472756D206172637520717569732070757275732E204E616D20706F73756572652C206C6163757320617420636F6E73657175617420706C6163657261742C206E756C6C61207065646520706F7375657265206F7263692C206E6F6E20657569736D6F6420747572706973206475692071756973206E69736C2E2050726F696E20706F7274612061646970697363696E67206E6962682E20446F6E65632074726973746971756520646F6C6F722061742074656C6C75732E20446F6E6563206E65717565206D617373612C20617563746F722069642C2066617563696275732076697461652C20756C6C616D636F727065722076656C2C206E6973692E2050726F696E206D6F6C6573746965206E6571756520736564206D617373612E204E616D2074656D706F722E204D6F72626920616C697175616D2073617069656E2061742074656C6C75732E2046757363652071756973207269737573206574206D69207072657469756D2070756C76696E61722E2046757363652073697420616D6574206C6967756C612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E646973736520657520656E696D2065742066656C6973207363656C65726973717565206C6F626F727469732E205072616573656E7420626962656E64756D2E20566976616D7573207665686963756C612E20496E7465676572206174206E696268207365642076656C69742072686F6E637573206D6F6C65737469652E2043726173206C616375732E2053656420756C6C616D636F727065722065726F732076656C20657261742E20467573636520657520746F72746F722073697420616D6574206469616D20657569736D6F642073616769747469732E204E756E632071756973206C61637573206964206E69626820636F6E76616C6C6973207661726975732E2053757370656E6469737365207669746165206D692E20566573746962756C756D207472697374697175652E20446F6E6563206D616C65737561646120697073756D206964206E657175652E204E756C6C616D20736564206C616375732E204475697320656765737461732C206A7573746F20757420636F6E677565206F726E6172652C2061756775652073617069656E206C7563747573206469616D2C20617420616363756D73616E20657261742073617069656E207574206C696265726F2E2050686173656C6C75732076656C206E756C6C612E2053757370656E646973736520617263752074656C6C75732C20706F72747469746F7220612C2070686172657472612066617563696275732C20616C697175616D2073697420616D65742C206D617373612E204E756C6C6120706F72747469746F722074696E636964756E74206C6F72656D2E204E756E6320646F6C6F72206F64696F2C20736167697474697320696E2C206C6F626F727469732076656C2C20766F6C7574706174207365642C206E6962682E0A0A5175697371756520626C616E646974206C656F2075742073617069656E2074656D70757320666163696C697369732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2041656E65616E20756C7472696369657320706F72747469746F72206A7573746F2E2046757363652072757472756D2065726F732075742075726E612E2050726F696E2071756973207175616D20656765742064756920616C697175616D20616363756D73616E2E20446F6E656320737573636970697420656C656966656E6420656C69742E2050656C6C656E746573717565206D61747469732C2066656C697320736F64616C657320696163756C697320696D706572646965742C206C616375732073656D20636F6E76616C6C69732061756775652C2073697420616D657420616C69717565742061726375207075727573206672696E67696C6C612072697375732E20496E206575206F64696F206964206D61676E61207068617265747261206F726E6172652E20416C697175616D20696E74657264756D2070756C76696E617220697073756D2E20536564206E657175652E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D2073697420616D6574206E6973692E2055742061742061756775652E204D617572697320766F6C757470617420626C616E646974206C6967756C612E204E756C6C61206575206D657475732E20566573746962756C756D206567657420656C69742E205072616573656E7420706F73756572652E20566573746962756C756D2069642073656D206E6F6E206C6563747573206D6F6C6C69732074696E636964756E742E20416C697175616D2069642066656C697320617420616E7465206F726E6172652074656D706F722E204E756C6C61206C61637573207475727069732C20666575676961742076697461652C2063757273757320717569732C20636F6E736563746574756572206E6F6E2C206D61757269732E204675736365206C61637573206D617373612C20706F72747469746F722075742C206D6F6C65737469652075742C2076656E656E6174697320612C206C6F72656D2E205072616573656E742073697420616D6574206F7263692E204D61757269732072686F6E6375732066656C69732076697461652066656C69732061646970697363696E6720696D706572646965742E204D616563656E6173206D6F6C6C6973206469616D206E6563206C656F2E0A0A467573636520656E696D20697073756D2C20756C7472696365732065752C206D6F6C65737469652069642C20656C656D656E74756D2069642C2073617069656E2E20496E746567657220612075726E612E204E616D2076656C6974206C696265726F2C2076656E656E6174697320656765742C2074656D706F722073697420616D65742C20666575676961742076697461652C20616E74652E204675736365206E756E632E205365642073656D706572206E69736C206E65632072697375732E20496E20736564206C696265726F2E2050726F696E20746F72746F72206E657175652C2074696E636964756E742061632C2074656D706F722061632C20706861726574726120717569732C2076656C69742E2044756973206C65637475732061756775652C20756C747269636965732076656C2C20636F6E7365717561742069642C20696163756C69732069642C20616E74652E20566976616D757320617563746F72206D65747573206120616E74652E204375726162697475722061726375206E6973692C20666163696C697369732061742C206C616F7265657420696E2C20636F6E736563746574756572207365642C206D61757269732E205175697371756520706C616365726174206469616D20736564206475692E20566976616D7573207072657469756D20636F6E64696D656E74756D206C6F72656D2E20437572616269747572206C616F726565742E2041656E65616E206F726369206C6967756C612C2063757273757320656765742C206C6163696E6961206E6F6E2C2066617563696275732076656C2C206C6F72656D2E0A0A416C697175616D206572617420766F6C75747061742E204375726162697475722065726F7320646F6C6F722C20636F6E67756520612C20636F6E64696D656E74756D207365642C206C75637475732075742C206E6962682E204D616563656E6173206E6F6E20746F72746F72206E65632074757270697320636F6D6D6F646F2070656C6C656E7465737175652E205072616573656E7420657569736D6F6420706C616365726174206D692E2053757370656E646973736520706F74656E74692E2050686173656C6C7573207574206E65717565207669746165206F726369206D617474697320696163756C69732E20496E746567657220656765742074656C6C75732E20446F6E656320617420616E74652E204E616D206C6163696E6961206C656F206567657420657261742E204D616563656E617320657569736D6F64206D61676E6120636F6E67756520746F72746F722E204D6F726269206E6563206D6173736120657520656E696D206D616C65737561646120736F6C6C696369747564696E2E2053656420616363756D73616E2E204E756C6C616D20697073756D2E205574206F64696F2E20416C697175616D206572617420766F6C75747061742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2050656C6C656E7465737175652069642076656C69742E204E616D206F64696F2073656D2C20616C69717565742075742C2074656D7075732073697420616D65742C20657569736D6F642065742C206E756E632E0A0A50656C6C656E746573717565206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205072616573656E74206D6175726973206E756E632C207661726975732075742C20636F6E76616C6C6973206D6F6C65737469652C206C75637475732073697420616D65742C206C656F2E205365642064696374756D206C6F72656D20657420617263752E204E756E632076656E656E617469732070656C6C656E746573717565206D617373612E204E756C6C6120666163696C6973692E2050686173656C6C757320696E20746F72746F722065676574207269737573207363656C657269737175652076756C7075746174652E20536564206E69626820656C69742C2073616769747469732061632C20636F6E64696D656E74756D206E65632C20636F6E76616C6C69732065742C206A7573746F2E20467573636520766F6C7574706174206D657475732E204E756E6320617563746F722E20566573746962756C756D206C656F2065726F732C2070656C6C656E7465737175652061632C206D6F6C6C697320756C7472696365732C2072686F6E637573206E6F6E2C20646F6C6F722E204D6175726973207665686963756C6120706C616365726174206E69736C2E20566573746962756C756D20626962656E64756D2C2061726375207175697320636F6E67756520656C656D656E74756D2C2076656C6974206E756E6320656C656966656E64207475727069732C206964206C7563747573207269737573206E69736C2073697420616D65742074656C6C75732E2050686173656C6C75732070656465206E657175652C20626C616E646974206E6F6E2C20636F6D6D6F646F2076697461652C20756C7472696369657320656765742C206D61676E612E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120666163696C6973692E20416C697175616D20616320616E74652E20437261732072697375732E204D6F726269206D6175726973206C616375732C20706F73756572652065752C20626C616E6469742065742C2070686172657472612061742C206D692E2050726F696E2061632070757275732E204475697320637572737573206E69736C2072757472756D207175616D2E20416C697175616D2061206F64696F206E6F6E206D61676E612070656C6C656E74657371756520756C747269636965732E204D616563656E6173206163206D6173736120717569732073617069656E20756C6C616D636F727065722074656D7075732E2043726173206375727375732076656C6974207365642073617069656E2E2050726F696E206E756C6C612E20566976616D757320736F64616C657320616C697175616D206E6962682E20457469616D206574206572617420757420616E7465206C6163696E696120657569736D6F642E204675736365206E6973692E2050726F696E2071756973206E756C6C612E0A0A517569737175652076656E656E617469732C2065726F7320736564206C616F7265657420736F6C6C696369747564696E2C206F72636920616E74652070656C6C656E746573717565206E69736C2C2073697420616D65742076697665727261207175616D2065726174206E6F6E2072697375732E20437261732065676574206C696265726F2E2053656420656C6974206D61676E612C2073656D7065722065752C206672696E67696C6C6120696E2C206469676E697373696D20736F64616C65732C20657261742E20566976616D757320666575676961742073656D2076656C206475692E20446F6E656320636F6E76616C6C697320736F6C6C696369747564696E206469616D2E2043726173207365642070757275732E20446F6E65632066656C69732065726F732C2073656D70657220656765742C2074656D706F7220636F6E7365637465747565722C20736167697474697320717569732C206E69736C2E204475697320696E20616E74652E2043726173206E6F6E207475727069732E204E756C6C612074656D706F722076656C697420616C697175657420747572706973206D6F6C657374696520706C6163657261742E2050726F696E20656C656D656E74756D206665726D656E74756D206D61757269732E20566976616D757320736564206F726369206C6163696E69612064756920706C6163657261742076656E656E617469732E20566573746962756C756D20666575676961742C2074656C6C757320696E20766F6C75747061742072757472756D2C206D61676E61206E69736920756C6C616D636F727065722065726F732C2069642070756C76696E6172206E657175652065726174207574206C616375732E20566976616D7573207365642061756775652E204E756C6C6120666163696C6973692E204D616563656E617320616E74652061756775652C20656C656D656E74756D2075742C20736F64616C65732076697461652C20636F6E64696D656E74756D206E65632C206C6F72656D2E20447569732070656465206F7263692C206672696E67696C6C612061742C20656C656966656E64206E65632C207072657469756D20696E2C20657261742E204E616D2073616769747469732C2074757270697320766974616520636F6E76616C6C69732070686172657472612C206F64696F2073656D207363656C65726973717565206C616375732C206E6563206C6F626F7274697320647569206469616D2076656C2065726F732E20496E2073656D7065722067726176696461206E657175652E0A0A496E7465676572206E756E632E205574207072657469756D20697073756D2073697420616D657420656C69742E20496E206E656320617263752E2053656420766573746962756C756D2076756C70757461746520697073756D2E2050656C6C656E7465737175652074696E636964756E742E204E756C6C61206772617669646120646F6C6F7220696E2074656C6C75732E2043726173207665686963756C612C20646F6C6F722075742070656C6C656E74657371756520616C697175616D2C206572617420656E696D20617563746F72206D617373612C207665686963756C61206C6F626F72746973206F64696F2065726F732071756973207175616D2E2050726F696E2064617069627573206E6571756520696E20656E696D2E2050726F696E20656C69742E20496E74656765722072686F6E6375732074696E636964756E7420656C69742E204675736365206C6F72656D206D657475732C2073656D7065722061632C20766F6C75747061742076697461652C20666163696C697369732075742C2074656C6C75732E20446F6E65632076656C20747572706973207669746165206E69736920706861726574726120706F72747469746F722E204D616563656E617320746F72746F722E204675736365206D692E204E756C6C616D206E6563207475727069732E2053656420736F64616C657320766573746962756C756D206E756E632E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A50656C6C656E74657371756520646F6C6F7220646F6C6F722C206C616F726565742065752C20616C697175657420717569732C207363656C657269737175652073697420616D65742C20617263752E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C616D206375727375732075726E61206567657420656C69742E205175697371756520626C616E6469742073617069656E20616320616E74652E2050726F696E206E756C6C612065726F732C206772617669646120766F6C75747061742C20736F64616C65732076656C2C206D6F6C6C69732065752C206D617373612E204E756C6C612074726973746971756520736F6C6C696369747564696E206E69736C2E20437572616269747572207669746165206C6F72656D2076697461652076656C69742065676573746173206F726E6172652E2041656E65616E20656765742065726F732E20416C697175616D206572617420766F6C75747061742E20467573636520612075726E61206964206F64696F20616C697175657420636F6E76616C6C69732E204375726162697475722073697420616D6574206E69736C20706F7375657265206C656F20706F737565726520646170696275732E2044756973206D6574757320657261742C206C75637475732076656C2C2072686F6E6375732061742C20636F6E76616C6C69732073697420616D65742C20656E696D2E20566976616D75732068656E6472657269742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D206567657420656C69742E0A0A4E756C6C616D2061206E756E632E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206D657475732075726E612C2074696E636964756E742065742C206C6163696E69612073697420616D65742C206C6F626F727469732076697461652C206C6967756C612E2050726F696E206574206D6175726973207669746165206D6920616363756D73616E2070656C6C656E7465737175652E20457469616D207175616D2070757275732C2068656E647265726974207365642C20666575676961742076697461652C20657569736D6F6420656765742C20746F72746F722E20557420616C697175616D206D61676E61207669746165206A7573746F2E2053757370656E6469737365206E6F6E206A7573746F2076656C2076656C697420636F6E64696D656E74756D2074656D7075732E20447569732074656D70757320697073756D2076697461652074656C6C75732E2050726F696E20696E206D617373612E20457469616D20756C6C616D636F727065722064696374756D2074656C6C75732E2050726F696E20616C69717565742066656C6973206174206C656F206C616F726565742070756C76696E61722E20566573746962756C756D20617263752070757275732C206D616C6573756164612073697420616D65742C206375727375732065752C20706C6163657261742073697420616D65742C206E756E632E204E616D206D61737361206F64696F2C20736F6C6C696369747564696E20696E2C2061646970697363696E6720612C20616C697175616D206E65632C2072697375732E20416C697175616D20626C616E6469742068656E647265726974206C696265726F2E204D617572697320677261766964612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204375726162697475722061206E6962682E20557420696E74657264756D206665726D656E74756D206E657175652E2050656C6C656E74657371756520736564206E756E632E204D6175726973207665686963756C61206E697369206574206E756E632E205072616573656E74206C6F72656D2E20446F6E65632073656D7065722E20496E7465676572206575206C6163757320696E2065737420616C697175616D2068656E6472657269742E20566573746962756C756D2065676574206E657175652E205365642073656D706572206C75637475732076656C69742E20437572616269747572206E6962682061756775652C20636F6E6775652065752C2068656E6472657269742069642C20636F6E6775652065742C20656E696D2E20496E746567657220706C61636572617420616C697175616D206C65637475732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20566976616D75732076697461652065726F732E20446F6E65632076656C206E69736C2E0A0A496E20766573746962756C756D20666163696C697369732075726E612E2055742072697375732E204D61757269732070686172657472612E2050656C6C656E746573717565206D61747469732E20496E746567657220737573636970697420616C697175616D20697073756D2E204475697320626C616E6469742C2073617069656E20657420756C7472696369657320636F6E64696D656E74756D2C2066656C6973206D6920656C656D656E74756D20706564652C206E6563207361676974746973206D65747573206D61757269732071756973207175616D2E205175697371756520616363756D73616E20617263752076656C206E756C6C612E20437261732073656D2073617069656E2C20706F72747469746F722069642C20756C747269636965732073616769747469732C206C75637475732065752C206E756C6C612E20496E746567657220717569732065726F732E204D6F726269207365642075726E6120612074656C6C7573207665686963756C612076756C7075746174652E20457469616D206E656320617567756520656765742066656C69732073656D706572207472697374697175652E205175697371756520757420646F6C6F722076656C2072697375732064696374756D20636F6E7365717561742E20536564206567657420646F6C6F7220736564206E756E63206C6163696E696120616C69717565742E2053757370656E646973736520616320746F72746F7220696E20697073756D20706F73756572652076656E656E617469732E20536564206567657420657261742E204E756C6C612066617563696275732E2044756973206C616F726565742C206D6173736120706F72747469746F7220616C697175657420656765737461732C20697073756D206C65637475732072686F6E637573207175616D2C20696E2061646970697363696E672065726F732073656D2075742074656C6C75732E2050656C6C656E74657371756520666575676961742074656D707573207175616D2E20566976616D757320696420646F6C6F7220656765742073617069656E20636F6E7365637465747565722074656D706F722E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120696163756C6973206665726D656E74756D206C696265726F2E204375726162697475722066617563696275732C206D61737361206D616C657375616461206375727375732074696E636964756E742C20657261742073656D20656C656966656E64206D61757269732C20736564206672696E67696C6C61206D6920616E74652061632070757275732E204475697320656C656D656E74756D206C65637475732E204E756E63206F726E617265206172637520657520746F72746F722E20566573746962756C756D2076656C20646F6C6F72206174207075727573206C6163696E6961206672696E67696C6C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E616D20696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204D616563656E61732074696E636964756E742C2065726F73206120656765737461732070656C6C656E7465737175652C2072697375732072697375732064696374756D206C696265726F2C20696420616C6971756574206D65747573206A7573746F20696E206D617373612E2050726F696E20612074656C6C75732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205365642070757275732E20536564206E6F6E20706564652E2041656E65616E206D617373612073617069656E2C20736F64616C65732073697420616D65742C20636F6E7365717561742064696374756D2C20656C656966656E642076697461652C20746F72746F722E20446F6E656320756C747269636573206C6163696E696120656C69742E0A0A4D6F7262692061646970697363696E6720736F64616C657320646F6C6F722E20557420756C6C616D636F7270657220756C74726963696573206573742E20496E2076656E656E617469732074656D7075732061756775652E2053757370656E646973736520746F72746F7220646F6C6F722C20616363756D73616E2065742C20737573636970697420612C2074696E636964756E742075742C206C696265726F2E20416C697175616D207363656C65726973717565206D61676E61207365642066656C69732E2051756973717565207574206E756E632061206D61676E612076756C70757461746520706C6163657261742E20416C697175616D2072686F6E637573207665686963756C61206475692E2053656420746F72746F722E204E756C6C616D2073697420616D6574206469616D2E204E756E63207365642065726F732E20536564206574206F64696F2074696E636964756E7420656C6974206772617669646120636F6E76616C6C69732E20437572616269747572207175697320746F72746F722061206C616375732073656D706572207661726975732E204D6175726973206174206175677565206E6F6E206D6920736F6C6C696369747564696E20616C697175616D2E20496E746567657220756C6C616D636F727065722E2050656C6C656E746573717565207375736369706974207175616D206E6F6E2070757275732E20416C697175616D2061632065726F73206174206172637520756C6C616D636F7270657220636F6E7365637465747565722E2053757370656E6469737365207072657469756D206D6174746973206C656F2E0A0A44756973206174206E756E632E2053656420646F6C6F72206573742C207661726975732061632C20706F7274612065742C2074696E636964756E742068656E6472657269742C2072697375732E20566976616D7573207574206D61676E612E205072616573656E74207574206D61757269732E20496E207075727573206C616375732C206D6174746973207365642C20766573746962756C756D206E65632C2074656D706F722061742C206E69736C2E204372617320756C6C616D636F727065722076656E656E617469732074656C6C75732E20557420646F6C6F722E204D616563656E6173206D616C6573756164612C207065646520612070756C76696E6172206D61747469732C2061726375206469616D207665686963756C612072697375732C207175697320706F72747469746F72206175677565206D6173736120696E2076656C69742E204E756E6320636F6E6775652E204D6F7262692076656C6974206D657475732C2072686F6E6375732065742C20616C697175616D20636F6E7365637465747565722C20756C74726963696573206D616C6573756164612C206C6967756C612E205365642076656C6974206E69736C2C2073616769747469732076697461652C20706861726574726120612C20706F7375657265207365642C206D617373612E204E756C6C6120666163696C6973692E20496E207661726975732C206C6967756C61206964206C6F626F7274697320736F64616C65732C206175677565206F726369206665726D656E74756D2074656C6C75732C2065752070756C76696E6172207269737573206C6967756C6120612073617069656E2E204D6F726269206C616F7265657420697073756D206E6F6E206D692E204E616D20637572737573206C6F72656D207574206D692E20566976616D7573206D61676E6120656E696D2C20706F7375657265206E6F6E2C2073656D70657220717569732C20736F64616C65732065752C20617263752E20457469616D206D692070757275732C207072657469756D20666575676961742C20766172697573207365642C2070656C6C656E74657371756520656765742C206C6967756C612E20496E206C656F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E6563207669746165206F726369206575206F72636920736F6C6C696369747564696E20666575676961742E0A0A5072616573656E74207075727573206D617373612C20657569736D6F642076697461652C2074656D707573206E65632C20636F6E7365717561742068656E6472657269742C206D657475732E2041656E65616E2066656C6973206573742C20656765737461732076697461652C20616363756D73616E20656765742C2070656C6C656E74657371756520696E2C2073617069656E2E204475697320646170696275732070656465206E6F6E2073617069656E2E204E756E632075726E612E20496E74656765722076656C206C696265726F2E204475697320617567756520617263752C2064617069627573206E6F6E2C20666163696C697369732076697461652C20706F73756572652075742C2065726F732E20446F6E6563207669746165206E756E632073697420616D6574206172637520696D706572646965742064696374756D2E204D6F72626920656C656966656E642C206C6F72656D20657520636F6E73656374657475657220766573746962756C756D2C206469616D206E756E63206F726E61726520617263752C2061632074656D706F722066656C697320646F6C6F7220656765742065726F732E2050686173656C6C7573206D617373612073656D2C20736F6C6C696369747564696E2061632C20736F64616C657320677261766964612C206C756374757320612C207175616D2E204E616D206E65717565207175616D2C20766976657272612061742C2076656E656E6174697320717569732C207361676974746973206E6F6E2C20656E696D2E0A0A4E756C6C6120666163696C6973692E2050656C6C656E7465737175652065676573746173206C6163696E6961206573742E205365642074696E636964756E742C2070656465207365642074696E636964756E7420766573746962756C756D2C2075726E6120646F6C6F722061646970697363696E672070757275732C207669746165206672696E67696C6C612066656C697320656C697420696E206E6962682E204E756C6C6120736564206E6973692E204D6175726973207375736369706974207363656C6572697371756520617263752E20457469616D206E6F6E20656E696D2076656C2065726F7320616363756D73616E206D616C6573756164612E204E756E632074696E636964756E7420636F6D6D6F646F206D61757269732E20496E2074696E636964756E7420726973757320717569732075726E612E204E756C6C61206469616D20746F72746F722C20616C69717565742065742C2074696E636964756E7420717569732C20736F6C6C696369747564696E2061632C20746F72746F722E2043726173206E69736C206E657175652C2076756C7075746174652073757363697069742C206D6F6C657374696520717569732C2070756C76696E61722061742C206E756C6C612E204E756C6C616D206163206D65747573206E6563206F64696F20706F7375657265207661726975732E2043726173207365642070656465206E65632064756920706F737565726520626962656E64756D2E204475697320657569736D6F6420756C6C616D636F72706572206C696265726F2E20416C697175616D2066617563696275732070756C76696E6172207475727069732E0A0A496E207574206E65717565206964206E756E63206665756769617420636F6D6D6F646F2E20437572616269747572206469676E697373696D2C2066656C697320617420736F6C6C696369747564696E206C6163696E69612C20656E696D20656C6974207375736369706974206E657175652C20736564206C7563747573206C6F72656D20697073756D20696E206C656F2E204475697320646170696275732C206F64696F207175697320617563746F7220636F6D6D6F646F2C206E69736C206F64696F206D61747469732074656C6C75732C206E65632074696E636964756E7420747572706973206469616D20696E20617263752E2043757261626974757220612073656D2E204E756C6C616D20766F6C7574706174206D61676E612E2050656C6C656E7465737175652073616769747469732C206E6571756520636F6E736571756174207072657469756D206375727375732C20646F6C6F72206C6163757320636F6E73656374657475657220617263752C20736564206C616F72656574206573742075726E61206574206D657475732E2053757370656E646973736520706C6163657261742C20647569206120706F7274612074656D706F722C206C6F72656D20647569206C6F626F72746973206E657175652C207365642076656E656E61746973206469616D20656E696D2069642065726F732E20457469616D206574206E69736C206E6F6E206C656374757320666175636962757320636F6E7365637465747565722E204D6F726269207363656C657269737175652C2073656D206E65632074656D70757320756C6C616D636F727065722C20697073756D206469616D2066657567696174206C6F72656D2C2061206672696E67696C6C612073617069656E20656C69742071756973206E6962682E204E756C6C616D206469616D2075726E612C2076697665727261207365642C2070686172657472612072686F6E6375732C2074696E636964756E742076656C2C206F7263692E20496E746567657220616363756D73616E206D617474697320657261742E204E616D2064696374756D2E204D6175726973206E6563206C656F2E204E756C6C6120696163756C69732E204E756C6C61206E69736C206D692C206461706962757320717569732C207665686963756C6120612C2063757273757320656765742C206F64696F2E0A0A50686173656C6C7573206461706962757320657569736D6F64206E6962682E20566976616D757320696D7065726469657420616E746520696E206C6967756C612E2050656C6C656E74657371756520616363756D73616E2E20496E20696D706572646965742C20647569206120617563746F72206672696E67696C6C612C206D65747573206E6973692063757273757320646F6C6F722C2076656C206C7563747573206C6967756C61206C6F72656D207669746165206D61757269732E205072616573656E74206D617474697320766573746962756C756D20656C69742E20416C697175616D20656E696D206C616375732C2070756C76696E6172206E6F6E2C206C6163696E69612073697420616D65742C20656C656966656E64206E6F6E2C2076656C69742E20566573746962756C756D206163206C656F2E204D617572697320696D70657264696574206A7573746F206163206C65637475732E20536564206D6F6C6573746965206C656374757320736564206475692E20536564206665726D656E74756D2074656D707573206D61757269732E204E616D206F726E617265206F7263692061632074656C6C75732E205574206D616C6573756164612C206C61637573206964206C6163696E696120616363756D73616E2C206469616D20656C69742061646970697363696E67206D657475732C20657420626962656E64756D2073617069656E206E69626820626C616E646974206F7263692E2053757370656E646973736520697073756D2074656C6C75732C20736167697474697320717569732C20766573746962756C756D206E6F6E2C2076756C7075746174652065752C2065726F732E205072616573656E74206174206E756C6C612069642070656465207363656C6572697371756520756C747269636965732E204372617320626C616E646974207072657469756D2074656C6C75732E204D616563656E6173206461706962757320636F6E64696D656E74756D2061756775652E2050686173656C6C75732074696E636964756E74207068617265747261206C6F72656D2E204D6F726269206E6F6E2065726F732E205365642074656D706F722C206E69736C20612074696E636964756E742074696E636964756E742C2065726F73206469616D2064696374756D2073656D2C2076656C206469676E697373696D20616E7465206469616D20736564206D61676E612E205072616573656E74206E6F6E206C6967756C61206964206D65747573206D6F6C657374696520636F6E7365637465747565722E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E64697373652076656C206D692E2043757261626974757220616E7465206E756C6C612C2072757472756D20612C20636F6E76616C6C69732076656C2C207665686963756C612061632C206E756E632E204E756E632073616769747469732C20656E696D2073697420616D657420617563746F722072757472756D2C206D617572697320617263752076756C707574617465206E657175652C20657420657569736D6F64206573742066656C6973207175697320616E74652E20566573746962756C756D207475727069732074656C6C75732C2068656E64726572697420696E2C206C6163696E696120636F6D6D6F646F2C20756C6C616D636F7270657220677261766964612C2072697375732E204D61757269732072686F6E637573206C6163696E69612072697375732E204D616563656E617320736F6C6C696369747564696E2065726174207669746165206E756E632E205072616573656E74207072657469756D2070656C6C656E7465737175652061756775652E20446F6E656320696E74657264756D2E205072616573656E742061632065726F732076697461652065726174206C6F626F72746973206672696E67696C6C612E2041656E65616E20636F6E7365717561742074656C6C75732E204E756C6C6120616363756D73616E20626962656E64756D2066656C69732E204D616563656E6173207072657469756D20616E7465206964206E6973692E2041656E65616E206D6920617263752C2073656D706572207365642C206D61747469732065752C2076656E656E617469732073697420616D65742C20617263752E20446F6E656320616C697175657420657569736D6F64206C656F2E2050726F696E206D61676E61206A7573746F2C2074726973746971756520612C2073656D7065722061632C20736F6C6C696369747564696E20612C206C6967756C612E204D6F7262692076656C69742E20416C697175616D2076656C206E6973692E0A0A496E2061206C6F72656D207574206E756E63206665756769617420636F6E6775652E20446F6E6563206665726D656E74756D20626962656E64756D206475692E2050726F696E207661726975732065737420717569732076656C69742E20446F6E656320616C69717565742073656D20616363756D73616E206D692E2053656420706C6163657261742E204E756C6C616D206163206E6973692061206D61737361206C6F626F727469732073757363697069742E204E756E63206964206C656F2E20416C697175616D206574206D617373612E204E756C6C616D20766573746962756C756D20656C656D656E74756D206D657475732E20496E20636F6E736563746574756572206E6973692076656C206A7573746F2E204D616563656E6173206567657420707572757320736564206D61737361207661726975732070656C6C656E7465737175652E2050686173656C6C75732066617563696275732066656C697320717569732066656C69732E2041656E65616E206F64696F20617263752C20626C616E64697420717569732C20666163696C6973697320696E2C20696D706572646965742065752C206C6F72656D2E204E616D20706F73756572652070756C76696E6172206D692E204675736365207472697374697175652C206D617572697320657420636F6E73656374657475657220756C747269636965732C206D6175726973206C65637475732074656D706F72206A7573746F2C206174206672696E67696C6C61206573742065737420736564206E6973692E20517569737175652066617563696275732E2053656420696E20746F72746F722074696E636964756E7420657374206C6163696E696120696163756C69732E204D616563656E61732061206D617373612E2050656C6C656E7465737175652061206E69626820617420707572757320706F7274612068656E6472657269742E0A0A4E756C6C616D207475727069732E2046757363652061632073656D20736564206F64696F2070656C6C656E74657371756520696D706572646965742E2043757261626974757220696E20617263752E205072616573656E74206C61637573206C616375732C20666575676961742069642C2070756C76696E617220696E2C2074696E636964756E74207365642C206E657175652E204D616563656E61732076697665727261206F64696F206567657420746F72746F722E20496E746567657220616C697175616D2C206C6F72656D2072757472756D2076656E656E61746973206469676E697373696D2C206C6967756C61206D61676E61206D616C65737561646120617263752C2076656C2066657567696174206C6F72656D20697073756D2071756973206D617373612E204D6F72626920616E74652E20566573746962756C756D206D6175726973206C696265726F2C20756C6C616D636F7270657220717569732C20756C74726963657320717569732C20666163696C69736973206E6F6E2C206D617373612E204D616563656E617320696D706572646965742E20416C697175616D206572617420766F6C75747061742E2050656C6C656E746573717565206469676E697373696D2067726176696461206C65637475732E20496E206E696268206F64696F2C20617563746F7220656765742C206461706962757320717569732C206469676E697373696D2076656E656E617469732C20617263752E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20447569732070656C6C656E746573717565206C6967756C612071756973206D617373612E2043757261626974757220636F6E64696D656E74756D2C206A7573746F2065676574206F726E617265206C75637475732C206C6F72656D206C6967756C6120736167697474697320706564652C206120706F727461206E756E63206E756E6320696E206E657175652E20517569737175652066656C6973206D61757269732C20636F6E64696D656E74756D2076697461652C20617563746F722076697461652C2074696E636964756E7420717569732C20706564652E204E756E63206C6163696E696120616E746520696E206C656F2E2050656C6C656E746573717565206C696265726F2E2041656E65616E2061206C6967756C61206574206E756E6320766573746962756C756D20636F6E7365637465747565722E0A0A4675736365206F726E6172652E205072616573656E742069642075726E612E20496E74656765722076656E656E617469732C207175616D206E6F6E20736167697474697320616363756D73616E2C20616E7465206E6962682073616769747469732061756775652C20736F6C6C696369747564696E2061646970697363696E6720646F6C6F722076656C697420657520657261742E2050726F696E207175697320656E696D206575207075727573207665686963756C6120616C697175616D2E204E756C6C612076656C20656E696D2076656C20656C697420736F6C6C696369747564696E206672696E67696C6C612E20416C697175616D206572617420766F6C75747061742E205365642073757363697069742066656C6973207574207475727069732E20457469616D2072757472756D20726973757320696D70657264696574206573742E20416C697175616D20612074656C6C75732061742074656C6C757320636F6D6D6F646F20646170696275732E204D61757269732072757472756D206D61676E61206574206F64696F2E20496E20617420646F6C6F722E20437572616269747572207665686963756C61206C656374757320696E20746F72746F722E204675736365206A7573746F2070757275732C206C75637475732076697461652C206D6F6C6C697320696E2C2070686172657472612061632C2070757275732E204E756C6C616D20706F737565726520696E74657264756D206A7573746F2E20437572616269747572207669746165206C616375732076656C206C656F20636F6E6775652070756C76696E61722E0A0A41656E65616E20656C656966656E64206E6962682076617269757320746F72746F722E2053757370656E64697373652076656C2065726F732E2050726F696E206E6563206469616D206120746F72746F7220756C747269636573206F726E6172652E20416C697175616D207363656C657269737175652066657567696174206A7573746F2E20566976616D757320616E74652075726E612C2061646970697363696E672076697461652C20706F72747469746F722065752C20736F64616C65732065742C2066656C69732E2053757370656E646973736520706F74656E74692E20437572616269747572206163206D6173736120696E206E69736C207361676974746973206D6F6C6C69732E204E616D207175616D206C6967756C612C20636F6E73656374657475657220656765742C20696163756C69732061742C207661726975732065752C206C656F2E204475697320646F6C6F72206C6967756C612C2074696E636964756E742061742C20756C6C616D636F72706572207365642C20616363756D73616E20616C697175616D2C206C6967756C612E2050686173656C6C75732076756C7075746174652C206C6F72656D2061742074696E636964756E742070686172657472612C207269737573206C6563747573206C6163696E6961206D61676E612C20717569732072757472756D20656E696D206D61676E612061742073656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E20447569732069642073656D2061206D617572697320736F6C6C696369747564696E2074696E636964756E742E20457469616D2065752070757275732065752061726375206672696E67696C6C612061646970697363696E672E20566976616D7573206F726E6172652074656D707573206469616D2E2050726F696E20747572706973207175616D2C206C6163696E6961206E6F6E2C20656765737461732061742C20636F6D6D6F646F20656765742C20706564652E205072616573656E742076756C70757461746520726973757320696E206573742E204E756C6C6120666163696C6973692E0A0A557420656C656D656E74756D206C6163696E69612070757275732E2050726F696E2076697461652061726375206163206E756C6C6120636F6E76616C6C697320616C697175616D2E204E756C6C6120636F6E6775652C206C696265726F2069642070656C6C656E746573717565206D61747469732C207175616D206C656374757320706F72747469746F72206469616D2C2061207363656C6572697371756520647569206C696265726F20696E2073617069656E2E204E756C6C616D2066656C6973206469616D2C207665686963756C612076656C2C206D6F6C65737469652075742C20766573746962756C756D20616C697175616D2C2073617069656E2E20446F6E656320636F6E76616C6C69732C2065737420757420656C656D656E74756D20766F6C75747061742C206D617572697320697073756D20677261766964612073656D2C20636F6D6D6F646F20666163696C697369732073617069656E206C65637475732073656D706572206C65637475732E205175697371756520706F72747469746F722065726F73207574206E6962682E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20457469616D206D617474697320726973757320736564206F64696F2E20566573746962756C756D206574206F64696F2E20496E206861632068616269746173736520706C617465612064696374756D73742E204E616D20747269737469717565206D61737361207574206C6967756C612E2051756973717565206E6962682074656C6C75732C207665686963756C612073697420616D65742C2061646970697363696E672061742C20636F6E76616C6C6973206E65632C206C6967756C612E20566573746962756C756D207072657469756D2C206D69206E6563206672696E67696C6C6120626962656E64756D2C20647569206E756E6320736F64616C657320706564652C20612073656D706572206D61676E61206E696268206E6F6E206469616D2E20446F6E6563206D61737361206E756E632C20766976657272612076656C2C20636F6E73656374657475657220706F7274612C2064617069627573206E6F6E2C20697073756D2E2044756973206E69736C206D61757269732C206375727375732076656C2C2073656D706572206E6F6E2C20736F6C6C696369747564696E20626962656E64756D2C2066656C69732E20566573746962756C756D206575206E657175652E0A0A43726173206E656320646F6C6F722E20446F6E6563206C616F726565742074656D707573206C65637475732E20437261732073656420746F72746F7220696E74657264756D206C6163757320656C656966656E64206469676E697373696D2E204D616563656E61732073697420616D657420656C69742E204E756C6C616D207175697320646F6C6F722076656C20647569207068617265747261206C75637475732E20496E2073697420616D6574207175616D2073697420616D6574207065646520756C74726963657320756C7472696365732E204D616563656E6173206469616D2E20496E74656765722075726E612E204375726162697475722064696374756D2C2076656C69742073656420706C6163657261742073757363697069742C206572617420747572706973206665726D656E74756D206A7573746F2C2073656420696E74657264756D206E657175652073656D206574206E6962682E20566976616D757320636F6E73657175617420636F6E76616C6C6973206D61676E612E204E616D20616C697175616D2C2065737420616320626962656E64756D20636F6D6D6F646F2C206D61676E61206573742064696374756D206D692C207669746165206D616C65737561646120656C6974206D61676E61207669746165206F64696F2E204D616563656E61732074656D706F722076756C7075746174652074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206475692E20457469616D20616363756D73616E207065646520636F6E67756520746F72746F722E0A0A4D6F7262692074656D706F72206C696265726F206163206C6F72656D2E20496E20616C697175657420766172697573206D61676E612E20496E20617263752E2050686173656C6C7573206F64696F2E2046757363652074696E636964756E7420616C69717565742066656C69732E20517569737175652076656C69742E20536564206C75637475732E20416C697175616D2066657567696174206672696E67696C6C61206D692E20416C697175616D206D6F6C657374696520766976657272612072697375732E2050726F696E20617263752E20566573746962756C756D206C6F626F727469732074656D707573206E6973692E205072616573656E742061206172637520696E2076656C697420766976657272612072757472756D2E0A0A496E20736564206C65637475732E20446F6E656320726973757320646F6C6F722C20626C616E6469742073697420616D65742C20656C656D656E74756D20636F6E76616C6C69732C20706861726574726120717569732C20706564652E20496E7465676572206F726E6172652E2041656E65616E20656765737461732064617069627573206A7573746F2E20536564207175616D206C656F2C20706F73756572652061742C20656C656D656E74756D2076697461652C20636F6D6D6F646F20656765742C206573742E20416C697175616D206D6F6C65737469652072686F6E63757320656E696D2E2043757261626974757220696163756C697320756C74726963657320706564652E204D6F72626920616C69717565742072757472756D206C616375732E20416C697175616D207175616D2E2053656420636F6D6D6F646F2C2074757270697320696E20706861726574726120706F73756572652C206D6920726973757320696D7065726469657420657261742C206120766573746962756C756D206D617373612074656C6C7573207665686963756C612073656D2E204D6175726973206672696E67696C6C6120756C747269636573206E756E632E204E616D206E69736920656E696D2C20656C656966656E642073697420616D65742C20756C747269636573207365642C206665726D656E74756D206E6F6E2C2061756775652E2050726F696E20636F6E677565206C6F626F72746973206E6973692E204D616563656E61732068656E6472657269742E204E616D20736564206E69736C2E204E756E6320656C656D656E74756D206F64696F2065752072697375732E20496E206D657475732E2050686173656C6C75732067726176696461207072657469756D206C6967756C612E204E756C6C61207669746165206E657175652E204E616D206E69736920746F72746F722C206F726E617265206E6F6E2C20626C616E6469742061742C206375727375732065752C20746F72746F722E0A0A4475697320626962656E64756D20697073756D20696E206E756E6320637572737573206D6F6C65737469652E204E756E63206F7263692E204E756C6C616D206E656320616E7465206E6F6E20657374206469676E697373696D20766976657272612E204D617572697320626C616E6469742C2076656C69742069642066657567696174207072657469756D2C20656C6974206D61676E612070656C6C656E74657371756520646F6C6F722C206174207361676974746973206C616375732076656C69742065676573746173206D61676E612E2050656C6C656E746573717565206375727375732C206469616D20636F6E736563746574756572207361676974746973206672696E67696C6C612C20746F72746F72206E6973692061646970697363696E67206E756E632C20657520766172697573206C6163757320726973757320616320656C69742E204D6175726973206964206E6973692071756973206C656F20657569736D6F642076656E656E617469732E2050656C6C656E74657371756520616320616E74652E204D617572697320617263752073617069656E2C2074656D706F722061742C20706F72747469746F722069642C20636F6E64696D656E74756D2075742C206475692E20457469616D206665726D656E74756D20756C747269636965732061756775652E20437261732075742065726F73206174206A7573746F20756C7472696369657320696163756C69732E2044756973206469676E697373696D2C206E69736C20657420666163696C69736973206665726D656E74756D2C2065726174207075727573206D6F6C65737469652074656C6C75732C20717569732074656D70757320697073756D206C656374757320617420656C69742E204E756C6C61207669746165206C6F72656D2E0A0A41656E65616E2076656C2073656D206574206469616D2073656D70657220636F6E6775652E20496E20626962656E64756D206469616D20717569732074656C6C75732E204E756E6320666163696C6973697320756C74726963696573206E6962682E2043726173206E756E6320656E696D2C2066657567696174207365642C20756C7472696365732076697461652C2073616769747469732076697461652C20697073756D2E204675736365207669746165206E756C6C612E20446F6E65632070656C6C656E7465737175652C2076656C697420696E20706F72747469746F7220656C656966656E642C20657374206E65717565206C6F626F727469732076656C69742C2073697420616D65742072757472756D20616E746520746F72746F72206E656320646F6C6F722E20446F6E6563207665686963756C612E204E756C6C6120666163696C6973692E20536564206567657374617320756C747269636573206E6962682E20446F6E656320656C6974206C65637475732C20636F6E76616C6C697320706F72747469746F722C20616C697175657420646170696275732C206665756769617420656765742C206C6967756C612E2053656420636F6E736563746574756572206A7573746F2E204D616563656E617320612073617069656E2073697420616D6574206E6973692064617069627573206C6F626F727469732E20566976616D7573206C7563747573206C6F72656D206E6F6E206E756C6C612E2053656420656765742065726174207669746165206C696265726F20696E74657264756D20706F73756572652E20437261732070756C76696E61722E204E756C6C616D20696D706572646965742C20646F6C6F722074656D706F72206469676E697373696D20626C616E6469742C206475692073617069656E2072686F6E637573206E657175652C206964206D616C657375616461206175677565206D61676E612073697420616D65742075726E612E204475697320736564206D61757269732E0A0A4D6F72626920616363756D73616E2E20536564206D61757269732061756775652C206672696E67696C6C61206E6F6E2C20617563746F722075742C20617563746F722065742C206F7263692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320757420706564652E20446F6E6563207669766572726120656E696D2076656C206C6F72656D2E2050656C6C656E746573717565206E65717565206D61757269732C20696E74657264756D2065752C2076656E656E617469732069642C20636F6E64696D656E74756D2065752C2073617069656E2E20446F6E656320697073756D20617263752C206C6163696E69612061646970697363696E672C206C616F726565742065742C206375727375732076656C2C2076656C69742E205574207361676974746973206D617572697320717569732072697375732E20496E7465676572206575206F64696F207669746165206C61637573207669766572726120616363756D73616E2E204D6F726269206C656F20616E74652C206469676E697373696D207365642C2076617269757320717569732C20766F6C75747061742076697461652C206E6973692E204E756C6C6120706C61636572617420696E74657264756D20656C69742E20446F6E6563206E65717565206475692C2073616769747469732076697461652C20736F6C6C696369747564696E20717569732C20636F6D6D6F646F2076697461652C206E657175652E204E756C6C612071756973206C6967756C61206F726E617265206C6967756C612064696374756D206F726E6172652E204D61757269732072757472756D2072757472756D206E657175652E2041656E65616E207665686963756C612074656D707573206573742E20446F6E656320766172697573207363656C6572697371756520706564652E20446F6E656320706C6163657261742076756C707574617465206C656F2E204E756C6C616D206E756E63206E69736C2C20706F7375657265206E6F6E2C20666575676961742076697461652C2070656C6C656E74657371756520717569732C206D61757269732E20496E20647569206E657175652C2063757273757320656765742C20736167697474697320656765742C20646170696275732076697461652C206D692E2050726F696E2065676574206573742E0A0A467573636520706F727461206573742E204D6175726973206D61676E612E20416C697175616D20697073756D206C616375732C20756C747269636965732069642C20766573746962756C756D206C75637475732C20616363756D73616E2075742C20616E74652E20536564206D61757269732E205365642061646970697363696E67206C656F2073697420616D6574206D61676E612E2053757370656E646973736520706F74656E74692E204E756E63206D6173736120656C69742C206672696E67696C6C6120656765742C20656765737461732076697461652C206C75637475732076697461652C20646F6C6F722E2050686173656C6C75732071756973206E756C6C61206575206E69736920696E74657264756D20736F6C6C696369747564696E2E204E756C6C616D2069642074656C6C75732E20496E746567657220696163756C697320646F6C6F722061632070757275732E205365642076656C206D692E20437572616269747572206E6F6E206D61676E612073697420616D6574206A7573746F20636F6E64696D656E74756D2076756C7075746174652E20517569737175652074696E636964756E742070656465206575206E69736C2E20566976616D7573206C6F626F727469732E204E756E63206D65747573206D657475732C20636F6E677565207365642C2074696E636964756E74207365642C207072657469756D2061742C206F64696F2E20446F6E6563206120617263752E20496E2073656D206A7573746F2C207665686963756C61207365642C207661726975732069642C20766F6C75747061742061742C2072697375732E205072616573656E7420696163756C6973206D617373612E20496E206172637520656C69742C2068656E64726572697420656765742C20756C6C616D636F7270657220696E2C20706F7274612069642C2074656C6C75732E20446F6E65632073616769747469732068656E647265726974206469616D2E0A0A53757370656E646973736520706F74656E74692E20536564206574206469616D206574206175677565207361676974746973206C6F626F727469732E2050686173656C6C757320646F6C6F722E2055742065742061726375206567657420616E74652074656D706F7220706F73756572652E20416C697175616D206665726D656E74756D207363656C65726973717565206475692E204D61757269732061742070757275732E20446F6E656320657261742073656D2C20766573746962756C756D206E65632C2066617563696275732061632C206D617474697320612C206C656F2E2053757370656E64697373652061646970697363696E67206C6163696E69612073656D2E204E756C6C616D206F72636920617263752C2064696374756D2065742C20666175636962757320766976657272612C20646170696275732065742C206E657175652E2043726173206E756E63206469616D2C2061646970697363696E67206E6F6E2C20736F6C6C696369747564696E20696E2C20696E74657264756D2076656C2C206D617373612E204D61757269732073616769747469732C206A7573746F206174207472697374697175652074656D7075732C206D6175726973206D617572697320616C697175616D20616E74652C2073697420616D657420706F7375657265206469616D206475692065676574206C6967756C612E20496E206469676E697373696D2C206E69736C207574206C6163696E696120636F6E64696D656E74756D2C2065726174206A7573746F20706F72747469746F72206E756C6C612C206E6F6E2067726176696461206C6967756C61206D61676E612065676574206D617373612E20566573746962756C756D207669746165206C6967756C61206174206D6920766573746962756C756D2073757363697069742E2044756973206C616F726565742E204E756C6C6120636F6D6D6F646F206C696265726F2073697420616D6574206C6F72656D2E20557420656C656D656E74756D2073656D2E20496E74656765722076656C20646F6C6F722E204E616D20666163696C69736973206D6920717569732073656D20756C7472696365732073616769747469732E205365642071756973207175616D206174206D65747573206D6F6C657374696520626962656E64756D2E0A0A50726F696E2064756920656E696D2C206C6163696E696120612C20666575676961742061632C20706C6163657261742076697461652C20706564652E205175697371756520656765737461732C206C656F206567657420616C697175616D207072657469756D2C206C696265726F206A7573746F2074696E636964756E742065726F732C2075742065676573746173206175677565207065646520656C656D656E74756D206E6962682E20437572616269747572206D6F6C6C697320736F64616C657320656E696D2E20446F6E65632061756775652E2050686173656C6C757320696420697073756D20706F737565726520647569207072657469756D2066617563696275732E204D6175726973206C756374757320616E74652073656D706572206E69736920696E74657264756D2061646970697363696E672E204475697320646170696275732C206F64696F207175697320766976657272612072686F6E6375732C206A7573746F207175616D20626962656E64756D20646F6C6F722C20696420646170696275732076656C697420657261742076656C20657261742E2046757363652073697420616D6574206E69736C2076656E656E61746973207175616D20756C74726963657320636F6E64696D656E74756D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632072686F6E637573207363656C65726973717565206C6967756C612E20566573746962756C756D206D69206F64696F2C20616363756D73616E2065742C2061646970697363696E6720656765742C206F726E6172652075742C207175616D2E204E756C6C616D20626C616E646974206D6F6C6573746965206D61757269732E20437572616269747572206469676E697373696D206D6175726973206574206C6F72656D2E2053757370656E64697373652061206A7573746F2E204E616D206D617474697320666175636962757320617263752E204475697320626C616E64697420656E696D206E6F6E206D617373612E0A0A4E756C6C616D206C6F72656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E204D617572697320636F6E73656374657475657220706F7375657265206D61757269732E204D616563656E61732074696E636964756E74206D617572697320696E2065726F732E204E756C6C61206575206D65747573206575206F72636920736F6C6C696369747564696E2066617563696275732E2053757370656E646973736520616C697175616D206D6175726973206964206573742E204372617320626C616E646974206475692065742075726E612E204E756C6C6120617263752E2053656420612075726E612E204E756C6C612064617069627573207665686963756C6120746F72746F722E20446F6E65632072697375732E20536564207175616D206D657475732C20656765737461732065752C206375727375732075742C2076697665727261206E6F6E2C206F64696F2E205574206A7573746F206A7573746F2C206D616C6573756164612073697420616D65742C20626C616E6469742073757363697069742C206D6F6C657374696520696E2C206A7573746F2E20566573746962756C756D20636F6E7365717561742C207175616D20616320666575676961742074696E636964756E742C20697073756D206C696265726F20656C656966656E64206F64696F2C206E6F6E20656C656966656E64207065646520697073756D206E6F6E20616E74652E204E756C6C616D2061206D657475732E0A0A4E616D206163206E6973692061742066656C697320637572737573206D61747469732E2050656C6C656E74657371756520636F6E7365717561742073656D2071756973206F7263692E20517569737175652074656D7075732E2041656E65616E20696D70657264696574206D6F6C657374696520706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652065752074656C6C75732E204E756C6C61206469616D2065726F732C20736F64616C65732075742C20736F64616C6573206E65632C2074696E636964756E742061632C206E756E632E204E756E63206C6163696E696120666175636962757320697073756D2E20566976616D75732076656C206E6571756520696E2065726174206665726D656E74756D206C75637475732E204E756C6C612065676574206D65747573206E656320617567756520626962656E64756D20706C6163657261742E20566976616D75732074656D7075732E205072616573656E7420636F6E677565206F726E61726520697073756D2E20457469616D206D61747469732066657567696174206A7573746F2E0A0A416C697175616D206475692E2041656E65616E20636F6D6D6F646F20746F72746F72207669746165206E756C6C612E204D6F72626920657420697073756D2E204D617572697320616320697073756D2E204E616D2076656C207269737573207574206C6563747573206D6F6C6C697320766976657272612E2043757261626974757220656C656D656E74756D206D6F6C6C6973206573742E204E756C6C616D20656C69742E20566573746962756C756D207375736369706974207072657469756D20656E696D2E20566573746962756C756D207574206D617373612E2050726F696E206E65632066656C69732E204D616563656E617320677261766964612C2061726375206E656320636F6E7365717561742073616769747469732C2065726F732074656C6C7573207363656C65726973717565206D61757269732C20766974616520616363756D73616E207175616D207175616D207574206E756E632E20496E7465676572206567657420616E74652065752076656C6974206C616F72656574206D616C6573756164612E204E756E632073616769747469732C206D617572697320766974616520706861726574726120766F6C75747061742C2074656C6C75732074656C6C757320656C656966656E642065726F732C2073697420616D65742072757472756D20697073756D206E69736920612076656C69742E205072616573656E7420766172697573206C656F20657520657261742E20566976616D757320636F6E73657175617420706C6163657261742070757275732E20446F6E6563207072657469756D20656C656D656E74756D206E6962682E2050726F696E20617420656C6974206E6F6E2073656D20616C6971756574206D61747469732E2053656420756C6C616D636F7270657220697073756D2073697420616D657420656C69742E0A0A4D617572697320696E206D657475732E2053757370656E6469737365206D61676E61206C6F72656D2C2066617563696275732076656C2C2074696E636964756E7420717569732C207363656C65726973717565206E6F6E2C2074656C6C75732E2046757363652071756973206C6F72656D2E2050726F696E2061206C616375732073697420616D6574206D617572697320696163756C69732070756C76696E61722E2053757370656E64697373652072686F6E6375732065726F73206E6563206D692E205072616573656E7420657569736D6F642C207475727069732076697461652072757472756D207072657469756D2C206F64696F206D6574757320766F6C7574706174206E657175652C20656765742074656D7075732073617069656E206E657175652073656420657261742E20446F6E6563206665726D656E74756D207075727573206174206C65637475732E204E756C6C616D2073656D2E2046757363652076656C206D6920717569732065726174206C6F626F7274697320706F73756572652E2041656E65616E20656765742075726E612E2053757370656E6469737365206C6967756C612E204475697320696E206E6973692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A4375726162697475722076756C707574617465206C656374757320696420706564652E2050686173656C6C75732065752076656C69742E20457469616D2076656E656E617469732061646970697363696E67206E6962682E20416C697175616D206375727375732070756C76696E61722074656C6C75732E20566573746962756C756D206E657175652E204D6175726973206E6563206A7573746F20657420657261742073656D7065722070656C6C656E7465737175652E204675736365206D61747469732064696374756D20646F6C6F722E20457469616D2065676574207075727573206575206D617373612076617269757320656C656D656E74756D2E2050656C6C656E746573717565206D617373612E20557420756C74726963696573206469616D2073656420697073756D2E204E756C6C616D206469616D2E2050656C6C656E746573717565206964206D61676E61206964206C696265726F2074726973746971756520616C697175616D2E0A0A557420656C656966656E642C20707572757320696420706C6163657261742076656E656E617469732C2075726E6120617567756520616C6971756574206C6967756C612C20696E20756C74726963696573206C656F2072697375732065742074656C6C75732E204D6175726973206574206E756C6C612069642075726E61207472697374697175652074656D7075732E20557420666163696C697369732C2075726E6120657520766573746962756C756D2072686F6E6375732C206C616375732065726F7320636F6E736563746574756572206D657475732C2065742072757472756D20647569206C656374757320696E2070757275732E204E756E632076656C206E69736C206E6F6E20697073756D2074696E636964756E74206D6F6C6C69732E204E616D207175616D206C616375732C206F726E6172652076697461652C2072686F6E637573206E6F6E2C20636F6E677565207365642C206F64696F2E2050726F696E206E696268206475692C20706F7274612076656C2C2076656E656E61746973206E6F6E2C2070656C6C656E7465737175652075742C206E6973692E20536564207472697374697175652066656C69732061206D61676E612E2053757370656E646973736520656765742074656C6C75732E2043726173206772617669646120696D706572646965742076656C69742E20496E74656765722068656E6472657269742072697375732E2050726F696E206F7263692E20416C697175616D20756C6C616D636F72706572206D61757269732071756973206D61757269732E204E756E63206C6163696E696120766573746962756C756D206D657475732E20447569732074656C6C75732E204E756C6C616D2066617563696275732C206C656F2061632076756C70757461746520736F6C6C696369747564696E2C206C656F20646F6C6F7220666175636962757320657261742C207175697320626962656E64756D206F726369206F64696F206E6F6E20617263752E0A0A4E756C6C616D20616363756D73616E206D617474697320646F6C6F722E20446F6E6563206574206475692E205072616573656E7420612066656C6973206D6F6C6C6973206C616375732073656D706572206C6163696E69612E204375726162697475722070656C6C656E746573717565206C7563747573206573742E2050726F696E206E756C6C61206475692C20636F6E64696D656E74756D2076656C2C206661756369627573206E6F6E2C20696E74657264756D2061632C20657261742E204D616563656E6173207363656C657269737175652C206C656374757320696420766F6C757470617420616363756D73616E2C2073617069656E20746F72746F722070656C6C656E746573717565206475692C207365642073656D706572206D61676E612073656D207574206C656F2E2050726F696E206E756C6C612E204E756C6C616D206461706962757320756C6C616D636F727065722073656D2E2053757370656E6469737365207665686963756C61206D6574757320696E206E756E632E2050656C6C656E746573717565206E6F6E207175616D2076656C206172637520756C74726963657320756C6C616D636F727065722E2050686173656C6C757320717569732066656C69732073697420616D65742074656C6C757320756C6C616D636F72706572206665726D656E74756D2E20536564207665686963756C6120736F6C6C696369747564696E2075726E612E20437572616269747572207068617265747261207363656C657269737175652072697375732E2050656C6C656E746573717565206964206D617373612071756973206D6574757320616C697175616D20696D706572646965742E20496E206E756E63206C616375732C206665756769617420696E2C206772617669646120656765742C2076656E656E617469732075742C2074656C6C75732E2053757370656E646973736520706F74656E74692E204E616D20636F6E7365717561742061646970697363696E67206475692E20496E206E756C6C61206E6973692C20666575676961742075742C206665726D656E74756D2076656C2C2067726176696461206E65632C20746F72746F722E20496E207365642061756775652E0A0A457469616D20756C6C616D636F7270657220617567756520617420656E696D2E20496E7465676572206469676E697373696D2E20416C697175616D2070756C76696E617220636F6E677565206E756C6C612E204D6F72626920656E696D206D617373612C206672696E67696C6C6120612C20616363756D73616E20656765742C20636F6E64696D656E74756D206E65632C20657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2041656E65616E2070686172657472612E20457469616D20706F72747469746F722070757275732061206D657475732E20416C697175616D20696E74657264756D2073656D2065676574206A7573746F2E205175697371756520766F6C7574706174206C7563747573206573742E2041656E65616E2061756775652E2050686173656C6C757320647569206C65637475732C20756C747269636573206E65632C20636F6D6D6F646F2076656C2C20617563746F722076656C2C206E6973692E20557420756C7472696365732070656C6C656E746573717565206E6973692E20496E74656765722061632076656C69742065742073656D20696D70657264696574206C75637475732E20467573636520766974616520747572706973206964206175677565206D6F6C6C697320636F6E7365637465747565722E0A0A4D616563656E6173206E6563206C616375732E204D616563656E617320636F6E64696D656E74756D206F64696F2065752066656C69732E204D6175726973207574206E69736C207669766572726120657261742066617563696275732061646970697363696E672E20457469616D20656765737461732E204E756E6320657420646F6C6F72207669746165207269737573206469676E697373696D20636F6D6D6F646F2E204D6F726269206C65637475732076656C69742C2074696E636964756E74206E65632C20616C69717565742076656C2C206D61747469732076697461652C206C6967756C612E204D616563656E617320756C747269636965732073656D70657220646F6C6F722E2053757370656E6469737365206D616C6573756164612E20496E7465676572206D617474697320656C69742E20446F6E656320616363756D73616E2C206C6163757320666163696C69736973207661726975732074656D7075732C206E756C6C6120656C697420706F72746120657261742C2065742072757472756D20656C69742073656D2073697420616D6574206475692E0A0A4D616563656E6173206D6F6C6C6973206D69206E6F6E206E756C6C612E20566976616D7573207475727069732E2053757370656E64697373652061206D657475732E20496E2071756973206D6920696E2074757270697320636F6E67756520617563746F722E204D616563656E6173206C616375732E2053757370656E646973736520736F6C6C696369747564696E2E2050686173656C6C757320706F727461206E756E63206E6F6E206E69736C2070756C76696E617220656765737461732E20536564206E756C6C612E20566573746962756C756D206163206D692E204D617572697320756C7472696369657320636F6E64696D656E74756D206E657175652E204E756C6C612074656D707573206A7573746F2076656C206D617373612E204E756C6C6120737573636970697420636F6E67756520617263752E205072616573656E74206964207475727069732E204D6175726973206E69626820706564652C20657569736D6F642073656D7065722C206D6F6C65737469652061632C2072686F6E6375732076697461652C20616E74652E204D616563656E617320657261742066656C69732C207669766572726120736F6C6C696369747564696E2C20736167697474697320656765742C2070656C6C656E746573717565206E65632C206F7263692E20467573636520756C74726963657320636F6E736571756174206C616375732E20416C697175616D2065726174206D61676E612C20666575676961742061742C207669766572726120612C206D6F6C6C6973206E6F6E2C207475727069732E0A0A446F6E6563206D692E204E616D2064696374756D2070656C6C656E7465737175652073656D2E20446F6E6563206D6F6C6C69732072686F6E63757320656C69742E2050686173656C6C75732072686F6E63757320706564652073697420616D65742072697375732E20446F6E656320656765742061756775652E204D616563656E6173206E6F6E206C65637475732E2050686173656C6C757320736F6C6C696369747564696E206E697369206E65632066656C69732E20416C697175616D207072657469756D2C2065737420656765742073656D70657220636F6E76616C6C69732C206E696268206E756E6320736F6C6C696369747564696E2070757275732C2069642074656D706F722070656465206475692076656C206D61676E612E20566976616D7573206163206C6F72656D2E20457469616D206E69736C20746F72746F722C2061646970697363696E672064696374756D2C20656C656D656E74756D20696E2C20666163696C69736973207365642C206E6962682E2050726F696E206D61757269732E2050726F696E2072757472756D206D6173736120656765742073656D2E204375726162697475722074656D706F722061646970697363696E6720656C69742E204375726162697475722070757275732074656C6C75732C206665726D656E74756D20656765742C20616C69717565742076697461652C20636F6E76616C6C69732061632C206D61757269732E0A0A496E746567657220636F6E7365717561742076656C69742065752065726F732074696E636964756E74207665686963756C612E204E756C6C616D206C6F72656D2073617069656E2C2072686F6E637573206E6F6E2C206D617474697320717569732C20756C747269636965732073697420616D65742C20656E696D2E2043757261626974757220636F6D6D6F646F2C206C696265726F20696E20657569736D6F642073757363697069742C2073656D207075727573206672696E67696C6C6120656E696D2C206163206D6F6C657374696520746F72746F72206F7263692065742076656C69742E20446F6E656320706564652E20457469616D20706C61636572617420636F6E64696D656E74756D207475727069732E2050686173656C6C7573206567657374617320656E696D206E6563206D61676E612E20566976616D757320636F6E64696D656E74756D2C206E756C6C612076656C206C7563747573207472697374697175652C2065726F7320726973757320766573746962756C756D206E756C6C612C20696E207665686963756C61206172637520697073756D2061742066656C69732E20446F6E656320616C697175616D20656C69742061742061756775652E205175697371756520612065726F73206575206C6967756C6120616363756D73616E2064696374756D2E20457469616D207665686963756C61207475727069732071756973206C696265726F2E20416C697175616D206E6F6E206D692E20446F6E6563206574206C656F2E2050726F696E206C656F206C696265726F2C20616C697175616D2074696E636964756E742C20636F6E677565206E65632C2061646970697363696E6720706F7274612C20656E696D2E204E756C6C61206C6F626F727469732C20746F72746F722073697420616D657420696D7065726469657420756C6C616D636F727065722C20646F6C6F72206F726369206D616C65737561646120706564652C207365642067726176696461206E6962682075726E612076656C206C6F72656D2E20536564207068617265747261206D616C6573756164612065726F732E205175697371756520657569736D6F6420616C697175657420657261742E2053757370656E646973736520616C6971756574206D61747469732070757275732E0A0A4E756E63206964206E756C6C612071756973206A7573746F20636F6E67756520736F6C6C696369747564696E2E205072616573656E742065726174207475727069732C2072686F6E6375732065752C207072657469756D2065752C2070656C6C656E74657371756520612C206E6962682E20566976616D75732074656D7075732E2043726173206E65632072697375732061742074757270697320696D70657264696574206C6F626F727469732E205574206D61747469732E204D616563656E6173206573742066656C69732C2070656C6C656E746573717565206E6F6E2C20696D70657264696574207365642C20656C656966656E642074696E636964756E742C206C6F72656D2E20496E2074696E636964756E742E205365642076656C206C656F2E20446F6E65632065742075726E6120696E207475727069732068656E64726572697420626C616E6469742E20446F6E656320636F6E64696D656E74756D20616363756D73616E206573742E2055742070686172657472612C206D65747573207669746165206D617474697320636F6E7365637465747565722C206C656F207175616D2076756C707574617465206F64696F2C206E6563206C616F72656574206E6973692076656C697420657520657261742E20496E7465676572206C65637475732061756775652C206567657374617320696E2C20696E74657264756D2065752C2076656E656E617469732076656C2C2073617069656E2E2051756973717565206574206573742076697461652065726F73206C616F72656574206C6F626F727469732E204E756C6C616D207574207269737573206E6F6E206E756C6C6120706C6163657261742061646970697363696E672E205072616573656E7420646170696275732E20457469616D20612066656C69732E20557420736F64616C657320636F6E736571756174206D61757269732E2044756973206C6F72656D2066656C69732C206C756374757320612C2074726973746971756520696E2C206D6F6C65737469652061742C2072697375732E20536564207665686963756C6120626962656E64756D2074656C6C75732E204E616D20636F6E73657175617420657569736D6F64206C616375732E0A0A41656E65616E20746F72746F7220656C69742C2067726176696461206E65632C206665726D656E74756D2065752C206C6F626F727469732069642C20697073756D2E204D616563656E61732065752070757275732E204372617320616320747572706973207574206E69736920696163756C69732072686F6E6375732E204E756C6C61207075727573206D657475732C206469676E697373696D206E65632C2074696E636964756E742076697461652C20646170696275732065752C206E6962682E204675736365206C6F626F727469732C206E756E63206174207669766572726120656C656966656E642C206A7573746F20747572706973207363656C657269737175652065726F732C2061632070656C6C656E746573717565206D65747573206E69736C2061742070757275732E2053656420656C656D656E74756D2074656C6C75732073656420656E696D20696E74657264756D20626C616E6469742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E746567657220756C7472696369657320616C6971756574206F64696F2E204D61757269732065676574206E756E63206120697073756D20756C74726963657320736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2041656E65616E20616363756D73616E2E20446F6E65632073617069656E206C65637475732C20636F6E6775652061742C20706F7274612069642C2068656E6472657269742076697461652C206E69736C2E204375726162697475722076656C207175616D2076656C206E6571756520616363756D73616E206C616F726565742E204D6F7262692073617069656E206573742C207072657469756D20696E2C20636F6E7365637465747565722061632C206D6F6C6C69732075742C206C696265726F2E20446F6E65632074696E636964756E742061646970697363696E67206D657475732E204E756E6320766573746962756C756D20656765737461732061756775652E20446F6E6563207363656C65726973717565206475692075742073656D2E2053757370656E64697373652076656C206D6574757320696420657374206D6F6C657374696520696163756C69732E0A0A566976616D75732070686172657472612C20656C6974206575206D616C65737561646120626C616E6469742C206469616D20746F72746F72206D6F6C6C6973206475692C207365642070756C76696E6172206D61737361206E756E63206574206D61676E612E2053656420706C61636572617420656C697420617563746F7220746F72746F722E204E756C6C6120616320657261742E2050656C6C656E74657371756520636F6E7365637465747565722C2064756920636F6E76616C6C69732074696E636964756E7420636F6E64696D656E74756D2C2073656D206F64696F20766F6C7574706174206C696265726F2C206E6F6E20656C656D656E74756D2066656C6973206E65717565206E6563206F64696F2E204D616563656E61732068656E6472657269742065726F73206964206469616D2E204D61757269732076656C207075727573206163206F72636920636F6E76616C6C697320636F6E76616C6C69732E205365642073697420616D6574206C616375732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652064696374756D20766172697573206C616375732E204D61757269732065676574206E69736C2E2053757370656E646973736520706C6163657261742C206E756C6C61206E6F6E206F726E617265206469676E697373696D2C206E69736C206469616D2073616769747469732074656C6C75732C20696E2073656D706572206E69736920646F6C6F72206174206E6962682E204475697320756C6C616D636F7270657220766976657272612066656C69732E20496E746567657220612074656C6C75732E2053757370656E64697373652065676574206E756E632E2041656E65616E206469616D206573742C20616363756D73616E2069642C20737573636970697420696E74657264756D2C206672696E67696C6C612076697461652C206A7573746F2E2050726F696E20706564652E204D616563656E6173206174206E6571756520696E206E6571756520766573746962756C756D20656C656966656E642E0A0A566573746962756C756D206E756C6C61206C6F72656D2C20706F72747469746F7220656765742C20657569736D6F642061632C20616C697175616D2061742C206E69736C2E204D616563656E6173206574206573742065676574206D6173736120766172697573206C6F626F727469732E20496E206D692E204475697320706F72747469746F72206665726D656E74756D2070757275732E20446F6E65632063757273757320696D70657264696574206C6967756C612E204D6F726269206574206C6967756C6120657420616E7465206D6F6C6573746965207665686963756C612E204D61757269732073656420646F6C6F722E2053656420696D706572646965742066656C69732075742073656D2E20536564207669746165206E6571756520656C656D656E74756D206C656F20617563746F72206665726D656E74756D2E2044756973206665756769617420756C6C616D636F7270657220657261742E2041656E65616E2070757275732E204D6F726269206665726D656E74756D20766573746962756C756D206573742E2050656C6C656E7465737175652076656E656E61746973206D61757269732E2050686173656C6C75732070756C76696E61722E20496E746567657220697073756D206C65637475732C20696163756C697320612C206C6163696E69612069642C20616363756D73616E2069642C20617263752E2050686173656C6C7573206174206573742E204675736365206E65717565207175616D2C20756C747269636965732069642C20696163756C69732076656C2C20646170696275732076697461652C206C616375732E20496E206C6F626F7274697320636F6E76616C6C697320616E74652E204E756C6C61206E756E632070757275732C2076756C70757461746520696E2C2068656E6472657269742065742C20626C616E6469742065742C206C6967756C612E0A0A50656C6C656E746573717565206C656F206D657475732C20736167697474697320696E2C206D6F6C65737469652076697461652C2064696374756D20696E2C20706564652E204D6F726269207072657469756D2066656C6973206E6563207175616D2E2050656C6C656E746573717565206D617474697320616E746520736564207175616D20736167697474697320646170696275732E2053757370656E64697373652073617069656E2E205072616573656E7420626962656E64756D20696163756C697320746F72746F722E20447569732061206E69736C2E2041656E65616E206D692E20446F6E65632064696374756D206172637520696E206573742E204D6F72626920696E74657264756D2076756C70757461746520697073756D2E2041656E65616E2073697420616D6574206D61676E61206E6F6E206E69736C2074726973746971756520706F73756572652E2050686173656C6C75732076656C6974206D657475732C2074656D706F722061632C206665726D656E74756D20656765742C20636F6E64696D656E74756D206E6F6E2C2076656C69742E20566573746962756C756D2073697420706F73756572652E0A0A4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204372617320616C6971756574206D61737361206E6563206475692E20437261732061726375206E756E632C2068656E6472657269742061632C20656C656966656E642065752C20756C6C616D636F72706572206E65632C2074656C6C75732E205365642070686172657472612070757275732073697420616D6574207175616D2E20437572616269747572206D6F6C6C69732E204E616D20766974616520706564652E20457469616D207269737573206D617373612C207665686963756C612073697420616D65742C207068617265747261206E65632C20736F6C6C696369747564696E2075742C206475692E20446F6E65632065676573746173206A7573746F206174207175616D2E2050726F696E206E69736C2072697375732C20766573746962756C756D206E65632C207072657469756D2076697461652C207472697374697175652061632C206C6F72656D2E20416C697175616D206572617420766F6C75747061742E204372617320736564206E6962682E2050656C6C656E74657371756520736F6C6C696369747564696E20657569736D6F642061756775652E0A0A457469616D206672696E67696C6C6120736F6C6C696369747564696E206F7263692E204D61757269732063757273757320656C69742071756973206C616375732E204372617320746F72746F722E20496E2061646970697363696E672C206C656374757320696420617563746F7220766573746962756C756D2C206E65717565207065646520616363756D73616E20646F6C6F722C206E6F6E20696D70657264696574206D61676E61206469616D20616363756D73616E2076656C69742E2053757370656E6469737365206174206C696265726F207574206E69736920626C616E6469742073616769747469732E2050686173656C6C7573206E6F6E206D61757269732E20467573636520656C656D656E74756D2073616769747469732073656D2E2053757370656E646973736520616C697175616D20656C656966656E642074656C6C75732E2050726F696E206C6967756C61206C6F72656D2C20696D7065726469657420717569732C2076656E656E617469732069642C20696163756C6973206D6F6C6C69732C206E69736C2E20457469616D20636F6E76616C6C69732070656465206174206D617373612E204D6F72626920616363756D73616E20647569206574206D61757269732E0A0A53656420736564206F7263692E204E756E632070757275732E2053757370656E646973736520706F74656E74692E205574206C7563747573206672696E67696C6C61206D61757269732E20446F6E6563206E6962682E2050686173656C6C757320706F7274612E2050686173656C6C75732073697420616D6574206F64696F20736564206D61676E6120736F64616C65732070686172657472612E2043726173206C65637475732E2053757370656E6469737365206C696265726F20697073756D2C20636F6D6D6F646F206E65632C20666163696C6973697320696E2C207375736369706974206C6F626F727469732C206C6967756C612E2044756973206D61737361206E756C6C612C2073656D7065722065742C20636F6E736571756174206E65632C2070686172657472612065752C20656C69742E20566976616D757320756C7472696369657320616C697175616D206F64696F2E20566573746962756C756D2073697420616D6574206D617373612E2053656420636F6E736571756174206C61637573207365642075726E612E20457469616D2066617563696275732066656C69732076656C206F7263692E2050686173656C6C757320756C6C616D636F727065722E2041656E65616E20636F6E736563746574756572206C61637573206174206C696265726F2E0A0A436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204475697320666163696C697369732C206C6967756C6120766974616520636F6E64696D656E74756D207363656C657269737175652C2076656C6974206F72636920677261766964612066656C69732C2076656C20756C74726963696573207175616D206D69206E6F6E206469616D2E20566976616D757320617563746F72206D65747573206E6F6E206C696265726F2E205072616573656E74206C6967756C61206E6973692C20636F6D6D6F646F20636F6E64696D656E74756D2C206D6F6C65737469652065742C20766976657272612065742C206A7573746F2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320736F6C6C696369747564696E2E204E756E6320626C616E6469742063757273757320697073756D2E2041656E65616E206E6563206C6967756C612075742074656C6C757320736F64616C6573206D61747469732E20496E74656765722073656D2E20416C697175616D206964206C6967756C612E2053656420746F72746F72206D61757269732C20626C616E6469742076697461652C206375727375732076656C2C20656C656D656E74756D2065742C206E756C6C612E20416C697175616D207363656C65726973717565206D65747573206574206E69736C2E20447569732061646970697363696E67206D61676E61206174206E657175652E20517569737175652076756C70757461746520656C656966656E64206E756E632E20416C697175616D206567657420656C69742E2050686173656C6C757320647569206F64696F2C20626962656E64756D2073616769747469732C20766573746962756C756D2069642C206469676E697373696D20696D706572646965742C206F7263692E204E756C6C616D2065752066656C6973206E6F6E206E756E63206C6163696E696120736F64616C65732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A53757370656E64697373652070656C6C656E7465737175652C206C696265726F206D617474697320756C7472696369657320616363756D73616E2C20746F72746F7220746F72746F72206D616C6573756164612073656D2C20657420736F64616C6573206C696265726F206F64696F20616320697073756D2E20566976616D75732071756973206D61676E61206E656320657374207375736369706974206C6F626F727469732E20437261732074656D70757320706F7375657265206E756E632E205175697371756520757420656E696D20612066656C697320656765737461732073656D7065722E20536564207068617265747261206D6174746973206E657175652E20467573636520747572706973206E756E632C20636F6E677565207365642C20636F6E736571756174206E6F6E2C20636F6E677565207365642C206E756C6C612E2053757370656E646973736520766172697573206C6F72656D20696420726973757320706F72746120766573746962756C756D2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204675736365207365642070757275732E20496E20612066656C69732E20496E7465676572206567657374617320617563746F72206F7263692E204D617572697320756C747269636573207375736369706974206E69736C2E204E756C6C616D2070757275732E0A0A437261732074656D706F722061646970697363696E6720697073756D2E2055742071756973206D692E204D616563656E617320696E206A7573746F207574206E756C6C6120636F6E6775652070686172657472612E2050656C6C656E746573717565207574206C696265726F20657520646F6C6F722076656E656E617469732073757363697069742E205072616573656E74206665756769617420636F6E736563746574756572206E6962682E204D6F7262692066617563696275732073656D206E6F6E2066656C69732E20496E2068656E6472657269742061726375206163206D617373612E20496E20616363756D73616E20756C747269636573206D692E2050726F696E206D616C65737561646120617563746F722066656C69732E2043757261626974757220696E74657264756D2E20536564206469616D20697073756D2C20756C7472696369657320696E2C2074656D706F722073697420616D65742C207669766572726120696D706572646965742C20656C69742E204D6F726269206D6F6C6573746965206E6973692E204D617572697320697073756D2E2046757363652064696374756D206D6F6C6C6973206D61676E612E204475697320636F6D6D6F646F206469676E697373696D206E756C6C612E20566573746962756C756D20617567756520656E696D2C20756C7472696369657320717569732C20696163756C6973206E65632C2074696E636964756E742076697461652C206469616D2E204D6175726973206C6163696E69612074656D70757320697073756D2E20536564206174206D61757269732E205574206C6F72656D2E20446F6E6563206C696265726F2E0A0A4475697320696163756C6973206C6163696E6961206C65637475732E2041656E65616E20636F6E76616C6C69732065726F7320616320616E74652E205365642071756973206F726369206E656320726973757320617563746F72206672696E67696C6C612E2050686173656C6C757320666163696C6973697320656C656D656E74756D206E6973692E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E6320706F727461206C61637573206E656320616E74652E204D6F726269206D617572697320657261742C2061646970697363696E6720696E2C2070756C76696E6172206E65632C206C6F626F72746973206E65632C206F64696F2E20557420656C656966656E64206C656374757320736564207175616D2E204E756C6C616D206D6F6C6C69732E20496E206E6F6E20747572706973206574206E69736C2068656E64726572697420626C616E6469742E204475697320656C656D656E74756D2E204E756E63206E6563206C696265726F2E2053757370656E646973736520766573746962756C756D207269737573206E6F6E20706564652E204D6F72626920696D70657264696574206F64696F2073697420616D6574206C696265726F2E2053656420736564206D6173736120766974616520697073756D206D61747469732074696E636964756E742E204E756C6C61206E656320746F72746F72207669746165206C696265726F20766F6C75747061742074656D7075732E20446F6E656320616C697175616D2E0A0A4475697320736564206E756E632E2043757261626974757220747572706973206E756C6C612C207665686963756C61207365642C206C756374757320717569732C20656C656D656E74756D20656765742C2066656C69732E204D616563656E61732065742070757275732E204D616563656E6173206C656F2074656C6C75732C2074696E636964756E7420612C20666163696C697369732076697461652C206C6F626F727469732073697420616D65742C2076656C69742E20446F6E656320636F6E76616C6C69732073617069656E2E204D616563656E6173206D6F6C6C6973206F64696F206575206E6962682E20457469616D20677261766964612E20496E7465676572206D6F6C65737469652C2073617069656E206575206D6F6C6573746965206C6163696E69612C206E756E63206E69626820616C697175616D206C6967756C612C2065752073616769747469732074656C6C7573206572617420736F6C6C696369747564696E206F64696F2E20447569732065742072697375732E2050686173656C6C7573206E697369206E657175652C20706C616365726174206E65632C20636F6E64696D656E74756D206E6F6E2C20756C7472696365732065752C2073656D2E20557420706564652E20457469616D206E756C6C61206D657475732C20766F6C75747061742069642C20636F6E76616C6C6973207365642C2073757363697069742076656C2C2075726E612E20446F6E65632076656C20656C69742E205574206C656F206E657175652C2076656E656E617469732066617563696275732C206C6163696E6961206E65632C2074696E636964756E742065752C20656E696D2E2043726173206964206475692061206C696265726F207068617265747261206469676E697373696D2E20446F6E65632065726F73206C656F2C20706F72746120717569732C206C616F726565742075742C2070656C6C656E74657371756520766F6C75747061742C206C65637475732E0A0A4E756C6C616D20626C616E6469742E20416C697175616D206572617420766F6C75747061742E2046757363652061646970697363696E6720656E696D2E2053757370656E6469737365206E6F6E206475692071756973206C6967756C6120706F72746120766573746962756C756D2E20446F6E65632065752074656C6C75732076656C206C6F72656D207072657469756D20706F72747469746F722E205072616573656E74206C75637475732E20416C697175616D2061632065726F7320696E206D6173736120646170696275732074696E636964756E742E20446F6E6563207574206D61676E612E20457469616D20617563746F72206C616375732073697420616D6574206C616375732E2053656420756C7472696369657320697073756D206E656320656C69742E205175697371756520612065737420696E207075727573207375736369706974207472697374697175652E0A0A41656E65616E20736564206475692076656C20646F6C6F722070756C76696E6172206C616F726565742E20566976616D7573207665686963756C61206C6F72656D20696E20706564652E20566976616D7573206574206469616D2E20496E7465676572206163206F64696F2076656C206469616D2068656E64726572697420626962656E64756D2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E756C6C612061206E6973692E2050686173656C6C75732074696E636964756E74206475692076697461652061756775652E20447569732066617563696275732C2064756920696E74657264756D206672696E67696C6C612074696E636964756E742C206F64696F20656C697420766573746962756C756D206C696265726F2C206163206D6F6C6573746965206D61676E61206C6563747573206964206C616375732E2041656E65616E206C6967756C612E204E756C6C6120666163696C6973692E0A0A46757363652076656C2073656D2065752076656C6974206672696E67696C6C61206F726E6172652E2053656420666575676961742074696E636964756E742066656C69732E204E756C6C616D2066656C6973206D692C20657569736D6F642073697420616D65742C206D6F6C6C69732061742C20736F64616C657320656765742C2061756775652E204E616D20696D70657264696574206E6962682061742076656C69742E2053656420757420657261742E20496E206475692E204E756C6C6120666163696C6973692E204E756C6C616D206175677565206C696265726F2C2074696E636964756E74206E65632C207072657469756D2065752C2070756C76696E617220696E2C206475692E204D6F7262692076697461652066656C69732E2050656C6C656E7465737175652076656C206A7573746F2076656C2076656C6974207361676974746973206D616C6573756164612E2050726F696E207665686963756C6120626C616E646974206D617373612E20457469616D2074696E636964756E742070686172657472612075726E612E20496E206D65747573206573742C20617563746F72206E65632C20626C616E64697420612C20637572737573206E65632C207175616D2E204D6175726973206163206D657475732061206C696265726F20636F6E6775652066617563696275732E204D6175726973206D617572697320646F6C6F722C20736F64616C657320696E2C206375727375732075742C20736F64616C65732072757472756D2C2065726F732E2051756973717565206D61757269732065726F732C2073616769747469732076697461652C206C6F626F727469732075742C20656C656966656E642069642C206E6973692E0A0A41656E65616E206E657175652E20566573746962756C756D20656765737461732070656C6C656E746573717565206C6967756C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2050686173656C6C7573207361676974746973206A7573746F2076656C2072697375732E20536564207072657469756D206E657175652076697461652075726E612E2050656C6C656E74657371756520636F6E677565206C696265726F206964206C6F72656D2E204D6175726973206C656F206C6F72656D2C20626C616E6469742073697420616D65742C20636F6E76616C6C697320717569732C20636F6E736563746574756572207365642C2065726F732E204D61757269732074696E636964756E742C20656E696D2061206772617669646120657569736D6F642C206D61676E61206E756C6C61206665726D656E74756D206C696265726F2C207669766572726120656765737461732076656C6974207175616D20657420746F72746F722E20566976616D757320616C6971756574206D61737361207669746165206A7573746F2E204E756C6C6120636F6E677565206C6163757320616320656C69742E0A0A50686173656C6C757320636F6D6D6F646F207175616D2076656C206C6967756C612E2050726F696E206E6F6E206D657475732061742065726F732070756C76696E6172206C75637475732E204D6175726973206469616D206C6F72656D2C20706F737565726520717569732C20677261766964612065742C2074696E636964756E74206E65632C206C6967756C612E20536564206469616D2E20416C697175616D20656C6974206C65637475732C2068656E6472657269742075742C20696D706572646965742073697420616D65742C207072657469756D2073697420616D65742C20697073756D2E204D6175726973207665686963756C61206E69736C20696E206475692E204375726162697475722065676574207175616D207574206D61676E6120656C656D656E74756D206665726D656E74756D2E204D6175726973207363656C657269737175652E2051756973717565206C616F726565742E20457469616D2074656D707573207475727069732E2050656C6C656E746573717565206175677565207175616D2C2068656E647265726974207365642C2074696E636964756E742061742C2070686172657472612061742C206E69736C2E20416C697175616D206C616375732E2053757370656E646973736520706F74656E74692E2041656E65616E2076656C6974206C696265726F2C20756C74726963657320696E2C206C6163696E69612065752C206C75637475732076656C2C20616E74652E20457469616D2064696374756D206D6920696E2066656C69732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20467573636520677261766964612064617069627573206E69736C2E2043726173207669746165206E69736C2E0A0A4D616563656E6173206469676E697373696D2C206C6967756C61206E6F6E20706F727461206375727375732C20656E696D206E756E63206D616C6573756164612073656D2C20657520706F72747469746F72206E756C6C612075726E61206575207175616D2E2046757363652065726F732E20416C697175616D2065726F732E204E616D20617563746F722E204E756C6C61206D6F6C657374696520706F727461206573742E2053757370656E646973736520706F74656E74692E20566976616D7573206D6F6C6573746965206C6F72656D2073656420657261742E20536564206567657420697073756D2E20496E746567657220616C697175616D2070756C76696E6172206E756C6C612E204372617320616C69717565742073656D207574206E756E632E2046757363652066617563696275732074656D707573206C65637475732E204372617320736F64616C65732C206E69736920616320666163696C6973697320756C7472696365732C2065726F73206172637520646170696275732073617069656E2C20657420756C747269636573206D61757269732074656C6C7573206E6F6E20646F6C6F722E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20437261732063757273757320766172697573206D657475732E205574207475727069732E20566976616D7573206567657420746F72746F722E0A0A536564206C616F726565742C2076656C6974206E6F6E20616363756D73616E206375727375732C206E756E632075726E6120706F7375657265206A7573746F2C20696E2064696374756D206C6563747573207065646520696420616E74652E20437261732076756C7075746174652E204372617320636F6E677565206475692073656420656C69742E2050726F696E206C616375732073656D2C20756C7472696365732061742C20636F6E73657175617420696E2C2074656D706F7220717569732C206D657475732E2050726F696E2076656C20617263752E204E616D20657569736D6F642068656E64726572697420656C69742E20557420657261742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2053656420706F73756572652E204D6F7262692065726F732075726E612C2073656D7065722061742C2073656D706572206E6F6E2C20636F6E76616C6C697320717569732C2076656C69742E204D616563656E6173206F7263692E20566573746962756C756D206C6F626F7274697320747269737469717565206D657475732E20566573746962756C756D206C6F72656D206E756C6C612C20736F6C6C696369747564696E2076697461652C20636F6E64696D656E74756D20717569732C20617563746F722075742C206475692E20566976616D757320766573746962756C756D206D61676E61207574206E6973692E2043757261626974757220656C656966656E64206475692076656C206E756E632E20437572616269747572206D6175726973206C616375732C206D616C6573756164612073697420616D65742C207375736369706974207365642C2072757472756D206C75637475732C2074656C6C75732E20496E746567657220666163696C697369732075726E61207669746165206C65637475732E0A0A41656E65616E207175616D206C656F2C206C6F626F7274697320717569732C206D616C6573756164612065752C2076756C7075746174652076697461652C206E69736C2E205072616573656E7420656765742065726F732E205574206665726D656E74756D20747572706973206964207175616D2E204E616D20746F72746F722E205072616573656E74206E6563206F7263692E204E756C6C6120626962656E64756D2061646970697363696E672061756775652E20557420636F6D6D6F646F2C206D61676E61206964206D616C65737561646120677261766964612C206175677565206F64696F206D616C657375616461206D692C20706F727461206D616C65737561646120656C697420657374207669746165206469616D2E204D6175726973206E6F6E206E756C6C612E2053757370656E64697373652074696E636964756E742C206E756E6320756C7472696369657320706F7274612076656E656E617469732C206D6920706564652074696E636964756E74206C696265726F2C20656765742076617269757320616E7465206C696265726F207574206C6967756C612E20437572616269747572207072657469756D20706F72747469746F7220746F72746F722E0A0A4D616563656E617320766974616520656C69742065676574206E69736920646170696275732064696374756D2E204E756E6320696E206C696265726F2E204E756C6C612064696374756D206F726369206575206572617420617563746F72206C6F626F727469732E2050686173656C6C75732072697375732E2053757370656E646973736520706F74656E74692E2053757370656E646973736520706F74656E74692E205072616573656E742061646970697363696E6720636F6E73657175617420656C69742E20496E74656765722069642061756775652E205072616573656E7420696E206A7573746F206E6563206D61676E6120646170696275732070756C76696E61722E2044756973206E69736C2E2053757370656E6469737365206163206F64696F2E20566976616D757320696D706572646965742E20446F6E6563206E6F6E2076656C69742073697420616D6574207269737573206469676E697373696D20636F6E6775652E204E616D20616C697175657420706F73756572652076656C69742E2043726173207475727069732E204D6F726269206D616C657375616461206469676E697373696D206D692E0A0A536564206C656F206E657175652C2076617269757320717569732C2076656E656E61746973207365642C207068617265747261207365642C206573742E204D6F72626920626C616E6469742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D2073656D7065722070656C6C656E746573717565206D692E2055742076656C206C6F72656D2E204E756E63206D6920746F72746F722C206C616F726565742061742C2066617563696275732065752C2074696E636964756E742073697420616D65742C20657261742E20447569732074656D706F72206D616C65737561646120697073756D2E2050686173656C6C757320616C69717565742E20446F6E656320657420656C69742E2050656C6C656E7465737175652070757275732E20566573746962756C756D2072757472756D2073656D706572206E6962682E204E756C6C6120666163696C6973692E2050686173656C6C757320657420656E696D2073697420616D657420616E746520766573746962756C756D207665686963756C612E2050686173656C6C7573206964206E69736C2E20446F6E6563206D6F6C6C6973206C656F2061742065726F732E204D61757269732070656C6C656E746573717565206E657175652061742070757275732E204D6F726269207175697320646F6C6F7220617420697073756D207363656C6572697371756520736F64616C65732E20457469616D20766F6C7574706174207475727069732061206D657475732E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206C6F72656D206C6F72656D2C20766573746962756C756D2061632C20657569736D6F6420656765742C20756C6C616D636F72706572206469676E697373696D2C2076656C69742E0A0A43756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204372617320756C7472696365732C206E6962682076656C20616C697175616D20766573746962756C756D2C2065726F7320656E696D2076656E656E61746973206475692C20696420696163756C697320656E696D206E756E632076656C206D617373612E204D6F72626920656C656966656E64206F726369206574206D617373612E20416C697175616D206572617420766F6C75747061742E204E756C6C61206D6F6C6C69732065676573746173207475727069732E20496E20736F64616C6573206E756E63206567657420746F72746F722E2053656420697073756D2065726F732C2074656D706F7220717569732C20616C69717565742076697461652C20696D70657264696574206E6F6E2C206C6F72656D2E2050656C6C656E746573717565207175697320656C6974206964206D69206C756374757320646170696275732E20536564206E756E6320617263752C2072686F6E637573206E65632C20636F6E76616C6C697320717569732C206375727375732061742C206E657175652E204D617572697320636F6E76616C6C697320707572757320617420657261742E2050656C6C656E74657371756520766573746962756C756D2E20566976616D7573206672696E67696C6C6120656C697420617420617263752E204E756C6C616D20616C697175657420656E696D206E656320617263752E204E616D20696420746F72746F722E204E756C6C612071756973206E756E632E20557420617263752E2053757370656E646973736520706F74656E74692E2050656C6C656E74657371756520756C6C616D636F72706572206C6967756C6120696420617263752E0A0A4E616D206E6F6E206C696265726F207669746165206E69736C207363656C65726973717565206672696E67696C6C612E20517569737175652076617269757320616E7465206964206D657475732072686F6E637573206672696E67696C6C612E204E756C6C6120666163696C6973692E205072616573656E7420656C656966656E6420706F72747469746F72206C6967756C612E20457469616D207175697320646F6C6F72206E6F6E20617567756520636F6D6D6F646F20617563746F722E20446F6E65632061206D692E20566573746962756C756D2074656D706F722E20446F6E65632066656C69732075726E612C20617563746F722061742C206375727375732064696374756D2C20677261766964612069642C20617263752E2041656E65616E2064696374756D206D616C65737561646120646F6C6F722E20566976616D7573206D61747469732E2050686173656C6C757320657520706564652E2046757363652061646970697363696E67206A7573746F206672696E67696C6C61206D657475732E20457469616D20616E74652E20496E7465676572206D6F6C6C6973206D617373612071756973206E756E632E20496E74656765722064696374756D206E65717565206C756374757320656E696D2E0A0A536564206575206C696265726F2E20496E74656765722074656D706F72206C6967756C6120696E2076656C69742E2055742074696E636964756E74206C6163696E69612073656D2E204E756C6C616D2076656C2072697375732E2053656420736F64616C657320616E7465206120646F6C6F722E204375726162697475722065726F732E2053656420736F64616C65732E20536564206E6F6E206D657475732E20566573746962756C756D20656C656D656E74756D20666175636962757320616E74652E204E756C6C612076656C206E6962682E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206E6563206C6F72656D20757420697073756D206C6163696E696120696163756C69732E204475697320657261742E20416C697175616D20657261742E204372617320696163756C69732E20496E206861632068616269746173736520706C617465612064696374756D73742E0A0A4E756C6C616D20616E74652E2043726173207669746165206573742E2050656C6C656E7465737175652076656C206D657475732061206C6967756C612064617069627573206D61747469732E2044756973206665756769617420616C69717565742066656C69732E20457469616D206964206E69736C207175697320657374206469676E697373696D20636F6E64696D656E74756D2E2053757370656E646973736520706F74656E74692E204D6F7262692076656C6974206C6F72656D2C206F726E61726520717569732C2070656C6C656E7465737175652076656C2C20706C61636572617420656765742C20746F72746F722E20566573746962756C756D2074696E636964756E74206D6F6C6573746965206C696265726F2E204E756C6C61206E756C6C6120656E696D2C206D616C6573756164612069642C20756C6C616D636F727065722076697461652C2064696374756D2061742C2070757275732E20446F6E6563206469676E697373696D206F64696F20757420656E696D2E2053757370656E6469737365206174206C65637475732E0A0A5072616573656E74206C6F626F727469732061756775652076656C206C65637475732E20557420696E206C6967756C612075742066656C697320636F6E6775652073757363697069742E2051756973717565206469676E697373696D20746F72746F72207574206D692E204675736365206D61676E61206E6973692C20656C656966656E642061632C206F726E6172652076656C2C20706F72747469746F722076697461652C207175616D2E20566573746962756C756D20736F64616C6573206A7573746F2071756973207475727069732E2046757363652075726E61206E6973692C2072686F6E63757320717569732C20636F6E64696D656E74756D2076656C2C2064696374756D2065752C206E756E632E20467573636520736564206E696268207669746165206F64696F20706F73756572652061646970697363696E672E2053656420706F72746120656C6974207175697320646F6C6F722E204E616D206C696265726F206E756C6C612C20617563746F72207365642C2074696E636964756E7420717569732C2066617563696275732073697420616D65742C206D692E2051756973717565206F7263692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E756C6C616D2069642073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632076656C2065726F732E0A0A566976616D7573206C7563747573206C6F626F72746973206C656F2E2053757370656E64697373652076656C20656C6974206120656E696D20756C6C616D636F7270657220706F73756572652E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20446F6E656320717569732070656465206D6174746973206C6563747573206D6F6C6C69732061646970697363696E672E2053656420616363756D73616E20706F737565726520657261742E205072616573656E7420657569736D6F642074696E636964756E742066656C69732E20446F6E6563206D692E20557420636F6D6D6F646F2061726375206C6163696E69612074656C6C75732E20416C697175616D2061206C696265726F2071756973206C65637475732073656D70657220766976657272612E20437572616269747572206C6163696E6961206D61757269732061742074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E756E632073697420616D6574206D61676E61206D6F6C6573746965206F726369207375736369706974206672696E67696C6C612E204675736365207072657469756D206D65747573206E6F6E2073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642068656E6472657269742E204E756C6C612066656C69732E2053757370656E646973736520706F74656E74692E20416C697175616D20626C616E64697420747269737469717565206E657175652E20437572616269747572207175697320657261742076656C206E756E6320616363756D73616E206D6F6C6C69732E0A0A447569732073616769747469732C2074656C6C757320757420616C697175616D206672696E67696C6C612C20646F6C6F72206D6920756C6C616D636F72706572206E69736C2C20757420747269737469717565207065646520656C697420736564206D61757269732E204375726162697475722069642066656C69732E20446F6E65632070756C76696E6172206C61637573206574206C65637475732E20416C697175616D2076756C7075746174652076756C707574617465206D657475732E20437572616269747572206D61676E612066656C69732C2061646970697363696E672061632C20616363756D73616E2076656C2C206D6F6C657374696520717569732C207175616D2E204D617572697320656C697420617263752C207072657469756D2076697461652C206D6F6C6C69732073697420616D65742C20736F6C6C696369747564696E2075742C206D692E20446F6E656320696D70657264696574206469676E697373696D206D692E204E756C6C616D2073697420616D657420746F72746F722E20416C697175616D206E65717565206E756C6C612C2076656E656E6174697320612C20706F72746120696E2C20706C6163657261742074656D7075732C206C616375732E205175697371756520766573746962756C756D20647569206574206C616375732E2050726F696E206469676E697373696D20636F6E7365637465747565722070757275732E20457469616D206772617669646120746F72746F7220696E206E756E632E2055742074656D706F722074726973746971756520746F72746F722E20536564206C616F726565742074696E636964756E74207175616D2E20566573746962756C756D20706F7274612074757270697320757420656C69742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20446F6E6563206E696268206475692C2066657567696174206E65632C206C616F726565742069642C206D616C65737561646120656765742C206E6973692E205574206E65717565206D617373612C207665686963756C612065752C20636F6D6D6F646F206E6F6E2C20756C747269636965732076697461652C2070757275732E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204D617572697320657569736D6F642C2066656C69732076656C2074656D706F7220616C69717565742C20746F72746F72206D6175726973206D616C657375616461206E756E632C2076656C206665726D656E74756D2073656D206469616D206964206475692E204E616D2072757472756D2073617069656E2065676574206F64696F2E20416C697175616D20736564206C696265726F206E6F6E206D692066617563696275732074656D7075732E2046757363652068656E6472657269742C206469616D206E6F6E20766F6C75747061742072757472756D2C2065726174206D657475732076656E656E61746973206C6967756C612C206E6F6E207363656C657269737175652070656465206C6967756C612076656C207175616D2E204D6F7262692072686F6E6375732065726F7320616320647569206665756769617420656C656D656E74756D2E2044756973206575206C696265726F2065742074656C6C757320636F6E67756520766976657272612E204D6F726269207175616D207175616D2C20656C656D656E74756D207365642C20756C6C616D636F7270657220696D706572646965742C20636F6D6D6F646F206E6F6E2C206F64696F2E204E616D20616C697175657420656765737461732075726E612E204D6175726973206F64696F2066656C69732C207661726975732065752C206C6163696E69612065752C20636F6E64696D656E74756D20612C206C65637475732E20536564206A7573746F206D617373612C2070756C76696E61722069642C2076617269757320612C20706F72747469746F72206E65632C206C696265726F2E20457469616D207661726975732E2043757261626974757220736F64616C65732C206F64696F20617420706F73756572652073656D7065722C2065726F73206E6962682074696E636964756E74206C65637475732C2076656C2072757472756D2073617069656E206E69736920696E206C6967756C612E2053757370656E6469737365206567657420617263752E2050686173656C6C757320696D70657264696574206573742061632073617069656E2E20446F6E6563206E756C6C6120746F72746F722C20706C6163657261742076656C2C2074656D70757320612C206C6F626F727469732076656C2C206E6962682E20416C697175616D20766172697573206E6973692E204E756C6C6120657420656E696D2E20467573636520636F6E76616C6C6973206C616F72656574206C616375732E0A0A50686173656C6C757320697073756D20646F6C6F722C206D6F6C657374696520717569732C20636F6E64696D656E74756D20696E2C20636F6D6D6F646F2065752C206469616D2E205175697371756520626962656E64756D206C6163696E6961206475692E204E756C6C616D20626C616E6469742076756C707574617465206F7263692E205574206C6163696E6961206D617373612076656C2061756775652E20416C697175616D20677261766964612C207175616D207175697320696D7065726469657420696D706572646965742C2074656C6C7573206469616D20706861726574726120657261742C206174207068617265747261206C61637573206E6962682065676573746173206D61676E612E204E756C6C61207361676974746973206C6F72656D207574206C6F72656D2E204475697320636F6E64696D656E74756D2C2064756920766974616520616C697175616D20706F73756572652C206469616D207175616D20636F6E76616C6C69732076656C69742C2075742067726176696461206C656F20697073756D206E6F6E2072697375732E205574206665726D656E74756D20736F6C6C696369747564696E20657261742E20446F6E6563207361676974746973207363656C657269737175652066656C69732E204E756E6320617263752E20457469616D2074656D7075732C206D61676E612073697420616D657420737573636970697420657569736D6F642C2065726F732073656D2072757472756D206475692C207669746165207361676974746973206E696268207075727573206E6F6E206C616375732E20536564206D6F6C6C69732061726375206567657420646F6C6F722E20446F6E6563206F726E6172652C20617263752073697420616D6574206665726D656E74756D2076756C7075746174652C20726973757320656E696D206665726D656E74756D206C696265726F2C2061206C6163696E696120646F6C6F72206D69206E6F6E2076656C69742E20457469616D206C6F626F72746973207075727573206120656C69742E204E756E63206E756C6C61206475692C206D617474697320717569732C20626962656E64756D20612C20756C7472696365732061632C2061756775652E20496E20616C697175616D207665686963756C61207475727069732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A496E7465676572206964206E69736C2E20517569737175652064696374756D20656C656D656E74756D206F64696F2E2041656E65616E206C75637475732E205365642065752073656D206120706564652076756C70757461746520636F6E64696D656E74756D2E2051756973717565206D61676E612E20446F6E656320616C697175616D206D617474697320697073756D2E204375726162697475722064696374756D20736F6C6C696369747564696E2073656D2E20416C697175616D2070756C76696E61722E204E756E6320736F6C6C696369747564696E207269737573206120657261742E20566976616D757320717569732074656C6C75732073697420616D6574206E69626820766573746962756C756D20636F6E7365717561742E204E756C6C61207072657469756D20736F6C6C696369747564696E20646F6C6F722E20416C697175616D20696163756C69732074696E636964756E74207475727069732E2050686173656C6C757320697073756D206C656F2C2076656E656E6174697320696E2C20736167697474697320696E2C206F726E6172652061742C206E756E632E0A0A50656C6C656E74657371756520756C7472696365732C2064756920657520696163756C6973206C75637475732C2074656C6C757320617567756520766F6C75747061742073617069656E2C20696E206469676E697373696D2075726E612066656C6973207574206D692E205365642061726375206475692C206469676E697373696D2069642C20706F72747469746F722075742C20696D706572646965742076697461652C20616E74652E204E756C6C61206475692073656D2C20636F6D6D6F646F206E65632C2073616769747469732065742C206C6163696E69612065742C20706564652E20457469616D20656C656966656E6420647569207574206E69736C2E20446F6E656320616E7465206D61757269732C2074656D7075732073697420616D65742C207661726975732076697461652C206772617669646120717569732C206D692E20496E207363656C657269737175652C2066656C697320766974616520766976657272612073616769747469732C2076656C6974206D6574757320756C74726963696573206E657175652C207175697320696D706572646965742076656C697420656C6974206574206D61676E612E2053757370656E646973736520706F74656E74692E205365642076656C69742065726F732C20657569736D6F64207365642C20636F6E64696D656E74756D206E65632C206661756369627573207365642C2073617069656E2E204E616D20616363756D73616E206C6967756C612073697420616D6574206E657175652E20416C697175616D206572617420766F6C75747061742E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E616D20657520706564652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642065752066656C69732073656420746F72746F722074656D706F72206665726D656E74756D2E2050686173656C6C757320636F6D6D6F646F2073656D2076656C206E69736C2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050726F696E206C656374757320656C69742C2070686172657472612073697420616D65742C20616363756D73616E207365642C2074696E636964756E742065742C206D61757269732E204475697320646170696275732070686172657472612073656D2E20496E746567657220696E206A7573746F2E205072616573656E742065726F732E20566573746962756C756D20616320616E74652E20416C697175616D207363656C657269737175652073656D2070656C6C656E746573717565206E69626820636F6E73656374657475657220736F64616C65732E20416C697175616D20636F6E736563746574756572206F64696F2E2044756973206C6563747573206F64696F2C206C75637475732065752C20636F6D6D6F646F20717569732C206D6F6C6C69732076697461652C2076656C69742E2043726173206E6563206E756E63206E6F6E20656C697420696163756C6973206D61747469732E2041656E65616E206A7573746F206E657175652C20736F6C6C696369747564696E20656765742C20756C6C616D636F7270657220656765742C20656765737461732069642C2073656D2E20496E2065752072697375732E2053656420656765737461732E0A0A496E7465676572206174206E657175652E20536564207072657469756D207363656C65726973717565206E756C6C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20467573636520757420706564652E20457469616D207669746165207175616D20612075726E612076617269757320696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2044756973207665686963756C612E20467573636520756C6C616D636F72706572206E696268206E6F6E20657261742E205175697371756520696E206E657175652E205072616573656E74206573742E2050656C6C656E74657371756520617263752E0A0A50726F696E20706F73756572652E2053757370656E646973736520706F74656E74692E20496E74656765722066656C6973206C616375732C20616C697175616D207365642C2076756C70757461746520696E2C206D6F6C6C69732076656C2C2074656C6C75732E20496E7465676572207665686963756C6120626962656E64756D206573742E204E756E63206E6F6E20646F6C6F7220696E2074656C6C7573206D617474697320666163696C697369732E20496E746567657220766573746962756C756D2C20617567756520617420636F6D6D6F646F20616C697175616D2C2064756920657374206D6174746973206C6967756C612C2073697420616D65742061646970697363696E67206F7263692073656D207669746165206D61676E612E205072616573656E7420656E696D2076656C69742C206D616C6573756164612061742C20636F6E677565206E65632C206C756374757320696E2C206A7573746F2E20536564207661726975732E204D6F7262692070686172657472612E20446F6E6563206575206D61737361206E65632074656C6C75732076756C7075746174652070756C76696E61722E20557420636F6D6D6F646F20747572706973206E6F6E2073656D2E20557420636F6E76616C6C697320756C6C616D636F727065722072697375732E20457469616D20696E74657264756D2070656465206964206E6973692E2043726173206D61676E612073617069656E2C20737573636970697420612C206C616F72656574206E6F6E2C2072686F6E6375732065742C2066656C69732E20496E7465676572206F726369206C6F72656D2C20766573746962756C756D2064696374756D2C20756C6C616D636F7270657220612C20706F72747469746F722065742C206475692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A4E756E63206574206D61676E612E2053656420626962656E64756D2074656C6C757320696E206469616D2E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E616D20766974616520746F72746F722E20496E7465676572206D61676E612E20447569732076656E656E617469732C206C656F2061632074656D706F72206C616F726565742C20656C6974206E756C6C6120706861726574726120706564652C206E6F6E206665726D656E74756D206E756E63206F64696F2061206F64696F2E2050726F696E206E6F6E2076656C69742E2053656420696D706572646965742061756775652071756973206E69736C2E20496E746567657220636F6E64696D656E74756D206E69736C206E6563206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20566976616D757320706C616365726174206C696265726F2E204475697320636F6E6775652064696374756D206D61676E612E20416C697175616D206461706962757320626962656E64756D20656E696D2E204E756E6320656C656966656E6420706564652076656C20697073756D2E0A0A457469616D2076697461652076656C69742E204D61757269732065726174206E756E632C206D616C6573756164612075742C20666575676961742061632C20706C61636572617420636F6E64696D656E74756D2C2061756775652E204E616D20766F6C75747061742E20416C697175616D207665686963756C6120697073756D206964206F64696F2E20566976616D757320736F6C6C696369747564696E207475727069732069642073617069656E2E20467573636520612066656C6973207669746165206F64696F20636F6E76616C6C697320626C616E6469742E204375726162697475722076697461652065726F732069642065726F7320706F727461207072657469756D2E204E756C6C6120696E206D61676E6120656765742075726E61206C6163696E696120636F6E76616C6C69732E20416C697175616D206D61747469732076656E656E617469732070757275732E2053656420736564206D69206567657420657261742074726973746971756520706F7274612E20446F6E656320617563746F7220646F6C6F72206120657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20496E206E6563206C6967756C612E204E756E6320656C656966656E642E20566573746962756C756D2071756973206E697369206567657420656C697420706F72747469746F7220636F6E6775652E204D616563656E61732066617563696275732C206D61676E6120656765742061646970697363696E672074696E636964756E742C20646F6C6F7220616E7465206D616C65737561646120656C69742C206E6F6E20656C656D656E74756D206C616375732074757270697320696E20706564652E0A0A5574206D616C657375616461206D69206E6563206D657475732E205072616573656E7420617563746F72206175677565206163206E69736C20756C7472696369657320666163696C697369732E204E616D2070757275732073617069656E2C2070656C6C656E746573717565206469676E697373696D2C20706F73756572652065752C206375727375732069642C206469616D2E205175697371756520736F6C6C696369747564696E2C20656C697420612070656C6C656E746573717565207363656C657269737175652C206C6F72656D20726973757320617563746F72207175616D2C207175697320636F6E7365717561742074656C6C7573206E657175652069642075726E612E2053757370656E6469737365206469616D20746F72746F722C20656C656966656E64206469676E697373696D2C20656765737461732075742C206C756374757320696E2C20616E74652E204475697320616E74652E204D616563656E6173206C75637475732E20437572616269747572206375727375732070686172657472612075726E612E204D616563656E617320696D706572646965742C2065726174206E6F6E20656C656D656E74756D20657569736D6F642C20746F72746F72206F64696F20657569736D6F64206C65637475732C20616320666163696C697369732073656D206E696268207669746165206E756C6C612E204E756E6320677261766964612E204D6F72626920736F6C6C696369747564696E206F64696F2071756973206C616375732E20416C697175616D2061206E696268206E6F6E2075726E6120706F72746120696D706572646965742E20416C697175616D206572617420766F6C75747061742E20496E20696163756C6973206C6163696E69612076656C69742E20536564206C696265726F206C616375732C207472697374697175652065752C206C6163696E69612061632C20616C697175657420656765742C2075726E612E0A0A457469616D206174206E69736C2E2050686173656C6C7573206661756369627573206C7563747573206C65637475732E20557420706C6163657261742076756C70757461746520646F6C6F722E2050686173656C6C75732076656C2076656C69742E204D6F72626920766976657272612E2050686173656C6C7573206F7263692E20496E7465676572206469676E697373696D206D6174746973206D61757269732E2050656C6C656E74657371756520706F7375657265206C656F20706F7375657265207175616D2E2051756973717565206E6563206D61676E61206174206469616D20766976657272612070656C6C656E7465737175652E2053757370656E64697373652076656C697420617263752C20756C7472696369657320717569732C20636F6E67756520612C2076656E656E6174697320656765742C206C616375732E20496E74656765722073616769747469732068656E64726572697420646F6C6F722E2046757363652074696E636964756E7420616E746520612073656D2E0A0A4D616563656E617320636F6E7365637465747565722C206A7573746F207365642072686F6E6375732076656E656E617469732C206E69626820617263752072757472756D20646F6C6F722C2073656420636F6E64696D656E74756D206C696265726F206C696265726F20657420697073756D2E20566976616D7573206D6174746973206A7573746F207574206C6F72656D2074696E636964756E74206C6F626F727469732E205574206E6F6E2076656C6974206964206E6571756520616C697175657420616363756D73616E2E205365642074656D7075732076697665727261206E756C6C612E2043757261626974757220756C6C616D636F727065722C206E6571756520717569732064617069627573207363656C657269737175652C2066656C6973206469616D2067726176696461206F7263692C206E6F6E20637572737573207175616D206E6571756520766974616520656C69742E20457469616D2070686172657472612074696E636964756E74206C616375732E204475697320657569736D6F64206672696E67696C6C61206573742E20457469616D206F726E6172652074696E636964756E74206C65637475732E2050726F696E20696E207475727069732E204E756E6320626C616E64697420626C616E646974207475727069732E2041656E65616E2075742061756775652E2044756973206F726369206A7573746F2C2074696E636964756E742065752C2072757472756D207365642C2072757472756D2065742C207475727069732E2043757261626974757220666163696C69736973206F64696F20696E20616E74652E20496E206861632068616269746173736520706C617465612064696374756D73742E205365642065726F73206573742C2070656C6C656E7465737175652061742C2074696E636964756E742065752C20756C74726963657320717569732C206D657475732E204D6F7262692073697420616D6574206A7573746F2E204D616563656E617320616320617263752E204D6175726973206469676E697373696D2E0A0A50656C6C656E74657371756520756C747269636965732072757472756D206F7263692E2041656E65616E206F726E6172652E20566976616D75732065752072697375732076656C206D6175726973206C6F626F727469732064696374756D2E205365642065742074757270697320617563746F72206D692072686F6E6375732070756C76696E61722E20536564206E6563206E756E6320612070757275732074656D706F7220766976657272612E2050656C6C656E7465737175652073757363697069742E20446F6E656320747269737469717565207269737573206E6F6E206E6962682E20457469616D206E69736C206D61676E612C20736F6C6C696369747564696E2075742C20756C7472696365732073697420616D65742C20656765737461732065752C206E756C6C612E20416C697175616D206572617420766F6C75747061742E20566573746962756C756D2070686172657472612E2053656420656765737461732C206D657475732073697420616D6574206C6F626F7274697320636F6E7365717561742C206572617420656C697420696D70657264696574206C696265726F2C20657520696E74657264756D207175616D206D61737361206567657420646F6C6F722E2053757370656E6469737365207669746165206F64696F2E2050726F696E20626C616E646974206D617572697320696163756C6973206D657475732E0A0A566976616D757320766573746962756C756D2E20457469616D206574206E69736C2E20416C697175616D20696E206469616D2076656C20656C697420706C6163657261742073757363697069742E204475697320736F64616C6573207075727573206163206E6962682E204E756C6C6120696E206F64696F206567657420656E696D206C756374757320626C616E6469742E2043757261626974757220756C74726963657320697073756D206E6F6E206E65717565206567657374617320656C656966656E642E20536564207475727069732E2050726F696E20636F6E7365637465747565722E20566976616D7573206D61747469732E20496E20616C69717565742E0A0A4E756E632069642065726F732E20446F6E65632076656E656E617469732C206E756C6C61206574206D6174746973206C75637475732C20616E7465206C656F2073656D706572206A7573746F2C206E6F6E2061646970697363696E67206F64696F20726973757320736564206C616375732E205072616573656E7420766974616520726973757320636F6E677565206C696265726F20636F6E6775652074656D7075732E2050686173656C6C75732061632065726F732E204E756C6C61207665686963756C612C206C6F72656D20696E20616C69717565742073757363697069742C2061726375206572617420656765737461732073656D2C2071756973206C6F626F72746973207175616D20616E7465206575206D617373612E20437572616269747572206E6F6E206D617373612E2053656420626962656E64756D206C6163696E6961206F64696F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20566976616D757320766F6C757470617420626C616E646974206C616375732E2050726F696E20706F7274612C2074656C6C757320757420617563746F72206C616F726565742C206C65637475732065726F73206665726D656E74756D206C65637475732C2069642073616769747469732061726375206A7573746F20696E207475727069732E2050686173656C6C757320636F6E7365717561742E204E616D2070656C6C656E7465737175652C206D69206964207669766572726120636F6E76616C6C69732C206E756E63206C696265726F20706C616365726174206C656F2C20656C656966656E6420706F7274612073656D206E69736C2076697461652073617069656E2E2050656C6C656E746573717565206C6967756C61206C696265726F2C20747269737469717565206E6F6E2C20706F72747469746F722072757472756D2C20706F72747469746F72206E6F6E2C20657261742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E74656765722064696374756D2074656C6C7573206120746F72746F722E20566976616D75732066656C6973206E756E632C206D6F6C6573746965206E6F6E2C2072686F6E63757320717569732C2070686172657472612069642C206475692E20446F6E6563207269737573206D657475732C206672696E67696C6C612076656C2C20616C69717565742065752C20706C6163657261742069642C206E657175652E0A0A53757370656E646973736520697073756D2E20566976616D7573206C65637475732E2053656420766976657272612C206D61737361206567657420636F6E76616C6C6973206D61747469732C207175616D2074757270697320636F6E736563746574756572206E756E632C206567657420706F7375657265206D61676E612073656D2069642076656C69742E20496E206E6563206D61757269732E2041656E65616E206120707572757320736564207175616D206C6F626F72746973206672696E67696C6C612E2050726F696E20756C74726963696573206C6163696E696120616E74652E205365642061646970697363696E67206572617420717569732076656C69742E204E756C6C616D207669746165206E69736C206964206A7573746F20736F6C6C696369747564696E206D6F6C65737469652E204E756C6C6120666163696C6973692E20536564206E65632075726E6120736564206E69736C206672696E67696C6C6120646170696275732E204E756C6C61206174206469616D2E20416C697175616D2065676574206E6962682E204E756E63206163206E6973692073697420616D65742074656C6C757320656765737461732074656D7075732E204E616D207363656C657269737175652075726E61206574206E657175652E20446F6E656320657374206F7263692C207361676974746973206E6F6E2C2076756C70757461746520612C20636F6D6D6F646F2065742C2061756775652E205574206461706962757320746F72746F722E205574206E756E632E20446F6E65632064696374756D2064617069627573206F64696F2E204E616D20756C7472696369657320756C6C616D636F72706572206C6967756C612E2050656C6C656E74657371756520616363756D73616E20766172697573206C656F2E0A0A4D6F72626920657569736D6F64206C616F7265657420657261742E20566976616D7573207175697320697073756D2E204D6F72626920657569736D6F642E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2053757370656E64697373652076656C2070757275732E204E756C6C616D206174206D61676E612E20437572616269747572206C61637573206C6F72656D2C20696163756C697320717569732C2064617069627573206E6F6E2C20766F6C75747061742076656C2C206E756C6C612E20446F6E656320757420617263752072686F6E63757320646F6C6F72207072657469756D2064696374756D2E204E756C6C616D2076656C206D657475732E20557420617263752E2050656C6C656E746573717565206E697369206E756E632C20706C61636572617420656765742C2074696E636964756E742076656C2C207068617265747261206E6F6E2C206E756E632E20496E74656765722074696E636964756E7420756C74726963696573206C65637475732E20496E74656765722073656D7065722C2070757275732073656420756C74726963657320666575676961742C206E756C6C61207065646520736F6C6C696369747564696E20657261742C2076656C20617563746F72206E756C6C6120697073756D2076656C206C65637475732E2041656E65616E206D692E0A0A4E756C6C616D20736564206E697369206574206172637520696D70657264696574206665726D656E74756D2E204D6175726973206E6563206D657475732E20496E20616320646F6C6F722E20496E206D6920617263752C20636F6E6775652061632C207068617265747261206E65632C207363656C657269737175652073697420616D65742C206D61676E612E20437572616269747572206C616375732E2043757261626974757220657420656C69742E20416C697175616D20756C6C616D636F72706572206E756E6320657520656C69742E2053656420636F6E76616C6C697320646F6C6F722061742076656C69742E20566573746962756C756D20646170696275732C20617567756520696420636F6E73656374657475657220706C6163657261742C206E756E63206D6173736120626C616E6469742073617069656E2C20696420616C697175616D20656C6974206E697369206964206D692E2050686173656C6C75732073617069656E206573742C20677261766964612065752C20626962656E64756D2075742C2061646970697363696E6720717569732C206573742E205574206D6F6C6573746965207175616D207669746165206F64696F2E20446F6E65632071756973207269737573206964206572617420666175636962757320736F6C6C696369747564696E2E204E616D2069642066656C69732E204D61757269732073656420656E696D207669746165206C656F20616363756D73616E207072657469756D2E0A0A4E616D206A7573746F2E20446F6E656320747572706973206E69736C2C20636F6D6D6F646F2065742C20696E74657264756D2061632C20636F6E736563746574756572206E6F6E2C206D617373612E2046757363652073656D206D657475732C206C616F72656574206E65632C20706F73756572652069642C20696D7065726469657420696E2C2076656C69742E20446F6E65632076756C707574617465206A7573746F2065676574207475727069732E204E756C6C6120706564652E204D6F7262692074696E636964756E742E20467573636520616C69717565742C207175616D20657420616C697175616D206672696E67696C6C612C20616E746520616E746520696163756C6973206475692C206E656320616C697175616D20617263752070757275732073656420657261742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050686173656C6C7573207375736369706974207175616D206574206573742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B0A0A496E7465676572207365642074656C6C75732E20536564207365642076656C697420756C74726963696573206C656F2072757472756D206C616F726565742E20536564206E6F6E2065726F7320616320707572757320736167697474697320666575676961742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E205365642068656E647265726974206C6967756C612073697420616D6574206E6962682E204D616563656E6173207475727069732E204D6F72626920636F6E7365637465747565722C20646F6C6F722065742061646970697363696E6720696D706572646965742C20616E7465206E65717565206665756769617420646F6C6F722C20617420706F727461207175616D206E657175652071756973206C6967756C612E204D61757269732073656D7065722076656C69742073697420616D657420697073756D2E2050656C6C656E7465737175652074656D7075732C20707572757320696E2072757472756D20636F6E7365717561742C20656E696D2065726174207665686963756C61206D617373612C20696420616363756D73616E206C656F2073617069656E206E65632070757275732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E20646F6C6F722E20496E746567657220666163696C69736973206C696265726F2073697420616D657420706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2055742076617269757320616C697175657420656E696D2E204E756C6C6120666163696C6973692E2043757261626974757220636F6E7365637465747565722C206F64696F206575207072657469756D2074696E636964756E742C206E756E63206E69736920616C6971756574206E657175652C2076656C20696D7065726469657420656C6974206D617373612073697420616D6574207475727069732E2050656C6C656E7465737175652074656D7075732C206F72636920766F6C757470617420626C616E646974206672696E67696C6C612C206F64696F2073656D20706F737565726520616E74652C20766974616520626962656E64756D2075726E61206C6F72656D2076697461652065726F732E205072616573656E7420766976657272612072686F6E63757320617263752E2053656420617563746F722C206573742073697420616D6574206D6F6C6C6973206D6F6C6C69732C207175616D207175616D20677261766964612073617069656E2C20696E20636F6D6D6F646F206D65747573206E756C6C6120617563746F7220656E696D2E20446F6E656320666163696C697369732E0A0A50726F696E2074696E636964756E742C2073617069656E206567657420756C747269636965732061646970697363696E672C20657374206F64696F2064696374756D20617263752C207574206D6F6C6C69732065726174206475692073697420616D65742076656C69742E204D6F726269206573742073656D2C20696E74657264756D2061742C20636F6E67756520612C20656C656D656E74756D2076697461652C206D657475732E2053757370656E64697373652069642061756775652E204D617572697320656E696D2073656D2C2070756C76696E617220656765742C2074656D70757320612C2074656D7075732073697420616D65742C2073617069656E2E20467573636520766573746962756C756D20636F6E736563746574756572206475692E2050656C6C656E74657371756520657261742E20536564206469676E697373696D20706C616365726174206F64696F2E204D616563656E61732073656D7065722072686F6E637573206C65637475732E2050686173656C6C7573207072657469756D2E2044756973206C696265726F20656C69742C20656C656966656E64206E65632C20656765737461732075742C20637572737573207365642C2066656C69732E204E616D206E69736C20617263752C20616C69717565742065742C20666163696C697369732065752C206C75637475732075742C2072697375732E20457469616D20756C7472696365732C20646F6C6F722073656420766F6C7574706174206D616C6573756164612C20747572706973206172637520696D7065726469657420746F72746F722C20657569736D6F6420636F6D6D6F646F206C696265726F206D61737361207574207175616D2E20496E7465676572206D6F6C6573746965207075727573206E6F6E20656C69742E2055742076656E656E617469732073656D70657220746F72746F722E20457469616D20626962656E64756D206567657374617320697073756D2E204D617572697320736F6C6C696369747564696E2073656D206E6563206E6962682E204E756C6C61207072657469756D206D65747573206575206D657475732E2050656C6C656E7465737175652073697420616D65742073656D2E0A0A53757370656E6469737365206163206E6973692E205574206C656F2E20566573746962756C756D2068656E647265726974207072657469756D20646F6C6F722E204E756E632066657567696174206D616C6573756164612070757275732E2043726173206574206E6962682E20437572616269747572206E756E6320657261742C206D616C6573756164612076697461652C206C616F726565742061632C20756C7472696369657320696E2C2070757275732E20566976616D75732074656C6C757320617263752C20736F64616C65732065752C20666163696C6973697320612C206C6163696E6961206E65632C206E756E632E2050656C6C656E7465737175652069642076656C69742E20496E206575206E6962682E204E756E63206E656320657261742E205365642064696374756D206E65717565207574206E69736C2E0A0A4D6F726269206C65637475732074656C6C75732C2074696E636964756E742061632C20706F72747469746F722061632C2074726973746971756520696E2C2065726F732E20446F6E6563206C7563747573206C7563747573206C656F2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2046757363652075742065737420657420656E696D207363656C6572697371756520616363756D73616E2E20446F6E6563206C6967756C612066656C69732C206C6163696E696120717569732C2070656C6C656E74657371756520696E2C2073656D70657220766573746962756C756D2C20656C69742E204D61757269732065676574206F72636920612066656C697320636F6E677565207665686963756C612E20557420736F6C6C696369747564696E2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204E756C6C616D20696420646F6C6F72207574206C6F72656D206469676E697373696D2076656E656E617469732E2053757370656E64697373652076697461652073617069656E2E2050726F696E206E6F6E206D61676E612075742065726F7320766976657272612070756C76696E61722E20446F6E65632071756973206F64696F2E204E756C6C616D206E6F6E20617263752076656C206C6F72656D20737573636970697420616C697175616D2E20416C697175616D2072757472756D2074757270697320696E206C656F2E0A0A5574206C7563747573206E6962682074726973746971756520657261742E2053757370656E646973736520626962656E64756D206F64696F20766974616520746F72746F722E20446F6E6563206C6163696E69612E204372617320736F64616C65732066656C6973206C7563747573206E756C6C612E204E616D20656C656966656E64207361676974746973206C6967756C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E64697373652076656C206E657175652E204D6F72626920616C6971756574207665686963756C61206D61676E612E2041656E65616E206174206F64696F2E20447569732070656C6C656E746573717565206D61676E612E204E756C6C6120617420746F72746F72207574206469616D2064696374756D2066617563696275732E204D617572697320717569732076656C69742E20446F6E6563206E6F6E2074656C6C7573207669746165206C6F72656D206672696E67696C6C6120706F72747469746F722E2046757363652075742073617069656E207175697320746F72746F7220666575676961742073616769747469732E20446F6E656320766976657272612073656D2076697461652073617069656E2E205072616573656E7420736F64616C65732C206C6163757320696E206672696E67696C6C6120766976657272612C206F64696F2061756775652061646970697363696E672075726E612C20766974616520696E74657264756D20616E74652073656D206E6F6E206E6973692E204E756C6C616D20746F72746F72206C6F72656D2C20656C656966656E642061632C206D6F6C6C6973206E6F6E2C206C616F726565742061632C2072697375732E20496E7465676572206F726E617265206C656F20736564206A7573746F2E2051756973717565206375727375732C2073656D206E6F6E20666163696C6973697320626962656E64756D2C206E697369206D69207661726975732066656C69732C206665726D656E74756D2066657567696174206C6F72656D2065726F73206C616F726565742072697375732E0A0A517569737175652073697420616D657420657374206574206C6F72656D207665686963756C61206C6163696E69612E20446F6E6563206E656320746F72746F722E2043726173206F64696F2E204E616D207363656C657269737175652076756C7075746174652075726E612E205072616573656E74206475692E20457469616D206E6563206E69736C206C6F626F7274697320697073756D20616C69717565742074656D7075732E204D616563656E6173207072657469756D20736F6C6C696369747564696E206D61757269732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206175677565206D617373612C20636F6E67756520656765742C20636F6E76616C6C697320656765742C207472697374697175652073697420616D65742C2065726F732E2053656420636F6E736571756174206E6973692065752066656C69732E2050656C6C656E746573717565206A7573746F2E2053757370656E6469737365206E6F6E2061756775652E20496E206469676E697373696D206C6F626F72746973206D61757269732E204D61757269732073616769747469732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E0A0A5365642061646970697363696E672E20446F6E656320612074656C6C75732076697461652065737420637572737573207665686963756C612E204E616D20616E74652073656D2C20736F64616C65732069642C206672696E67696C6C612076656C2C20636F6E64696D656E74756D2076656C2C206E756C6C612E205175697371756520736F64616C65732E20457469616D20696D7065726469657420656C6974206964206F64696F2E20416C697175616D206572617420766F6C75747061742E204D616563656E617320706F7274612074656D706F7220617263752E204E756C6C612073656D2061756775652C2070656C6C656E7465737175652061632C20636F6E7365717561742075742C20636F6E64696D656E74756D20657569736D6F642C2072697375732E2053656420616C697175616D2074696E636964756E74206D692E20496E20696E74657264756D206C6F626F72746973206F7263692E0A0A536564207665686963756C612068656E6472657269742070757275732E20457469616D2061206469616D2E2043757261626974757220636F6E76616C6C69732E2053757370656E64697373652061206E6973692E20446F6E6563206964206D61676E6120696E207175616D20736F6C6C696369747564696E20756C747269636965732E20446F6E656320766976657272612E205175697371756520766F6C757470617420657374207365642073656D2E20416C697175616D206A7573746F2E20566573746962756C756D20746F72746F72206D617373612C20706F72747469746F72207365642C2076617269757320717569732C20696163756C697320717569732C206F64696F2E20416C697175616D2065676574206E657175652E0A0A4D6175726973206E756C6C612E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566573746962756C756D206575207175616D20696E206E6571756520756C7472696365732070656C6C656E7465737175652E204372617320696E20646F6C6F722071756973207175616D207661726975732068656E6472657269742E20416C697175616D206E697369206C616375732C206C6F626F727469732065752C20636F6E76616C6C69732073697420616D65742C20666163696C697369732075742C206D692E20416C697175616D206174206E657175652E204372617320736167697474697320656C656D656E74756D206A7573746F2E20566573746962756C756D207574206C656374757320616C6971756574207075727573206D616C65737561646120766F6C75747061742E2044756973206174206C616375732061646970697363696E67206C696265726F2074696E636964756E7420766573746962756C756D2E204D6F7262692061206C696265726F2E20437261732070757275732E204D6F72626920757420617567756520657420707572757320696E74657264756D207363656C657269737175652E20496E74656765722061206475692E20496E206861632068616269746173736520706C617465612064696374756D73742E2044756973207068617265747261206D657475732065676574206D61757269732E20416C697175616D20696E74657264756D20756C6C616D636F72706572206D617373612E0A0A457469616D206F726E6172652E204E756C6C616D20657569736D6F642E2041656E65616E20636F6E7365717561742067726176696461206C6967756C612E20416C697175616D206573742E2050726F696E207669746165206C616375732E205072616573656E7420612065726F732073697420616D657420647569206C756374757320636F6D6D6F646F2E2050686173656C6C7573207665686963756C612061726375206567657420646F6C6F722E205072616573656E74206665726D656E74756D20636F6E677565206C656F2E20416C697175616D20766F6C7574706174207075727573207574206C6F72656D2E2046757363652068656E64726572697420656E696D206174206C656F2E20416C697175616D2072686F6E637573206E69736C2E20566976616D75732064696374756D2065676573746173206D692E2053757370656E64697373652070656C6C656E74657371756520626962656E64756D20646F6C6F722E2050656C6C656E7465737175652074696E636964756E742C207475727069732073656D7065722070656C6C656E74657371756520636F6E64696D656E74756D2C20697073756D206D6574757320736F64616C6573206C6967756C612C20696420766F6C7574706174206469616D2074757270697320757420656C69742E0A0A5072616573656E7420736564206C616375732E204E616D20656C656966656E64206D6F6C6573746965206D61757269732E20446F6E65632064617069627573206665726D656E74756D206D617373612E20446F6E656320766976657272612066617563696275732070757275732E2043757261626974757220636F6E6775652C206C696265726F20766974616520766976657272612070656C6C656E7465737175652C206469616D2076656C697420736F64616C657320656E696D2C20736564207375736369706974206C6563747573206E697369206E6563206E657175652E20566573746962756C756D206D616C6573756164612C206C616375732061742063757273757320636F6E6775652C2076656C6974206C65637475732074726973746971756520646F6C6F722C2073697420616D657420736F64616C6573206E6571756520697073756D2061206C696265726F2E20566573746962756C756D206574207175616D2E2043757261626974757220706C6163657261742E20437572616269747572206E756E6320617263752C20657569736D6F64206E65632C2076756C7075746174652068656E6472657269742C20616C697175657420656765742C207175616D2E204375726162697475722076656C20656E696D2E2053757370656E646973736520706F74656E74692E0A0A4E756E6320636F6E736571756174206F726369207574206C616375732E2046757363652076656C697420646F6C6F722C2064617069627573207365642C20626C616E6469742073697420616D65742C2072686F6E6375732069642C2072697375732E20447569732075726E61206E6962682C207363656C6572697371756520717569732C206461706962757320612C207363656C65726973717565207365642C206E6962682E20446F6E6563206C75637475732E205574206575206D617572697320637572737573206469616D206C6163696E69612072686F6E6375732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20416C697175616D207665686963756C61206D6F6C6573746965206A7573746F2E204D616563656E617320696D70657264696574207065646520736564206D692E2053757370656E6469737365206E756C6C6120646F6C6F722C2068656E64726572697420656765742C2068656E6472657269742069642C2064696374756D2076656C2C206C656F2E204475697320616363756D73616E2E2043757261626974757220696E2066656C69732E204E756E63206C6F72656D2E205574206C656F20646F6C6F722C206C616F72656574206E65632C2076756C7075746174652061742C20656C656966656E6420696E2C206E756C6C612E2051756973717565206E756E632070757275732C2076617269757320656765742C20616363756D73616E206E65632C20616C69717565742065742C206E6962682E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20437261732061646970697363696E67207669766572726120646F6C6F722E204D617572697320706F72747469746F7220756C7472696365732070757275732E204E756C6C6120666163696C6973692E205072616573656E7420666175636962757320616E7465207669746165206D61757269732E0A0A5072616573656E74206C6163696E6961206C656374757320736564206E69736C2E20496E2074656D70757320636F6E677565206D61757269732E20496E746567657220666163696C69736973206F726E61726520656E696D2E204E756C6C61206964206D617373612E20446F6E656320636F6D6D6F646F206469616D2061742074656C6C75732E204E616D20646170696275732076697665727261206573742E204E616D2074656C6C75732E205072616573656E742061206C696265726F2E20496E206661756369627573206573742065676574206E6962682E204E756C6C612065726F73206F7263692C20696D70657264696574206E6F6E2C20626C616E646974206E6F6E2C2074656D706F7220656765742C206D692E2050656C6C656E74657371756520636F6E76616C6C69732E0A0A517569737175652065676574206D69206163206C656F20657569736D6F642066617563696275732E2050686173656C6C75732072686F6E637573207075727573206964206475692E20566573746962756C756D206D616C65737561646120656C656966656E6420616E74652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050656C6C656E74657371756520626C616E646974206D6174746973206F64696F2E2053757370656E646973736520636F6E7365717561742C206C65637475732061632073656D70657220736F6C6C696369747564696E2C206D692076656C69742064696374756D2061756775652C2061632074656D70757320646F6C6F7220657261742073697420616D6574206475692E2050726F696E2068656E6472657269742C2066656C6973207175697320766F6C757470617420706F73756572652C206469616D206F64696F206D616C657375616461206F64696F2C206120696E74657264756D206F726369206469616D20717569732073617069656E2E2050656C6C656E746573717565206F64696F206F64696F2C20766976657272612076656C2C20677261766964612065752C206D6F6C6573746965207365642C206E756C6C612E2050686173656C6C7573206D617572697320706564652C20636F6D6D6F646F2075742C20657569736D6F642065752C2068656E6472657269742065752C206573742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C6120656C656D656E74756D206C616375732065752061756775652E2053656420657261742E2050726F696E20706F7274612E204D616563656E61732071756973206D692E2050686173656C6C757320617420656E696D206163206A7573746F206772617669646120756C7472696365732E2043726173206C656F2E0A0A496E746567657220757420617263752E20446F6E656320736564206D61676E612E2050726F696E2066656C69732E20496E20696163756C69732C206C6967756C61206964206672696E67696C6C61207072657469756D2C206E696268206469616D20616363756D73616E2074656C6C75732C206567657420616363756D73616E206D657475732064756920766172697573207475727069732E2050686173656C6C7573206F726369206D657475732C20656C656966656E64207365642C2074656D706F722061632C207363656C657269737175652061632C2075726E612E20496E74656765722076697665727261206E657175652061206D61757269732E204D617572697320706F72747469746F7220646F6C6F722065752076656C69742E20496E7465676572206F64696F20656C69742C20766573746962756C756D2075742C20766F6C75747061742069642C2072686F6E63757320636F6D6D6F646F2C2075726E612E20457469616D20706C61636572617420706861726574726120657261742E2055742074656D706F72206573742E20496E7465676572206469676E697373696D20626C616E6469742074656C6C75732E204D6F726269206E69626820646F6C6F722C207363656C657269737175652069642C20636F6D6D6F646F206D616C6573756164612C206D61747469732061742C206D692E20437261732074696E636964756E7420636F6D6D6F646F2070757275732E20496E2074696E636964756E742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D20756C6C616D636F727065722E2055742068656E6472657269742E204D6F72626920756C7472696365732E0A0A5072616573656E7420696163756C69732C2065726F73206163206567657374617320736F64616C65732C2075726E61206C656F206665726D656E74756D206C6967756C612C2073697420616D657420616C697175616D2076656C69742073656D206E6F6E2070757275732E20446F6E65632072757472756D206172637520717569732070757275732E204E616D20706F73756572652C206C6163757320617420636F6E73657175617420706C6163657261742C206E756C6C61207065646520706F7375657265206F7263692C206E6F6E20657569736D6F6420747572706973206475692071756973206E69736C2E2050726F696E20706F7274612061646970697363696E67206E6962682E20446F6E65632074726973746971756520646F6C6F722061742074656C6C75732E20446F6E6563206E65717565206D617373612C20617563746F722069642C2066617563696275732076697461652C20756C6C616D636F727065722076656C2C206E6973692E2050726F696E206D6F6C6573746965206E6571756520736564206D617373612E204E616D2074656D706F722E204D6F72626920616C697175616D2073617069656E2061742074656C6C75732E2046757363652071756973207269737573206574206D69207072657469756D2070756C76696E61722E2046757363652073697420616D6574206C6967756C612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E646973736520657520656E696D2065742066656C6973207363656C65726973717565206C6F626F727469732E205072616573656E7420626962656E64756D2E20566976616D7573207665686963756C612E20496E7465676572206174206E696268207365642076656C69742072686F6E637573206D6F6C65737469652E2043726173206C616375732E2053656420756C6C616D636F727065722065726F732076656C20657261742E20467573636520657520746F72746F722073697420616D6574206469616D20657569736D6F642073616769747469732E204E756E632071756973206C61637573206964206E69626820636F6E76616C6C6973207661726975732E2053757370656E6469737365207669746165206D692E20566573746962756C756D207472697374697175652E20446F6E6563206D616C65737561646120697073756D206964206E657175652E204E756C6C616D20736564206C616375732E204475697320656765737461732C206A7573746F20757420636F6E677565206F726E6172652C2061756775652073617069656E206C7563747573206469616D2C20617420616363756D73616E20657261742073617069656E207574206C696265726F2E2050686173656C6C75732076656C206E756C6C612E2053757370656E646973736520617263752074656C6C75732C20706F72747469746F7220612C2070686172657472612066617563696275732C20616C697175616D2073697420616D65742C206D617373612E204E756C6C6120706F72747469746F722074696E636964756E74206C6F72656D2E204E756E6320646F6C6F72206F64696F2C20736167697474697320696E2C206C6F626F727469732076656C2C20766F6C7574706174207365642C206E6962682E0A0A5175697371756520626C616E646974206C656F2075742073617069656E2074656D70757320666163696C697369732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2041656E65616E20756C7472696369657320706F72747469746F72206A7573746F2E2046757363652072757472756D2065726F732075742075726E612E2050726F696E2071756973207175616D20656765742064756920616C697175616D20616363756D73616E2E20446F6E656320737573636970697420656C656966656E6420656C69742E2050656C6C656E746573717565206D61747469732C2066656C697320736F64616C657320696163756C697320696D706572646965742C206C616375732073656D20636F6E76616C6C69732061756775652C2073697420616D657420616C69717565742061726375207075727573206672696E67696C6C612072697375732E20496E206575206F64696F206964206D61676E61207068617265747261206F726E6172652E20416C697175616D20696E74657264756D2070756C76696E617220697073756D2E20536564206E657175652E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D2073697420616D6574206E6973692E2055742061742061756775652E204D617572697320766F6C757470617420626C616E646974206C6967756C612E204E756C6C61206575206D657475732E20566573746962756C756D206567657420656C69742E205072616573656E7420706F73756572652E20566573746962756C756D2069642073656D206E6F6E206C6563747573206D6F6C6C69732074696E636964756E742E20416C697175616D2069642066656C697320617420616E7465206F726E6172652074656D706F722E204E756C6C61206C61637573207475727069732C20666575676961742076697461652C2063757273757320717569732C20636F6E736563746574756572206E6F6E2C206D61757269732E204675736365206C61637573206D617373612C20706F72747469746F722075742C206D6F6C65737469652075742C2076656E656E6174697320612C206C6F72656D2E205072616573656E742073697420616D6574206F7263692E204D61757269732072686F6E6375732066656C69732076697461652066656C69732061646970697363696E6720696D706572646965742E204D616563656E6173206D6F6C6C6973206469616D206E6563206C656F2E0A0A467573636520656E696D20697073756D2C20756C7472696365732065752C206D6F6C65737469652069642C20656C656D656E74756D2069642C2073617069656E2E20496E746567657220612075726E612E204E616D2076656C6974206C696265726F2C2076656E656E6174697320656765742C2074656D706F722073697420616D65742C20666575676961742076697461652C20616E74652E204675736365206E756E632E205365642073656D706572206E69736C206E65632072697375732E20496E20736564206C696265726F2E2050726F696E20746F72746F72206E657175652C2074696E636964756E742061632C2074656D706F722061632C20706861726574726120717569732C2076656C69742E2044756973206C65637475732061756775652C20756C747269636965732076656C2C20636F6E7365717561742069642C20696163756C69732069642C20616E74652E20566976616D757320617563746F72206D65747573206120616E74652E204375726162697475722061726375206E6973692C20666163696C697369732061742C206C616F7265657420696E2C20636F6E736563746574756572207365642C206D61757269732E205175697371756520706C616365726174206469616D20736564206475692E20566976616D7573207072657469756D20636F6E64696D656E74756D206C6F72656D2E20437572616269747572206C616F726565742E2041656E65616E206F726369206C6967756C612C2063757273757320656765742C206C6163696E6961206E6F6E2C2066617563696275732076656C2C206C6F72656D2E0A0A416C697175616D206572617420766F6C75747061742E204375726162697475722065726F7320646F6C6F722C20636F6E67756520612C20636F6E64696D656E74756D207365642C206C75637475732075742C206E6962682E204D616563656E6173206E6F6E20746F72746F72206E65632074757270697320636F6D6D6F646F2070656C6C656E7465737175652E205072616573656E7420657569736D6F6420706C616365726174206D692E2053757370656E646973736520706F74656E74692E2050686173656C6C7573207574206E65717565207669746165206F726369206D617474697320696163756C69732E20496E746567657220656765742074656C6C75732E20446F6E656320617420616E74652E204E616D206C6163696E6961206C656F206567657420657261742E204D616563656E617320657569736D6F64206D61676E6120636F6E67756520746F72746F722E204D6F726269206E6563206D6173736120657520656E696D206D616C65737561646120736F6C6C696369747564696E2E2053656420616363756D73616E2E204E756C6C616D20697073756D2E205574206F64696F2E20416C697175616D206572617420766F6C75747061742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2050656C6C656E7465737175652069642076656C69742E204E616D206F64696F2073656D2C20616C69717565742075742C2074656D7075732073697420616D65742C20657569736D6F642065742C206E756E632E0A0A50656C6C656E746573717565206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205072616573656E74206D6175726973206E756E632C207661726975732075742C20636F6E76616C6C6973206D6F6C65737469652C206C75637475732073697420616D65742C206C656F2E205365642064696374756D206C6F72656D20657420617263752E204E756E632076656E656E617469732070656C6C656E746573717565206D617373612E204E756C6C6120666163696C6973692E2050686173656C6C757320696E20746F72746F722065676574207269737573207363656C657269737175652076756C7075746174652E20536564206E69626820656C69742C2073616769747469732061632C20636F6E64696D656E74756D206E65632C20636F6E76616C6C69732065742C206A7573746F2E20467573636520766F6C7574706174206D657475732E204E756E6320617563746F722E20566573746962756C756D206C656F2065726F732C2070656C6C656E7465737175652061632C206D6F6C6C697320756C7472696365732C2072686F6E637573206E6F6E2C20646F6C6F722E204D6175726973207665686963756C6120706C616365726174206E69736C2E20566573746962756C756D20626962656E64756D2C2061726375207175697320636F6E67756520656C656D656E74756D2C2076656C6974206E756E6320656C656966656E64207475727069732C206964206C7563747573207269737573206E69736C2073697420616D65742074656C6C75732E2050686173656C6C75732070656465206E657175652C20626C616E646974206E6F6E2C20636F6D6D6F646F2076697461652C20756C7472696369657320656765742C206D61676E612E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120666163696C6973692E20416C697175616D20616320616E74652E20437261732072697375732E204D6F726269206D6175726973206C616375732C20706F73756572652065752C20626C616E6469742065742C2070686172657472612061742C206D692E2050726F696E2061632070757275732E204475697320637572737573206E69736C2072757472756D207175616D2E20416C697175616D2061206F64696F206E6F6E206D61676E612070656C6C656E74657371756520756C747269636965732E204D616563656E6173206163206D6173736120717569732073617069656E20756C6C616D636F727065722074656D7075732E2043726173206375727375732076656C6974207365642073617069656E2E2050726F696E206E756C6C612E20566976616D757320736F64616C657320616C697175616D206E6962682E20457469616D206574206572617420757420616E7465206C6163696E696120657569736D6F642E204675736365206E6973692E2050726F696E2071756973206E756C6C612E0A0A517569737175652076656E656E617469732C2065726F7320736564206C616F7265657420736F6C6C696369747564696E2C206F72636920616E74652070656C6C656E746573717565206E69736C2C2073697420616D65742076697665727261207175616D2065726174206E6F6E2072697375732E20437261732065676574206C696265726F2E2053656420656C6974206D61676E612C2073656D7065722065752C206672696E67696C6C6120696E2C206469676E697373696D20736F64616C65732C20657261742E20566976616D757320666575676961742073656D2076656C206475692E20446F6E656320636F6E76616C6C697320736F6C6C696369747564696E206469616D2E2043726173207365642070757275732E20446F6E65632066656C69732065726F732C2073656D70657220656765742C2074656D706F7220636F6E7365637465747565722C20736167697474697320717569732C206E69736C2E204475697320696E20616E74652E2043726173206E6F6E207475727069732E204E756C6C612074656D706F722076656C697420616C697175657420747572706973206D6F6C657374696520706C6163657261742E2050726F696E20656C656D656E74756D206665726D656E74756D206D61757269732E20566976616D757320736564206F726369206C6163696E69612064756920706C6163657261742076656E656E617469732E20566573746962756C756D20666575676961742C2074656C6C757320696E20766F6C75747061742072757472756D2C206D61676E61206E69736920756C6C616D636F727065722065726F732C2069642070756C76696E6172206E657175652065726174207574206C616375732E20566976616D7573207365642061756775652E204E756C6C6120666163696C6973692E204D616563656E617320616E74652061756775652C20656C656D656E74756D2075742C20736F64616C65732076697461652C20636F6E64696D656E74756D206E65632C206C6F72656D2E20447569732070656465206F7263692C206672696E67696C6C612061742C20656C656966656E64206E65632C207072657469756D20696E2C20657261742E204E616D2073616769747469732C2074757270697320766974616520636F6E76616C6C69732070686172657472612C206F64696F2073656D207363656C65726973717565206C616375732C206E6563206C6F626F7274697320647569206469616D2076656C2065726F732E20496E2073656D7065722067726176696461206E657175652E0A0A496E7465676572206E756E632E205574207072657469756D20697073756D2073697420616D657420656C69742E20496E206E656320617263752E2053656420766573746962756C756D2076756C70757461746520697073756D2E2050656C6C656E7465737175652074696E636964756E742E204E756C6C61206772617669646120646F6C6F7220696E2074656C6C75732E2043726173207665686963756C612C20646F6C6F722075742070656C6C656E74657371756520616C697175616D2C206572617420656E696D20617563746F72206D617373612C207665686963756C61206C6F626F72746973206F64696F2065726F732071756973207175616D2E2050726F696E2064617069627573206E6571756520696E20656E696D2E2050726F696E20656C69742E20496E74656765722072686F6E6375732074696E636964756E7420656C69742E204675736365206C6F72656D206D657475732C2073656D7065722061632C20766F6C75747061742076697461652C20666163696C697369732075742C2074656C6C75732E20446F6E65632076656C20747572706973207669746165206E69736920706861726574726120706F72747469746F722E204D616563656E617320746F72746F722E204675736365206D692E204E756C6C616D206E6563207475727069732E2053656420736F64616C657320766573746962756C756D206E756E632E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A50656C6C656E74657371756520646F6C6F7220646F6C6F722C206C616F726565742065752C20616C697175657420717569732C207363656C657269737175652073697420616D65742C20617263752E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C616D206375727375732075726E61206567657420656C69742E205175697371756520626C616E6469742073617069656E20616320616E74652E2050726F696E206E756C6C612065726F732C206772617669646120766F6C75747061742C20736F64616C65732076656C2C206D6F6C6C69732065752C206D617373612E204E756C6C612074726973746971756520736F6C6C696369747564696E206E69736C2E20437572616269747572207669746165206C6F72656D2076697461652076656C69742065676573746173206F726E6172652E2041656E65616E20656765742065726F732E20416C697175616D206572617420766F6C75747061742E20467573636520612075726E61206964206F64696F20616C697175657420636F6E76616C6C69732E204375726162697475722073697420616D6574206E69736C20706F7375657265206C656F20706F737565726520646170696275732E2044756973206D6574757320657261742C206C75637475732076656C2C2072686F6E6375732061742C20636F6E76616C6C69732073697420616D65742C20656E696D2E20566976616D75732068656E6472657269742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D206567657420656C69742E0A0A4E756C6C616D2061206E756E632E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206D657475732075726E612C2074696E636964756E742065742C206C6163696E69612073697420616D65742C206C6F626F727469732076697461652C206C6967756C612E2050726F696E206574206D6175726973207669746165206D6920616363756D73616E2070656C6C656E7465737175652E20457469616D207175616D2070757275732C2068656E647265726974207365642C20666575676961742076697461652C20657569736D6F6420656765742C20746F72746F722E20557420616C697175616D206D61676E61207669746165206A7573746F2E2053757370656E6469737365206E6F6E206A7573746F2076656C2076656C697420636F6E64696D656E74756D2074656D7075732E20447569732074656D70757320697073756D2076697461652074656C6C75732E2050726F696E20696E206D617373612E20457469616D20756C6C616D636F727065722064696374756D2074656C6C75732E2050726F696E20616C69717565742066656C6973206174206C656F206C616F726565742070756C76696E61722E20566573746962756C756D20617263752070757275732C206D616C6573756164612073697420616D65742C206375727375732065752C20706C6163657261742073697420616D65742C206E756E632E204E616D206D61737361206F64696F2C20736F6C6C696369747564696E20696E2C2061646970697363696E6720612C20616C697175616D206E65632C2072697375732E20416C697175616D20626C616E6469742068656E647265726974206C696265726F2E204D617572697320677261766964612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204375726162697475722061206E6962682E20557420696E74657264756D206665726D656E74756D206E657175652E2050656C6C656E74657371756520736564206E756E632E204D6175726973207665686963756C61206E697369206574206E756E632E205072616573656E74206C6F72656D2E20446F6E65632073656D7065722E20496E7465676572206575206C6163757320696E2065737420616C697175616D2068656E6472657269742E20566573746962756C756D2065676574206E657175652E205365642073656D706572206C75637475732076656C69742E20437572616269747572206E6962682061756775652C20636F6E6775652065752C2068656E6472657269742069642C20636F6E6775652065742C20656E696D2E20496E746567657220706C61636572617420616C697175616D206C65637475732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20566976616D75732076697461652065726F732E20446F6E65632076656C206E69736C2E0A0A496E20766573746962756C756D20666163696C697369732075726E612E2055742072697375732E204D61757269732070686172657472612E2050656C6C656E746573717565206D61747469732E20496E746567657220737573636970697420616C697175616D20697073756D2E204475697320626C616E6469742C2073617069656E20657420756C7472696369657320636F6E64696D656E74756D2C2066656C6973206D6920656C656D656E74756D20706564652C206E6563207361676974746973206D65747573206D61757269732071756973207175616D2E205175697371756520616363756D73616E20617263752076656C206E756C6C612E20437261732073656D2073617069656E2C20706F72747469746F722069642C20756C747269636965732073616769747469732C206C75637475732065752C206E756C6C612E20496E746567657220717569732065726F732E204D6F726269207365642075726E6120612074656C6C7573207665686963756C612076756C7075746174652E20457469616D206E656320617567756520656765742066656C69732073656D706572207472697374697175652E205175697371756520757420646F6C6F722076656C2072697375732064696374756D20636F6E7365717561742E20536564206567657420646F6C6F7220736564206E756E63206C6163696E696120616C69717565742E2053757370656E646973736520616320746F72746F7220696E20697073756D20706F73756572652076656E656E617469732E20536564206567657420657261742E204E756C6C612066617563696275732E2044756973206C616F726565742C206D6173736120706F72747469746F7220616C697175657420656765737461732C20697073756D206C65637475732072686F6E637573207175616D2C20696E2061646970697363696E672065726F732073656D2075742074656C6C75732E2050656C6C656E74657371756520666575676961742074656D707573207175616D2E20566976616D757320696420646F6C6F7220656765742073617069656E20636F6E7365637465747565722074656D706F722E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120696163756C6973206665726D656E74756D206C696265726F2E204375726162697475722066617563696275732C206D61737361206D616C657375616461206375727375732074696E636964756E742C20657261742073656D20656C656966656E64206D61757269732C20736564206672696E67696C6C61206D6920616E74652061632070757275732E204475697320656C656D656E74756D206C65637475732E204E756E63206F726E617265206172637520657520746F72746F722E20566573746962756C756D2076656C20646F6C6F72206174207075727573206C6163696E6961206672696E67696C6C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E616D20696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204D616563656E61732074696E636964756E742C2065726F73206120656765737461732070656C6C656E7465737175652C2072697375732072697375732064696374756D206C696265726F2C20696420616C6971756574206D65747573206A7573746F20696E206D617373612E2050726F696E20612074656C6C75732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205365642070757275732E20536564206E6F6E20706564652E2041656E65616E206D617373612073617069656E2C20736F64616C65732073697420616D65742C20636F6E7365717561742064696374756D2C20656C656966656E642076697461652C20746F72746F722E20446F6E656320756C747269636573206C6163696E696120656C69742E0A0A4D6F7262692061646970697363696E6720736F64616C657320646F6C6F722E20557420756C6C616D636F7270657220756C74726963696573206573742E20496E2076656E656E617469732074656D7075732061756775652E2053757370656E646973736520746F72746F7220646F6C6F722C20616363756D73616E2065742C20737573636970697420612C2074696E636964756E742075742C206C696265726F2E20416C697175616D207363656C65726973717565206D61676E61207365642066656C69732E2051756973717565207574206E756E632061206D61676E612076756C70757461746520706C6163657261742E20416C697175616D2072686F6E637573207665686963756C61206475692E2053656420746F72746F722E204E756C6C616D2073697420616D6574206469616D2E204E756E63207365642065726F732E20536564206574206F64696F2074696E636964756E7420656C6974206772617669646120636F6E76616C6C69732E20437572616269747572207175697320746F72746F722061206C616375732073656D706572207661726975732E204D6175726973206174206175677565206E6F6E206D6920736F6C6C696369747564696E20616C697175616D2E20496E746567657220756C6C616D636F727065722E2050656C6C656E746573717565207375736369706974207175616D206E6F6E2070757275732E20416C697175616D2061632065726F73206174206172637520756C6C616D636F7270657220636F6E7365637465747565722E2053757370656E6469737365207072657469756D206D6174746973206C656F2E0A0A44756973206174206E756E632E2053656420646F6C6F72206573742C207661726975732061632C20706F7274612065742C2074696E636964756E742068656E6472657269742C2072697375732E20566976616D7573207574206D61676E612E205072616573656E74207574206D61757269732E20496E207075727573206C616375732C206D6174746973207365642C20766573746962756C756D206E65632C2074656D706F722061742C206E69736C2E204372617320756C6C616D636F727065722076656E656E617469732074656C6C75732E20557420646F6C6F722E204D616563656E6173206D616C6573756164612C207065646520612070756C76696E6172206D61747469732C2061726375206469616D207665686963756C612072697375732C207175697320706F72747469746F72206175677565206D6173736120696E2076656C69742E204E756E6320636F6E6775652E204D6F7262692076656C6974206D657475732C2072686F6E6375732065742C20616C697175616D20636F6E7365637465747565722C20756C74726963696573206D616C6573756164612C206C6967756C612E205365642076656C6974206E69736C2C2073616769747469732076697461652C20706861726574726120612C20706F7375657265207365642C206D617373612E204E756C6C6120666163696C6973692E20496E207661726975732C206C6967756C61206964206C6F626F7274697320736F64616C65732C206175677565206F726369206665726D656E74756D2074656C6C75732C2065752070756C76696E6172207269737573206C6967756C6120612073617069656E2E204D6F726269206C616F7265657420697073756D206E6F6E206D692E204E616D20637572737573206C6F72656D207574206D692E20566976616D7573206D61676E6120656E696D2C20706F7375657265206E6F6E2C2073656D70657220717569732C20736F64616C65732065752C20617263752E20457469616D206D692070757275732C207072657469756D20666575676961742C20766172697573207365642C2070656C6C656E74657371756520656765742C206C6967756C612E20496E206C656F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E6563207669746165206F726369206575206F72636920736F6C6C696369747564696E20666575676961742E0A0A5072616573656E74207075727573206D617373612C20657569736D6F642076697461652C2074656D707573206E65632C20636F6E7365717561742068656E6472657269742C206D657475732E2041656E65616E2066656C6973206573742C20656765737461732076697461652C20616363756D73616E20656765742C2070656C6C656E74657371756520696E2C2073617069656E2E204475697320646170696275732070656465206E6F6E2073617069656E2E204E756E632075726E612E20496E74656765722076656C206C696265726F2E204475697320617567756520617263752C2064617069627573206E6F6E2C20666163696C697369732076697461652C20706F73756572652075742C2065726F732E20446F6E6563207669746165206E756E632073697420616D6574206172637520696D706572646965742064696374756D2E204D6F72626920656C656966656E642C206C6F72656D20657520636F6E73656374657475657220766573746962756C756D2C206469616D206E756E63206F726E61726520617263752C2061632074656D706F722066656C697320646F6C6F7220656765742065726F732E2050686173656C6C7573206D617373612073656D2C20736F6C6C696369747564696E2061632C20736F64616C657320677261766964612C206C756374757320612C207175616D2E204E616D206E65717565207175616D2C20766976657272612061742C2076656E656E6174697320717569732C207361676974746973206E6F6E2C20656E696D2E0A0A4E756C6C6120666163696C6973692E2050656C6C656E7465737175652065676573746173206C6163696E6961206573742E205365642074696E636964756E742C2070656465207365642074696E636964756E7420766573746962756C756D2C2075726E6120646F6C6F722061646970697363696E672070757275732C207669746165206672696E67696C6C612066656C697320656C697420696E206E6962682E204E756C6C6120736564206E6973692E204D6175726973207375736369706974207363656C6572697371756520617263752E20457469616D206E6F6E20656E696D2076656C2065726F7320616363756D73616E206D616C6573756164612E204E756E632074696E636964756E7420636F6D6D6F646F206D61757269732E20496E2074696E636964756E7420726973757320717569732075726E612E204E756C6C61206469616D20746F72746F722C20616C69717565742065742C2074696E636964756E7420717569732C20736F6C6C696369747564696E2061632C20746F72746F722E2043726173206E69736C206E657175652C2076756C7075746174652073757363697069742C206D6F6C657374696520717569732C2070756C76696E61722061742C206E756C6C612E204E756C6C616D206163206D65747573206E6563206F64696F20706F7375657265207661726975732E2043726173207365642070656465206E65632064756920706F737565726520626962656E64756D2E204475697320657569736D6F6420756C6C616D636F72706572206C696265726F2E20416C697175616D2066617563696275732070756C76696E6172207475727069732E0A0A496E207574206E65717565206964206E756E63206665756769617420636F6D6D6F646F2E20437572616269747572206469676E697373696D2C2066656C697320617420736F6C6C696369747564696E206C6163696E69612C20656E696D20656C6974207375736369706974206E657175652C20736564206C7563747573206C6F72656D20697073756D20696E206C656F2E204475697320646170696275732C206F64696F207175697320617563746F7220636F6D6D6F646F2C206E69736C206F64696F206D61747469732074656C6C75732C206E65632074696E636964756E7420747572706973206469616D20696E20617263752E2043757261626974757220612073656D2E204E756C6C616D20766F6C7574706174206D61676E612E2050656C6C656E7465737175652073616769747469732C206E6571756520636F6E736571756174207072657469756D206375727375732C20646F6C6F72206C6163757320636F6E73656374657475657220617263752C20736564206C616F72656574206573742075726E61206574206D657475732E2053757370656E646973736520706C6163657261742C20647569206120706F7274612074656D706F722C206C6F72656D20647569206C6F626F72746973206E657175652C207365642076656E656E61746973206469616D20656E696D2069642065726F732E20457469616D206574206E69736C206E6F6E206C656374757320666175636962757320636F6E7365637465747565722E204D6F726269207363656C657269737175652C2073656D206E65632074656D70757320756C6C616D636F727065722C20697073756D206469616D2066657567696174206C6F72656D2C2061206672696E67696C6C612073617069656E20656C69742071756973206E6962682E204E756C6C616D206469616D2075726E612C2076697665727261207365642C2070686172657472612072686F6E6375732C2074696E636964756E742076656C2C206F7263692E20496E746567657220616363756D73616E206D617474697320657261742E204E616D2064696374756D2E204D6175726973206E6563206C656F2E204E756C6C6120696163756C69732E204E756C6C61206E69736C206D692C206461706962757320717569732C207665686963756C6120612C2063757273757320656765742C206F64696F2E0A0A50686173656C6C7573206461706962757320657569736D6F64206E6962682E20566976616D757320696D7065726469657420616E746520696E206C6967756C612E2050656C6C656E74657371756520616363756D73616E2E20496E20696D706572646965742C20647569206120617563746F72206672696E67696C6C612C206D65747573206E6973692063757273757320646F6C6F722C2076656C206C7563747573206C6967756C61206C6F72656D207669746165206D61757269732E205072616573656E74206D617474697320766573746962756C756D20656C69742E20416C697175616D20656E696D206C616375732C2070756C76696E6172206E6F6E2C206C6163696E69612073697420616D65742C20656C656966656E64206E6F6E2C2076656C69742E20566573746962756C756D206163206C656F2E204D617572697320696D70657264696574206A7573746F206163206C65637475732E20536564206D6F6C6573746965206C656374757320736564206475692E20536564206665726D656E74756D2074656D707573206D61757269732E204E616D206F726E617265206F7263692061632074656C6C75732E205574206D616C6573756164612C206C61637573206964206C6163696E696120616363756D73616E2C206469616D20656C69742061646970697363696E67206D657475732C20657420626962656E64756D2073617069656E206E69626820626C616E646974206F7263692E2053757370656E646973736520697073756D2074656C6C75732C20736167697474697320717569732C20766573746962756C756D206E6F6E2C2076756C7075746174652065752C2065726F732E205072616573656E74206174206E756C6C612069642070656465207363656C6572697371756520756C747269636965732E204372617320626C616E646974207072657469756D2074656C6C75732E204D616563656E6173206461706962757320636F6E64696D656E74756D2061756775652E2050686173656C6C75732074696E636964756E74207068617265747261206C6F72656D2E204D6F726269206E6F6E2065726F732E205365642074656D706F722C206E69736C20612074696E636964756E742074696E636964756E742C2065726F73206469616D2064696374756D2073656D2C2076656C206469676E697373696D20616E7465206469616D20736564206D61676E612E205072616573656E74206E6F6E206C6967756C61206964206D65747573206D6F6C657374696520636F6E7365637465747565722E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E64697373652076656C206D692E2043757261626974757220616E7465206E756C6C612C2072757472756D20612C20636F6E76616C6C69732076656C2C207665686963756C612061632C206E756E632E204E756E632073616769747469732C20656E696D2073697420616D657420617563746F722072757472756D2C206D617572697320617263752076756C707574617465206E657175652C20657420657569736D6F64206573742066656C6973207175697320616E74652E20566573746962756C756D207475727069732074656C6C75732C2068656E64726572697420696E2C206C6163696E696120636F6D6D6F646F2C20756C6C616D636F7270657220677261766964612C2072697375732E204D61757269732072686F6E637573206C6163696E69612072697375732E204D616563656E617320736F6C6C696369747564696E2065726174207669746165206E756E632E205072616573656E74207072657469756D2070656C6C656E7465737175652061756775652E20446F6E656320696E74657264756D2E205072616573656E742061632065726F732076697461652065726174206C6F626F72746973206672696E67696C6C612E2041656E65616E20636F6E7365717561742074656C6C75732E204E756C6C6120616363756D73616E20626962656E64756D2066656C69732E204D616563656E6173207072657469756D20616E7465206964206E6973692E2041656E65616E206D6920617263752C2073656D706572207365642C206D61747469732065752C2076656E656E617469732073697420616D65742C20617263752E20446F6E656320616C697175657420657569736D6F64206C656F2E2050726F696E206D61676E61206A7573746F2C2074726973746971756520612C2073656D7065722061632C20736F6C6C696369747564696E20612C206C6967756C612E204D6F7262692076656C69742E20416C697175616D2076656C206E6973692E0A0A496E2061206C6F72656D207574206E756E63206665756769617420636F6E6775652E20446F6E6563206665726D656E74756D20626962656E64756D206475692E2050726F696E207661726975732065737420717569732076656C69742E20446F6E656320616C69717565742073656D20616363756D73616E206D692E2053656420706C6163657261742E204E756C6C616D206163206E6973692061206D61737361206C6F626F727469732073757363697069742E204E756E63206964206C656F2E20416C697175616D206574206D617373612E204E756C6C616D20766573746962756C756D20656C656D656E74756D206D657475732E20496E20636F6E736563746574756572206E6973692076656C206A7573746F2E204D616563656E6173206567657420707572757320736564206D61737361207661726975732070656C6C656E7465737175652E2050686173656C6C75732066617563696275732066656C697320717569732066656C69732E2041656E65616E206F64696F20617263752C20626C616E64697420717569732C20666163696C6973697320696E2C20696D706572646965742065752C206C6F72656D2E204E616D20706F73756572652070756C76696E6172206D692E204675736365207472697374697175652C206D617572697320657420636F6E73656374657475657220756C747269636965732C206D6175726973206C65637475732074656D706F72206A7573746F2C206174206672696E67696C6C61206573742065737420736564206E6973692E20517569737175652066617563696275732E2053656420696E20746F72746F722074696E636964756E7420657374206C6163696E696120696163756C69732E204D616563656E61732061206D617373612E2050656C6C656E7465737175652061206E69626820617420707572757320706F7274612068656E6472657269742E0A0A4E756C6C616D207475727069732E2046757363652061632073656D20736564206F64696F2070656C6C656E74657371756520696D706572646965742E2043757261626974757220696E20617263752E205072616573656E74206C61637573206C616375732C20666575676961742069642C2070756C76696E617220696E2C2074696E636964756E74207365642C206E657175652E204D616563656E61732076697665727261206F64696F206567657420746F72746F722E20496E746567657220616C697175616D2C206C6F72656D2072757472756D2076656E656E61746973206469676E697373696D2C206C6967756C61206D61676E61206D616C65737561646120617263752C2076656C2066657567696174206C6F72656D20697073756D2071756973206D617373612E204D6F72626920616E74652E20566573746962756C756D206D6175726973206C696265726F2C20756C6C616D636F7270657220717569732C20756C74726963657320717569732C20666163696C69736973206E6F6E2C206D617373612E204D616563656E617320696D706572646965742E20416C697175616D206572617420766F6C75747061742E2050656C6C656E746573717565206469676E697373696D2067726176696461206C65637475732E20496E206E696268206F64696F2C20617563746F7220656765742C206461706962757320717569732C206469676E697373696D2076656E656E617469732C20617263752E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20447569732070656C6C656E746573717565206C6967756C612071756973206D617373612E2043757261626974757220636F6E64696D656E74756D2C206A7573746F2065676574206F726E617265206C75637475732C206C6F72656D206C6967756C6120736167697474697320706564652C206120706F727461206E756E63206E756E6320696E206E657175652E20517569737175652066656C6973206D61757269732C20636F6E64696D656E74756D2076697461652C20617563746F722076697461652C2074696E636964756E7420717569732C20706564652E204E756E63206C6163696E696120616E746520696E206C656F2E2050656C6C656E746573717565206C696265726F2E2041656E65616E2061206C6967756C61206574206E756E6320766573746962756C756D20636F6E7365637465747565722E0A0A4675736365206F726E6172652E205072616573656E742069642075726E612E20496E74656765722076656E656E617469732C207175616D206E6F6E20736167697474697320616363756D73616E2C20616E7465206E6962682073616769747469732061756775652C20736F6C6C696369747564696E2061646970697363696E6720646F6C6F722076656C697420657520657261742E2050726F696E207175697320656E696D206575207075727573207665686963756C6120616C697175616D2E204E756C6C612076656C20656E696D2076656C20656C697420736F6C6C696369747564696E206672696E67696C6C612E20416C697175616D206572617420766F6C75747061742E205365642073757363697069742066656C6973207574207475727069732E20457469616D2072757472756D20726973757320696D70657264696574206573742E20416C697175616D20612074656C6C75732061742074656C6C757320636F6D6D6F646F20646170696275732E204D61757269732072757472756D206D61676E61206574206F64696F2E20496E20617420646F6C6F722E20437572616269747572207665686963756C61206C656374757320696E20746F72746F722E204675736365206A7573746F2070757275732C206C75637475732076697461652C206D6F6C6C697320696E2C2070686172657472612061632C2070757275732E204E756C6C616D20706F737565726520696E74657264756D206A7573746F2E20437572616269747572207669746165206C616375732076656C206C656F20636F6E6775652070756C76696E61722E0A0A41656E65616E20656C656966656E64206E6962682076617269757320746F72746F722E2053757370656E64697373652076656C2065726F732E2050726F696E206E6563206469616D206120746F72746F7220756C747269636573206F726E6172652E20416C697175616D207363656C657269737175652066657567696174206A7573746F2E20566976616D757320616E74652075726E612C2061646970697363696E672076697461652C20706F72747469746F722065752C20736F64616C65732065742C2066656C69732E2053757370656E646973736520706F74656E74692E20437572616269747572206163206D6173736120696E206E69736C207361676974746973206D6F6C6C69732E204E616D207175616D206C6967756C612C20636F6E73656374657475657220656765742C20696163756C69732061742C207661726975732065752C206C656F2E204475697320646F6C6F72206C6967756C612C2074696E636964756E742061742C20756C6C616D636F72706572207365642C20616363756D73616E20616C697175616D2C206C6967756C612E2050686173656C6C75732076756C7075746174652C206C6F72656D2061742074696E636964756E742070686172657472612C207269737573206C6563747573206C6163696E6961206D61676E612C20717569732072757472756D20656E696D206D61676E612061742073656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E20447569732069642073656D2061206D617572697320736F6C6C696369747564696E2074696E636964756E742E20457469616D2065752070757275732065752061726375206672696E67696C6C612061646970697363696E672E20566976616D7573206F726E6172652074656D707573206469616D2E2050726F696E20747572706973207175616D2C206C6163696E6961206E6F6E2C20656765737461732061742C20636F6D6D6F646F20656765742C20706564652E205072616573656E742076756C70757461746520726973757320696E206573742E204E756C6C6120666163696C6973692E0A0A557420656C656D656E74756D206C6163696E69612070757275732E2050726F696E2076697461652061726375206163206E756C6C6120636F6E76616C6C697320616C697175616D2E204E756C6C6120636F6E6775652C206C696265726F2069642070656C6C656E746573717565206D61747469732C207175616D206C656374757320706F72747469746F72206469616D2C2061207363656C6572697371756520647569206C696265726F20696E2073617069656E2E204E756C6C616D2066656C6973206469616D2C207665686963756C612076656C2C206D6F6C65737469652075742C20766573746962756C756D20616C697175616D2C2073617069656E2E20446F6E656320636F6E76616C6C69732C2065737420757420656C656D656E74756D20766F6C75747061742C206D617572697320697073756D20677261766964612073656D2C20636F6D6D6F646F20666163696C697369732073617069656E206C65637475732073656D706572206C65637475732E205175697371756520706F72747469746F722065726F73207574206E6962682E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20457469616D206D617474697320726973757320736564206F64696F2E20566573746962756C756D206574206F64696F2E20496E206861632068616269746173736520706C617465612064696374756D73742E204E616D20747269737469717565206D61737361207574206C6967756C612E2051756973717565206E6962682074656C6C75732C207665686963756C612073697420616D65742C2061646970697363696E672061742C20636F6E76616C6C6973206E65632C206C6967756C612E20566573746962756C756D207072657469756D2C206D69206E6563206672696E67696C6C6120626962656E64756D2C20647569206E756E6320736F64616C657320706564652C20612073656D706572206D61676E61206E696268206E6F6E206469616D2E20446F6E6563206D61737361206E756E632C20766976657272612076656C2C20636F6E73656374657475657220706F7274612C2064617069627573206E6F6E2C20697073756D2E2044756973206E69736C206D61757269732C206375727375732076656C2C2073656D706572206E6F6E2C20736F6C6C696369747564696E20626962656E64756D2C2066656C69732E20566573746962756C756D206575206E657175652E0A0A43726173206E656320646F6C6F722E20446F6E6563206C616F726565742074656D707573206C65637475732E20437261732073656420746F72746F7220696E74657264756D206C6163757320656C656966656E64206469676E697373696D2E204D616563656E61732073697420616D657420656C69742E204E756C6C616D207175697320646F6C6F722076656C20647569207068617265747261206C75637475732E20496E2073697420616D6574207175616D2073697420616D6574207065646520756C74726963657320756C7472696365732E204D616563656E6173206469616D2E20496E74656765722075726E612E204375726162697475722064696374756D2C2076656C69742073656420706C6163657261742073757363697069742C206572617420747572706973206665726D656E74756D206A7573746F2C2073656420696E74657264756D206E657175652073656D206574206E6962682E20566976616D757320636F6E73657175617420636F6E76616C6C6973206D61676E612E204E616D20616C697175616D2C2065737420616320626962656E64756D20636F6D6D6F646F2C206D61676E61206573742064696374756D206D692C207669746165206D616C65737561646120656C6974206D61676E61207669746165206F64696F2E204D616563656E61732074656D706F722076756C7075746174652074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206475692E20457469616D20616363756D73616E207065646520636F6E67756520746F72746F722E0A0A4D6F7262692074656D706F72206C696265726F206163206C6F72656D2E20496E20616C697175657420766172697573206D61676E612E20496E20617263752E2050686173656C6C7573206F64696F2E2046757363652074696E636964756E7420616C69717565742066656C69732E20517569737175652076656C69742E20536564206C75637475732E20416C697175616D2066657567696174206672696E67696C6C61206D692E20416C697175616D206D6F6C657374696520766976657272612072697375732E2050726F696E20617263752E20566573746962756C756D206C6F626F727469732074656D707573206E6973692E205072616573656E742061206172637520696E2076656C697420766976657272612072757472756D2E0A0A496E20736564206C65637475732E20446F6E656320726973757320646F6C6F722C20626C616E6469742073697420616D65742C20656C656D656E74756D20636F6E76616C6C69732C20706861726574726120717569732C20706564652E20496E7465676572206F726E6172652E2041656E65616E20656765737461732064617069627573206A7573746F2E20536564207175616D206C656F2C20706F73756572652061742C20656C656D656E74756D2076697461652C20636F6D6D6F646F20656765742C206573742E20416C697175616D206D6F6C65737469652072686F6E63757320656E696D2E2043757261626974757220696163756C697320756C74726963657320706564652E204D6F72626920616C69717565742072757472756D206C616375732E20416C697175616D207175616D2E2053656420636F6D6D6F646F2C2074757270697320696E20706861726574726120706F73756572652C206D6920726973757320696D7065726469657420657261742C206120766573746962756C756D206D617373612074656C6C7573207665686963756C612073656D2E204D6175726973206672696E67696C6C6120756C747269636573206E756E632E204E616D206E69736920656E696D2C20656C656966656E642073697420616D65742C20756C747269636573207365642C206665726D656E74756D206E6F6E2C2061756775652E2050726F696E20636F6E677565206C6F626F72746973206E6973692E204D616563656E61732068656E6472657269742E204E616D20736564206E69736C2E204E756E6320656C656D656E74756D206F64696F2065752072697375732E20496E206D657475732E2050686173656C6C75732067726176696461207072657469756D206C6967756C612E204E756C6C61207669746165206E657175652E204E616D206E69736920746F72746F722C206F726E617265206E6F6E2C20626C616E6469742061742C206375727375732065752C20746F72746F722E0A0A4475697320626962656E64756D20697073756D20696E206E756E6320637572737573206D6F6C65737469652E204E756E63206F7263692E204E756C6C616D206E656320616E7465206E6F6E20657374206469676E697373696D20766976657272612E204D617572697320626C616E6469742C2076656C69742069642066657567696174207072657469756D2C20656C6974206D61676E612070656C6C656E74657371756520646F6C6F722C206174207361676974746973206C616375732076656C69742065676573746173206D61676E612E2050656C6C656E746573717565206375727375732C206469616D20636F6E736563746574756572207361676974746973206672696E67696C6C612C20746F72746F72206E6973692061646970697363696E67206E756E632C20657520766172697573206C6163757320726973757320616320656C69742E204D6175726973206964206E6973692071756973206C656F20657569736D6F642076656E656E617469732E2050656C6C656E74657371756520616320616E74652E204D617572697320617263752073617069656E2C2074656D706F722061742C20706F72747469746F722069642C20636F6E64696D656E74756D2075742C206475692E20457469616D206665726D656E74756D20756C747269636965732061756775652E20437261732075742065726F73206174206A7573746F20756C7472696369657320696163756C69732E2044756973206469676E697373696D2C206E69736C20657420666163696C69736973206665726D656E74756D2C2065726174207075727573206D6F6C65737469652074656C6C75732C20717569732074656D70757320697073756D206C656374757320617420656C69742E204E756C6C61207669746165206C6F72656D2E0A0A41656E65616E2076656C2073656D206574206469616D2073656D70657220636F6E6775652E20496E20626962656E64756D206469616D20717569732074656C6C75732E204E756E6320666163696C6973697320756C74726963696573206E6962682E2043726173206E756E6320656E696D2C2066657567696174207365642C20756C7472696365732076697461652C2073616769747469732076697461652C20697073756D2E204675736365207669746165206E756C6C612E20446F6E65632070656C6C656E7465737175652C2076656C697420696E20706F72747469746F7220656C656966656E642C20657374206E65717565206C6F626F727469732076656C69742C2073697420616D65742072757472756D20616E746520746F72746F72206E656320646F6C6F722E20446F6E6563207665686963756C612E204E756C6C6120666163696C6973692E20536564206567657374617320756C747269636573206E6962682E20446F6E656320656C6974206C65637475732C20636F6E76616C6C697320706F72747469746F722C20616C697175657420646170696275732C206665756769617420656765742C206C6967756C612E2053656420636F6E736563746574756572206A7573746F2E204D616563656E617320612073617069656E2073697420616D6574206E6973692064617069627573206C6F626F727469732E20566976616D7573206C7563747573206C6F72656D206E6F6E206E756C6C612E2053656420656765742065726174207669746165206C696265726F20696E74657264756D20706F73756572652E20437261732070756C76696E61722E204E756C6C616D20696D706572646965742C20646F6C6F722074656D706F72206469676E697373696D20626C616E6469742C206475692073617069656E2072686F6E637573206E657175652C206964206D616C657375616461206175677565206D61676E612073697420616D65742075726E612E204475697320736564206D61757269732E0A0A4D6F72626920616363756D73616E2E20536564206D61757269732061756775652C206672696E67696C6C61206E6F6E2C20617563746F722075742C20617563746F722065742C206F7263692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320757420706564652E20446F6E6563207669766572726120656E696D2076656C206C6F72656D2E2050656C6C656E746573717565206E65717565206D61757269732C20696E74657264756D2065752C2076656E656E617469732069642C20636F6E64696D656E74756D2065752C2073617069656E2E20446F6E656320697073756D20617263752C206C6163696E69612061646970697363696E672C206C616F726565742065742C206375727375732076656C2C2076656C69742E205574207361676974746973206D617572697320717569732072697375732E20496E7465676572206575206F64696F207669746165206C61637573207669766572726120616363756D73616E2E204D6F726269206C656F20616E74652C206469676E697373696D207365642C2076617269757320717569732C20766F6C75747061742076697461652C206E6973692E204E756C6C6120706C61636572617420696E74657264756D20656C69742E20446F6E6563206E65717565206475692C2073616769747469732076697461652C20736F6C6C696369747564696E20717569732C20636F6D6D6F646F2076697461652C206E657175652E204E756C6C612071756973206C6967756C61206F726E617265206C6967756C612064696374756D206F726E6172652E204D61757269732072757472756D2072757472756D206E657175652E2041656E65616E207665686963756C612074656D707573206573742E20446F6E656320766172697573207363656C6572697371756520706564652E20446F6E656320706C6163657261742076756C707574617465206C656F2E204E756C6C616D206E756E63206E69736C2C20706F7375657265206E6F6E2C20666575676961742076697461652C2070656C6C656E74657371756520717569732C206D61757269732E20496E20647569206E657175652C2063757273757320656765742C20736167697474697320656765742C20646170696275732076697461652C206D692E2050726F696E2065676574206573742E0A0A467573636520706F727461206573742E204D6175726973206D61676E612E20416C697175616D20697073756D206C616375732C20756C747269636965732069642C20766573746962756C756D206C75637475732C20616363756D73616E2075742C20616E74652E20536564206D61757269732E205365642061646970697363696E67206C656F2073697420616D6574206D61676E612E2053757370656E646973736520706F74656E74692E204E756E63206D6173736120656C69742C206672696E67696C6C6120656765742C20656765737461732076697461652C206C75637475732076697461652C20646F6C6F722E2050686173656C6C75732071756973206E756C6C61206575206E69736920696E74657264756D20736F6C6C696369747564696E2E204E756C6C616D2069642074656C6C75732E20496E746567657220696163756C697320646F6C6F722061632070757275732E205365642076656C206D692E20437572616269747572206E6F6E206D61676E612073697420616D6574206A7573746F20636F6E64696D656E74756D2076756C7075746174652E20517569737175652074696E636964756E742070656465206575206E69736C2E20566976616D7573206C6F626F727469732E204E756E63206D65747573206D657475732C20636F6E677565207365642C2074696E636964756E74207365642C207072657469756D2061742C206F64696F2E20446F6E6563206120617263752E20496E2073656D206A7573746F2C207665686963756C61207365642C207661726975732069642C20766F6C75747061742061742C2072697375732E205072616573656E7420696163756C6973206D617373612E20496E206172637520656C69742C2068656E64726572697420656765742C20756C6C616D636F7270657220696E2C20706F7274612069642C2074656C6C75732E20446F6E65632073616769747469732068656E647265726974206469616D2E0A0A53757370656E646973736520706F74656E74692E20536564206574206469616D206574206175677565207361676974746973206C6F626F727469732E2050686173656C6C757320646F6C6F722E2055742065742061726375206567657420616E74652074656D706F7220706F73756572652E20416C697175616D206665726D656E74756D207363656C65726973717565206475692E204D61757269732061742070757275732E20446F6E656320657261742073656D2C20766573746962756C756D206E65632C2066617563696275732061632C206D617474697320612C206C656F2E2053757370656E64697373652061646970697363696E67206C6163696E69612073656D2E204E756C6C616D206F72636920617263752C2064696374756D2065742C20666175636962757320766976657272612C20646170696275732065742C206E657175652E2043726173206E756E63206469616D2C2061646970697363696E67206E6F6E2C20736F6C6C696369747564696E20696E2C20696E74657264756D2076656C2C206D617373612E204D61757269732073616769747469732C206A7573746F206174207472697374697175652074656D7075732C206D6175726973206D617572697320616C697175616D20616E74652C2073697420616D657420706F7375657265206469616D206475692065676574206C6967756C612E20496E206469676E697373696D2C206E69736C207574206C6163696E696120636F6E64696D656E74756D2C2065726174206A7573746F20706F72747469746F72206E756C6C612C206E6F6E2067726176696461206C6967756C61206D61676E612065676574206D617373612E20566573746962756C756D207669746165206C6967756C61206174206D6920766573746962756C756D2073757363697069742E2044756973206C616F726565742E204E756C6C6120636F6D6D6F646F206C696265726F2073697420616D6574206C6F72656D2E20557420656C656D656E74756D2073656D2E20496E74656765722076656C20646F6C6F722E204E616D20666163696C69736973206D6920717569732073656D20756C7472696365732073616769747469732E205365642071756973207175616D206174206D65747573206D6F6C657374696520626962656E64756D2E0A0A50726F696E2064756920656E696D2C206C6163696E696120612C20666575676961742061632C20706C6163657261742076697461652C20706564652E205175697371756520656765737461732C206C656F206567657420616C697175616D207072657469756D2C206C696265726F206A7573746F2074696E636964756E742065726F732C2075742065676573746173206175677565207065646520656C656D656E74756D206E6962682E20437572616269747572206D6F6C6C697320736F64616C657320656E696D2E20446F6E65632061756775652E2050686173656C6C757320696420697073756D20706F737565726520647569207072657469756D2066617563696275732E204D6175726973206C756374757320616E74652073656D706572206E69736920696E74657264756D2061646970697363696E672E204475697320646170696275732C206F64696F207175697320766976657272612072686F6E6375732C206A7573746F207175616D20626962656E64756D20646F6C6F722C20696420646170696275732076656C697420657261742076656C20657261742E2046757363652073697420616D6574206E69736C2076656E656E61746973207175616D20756C74726963657320636F6E64696D656E74756D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632072686F6E637573207363656C65726973717565206C6967756C612E20566573746962756C756D206D69206F64696F2C20616363756D73616E2065742C2061646970697363696E6720656765742C206F726E6172652075742C207175616D2E204E756C6C616D20626C616E646974206D6F6C6573746965206D61757269732E20437572616269747572206469676E697373696D206D6175726973206574206C6F72656D2E2053757370656E64697373652061206A7573746F2E204E616D206D617474697320666175636962757320617263752E204475697320626C616E64697420656E696D206E6F6E206D617373612E0A0A4E756C6C616D206C6F72656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E204D617572697320636F6E73656374657475657220706F7375657265206D61757269732E204D616563656E61732074696E636964756E74206D617572697320696E2065726F732E204E756C6C61206575206D65747573206575206F72636920736F6C6C696369747564696E2066617563696275732E2053757370656E646973736520616C697175616D206D6175726973206964206573742E204372617320626C616E646974206475692065742075726E612E204E756C6C6120617263752E2053656420612075726E612E204E756C6C612064617069627573207665686963756C6120746F72746F722E20446F6E65632072697375732E20536564207175616D206D657475732C20656765737461732065752C206375727375732075742C2076697665727261206E6F6E2C206F64696F2E205574206A7573746F206A7573746F2C206D616C6573756164612073697420616D65742C20626C616E6469742073757363697069742C206D6F6C657374696520696E2C206A7573746F2E20566573746962756C756D20636F6E7365717561742C207175616D20616320666575676961742074696E636964756E742C20697073756D206C696265726F20656C656966656E64206F64696F2C206E6F6E20656C656966656E64207065646520697073756D206E6F6E20616E74652E204E756C6C616D2061206D657475732E0A0A4E616D206163206E6973692061742066656C697320637572737573206D61747469732E2050656C6C656E74657371756520636F6E7365717561742073656D2071756973206F7263692E20517569737175652074656D7075732E2041656E65616E20696D70657264696574206D6F6C657374696520706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652065752074656C6C75732E204E756C6C61206469616D2065726F732C20736F64616C65732075742C20736F64616C6573206E65632C2074696E636964756E742061632C206E756E632E204E756E63206C6163696E696120666175636962757320697073756D2E20566976616D75732076656C206E6571756520696E2065726174206665726D656E74756D206C75637475732E204E756C6C612065676574206D65747573206E656320617567756520626962656E64756D20706C6163657261742E20566976616D75732074656D7075732E205072616573656E7420636F6E677565206F726E61726520697073756D2E20457469616D206D61747469732066657567696174206A7573746F2E0A0A416C697175616D206475692E2041656E65616E20636F6D6D6F646F20746F72746F72207669746165206E756C6C612E204D6F72626920657420697073756D2E204D617572697320616320697073756D2E204E616D2076656C207269737573207574206C6563747573206D6F6C6C697320766976657272612E2043757261626974757220656C656D656E74756D206D6F6C6C6973206573742E204E756C6C616D20656C69742E20566573746962756C756D207375736369706974207072657469756D20656E696D2E20566573746962756C756D207574206D617373612E2050726F696E206E65632066656C69732E204D616563656E617320677261766964612C2061726375206E656320636F6E7365717561742073616769747469732C2065726F732074656C6C7573207363656C65726973717565206D61757269732C20766974616520616363756D73616E207175616D207175616D207574206E756E632E20496E7465676572206567657420616E74652065752076656C6974206C616F72656574206D616C6573756164612E204E756E632073616769747469732C206D617572697320766974616520706861726574726120766F6C75747061742C2074656C6C75732074656C6C757320656C656966656E642065726F732C2073697420616D65742072757472756D20697073756D206E69736920612076656C69742E205072616573656E7420766172697573206C656F20657520657261742E20566976616D757320636F6E73657175617420706C6163657261742070757275732E20446F6E6563207072657469756D20656C656D656E74756D206E6962682E2050726F696E20617420656C6974206E6F6E2073656D20616C6971756574206D61747469732E2053656420756C6C616D636F7270657220697073756D2073697420616D657420656C69742E0A0A4D617572697320696E206D657475732E2053757370656E6469737365206D61676E61206C6F72656D2C2066617563696275732076656C2C2074696E636964756E7420717569732C207363656C65726973717565206E6F6E2C2074656C6C75732E2046757363652071756973206C6F72656D2E2050726F696E2061206C616375732073697420616D6574206D617572697320696163756C69732070756C76696E61722E2053757370656E64697373652072686F6E6375732065726F73206E6563206D692E205072616573656E7420657569736D6F642C207475727069732076697461652072757472756D207072657469756D2C206F64696F206D6574757320766F6C7574706174206E657175652C20656765742074656D7075732073617069656E206E657175652073656420657261742E20446F6E6563206665726D656E74756D207075727573206174206C65637475732E204E756C6C616D2073656D2E2046757363652076656C206D6920717569732065726174206C6F626F7274697320706F73756572652E2041656E65616E20656765742075726E612E2053757370656E6469737365206C6967756C612E204475697320696E206E6973692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A4375726162697475722076756C707574617465206C656374757320696420706564652E2050686173656C6C75732065752076656C69742E20457469616D2076656E656E617469732061646970697363696E67206E6962682E20416C697175616D206375727375732070756C76696E61722074656C6C75732E20566573746962756C756D206E657175652E204D6175726973206E6563206A7573746F20657420657261742073656D7065722070656C6C656E7465737175652E204675736365206D61747469732064696374756D20646F6C6F722E20457469616D2065676574207075727573206575206D617373612076617269757320656C656D656E74756D2E2050656C6C656E746573717565206D617373612E20557420756C74726963696573206469616D2073656420697073756D2E204E756C6C616D206469616D2E2050656C6C656E746573717565206964206D61676E61206964206C696265726F2074726973746971756520616C697175616D2E0A0A557420656C656966656E642C20707572757320696420706C6163657261742076656E656E617469732C2075726E6120617567756520616C6971756574206C6967756C612C20696E20756C74726963696573206C656F2072697375732065742074656C6C75732E204D6175726973206574206E756C6C612069642075726E61207472697374697175652074656D7075732E20557420666163696C697369732C2075726E6120657520766573746962756C756D2072686F6E6375732C206C616375732065726F7320636F6E736563746574756572206D657475732C2065742072757472756D20647569206C656374757320696E2070757275732E204E756E632076656C206E69736C206E6F6E20697073756D2074696E636964756E74206D6F6C6C69732E204E616D207175616D206C616375732C206F726E6172652076697461652C2072686F6E637573206E6F6E2C20636F6E677565207365642C206F64696F2E2050726F696E206E696268206475692C20706F7274612076656C2C2076656E656E61746973206E6F6E2C2070656C6C656E7465737175652075742C206E6973692E20536564207472697374697175652066656C69732061206D61676E612E2053757370656E646973736520656765742074656C6C75732E2043726173206772617669646120696D706572646965742076656C69742E20496E74656765722068656E6472657269742072697375732E2050726F696E206F7263692E20416C697175616D20756C6C616D636F72706572206D61757269732071756973206D61757269732E204E756E63206C6163696E696120766573746962756C756D206D657475732E20447569732074656C6C75732E204E756C6C616D2066617563696275732C206C656F2061632076756C70757461746520736F6C6C696369747564696E2C206C656F20646F6C6F7220666175636962757320657261742C207175697320626962656E64756D206F726369206F64696F206E6F6E20617263752E0A0A4E756C6C616D20616363756D73616E206D617474697320646F6C6F722E20446F6E6563206574206475692E205072616573656E7420612066656C6973206D6F6C6C6973206C616375732073656D706572206C6163696E69612E204375726162697475722070656C6C656E746573717565206C7563747573206573742E2050726F696E206E756C6C61206475692C20636F6E64696D656E74756D2076656C2C206661756369627573206E6F6E2C20696E74657264756D2061632C20657261742E204D616563656E6173207363656C657269737175652C206C656374757320696420766F6C757470617420616363756D73616E2C2073617069656E20746F72746F722070656C6C656E746573717565206475692C207365642073656D706572206D61676E612073656D207574206C656F2E2050726F696E206E756C6C612E204E756C6C616D206461706962757320756C6C616D636F727065722073656D2E2053757370656E6469737365207665686963756C61206D6574757320696E206E756E632E2050656C6C656E746573717565206E6F6E207175616D2076656C206172637520756C74726963657320756C6C616D636F727065722E2050686173656C6C757320717569732066656C69732073697420616D65742074656C6C757320756C6C616D636F72706572206665726D656E74756D2E20536564207665686963756C6120736F6C6C696369747564696E2075726E612E20437572616269747572207068617265747261207363656C657269737175652072697375732E2050656C6C656E746573717565206964206D617373612071756973206D6574757320616C697175616D20696D706572646965742E20496E206E756E63206C616375732C206665756769617420696E2C206772617669646120656765742C2076656E656E617469732075742C2074656C6C75732E2053757370656E646973736520706F74656E74692E204E616D20636F6E7365717561742061646970697363696E67206475692E20496E206E756C6C61206E6973692C20666575676961742075742C206665726D656E74756D2076656C2C2067726176696461206E65632C20746F72746F722E20496E207365642061756775652E0A0A457469616D20756C6C616D636F7270657220617567756520617420656E696D2E20496E7465676572206469676E697373696D2E20416C697175616D2070756C76696E617220636F6E677565206E756C6C612E204D6F72626920656E696D206D617373612C206672696E67696C6C6120612C20616363756D73616E20656765742C20636F6E64696D656E74756D206E65632C20657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2041656E65616E2070686172657472612E20457469616D20706F72747469746F722070757275732061206D657475732E20416C697175616D20696E74657264756D2073656D2065676574206A7573746F2E205175697371756520766F6C7574706174206C7563747573206573742E2041656E65616E2061756775652E2050686173656C6C757320647569206C65637475732C20756C747269636573206E65632C20636F6D6D6F646F2076656C2C20617563746F722076656C2C206E6973692E20557420756C7472696365732070656C6C656E746573717565206E6973692E20496E74656765722061632076656C69742065742073656D20696D70657264696574206C75637475732E20467573636520766974616520747572706973206964206175677565206D6F6C6C697320636F6E7365637465747565722E0A0A4D616563656E6173206E6563206C616375732E204D616563656E617320636F6E64696D656E74756D206F64696F2065752066656C69732E204D6175726973207574206E69736C207669766572726120657261742066617563696275732061646970697363696E672E20457469616D20656765737461732E204E756E6320657420646F6C6F72207669746165207269737573206469676E697373696D20636F6D6D6F646F2E204D6F726269206C65637475732076656C69742C2074696E636964756E74206E65632C20616C69717565742076656C2C206D61747469732076697461652C206C6967756C612E204D616563656E617320756C747269636965732073656D70657220646F6C6F722E2053757370656E6469737365206D616C6573756164612E20496E7465676572206D617474697320656C69742E20446F6E656320616363756D73616E2C206C6163757320666163696C69736973207661726975732074656D7075732C206E756C6C6120656C697420706F72746120657261742C2065742072757472756D20656C69742073656D2073697420616D6574206475692E0A0A4D616563656E6173206D6F6C6C6973206D69206E6F6E206E756C6C612E20566976616D7573207475727069732E2053757370656E64697373652061206D657475732E20496E2071756973206D6920696E2074757270697320636F6E67756520617563746F722E204D616563656E6173206C616375732E2053757370656E646973736520736F6C6C696369747564696E2E2050686173656C6C757320706F727461206E756E63206E6F6E206E69736C2070756C76696E617220656765737461732E20536564206E756C6C612E20566573746962756C756D206163206D692E204D617572697320756C7472696369657320636F6E64696D656E74756D206E657175652E204E756C6C612074656D707573206A7573746F2076656C206D617373612E204E756C6C6120737573636970697420636F6E67756520617263752E205072616573656E74206964207475727069732E204D6175726973206E69626820706564652C20657569736D6F642073656D7065722C206D6F6C65737469652061632C2072686F6E6375732076697461652C20616E74652E204D616563656E617320657261742066656C69732C207669766572726120736F6C6C696369747564696E2C20736167697474697320656765742C2070656C6C656E746573717565206E65632C206F7263692E20467573636520756C74726963657320636F6E736571756174206C616375732E20416C697175616D2065726174206D61676E612C20666575676961742061742C207669766572726120612C206D6F6C6C6973206E6F6E2C207475727069732E0A0A446F6E6563206D692E204E616D2064696374756D2070656C6C656E7465737175652073656D2E20446F6E6563206D6F6C6C69732072686F6E63757320656C69742E2050686173656C6C75732072686F6E63757320706564652073697420616D65742072697375732E20446F6E656320656765742061756775652E204D616563656E6173206E6F6E206C65637475732E2050686173656C6C757320736F6C6C696369747564696E206E697369206E65632066656C69732E20416C697175616D207072657469756D2C2065737420656765742073656D70657220636F6E76616C6C69732C206E696268206E756E6320736F6C6C696369747564696E2070757275732C2069642074656D706F722070656465206475692076656C206D61676E612E20566976616D7573206163206C6F72656D2E20457469616D206E69736C20746F72746F722C2061646970697363696E672064696374756D2C20656C656D656E74756D20696E2C20666163696C69736973207365642C206E6962682E2050726F696E206D61757269732E2050726F696E2072757472756D206D6173736120656765742073656D2E204375726162697475722074656D706F722061646970697363696E6720656C69742E204375726162697475722070757275732074656C6C75732C206665726D656E74756D20656765742C20616C69717565742076697461652C20636F6E76616C6C69732061632C206D61757269732E0A0A496E746567657220636F6E7365717561742076656C69742065752065726F732074696E636964756E74207665686963756C612E204E756C6C616D206C6F72656D2073617069656E2C2072686F6E637573206E6F6E2C206D617474697320717569732C20756C747269636965732073697420616D65742C20656E696D2E2043757261626974757220636F6D6D6F646F2C206C696265726F20696E20657569736D6F642073757363697069742C2073656D207075727573206672696E67696C6C6120656E696D2C206163206D6F6C657374696520746F72746F72206F7263692065742076656C69742E20446F6E656320706564652E20457469616D20706C61636572617420636F6E64696D656E74756D207475727069732E2050686173656C6C7573206567657374617320656E696D206E6563206D61676E612E20566976616D757320636F6E64696D656E74756D2C206E756C6C612076656C206C7563747573207472697374697175652C2065726F7320726973757320766573746962756C756D206E756C6C612C20696E207665686963756C61206172637520697073756D2061742066656C69732E20446F6E656320616C697175616D20656C69742061742061756775652E205175697371756520612065726F73206575206C6967756C6120616363756D73616E2064696374756D2E20457469616D207665686963756C61207475727069732071756973206C696265726F2E20416C697175616D206E6F6E206D692E20446F6E6563206574206C656F2E2050726F696E206C656F206C696265726F2C20616C697175616D2074696E636964756E742C20636F6E677565206E65632C2061646970697363696E6720706F7274612C20656E696D2E204E756C6C61206C6F626F727469732C20746F72746F722073697420616D657420696D7065726469657420756C6C616D636F727065722C20646F6C6F72206F726369206D616C65737561646120706564652C207365642067726176696461206E6962682075726E612076656C206C6F72656D2E20536564207068617265747261206D616C6573756164612065726F732E205175697371756520657569736D6F6420616C697175657420657261742E2053757370656E646973736520616C6971756574206D61747469732070757275732E0A0A4E756E63206964206E756C6C612071756973206A7573746F20636F6E67756520736F6C6C696369747564696E2E205072616573656E742065726174207475727069732C2072686F6E6375732065752C207072657469756D2065752C2070656C6C656E74657371756520612C206E6962682E20566976616D75732074656D7075732E2043726173206E65632072697375732061742074757270697320696D70657264696574206C6F626F727469732E205574206D61747469732E204D616563656E6173206573742066656C69732C2070656C6C656E746573717565206E6F6E2C20696D70657264696574207365642C20656C656966656E642074696E636964756E742C206C6F72656D2E20496E2074696E636964756E742E205365642076656C206C656F2E20446F6E65632065742075726E6120696E207475727069732068656E64726572697420626C616E6469742E20446F6E656320636F6E64696D656E74756D20616363756D73616E206573742E2055742070686172657472612C206D65747573207669746165206D617474697320636F6E7365637465747565722C206C656F207175616D2076756C707574617465206F64696F2C206E6563206C616F72656574206E6973692076656C697420657520657261742E20496E7465676572206C65637475732061756775652C206567657374617320696E2C20696E74657264756D2065752C2076656E656E617469732076656C2C2073617069656E2E2051756973717565206574206573742076697461652065726F73206C616F72656574206C6F626F727469732E204E756C6C616D207574207269737573206E6F6E206E756C6C6120706C6163657261742061646970697363696E672E205072616573656E7420646170696275732E20457469616D20612066656C69732E20557420736F64616C657320636F6E736571756174206D61757269732E2044756973206C6F72656D2066656C69732C206C756374757320612C2074726973746971756520696E2C206D6F6C65737469652061742C2072697375732E20536564207665686963756C6120626962656E64756D2074656C6C75732E204E616D20636F6E73657175617420657569736D6F64206C616375732E0A0A41656E65616E20746F72746F7220656C69742C2067726176696461206E65632C206665726D656E74756D2065752C206C6F626F727469732069642C20697073756D2E204D616563656E61732065752070757275732E204372617320616320747572706973207574206E69736920696163756C69732072686F6E6375732E204E756C6C61207075727573206D657475732C206469676E697373696D206E65632C2074696E636964756E742076697461652C20646170696275732065752C206E6962682E204675736365206C6F626F727469732C206E756E63206174207669766572726120656C656966656E642C206A7573746F20747572706973207363656C657269737175652065726F732C2061632070656C6C656E746573717565206D65747573206E69736C2061742070757275732E2053656420656C656D656E74756D2074656C6C75732073656420656E696D20696E74657264756D20626C616E6469742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E746567657220756C7472696369657320616C6971756574206F64696F2E204D61757269732065676574206E756E63206120697073756D20756C74726963657320736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2041656E65616E20616363756D73616E2E20446F6E65632073617069656E206C65637475732C20636F6E6775652061742C20706F7274612069642C2068656E6472657269742076697461652C206E69736C2E204375726162697475722076656C207175616D2076656C206E6571756520616363756D73616E206C616F726565742E204D6F7262692073617069656E206573742C207072657469756D20696E2C20636F6E7365637465747565722061632C206D6F6C6C69732075742C206C696265726F2E20446F6E65632074696E636964756E742061646970697363696E67206D657475732E204E756E6320766573746962756C756D20656765737461732061756775652E20446F6E6563207363656C65726973717565206475692075742073656D2E2053757370656E64697373652076656C206D6574757320696420657374206D6F6C657374696520696163756C69732E0A0A566976616D75732070686172657472612C20656C6974206575206D616C65737561646120626C616E6469742C206469616D20746F72746F72206D6F6C6C6973206475692C207365642070756C76696E6172206D61737361206E756E63206574206D61676E612E2053656420706C61636572617420656C697420617563746F7220746F72746F722E204E756C6C6120616320657261742E2050656C6C656E74657371756520636F6E7365637465747565722C2064756920636F6E76616C6C69732074696E636964756E7420636F6E64696D656E74756D2C2073656D206F64696F20766F6C7574706174206C696265726F2C206E6F6E20656C656D656E74756D2066656C6973206E65717565206E6563206F64696F2E204D616563656E61732068656E6472657269742065726F73206964206469616D2E204D61757269732076656C207075727573206163206F72636920636F6E76616C6C697320636F6E76616C6C69732E205365642073697420616D6574206C616375732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652064696374756D20766172697573206C616375732E204D61757269732065676574206E69736C2E2053757370656E646973736520706C6163657261742C206E756C6C61206E6F6E206F726E617265206469676E697373696D2C206E69736C206469616D2073616769747469732074656C6C75732C20696E2073656D706572206E69736920646F6C6F72206174206E6962682E204475697320756C6C616D636F7270657220766976657272612066656C69732E20496E746567657220612074656C6C75732E2053757370656E64697373652065676574206E756E632E2041656E65616E206469616D206573742C20616363756D73616E2069642C20737573636970697420696E74657264756D2C206672696E67696C6C612076697461652C206A7573746F2E2050726F696E20706564652E204D616563656E6173206174206E6571756520696E206E6571756520766573746962756C756D20656C656966656E642E0A0A566573746962756C756D206E756C6C61206C6F72656D2C20706F72747469746F7220656765742C20657569736D6F642061632C20616C697175616D2061742C206E69736C2E204D616563656E6173206574206573742065676574206D6173736120766172697573206C6F626F727469732E20496E206D692E204475697320706F72747469746F72206665726D656E74756D2070757275732E20446F6E65632063757273757320696D70657264696574206C6967756C612E204D6F726269206574206C6967756C6120657420616E7465206D6F6C6573746965207665686963756C612E204D61757269732073656420646F6C6F722E2053656420696D706572646965742066656C69732075742073656D2E20536564207669746165206E6571756520656C656D656E74756D206C656F20617563746F72206665726D656E74756D2E2044756973206665756769617420756C6C616D636F7270657220657261742E2041656E65616E2070757275732E204D6F726269206665726D656E74756D20766573746962756C756D206573742E2050656C6C656E7465737175652076656E656E61746973206D61757269732E2050686173656C6C75732070756C76696E61722E20496E746567657220697073756D206C65637475732C20696163756C697320612C206C6163696E69612069642C20616363756D73616E2069642C20617263752E2050686173656C6C7573206174206573742E204675736365206E65717565207175616D2C20756C747269636965732069642C20696163756C69732076656C2C20646170696275732076697461652C206C616375732E20496E206C6F626F7274697320636F6E76616C6C697320616E74652E204E756C6C61206E756E632070757275732C2076756C70757461746520696E2C2068656E6472657269742065742C20626C616E6469742065742C206C6967756C612E0A0A50656C6C656E746573717565206C656F206D657475732C20736167697474697320696E2C206D6F6C65737469652076697461652C2064696374756D20696E2C20706564652E204D6F726269207072657469756D2066656C6973206E6563207175616D2E2050656C6C656E746573717565206D617474697320616E746520736564207175616D20736167697474697320646170696275732E2053757370656E64697373652073617069656E2E205072616573656E7420626962656E64756D20696163756C697320746F72746F722E20447569732061206E69736C2E2041656E65616E206D692E20446F6E65632064696374756D206172637520696E206573742E204D6F72626920696E74657264756D2076756C70757461746520697073756D2E2041656E65616E2073697420616D6574206D61676E61206E6F6E206E69736C2074726973746971756520706F73756572652E2050686173656C6C75732076656C6974206D657475732C2074656D706F722061632C206665726D656E74756D20656765742C20636F6E64696D656E74756D206E6F6E2C2076656C69742E20566573746962756C756D2073697420706F73756572652E0A0A4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204372617320616C6971756574206D61737361206E6563206475692E20437261732061726375206E756E632C2068656E6472657269742061632C20656C656966656E642065752C20756C6C616D636F72706572206E65632C2074656C6C75732E205365642070686172657472612070757275732073697420616D6574207175616D2E20437572616269747572206D6F6C6C69732E204E616D20766974616520706564652E20457469616D207269737573206D617373612C207665686963756C612073697420616D65742C207068617265747261206E65632C20736F6C6C696369747564696E2075742C206475692E20446F6E65632065676573746173206A7573746F206174207175616D2E2050726F696E206E69736C2072697375732C20766573746962756C756D206E65632C207072657469756D2076697461652C207472697374697175652061632C206C6F72656D2E20416C697175616D206572617420766F6C75747061742E204372617320736564206E6962682E2050656C6C656E74657371756520736F6C6C696369747564696E20657569736D6F642061756775652E0A0A457469616D206672696E67696C6C6120736F6C6C696369747564696E206F7263692E204D61757269732063757273757320656C69742071756973206C616375732E204372617320746F72746F722E20496E2061646970697363696E672C206C656374757320696420617563746F7220766573746962756C756D2C206E65717565207065646520616363756D73616E20646F6C6F722C206E6F6E20696D70657264696574206D61676E61206469616D20616363756D73616E2076656C69742E2053757370656E6469737365206174206C696265726F207574206E69736920626C616E6469742073616769747469732E2050686173656C6C7573206E6F6E206D61757269732E20467573636520656C656D656E74756D2073616769747469732073656D2E2053757370656E646973736520616C697175616D20656C656966656E642074656C6C75732E2050726F696E206C6967756C61206C6F72656D2C20696D7065726469657420717569732C2076656E656E617469732069642C20696163756C6973206D6F6C6C69732C206E69736C2E20457469616D20636F6E76616C6C69732070656465206174206D617373612E204D6F72626920616363756D73616E20647569206574206D61757269732E0A0A53656420736564206F7263692E204E756E632070757275732E2053757370656E646973736520706F74656E74692E205574206C7563747573206672696E67696C6C61206D61757269732E20446F6E6563206E6962682E2050686173656C6C757320706F7274612E2050686173656C6C75732073697420616D6574206F64696F20736564206D61676E6120736F64616C65732070686172657472612E2043726173206C65637475732E2053757370656E6469737365206C696265726F20697073756D2C20636F6D6D6F646F206E65632C20666163696C6973697320696E2C207375736369706974206C6F626F727469732C206C6967756C612E2044756973206D61737361206E756C6C612C2073656D7065722065742C20636F6E736571756174206E65632C2070686172657472612065752C20656C69742E20566976616D757320756C7472696369657320616C697175616D206F64696F2E20566573746962756C756D2073697420616D6574206D617373612E2053656420636F6E736571756174206C61637573207365642075726E612E20457469616D2066617563696275732066656C69732076656C206F7263692E2050686173656C6C757320756C6C616D636F727065722E2041656E65616E20636F6E736563746574756572206C61637573206174206C696265726F2E0A0A436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204475697320666163696C697369732C206C6967756C6120766974616520636F6E64696D656E74756D207363656C657269737175652C2076656C6974206F72636920677261766964612066656C69732C2076656C20756C74726963696573207175616D206D69206E6F6E206469616D2E20566976616D757320617563746F72206D65747573206E6F6E206C696265726F2E205072616573656E74206C6967756C61206E6973692C20636F6D6D6F646F20636F6E64696D656E74756D2C206D6F6C65737469652065742C20766976657272612065742C206A7573746F2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320736F6C6C696369747564696E2E204E756E6320626C616E6469742063757273757320697073756D2E2041656E65616E206E6563206C6967756C612075742074656C6C757320736F64616C6573206D61747469732E20496E74656765722073656D2E20416C697175616D206964206C6967756C612E2053656420746F72746F72206D61757269732C20626C616E6469742076697461652C206375727375732076656C2C20656C656D656E74756D2065742C206E756C6C612E20416C697175616D207363656C65726973717565206D65747573206574206E69736C2E20447569732061646970697363696E67206D61676E61206174206E657175652E20517569737175652076756C70757461746520656C656966656E64206E756E632E20416C697175616D206567657420656C69742E2050686173656C6C757320647569206F64696F2C20626962656E64756D2073616769747469732C20766573746962756C756D2069642C206469676E697373696D20696D706572646965742C206F7263692E204E756C6C616D2065752066656C6973206E6F6E206E756E63206C6163696E696120736F64616C65732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A53757370656E64697373652070656C6C656E7465737175652C206C696265726F206D617474697320756C7472696369657320616363756D73616E2C20746F72746F7220746F72746F72206D616C6573756164612073656D2C20657420736F64616C6573206C696265726F206F64696F20616320697073756D2E20566976616D75732071756973206D61676E61206E656320657374207375736369706974206C6F626F727469732E20437261732074656D70757320706F7375657265206E756E632E205175697371756520757420656E696D20612066656C697320656765737461732073656D7065722E20536564207068617265747261206D6174746973206E657175652E20467573636520747572706973206E756E632C20636F6E677565207365642C20636F6E736571756174206E6F6E2C20636F6E677565207365642C206E756C6C612E2053757370656E646973736520766172697573206C6F72656D20696420726973757320706F72746120766573746962756C756D2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204675736365207365642070757275732E20496E20612066656C69732E20496E7465676572206567657374617320617563746F72206F7263692E204D617572697320756C747269636573207375736369706974206E69736C2E204E756C6C616D2070757275732E0A0A437261732074656D706F722061646970697363696E6720697073756D2E2055742071756973206D692E204D616563656E617320696E206A7573746F207574206E756C6C6120636F6E6775652070686172657472612E2050656C6C656E746573717565207574206C696265726F20657520646F6C6F722076656E656E617469732073757363697069742E205072616573656E74206665756769617420636F6E736563746574756572206E6962682E204D6F7262692066617563696275732073656D206E6F6E2066656C69732E20496E2068656E6472657269742061726375206163206D617373612E20496E20616363756D73616E20756C747269636573206D692E2050726F696E206D616C65737561646120617563746F722066656C69732E2043757261626974757220696E74657264756D2E20536564206469616D20697073756D2C20756C7472696369657320696E2C2074656D706F722073697420616D65742C207669766572726120696D706572646965742C20656C69742E204D6F726269206D6F6C6573746965206E6973692E204D617572697320697073756D2E2046757363652064696374756D206D6F6C6C6973206D61676E612E204475697320636F6D6D6F646F206469676E697373696D206E756C6C612E20566573746962756C756D20617567756520656E696D2C20756C7472696369657320717569732C20696163756C6973206E65632C2074696E636964756E742076697461652C206469616D2E204D6175726973206C6163696E69612074656D70757320697073756D2E20536564206174206D61757269732E205574206C6F72656D2E20446F6E6563206C696265726F2E0A0A4475697320696163756C6973206C6163696E6961206C65637475732E2041656E65616E20636F6E76616C6C69732065726F7320616320616E74652E205365642071756973206F726369206E656320726973757320617563746F72206672696E67696C6C612E2050686173656C6C757320666163696C6973697320656C656D656E74756D206E6973692E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E6320706F727461206C61637573206E656320616E74652E204D6F726269206D617572697320657261742C2061646970697363696E6720696E2C2070756C76696E6172206E65632C206C6F626F72746973206E65632C206F64696F2E20557420656C656966656E64206C656374757320736564207175616D2E204E756C6C616D206D6F6C6C69732E20496E206E6F6E20747572706973206574206E69736C2068656E64726572697420626C616E6469742E204475697320656C656D656E74756D2E204E756E63206E6563206C696265726F2E2053757370656E646973736520766573746962756C756D207269737573206E6F6E20706564652E204D6F72626920696D70657264696574206F64696F2073697420616D6574206C696265726F2E2053656420736564206D6173736120766974616520697073756D206D61747469732074696E636964756E742E204E756C6C61206E656320746F72746F72207669746165206C696265726F20766F6C75747061742074656D7075732E20446F6E656320616C697175616D2E0A0A4475697320736564206E756E632E2043757261626974757220747572706973206E756C6C612C207665686963756C61207365642C206C756374757320717569732C20656C656D656E74756D20656765742C2066656C69732E204D616563656E61732065742070757275732E204D616563656E6173206C656F2074656C6C75732C2074696E636964756E7420612C20666163696C697369732076697461652C206C6F626F727469732073697420616D65742C2076656C69742E20446F6E656320636F6E76616C6C69732073617069656E2E204D616563656E6173206D6F6C6C6973206F64696F206575206E6962682E20457469616D20677261766964612E20496E7465676572206D6F6C65737469652C2073617069656E206575206D6F6C6573746965206C6163696E69612C206E756E63206E69626820616C697175616D206C6967756C612C2065752073616769747469732074656C6C7573206572617420736F6C6C696369747564696E206F64696F2E20447569732065742072697375732E2050686173656C6C7573206E697369206E657175652C20706C616365726174206E65632C20636F6E64696D656E74756D206E6F6E2C20756C7472696365732065752C2073656D2E20557420706564652E20457469616D206E756C6C61206D657475732C20766F6C75747061742069642C20636F6E76616C6C6973207365642C2073757363697069742076656C2C2075726E612E20446F6E65632076656C20656C69742E205574206C656F206E657175652C2076656E656E617469732066617563696275732C206C6163696E6961206E65632C2074696E636964756E742065752C20656E696D2E2043726173206964206475692061206C696265726F207068617265747261206469676E697373696D2E20446F6E65632065726F73206C656F2C20706F72746120717569732C206C616F726565742075742C2070656C6C656E74657371756520766F6C75747061742C206C65637475732E0A0A4E756C6C616D20626C616E6469742E20416C697175616D206572617420766F6C75747061742E2046757363652061646970697363696E6720656E696D2E2053757370656E6469737365206E6F6E206475692071756973206C6967756C6120706F72746120766573746962756C756D2E20446F6E65632065752074656C6C75732076656C206C6F72656D207072657469756D20706F72747469746F722E205072616573656E74206C75637475732E20416C697175616D2061632065726F7320696E206D6173736120646170696275732074696E636964756E742E20446F6E6563207574206D61676E612E20457469616D20617563746F72206C616375732073697420616D6574206C616375732E2053656420756C7472696369657320697073756D206E656320656C69742E205175697371756520612065737420696E207075727573207375736369706974207472697374697175652E0A0A41656E65616E20736564206475692076656C20646F6C6F722070756C76696E6172206C616F726565742E20566976616D7573207665686963756C61206C6F72656D20696E20706564652E20566976616D7573206574206469616D2E20496E7465676572206163206F64696F2076656C206469616D2068656E64726572697420626962656E64756D2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E756C6C612061206E6973692E2050686173656C6C75732074696E636964756E74206475692076697461652061756775652E20447569732066617563696275732C2064756920696E74657264756D206672696E67696C6C612074696E636964756E742C206F64696F20656C697420766573746962756C756D206C696265726F2C206163206D6F6C6573746965206D61676E61206C6563747573206964206C616375732E2041656E65616E206C6967756C612E204E756C6C6120666163696C6973692E0A0A46757363652076656C2073656D2065752076656C6974206672696E67696C6C61206F726E6172652E2053656420666575676961742074696E636964756E742066656C69732E204E756C6C616D2066656C6973206D692C20657569736D6F642073697420616D65742C206D6F6C6C69732061742C20736F64616C657320656765742C2061756775652E204E616D20696D70657264696574206E6962682061742076656C69742E2053656420757420657261742E20496E206475692E204E756C6C6120666163696C6973692E204E756C6C616D206175677565206C696265726F2C2074696E636964756E74206E65632C207072657469756D2065752C2070756C76696E617220696E2C206475692E204D6F7262692076697461652066656C69732E2050656C6C656E7465737175652076656C206A7573746F2076656C2076656C6974207361676974746973206D616C6573756164612E2050726F696E207665686963756C6120626C616E646974206D617373612E20457469616D2074696E636964756E742070686172657472612075726E612E20496E206D65747573206573742C20617563746F72206E65632C20626C616E64697420612C20637572737573206E65632C207175616D2E204D6175726973206163206D657475732061206C696265726F20636F6E6775652066617563696275732E204D6175726973206D617572697320646F6C6F722C20736F64616C657320696E2C206375727375732075742C20736F64616C65732072757472756D2C2065726F732E2051756973717565206D61757269732065726F732C2073616769747469732076697461652C206C6F626F727469732075742C20656C656966656E642069642C206E6973692E0A0A41656E65616E206E657175652E20566573746962756C756D20656765737461732070656C6C656E746573717565206C6967756C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2050686173656C6C7573207361676974746973206A7573746F2076656C2072697375732E20536564207072657469756D206E657175652076697461652075726E612E2050656C6C656E74657371756520636F6E677565206C696265726F206964206C6F72656D2E204D6175726973206C656F206C6F72656D2C20626C616E6469742073697420616D65742C20636F6E76616C6C697320717569732C20636F6E736563746574756572207365642C2065726F732E204D61757269732074696E636964756E742C20656E696D2061206772617669646120657569736D6F642C206D61676E61206E756C6C61206665726D656E74756D206C696265726F2C207669766572726120656765737461732076656C6974207175616D20657420746F72746F722E20566976616D757320616C6971756574206D61737361207669746165206A7573746F2E204E756C6C6120636F6E677565206C6163757320616320656C69742E0A0A50686173656C6C757320636F6D6D6F646F207175616D2076656C206C6967756C612E2050726F696E206E6F6E206D657475732061742065726F732070756C76696E6172206C75637475732E204D6175726973206469616D206C6F72656D2C20706F737565726520717569732C20677261766964612065742C2074696E636964756E74206E65632C206C6967756C612E20536564206469616D2E20416C697175616D20656C6974206C65637475732C2068656E6472657269742075742C20696D706572646965742073697420616D65742C207072657469756D2073697420616D65742C20697073756D2E204D6175726973207665686963756C61206E69736C20696E206475692E204375726162697475722065676574207175616D207574206D61676E6120656C656D656E74756D206665726D656E74756D2E204D6175726973207363656C657269737175652E2051756973717565206C616F726565742E20457469616D2074656D707573207475727069732E2050656C6C656E746573717565206175677565207175616D2C2068656E647265726974207365642C2074696E636964756E742061742C2070686172657472612061742C206E69736C2E20416C697175616D206C616375732E2053757370656E646973736520706F74656E74692E2041656E65616E2076656C6974206C696265726F2C20756C74726963657320696E2C206C6163696E69612065752C206C75637475732076656C2C20616E74652E20457469616D2064696374756D206D6920696E2066656C69732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20467573636520677261766964612064617069627573206E69736C2E2043726173207669746165206E69736C2E0A0A4D616563656E6173206469676E697373696D2C206C6967756C61206E6F6E20706F727461206375727375732C20656E696D206E756E63206D616C6573756164612073656D2C20657520706F72747469746F72206E756C6C612075726E61206575207175616D2E2046757363652065726F732E20416C697175616D2065726F732E204E616D20617563746F722E204E756C6C61206D6F6C657374696520706F727461206573742E2053757370656E646973736520706F74656E74692E20566976616D7573206D6F6C6573746965206C6F72656D2073656420657261742E20536564206567657420697073756D2E20496E746567657220616C697175616D2070756C76696E6172206E756C6C612E204372617320616C69717565742073656D207574206E756E632E2046757363652066617563696275732074656D707573206C65637475732E204372617320736F64616C65732C206E69736920616320666163696C6973697320756C7472696365732C2065726F73206172637520646170696275732073617069656E2C20657420756C747269636573206D61757269732074656C6C7573206E6F6E20646F6C6F722E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20437261732063757273757320766172697573206D657475732E205574207475727069732E20566976616D7573206567657420746F72746F722E0A0A536564206C616F726565742C2076656C6974206E6F6E20616363756D73616E206375727375732C206E756E632075726E6120706F7375657265206A7573746F2C20696E2064696374756D206C6563747573207065646520696420616E74652E20437261732076756C7075746174652E204372617320636F6E677565206475692073656420656C69742E2050726F696E206C616375732073656D2C20756C7472696365732061742C20636F6E73657175617420696E2C2074656D706F7220717569732C206D657475732E2050726F696E2076656C20617263752E204E616D20657569736D6F642068656E64726572697420656C69742E20557420657261742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2053656420706F73756572652E204D6F7262692065726F732075726E612C2073656D7065722061742C2073656D706572206E6F6E2C20636F6E76616C6C697320717569732C2076656C69742E204D616563656E6173206F7263692E20566573746962756C756D206C6F626F7274697320747269737469717565206D657475732E20566573746962756C756D206C6F72656D206E756C6C612C20736F6C6C696369747564696E2076697461652C20636F6E64696D656E74756D20717569732C20617563746F722075742C206475692E20566976616D757320766573746962756C756D206D61676E61207574206E6973692E2043757261626974757220656C656966656E64206475692076656C206E756E632E20437572616269747572206D6175726973206C616375732C206D616C6573756164612073697420616D65742C207375736369706974207365642C2072757472756D206C75637475732C2074656C6C75732E20496E746567657220666163696C697369732075726E61207669746165206C65637475732E0A0A41656E65616E207175616D206C656F2C206C6F626F7274697320717569732C206D616C6573756164612065752C2076756C7075746174652076697461652C206E69736C2E205072616573656E7420656765742065726F732E205574206665726D656E74756D20747572706973206964207175616D2E204E616D20746F72746F722E205072616573656E74206E6563206F7263692E204E756C6C6120626962656E64756D2061646970697363696E672061756775652E20557420636F6D6D6F646F2C206D61676E61206964206D616C65737561646120677261766964612C206175677565206F64696F206D616C657375616461206D692C20706F727461206D616C65737561646120656C697420657374207669746165206469616D2E204D6175726973206E6F6E206E756C6C612E2053757370656E64697373652074696E636964756E742C206E756E6320756C7472696369657320706F7274612076656E656E617469732C206D6920706564652074696E636964756E74206C696265726F2C20656765742076617269757320616E7465206C696265726F207574206C6967756C612E20437572616269747572207072657469756D20706F72747469746F7220746F72746F722E0A0A4D616563656E617320766974616520656C69742065676574206E69736920646170696275732064696374756D2E204E756E6320696E206C696265726F2E204E756C6C612064696374756D206F726369206575206572617420617563746F72206C6F626F727469732E2050686173656C6C75732072697375732E2053757370656E646973736520706F74656E74692E2053757370656E646973736520706F74656E74692E205072616573656E742061646970697363696E6720636F6E73657175617420656C69742E20496E74656765722069642061756775652E205072616573656E7420696E206A7573746F206E6563206D61676E6120646170696275732070756C76696E61722E2044756973206E69736C2E2053757370656E6469737365206163206F64696F2E20566976616D757320696D706572646965742E20446F6E6563206E6F6E2076656C69742073697420616D6574207269737573206469676E697373696D20636F6E6775652E204E616D20616C697175657420706F73756572652076656C69742E2043726173207475727069732E204D6F726269206D616C657375616461206469676E697373696D206D692E0A0A536564206C656F206E657175652C2076617269757320717569732C2076656E656E61746973207365642C207068617265747261207365642C206573742E204D6F72626920626C616E6469742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D2073656D7065722070656C6C656E746573717565206D692E2055742076656C206C6F72656D2E204E756E63206D6920746F72746F722C206C616F726565742061742C2066617563696275732065752C2074696E636964756E742073697420616D65742C20657261742E20447569732074656D706F72206D616C65737561646120697073756D2E2050686173656C6C757320616C69717565742E20446F6E656320657420656C69742E2050656C6C656E7465737175652070757275732E20566573746962756C756D2072757472756D2073656D706572206E6962682E204E756C6C6120666163696C6973692E2050686173656C6C757320657420656E696D2073697420616D657420616E746520766573746962756C756D207665686963756C612E2050686173656C6C7573206964206E69736C2E20446F6E6563206D6F6C6C6973206C656F2061742065726F732E204D61757269732070656C6C656E746573717565206E657175652061742070757275732E204D6F726269207175697320646F6C6F7220617420697073756D207363656C6572697371756520736F64616C65732E20457469616D20766F6C7574706174207475727069732061206D657475732E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206C6F72656D206C6F72656D2C20766573746962756C756D2061632C20657569736D6F6420656765742C20756C6C616D636F72706572206469676E697373696D2C2076656C69742E0A0A43756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204372617320756C7472696365732C206E6962682076656C20616C697175616D20766573746962756C756D2C2065726F7320656E696D2076656E656E61746973206475692C20696420696163756C697320656E696D206E756E632076656C206D617373612E204D6F72626920656C656966656E64206F726369206574206D617373612E20416C697175616D206572617420766F6C75747061742E204E756C6C61206D6F6C6C69732065676573746173207475727069732E20496E20736F64616C6573206E756E63206567657420746F72746F722E2053656420697073756D2065726F732C2074656D706F7220717569732C20616C69717565742076697461652C20696D70657264696574206E6F6E2C206C6F72656D2E2050656C6C656E746573717565207175697320656C6974206964206D69206C756374757320646170696275732E20536564206E756E6320617263752C2072686F6E637573206E65632C20636F6E76616C6C697320717569732C206375727375732061742C206E657175652E204D617572697320636F6E76616C6C697320707572757320617420657261742E2050656C6C656E74657371756520766573746962756C756D2E20566976616D7573206672696E67696C6C6120656C697420617420617263752E204E756C6C616D20616C697175657420656E696D206E656320617263752E204E616D20696420746F72746F722E204E756C6C612071756973206E756E632E20557420617263752E2053757370656E646973736520706F74656E74692E2050656C6C656E74657371756520756C6C616D636F72706572206C6967756C6120696420617263752E0A0A4E616D206E6F6E206C696265726F207669746165206E69736C207363656C65726973717565206672696E67696C6C612E20517569737175652076617269757320616E7465206964206D657475732072686F6E637573206672696E67696C6C612E204E756C6C6120666163696C6973692E205072616573656E7420656C656966656E6420706F72747469746F72206C6967756C612E20457469616D207175697320646F6C6F72206E6F6E20617567756520636F6D6D6F646F20617563746F722E20446F6E65632061206D692E20566573746962756C756D2074656D706F722E20446F6E65632066656C69732075726E612C20617563746F722061742C206375727375732064696374756D2C20677261766964612069642C20617263752E2041656E65616E2064696374756D206D616C65737561646120646F6C6F722E20566976616D7573206D61747469732E2050686173656C6C757320657520706564652E2046757363652061646970697363696E67206A7573746F206672696E67696C6C61206D657475732E20457469616D20616E74652E20496E7465676572206D6F6C6C6973206D617373612071756973206E756E632E20496E74656765722064696374756D206E65717565206C756374757320656E696D2E0A0A536564206575206C696265726F2E20496E74656765722074656D706F72206C6967756C6120696E2076656C69742E2055742074696E636964756E74206C6163696E69612073656D2E204E756C6C616D2076656C2072697375732E2053656420736F64616C657320616E7465206120646F6C6F722E204375726162697475722065726F732E2053656420736F64616C65732E20536564206E6F6E206D657475732E20566573746962756C756D20656C656D656E74756D20666175636962757320616E74652E204E756C6C612076656C206E6962682E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206E6563206C6F72656D20757420697073756D206C6163696E696120696163756C69732E204475697320657261742E20416C697175616D20657261742E204372617320696163756C69732E20496E206861632068616269746173736520706C617465612064696374756D73742E0A0A4E756C6C616D20616E74652E2043726173207669746165206573742E2050656C6C656E7465737175652076656C206D657475732061206C6967756C612064617069627573206D61747469732E2044756973206665756769617420616C69717565742066656C69732E20457469616D206964206E69736C207175697320657374206469676E697373696D20636F6E64696D656E74756D2E2053757370656E646973736520706F74656E74692E204D6F7262692076656C6974206C6F72656D2C206F726E61726520717569732C2070656C6C656E7465737175652076656C2C20706C61636572617420656765742C20746F72746F722E20566573746962756C756D2074696E636964756E74206D6F6C6573746965206C696265726F2E204E756C6C61206E756C6C6120656E696D2C206D616C6573756164612069642C20756C6C616D636F727065722076697461652C2064696374756D2061742C2070757275732E20446F6E6563206469676E697373696D206F64696F20757420656E696D2E2053757370656E6469737365206174206C65637475732E0A0A5072616573656E74206C6F626F727469732061756775652076656C206C65637475732E20557420696E206C6967756C612075742066656C697320636F6E6775652073757363697069742E2051756973717565206469676E697373696D20746F72746F72207574206D692E204675736365206D61676E61206E6973692C20656C656966656E642061632C206F726E6172652076656C2C20706F72747469746F722076697461652C207175616D2E20566573746962756C756D20736F64616C6573206A7573746F2071756973207475727069732E2046757363652075726E61206E6973692C2072686F6E63757320717569732C20636F6E64696D656E74756D2076656C2C2064696374756D2065752C206E756E632E20467573636520736564206E696268207669746165206F64696F20706F73756572652061646970697363696E672E2053656420706F72746120656C6974207175697320646F6C6F722E204E616D206C696265726F206E756C6C612C20617563746F72207365642C2074696E636964756E7420717569732C2066617563696275732073697420616D65742C206D692E2051756973717565206F7263692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E756C6C616D2069642073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632076656C2065726F732E0A0A566976616D7573206C7563747573206C6F626F72746973206C656F2E2053757370656E64697373652076656C20656C6974206120656E696D20756C6C616D636F7270657220706F73756572652E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20446F6E656320717569732070656465206D6174746973206C6563747573206D6F6C6C69732061646970697363696E672E2053656420616363756D73616E20706F737565726520657261742E205072616573656E7420657569736D6F642074696E636964756E742066656C69732E20446F6E6563206D692E20557420636F6D6D6F646F2061726375206C6163696E69612074656C6C75732E20416C697175616D2061206C696265726F2071756973206C65637475732073656D70657220766976657272612E20437572616269747572206C6163696E6961206D61757269732061742074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E756E632073697420616D6574206D61676E61206D6F6C6573746965206F726369207375736369706974206672696E67696C6C612E204675736365207072657469756D206D65747573206E6F6E2073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642068656E6472657269742E204E756C6C612066656C69732E2053757370656E646973736520706F74656E74692E20416C697175616D20626C616E64697420747269737469717565206E657175652E20437572616269747572207175697320657261742076656C206E756E6320616363756D73616E206D6F6C6C69732E0A0A447569732073616769747469732C2074656C6C757320757420616C697175616D206672696E67696C6C612C20646F6C6F72206D6920756C6C616D636F72706572206E69736C2C20757420747269737469717565207065646520656C697420736564206D61757269732E204375726162697475722069642066656C69732E20446F6E65632070756C76696E6172206C61637573206574206C65637475732E20416C697175616D2076756C7075746174652076756C707574617465206D657475732E20437572616269747572206D61676E612066656C69732C2061646970697363696E672061632C20616363756D73616E2076656C2C206D6F6C657374696520717569732C207175616D2E204D617572697320656C697420617263752C207072657469756D2076697461652C206D6F6C6C69732073697420616D65742C20736F6C6C696369747564696E2075742C206D692E20446F6E656320696D70657264696574206469676E697373696D206D692E204E756C6C616D2073697420616D657420746F72746F722E20416C697175616D206E65717565206E756C6C612C2076656E656E6174697320612C20706F72746120696E2C20706C6163657261742074656D7075732C206C616375732E205175697371756520766573746962756C756D20647569206574206C616375732E2050726F696E206469676E697373696D20636F6E7365637465747565722070757275732E20457469616D206772617669646120746F72746F7220696E206E756E632E2055742074656D706F722074726973746971756520746F72746F722E20536564206C616F726565742074696E636964756E74207175616D2E20566573746962756C756D20706F7274612074757270697320757420656C69742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20446F6E6563206E696268206475692C2066657567696174206E65632C206C616F726565742069642C206D616C65737561646120656765742C206E6973692E205574206E65717565206D617373612C207665686963756C612065752C20636F6D6D6F646F206E6F6E2C20756C747269636965732076697461652C2070757275732E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204D617572697320657569736D6F642C2066656C69732076656C2074656D706F7220616C69717565742C20746F72746F72206D6175726973206D616C657375616461206E756E632C2076656C206665726D656E74756D2073656D206469616D206964206475692E204E616D2072757472756D2073617069656E2065676574206F64696F2E20416C697175616D20736564206C696265726F206E6F6E206D692066617563696275732074656D7075732E2046757363652068656E6472657269742C206469616D206E6F6E20766F6C75747061742072757472756D2C2065726174206D657475732076656E656E61746973206C6967756C612C206E6F6E207363656C657269737175652070656465206C6967756C612076656C207175616D2E204D6F7262692072686F6E6375732065726F7320616320647569206665756769617420656C656D656E74756D2E2044756973206575206C696265726F2065742074656C6C757320636F6E67756520766976657272612E204D6F726269207175616D207175616D2C20656C656D656E74756D207365642C20756C6C616D636F7270657220696D706572646965742C20636F6D6D6F646F206E6F6E2C206F64696F2E204E616D20616C697175657420656765737461732075726E612E204D6175726973206F64696F2066656C69732C207661726975732065752C206C6163696E69612065752C20636F6E64696D656E74756D20612C206C65637475732E20536564206A7573746F206D617373612C2070756C76696E61722069642C2076617269757320612C20706F72747469746F72206E65632C206C696265726F2E20457469616D207661726975732E2043757261626974757220736F64616C65732C206F64696F20617420706F73756572652073656D7065722C2065726F73206E6962682074696E636964756E74206C65637475732C2076656C2072757472756D2073617069656E206E69736920696E206C6967756C612E2053757370656E6469737365206567657420617263752E2050686173656C6C757320696D70657264696574206573742061632073617069656E2E20446F6E6563206E756C6C6120746F72746F722C20706C6163657261742076656C2C2074656D70757320612C206C6F626F727469732076656C2C206E6962682E20416C697175616D20766172697573206E6973692E204E756C6C6120657420656E696D2E20467573636520636F6E76616C6C6973206C616F72656574206C616375732E0A0A50686173656C6C757320697073756D20646F6C6F722C206D6F6C657374696520717569732C20636F6E64696D656E74756D20696E2C20636F6D6D6F646F2065752C206469616D2E205175697371756520626962656E64756D206C6163696E6961206475692E204E756C6C616D20626C616E6469742076756C707574617465206F7263692E205574206C6163696E6961206D617373612076656C2061756775652E20416C697175616D20677261766964612C207175616D207175697320696D7065726469657420696D706572646965742C2074656C6C7573206469616D20706861726574726120657261742C206174207068617265747261206C61637573206E6962682065676573746173206D61676E612E204E756C6C61207361676974746973206C6F72656D207574206C6F72656D2E204475697320636F6E64696D656E74756D2C2064756920766974616520616C697175616D20706F73756572652C206469616D207175616D20636F6E76616C6C69732076656C69742C2075742067726176696461206C656F20697073756D206E6F6E2072697375732E205574206665726D656E74756D20736F6C6C696369747564696E20657261742E20446F6E6563207361676974746973207363656C657269737175652066656C69732E204E756E6320617263752E20457469616D2074656D7075732C206D61676E612073697420616D657420737573636970697420657569736D6F642C2065726F732073656D2072757472756D206475692C207669746165207361676974746973206E696268207075727573206E6F6E206C616375732E20536564206D6F6C6C69732061726375206567657420646F6C6F722E20446F6E6563206F726E6172652C20617263752073697420616D6574206665726D656E74756D2076756C7075746174652C20726973757320656E696D206665726D656E74756D206C696265726F2C2061206C6163696E696120646F6C6F72206D69206E6F6E2076656C69742E20457469616D206C6F626F72746973207075727573206120656C69742E204E756E63206E756C6C61206475692C206D617474697320717569732C20626962656E64756D20612C20756C7472696365732061632C2061756775652E20496E20616C697175616D207665686963756C61207475727069732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A496E7465676572206964206E69736C2E20517569737175652064696374756D20656C656D656E74756D206F64696F2E2041656E65616E206C75637475732E205365642065752073656D206120706564652076756C70757461746520636F6E64696D656E74756D2E2051756973717565206D61676E612E20446F6E656320616C697175616D206D617474697320697073756D2E204375726162697475722064696374756D20736F6C6C696369747564696E2073656D2E20416C697175616D2070756C76696E61722E204E756E6320736F6C6C696369747564696E207269737573206120657261742E20566976616D757320717569732074656C6C75732073697420616D6574206E69626820766573746962756C756D20636F6E7365717561742E204E756C6C61207072657469756D20736F6C6C696369747564696E20646F6C6F722E20416C697175616D20696163756C69732074696E636964756E74207475727069732E2050686173656C6C757320697073756D206C656F2C2076656E656E6174697320696E2C20736167697474697320696E2C206F726E6172652061742C206E756E632E0A0A50656C6C656E74657371756520756C7472696365732C2064756920657520696163756C6973206C75637475732C2074656C6C757320617567756520766F6C75747061742073617069656E2C20696E206469676E697373696D2075726E612066656C6973207574206D692E205365642061726375206475692C206469676E697373696D2069642C20706F72747469746F722075742C20696D706572646965742076697461652C20616E74652E204E756C6C61206475692073656D2C20636F6D6D6F646F206E65632C2073616769747469732065742C206C6163696E69612065742C20706564652E20457469616D20656C656966656E6420647569207574206E69736C2E20446F6E656320616E7465206D61757269732C2074656D7075732073697420616D65742C207661726975732076697461652C206772617669646120717569732C206D692E20496E207363656C657269737175652C2066656C697320766974616520766976657272612073616769747469732C2076656C6974206D6574757320756C74726963696573206E657175652C207175697320696D706572646965742076656C697420656C6974206574206D61676E612E2053757370656E646973736520706F74656E74692E205365642076656C69742065726F732C20657569736D6F64207365642C20636F6E64696D656E74756D206E65632C206661756369627573207365642C2073617069656E2E204E616D20616363756D73616E206C6967756C612073697420616D6574206E657175652E20416C697175616D206572617420766F6C75747061742E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E616D20657520706564652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642065752066656C69732073656420746F72746F722074656D706F72206665726D656E74756D2E2050686173656C6C757320636F6D6D6F646F2073656D2076656C206E69736C2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050726F696E206C656374757320656C69742C2070686172657472612073697420616D65742C20616363756D73616E207365642C2074696E636964756E742065742C206D61757269732E204475697320646170696275732070686172657472612073656D2E20496E746567657220696E206A7573746F2E205072616573656E742065726F732E20566573746962756C756D20616320616E74652E20416C697175616D207363656C657269737175652073656D2070656C6C656E746573717565206E69626820636F6E73656374657475657220736F64616C65732E20416C697175616D20636F6E736563746574756572206F64696F2E2044756973206C6563747573206F64696F2C206C75637475732065752C20636F6D6D6F646F20717569732C206D6F6C6C69732076697461652C2076656C69742E2043726173206E6563206E756E63206E6F6E20656C697420696163756C6973206D61747469732E2041656E65616E206A7573746F206E657175652C20736F6C6C696369747564696E20656765742C20756C6C616D636F7270657220656765742C20656765737461732069642C2073656D2E20496E2065752072697375732E2053656420656765737461732E0A0A496E7465676572206174206E657175652E20536564207072657469756D207363656C65726973717565206E756C6C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20467573636520757420706564652E20457469616D207669746165207175616D20612075726E612076617269757320696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2044756973207665686963756C612E20467573636520756C6C616D636F72706572206E696268206E6F6E20657261742E205175697371756520696E206E657175652E205072616573656E74206573742E2050656C6C656E74657371756520617263752E0A0A50726F696E20706F73756572652E2053757370656E646973736520706F74656E74692E20496E74656765722066656C6973206C616375732C20616C697175616D207365642C2076756C70757461746520696E2C206D6F6C6C69732076656C2C2074656C6C75732E20496E7465676572207665686963756C6120626962656E64756D206573742E204E756E63206E6F6E20646F6C6F7220696E2074656C6C7573206D617474697320666163696C697369732E20496E746567657220766573746962756C756D2C20617567756520617420636F6D6D6F646F20616C697175616D2C2064756920657374206D6174746973206C6967756C612C2073697420616D65742061646970697363696E67206F7263692073656D207669746165206D61676E612E205072616573656E7420656E696D2076656C69742C206D616C6573756164612061742C20636F6E677565206E65632C206C756374757320696E2C206A7573746F2E20536564207661726975732E204D6F7262692070686172657472612E20446F6E6563206575206D61737361206E65632074656C6C75732076756C7075746174652070756C76696E61722E20557420636F6D6D6F646F20747572706973206E6F6E2073656D2E20557420636F6E76616C6C697320756C6C616D636F727065722072697375732E20457469616D20696E74657264756D2070656465206964206E6973692E2043726173206D61676E612073617069656E2C20737573636970697420612C206C616F72656574206E6F6E2C2072686F6E6375732065742C2066656C69732E20496E7465676572206F726369206C6F72656D2C20766573746962756C756D2064696374756D2C20756C6C616D636F7270657220612C20706F72747469746F722065742C206475692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A4E756E63206574206D61676E612E2053656420626962656E64756D2074656C6C757320696E206469616D2E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E616D20766974616520746F72746F722E20496E7465676572206D61676E612E20447569732076656E656E617469732C206C656F2061632074656D706F72206C616F726565742C20656C6974206E756C6C6120706861726574726120706564652C206E6F6E206665726D656E74756D206E756E63206F64696F2061206F64696F2E2050726F696E206E6F6E2076656C69742E2053656420696D706572646965742061756775652071756973206E69736C2E20496E746567657220636F6E64696D656E74756D206E69736C206E6563206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20566976616D757320706C616365726174206C696265726F2E204475697320636F6E6775652064696374756D206D61676E612E20416C697175616D206461706962757320626962656E64756D20656E696D2E204E756E6320656C656966656E6420706564652076656C20697073756D2E0A0A457469616D2076697461652076656C69742E204D61757269732065726174206E756E632C206D616C6573756164612075742C20666575676961742061632C20706C61636572617420636F6E64696D656E74756D2C2061756775652E204E616D20766F6C75747061742E20416C697175616D207665686963756C6120697073756D206964206F64696F2E20566976616D757320736F6C6C696369747564696E207475727069732069642073617069656E2E20467573636520612066656C6973207669746165206F64696F20636F6E76616C6C697320626C616E6469742E204375726162697475722076697461652065726F732069642065726F7320706F727461207072657469756D2E204E756C6C6120696E206D61676E6120656765742075726E61206C6163696E696120636F6E76616C6C69732E20416C697175616D206D61747469732076656E656E617469732070757275732E2053656420736564206D69206567657420657261742074726973746971756520706F7274612E20446F6E656320617563746F7220646F6C6F72206120657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20496E206E6563206C6967756C612E204E756E6320656C656966656E642E20566573746962756C756D2071756973206E697369206567657420656C697420706F72747469746F7220636F6E6775652E204D616563656E61732066617563696275732C206D61676E6120656765742061646970697363696E672074696E636964756E742C20646F6C6F7220616E7465206D616C65737561646120656C69742C206E6F6E20656C656D656E74756D206C616375732074757270697320696E20706564652E0A0A5574206D616C657375616461206D69206E6563206D657475732E205072616573656E7420617563746F72206175677565206163206E69736C20756C7472696369657320666163696C697369732E204E616D2070757275732073617069656E2C2070656C6C656E746573717565206469676E697373696D2C20706F73756572652065752C206375727375732069642C206469616D2E205175697371756520736F6C6C696369747564696E2C20656C697420612070656C6C656E746573717565207363656C657269737175652C206C6F72656D20726973757320617563746F72207175616D2C207175697320636F6E7365717561742074656C6C7573206E657175652069642075726E612E2053757370656E6469737365206469616D20746F72746F722C20656C656966656E64206469676E697373696D2C20656765737461732075742C206C756374757320696E2C20616E74652E204475697320616E74652E204D616563656E6173206C75637475732E20437572616269747572206375727375732070686172657472612075726E612E204D616563656E617320696D706572646965742C2065726174206E6F6E20656C656D656E74756D20657569736D6F642C20746F72746F72206F64696F20657569736D6F64206C65637475732C20616320666163696C697369732073656D206E696268207669746165206E756C6C612E204E756E6320677261766964612E204D6F72626920736F6C6C696369747564696E206F64696F2071756973206C616375732E20416C697175616D2061206E696268206E6F6E2075726E6120706F72746120696D706572646965742E20416C697175616D206572617420766F6C75747061742E20496E20696163756C6973206C6163696E69612076656C69742E20536564206C696265726F206C616375732C207472697374697175652065752C206C6163696E69612061632C20616C697175657420656765742C2075726E612E0A0A457469616D206174206E69736C2E2050686173656C6C7573206661756369627573206C7563747573206C65637475732E20557420706C6163657261742076756C70757461746520646F6C6F722E2050686173656C6C75732076656C2076656C69742E204D6F72626920766976657272612E2050686173656C6C7573206F7263692E20496E7465676572206469676E697373696D206D6174746973206D61757269732E2050656C6C656E74657371756520706F7375657265206C656F20706F7375657265207175616D2E2051756973717565206E6563206D61676E61206174206469616D20766976657272612070656C6C656E7465737175652E2053757370656E64697373652076656C697420617263752C20756C7472696369657320717569732C20636F6E67756520612C2076656E656E6174697320656765742C206C616375732E20496E74656765722073616769747469732068656E64726572697420646F6C6F722E2046757363652074696E636964756E7420616E746520612073656D2E0A0A4D616563656E617320636F6E7365637465747565722C206A7573746F207365642072686F6E6375732076656E656E617469732C206E69626820617263752072757472756D20646F6C6F722C2073656420636F6E64696D656E74756D206C696265726F206C696265726F20657420697073756D2E20566976616D7573206D6174746973206A7573746F207574206C6F72656D2074696E636964756E74206C6F626F727469732E205574206E6F6E2076656C6974206964206E6571756520616C697175657420616363756D73616E2E205365642074656D7075732076697665727261206E756C6C612E2043757261626974757220756C6C616D636F727065722C206E6571756520717569732064617069627573207363656C657269737175652C2066656C6973206469616D2067726176696461206F7263692C206E6F6E20637572737573207175616D206E6571756520766974616520656C69742E20457469616D2070686172657472612074696E636964756E74206C616375732E204475697320657569736D6F64206672696E67696C6C61206573742E20457469616D206F726E6172652074696E636964756E74206C65637475732E2050726F696E20696E207475727069732E204E756E6320626C616E64697420626C616E646974207475727069732E2041656E65616E2075742061756775652E2044756973206F726369206A7573746F2C2074696E636964756E742065752C2072757472756D207365642C2072757472756D2065742C207475727069732E2043757261626974757220666163696C69736973206F64696F20696E20616E74652E20496E206861632068616269746173736520706C617465612064696374756D73742E205365642065726F73206573742C2070656C6C656E7465737175652061742C2074696E636964756E742065752C20756C74726963657320717569732C206D657475732E204D6F7262692073697420616D6574206A7573746F2E204D616563656E617320616320617263752E204D6175726973206469676E697373696D2E0A0A50656C6C656E74657371756520756C747269636965732072757472756D206F7263692E2041656E65616E206F726E6172652E20566976616D75732065752072697375732076656C206D6175726973206C6F626F727469732064696374756D2E205365642065742074757270697320617563746F72206D692072686F6E6375732070756C76696E61722E20536564206E6563206E756E6320612070757275732074656D706F7220766976657272612E2050656C6C656E7465737175652073757363697069742E20446F6E656320747269737469717565207269737573206E6F6E206E6962682E20457469616D206E69736C206D61676E612C20736F6C6C696369747564696E2075742C20756C7472696365732073697420616D65742C20656765737461732065752C206E756C6C612E20416C697175616D206572617420766F6C75747061742E20566573746962756C756D2070686172657472612E2053656420656765737461732C206D657475732073697420616D6574206C6F626F7274697320636F6E7365717561742C206572617420656C697420696D70657264696574206C696265726F2C20657520696E74657264756D207175616D206D61737361206567657420646F6C6F722E2053757370656E6469737365207669746165206F64696F2E2050726F696E20626C616E646974206D617572697320696163756C6973206D657475732E0A0A566976616D757320766573746962756C756D2E20457469616D206574206E69736C2E20416C697175616D20696E206469616D2076656C20656C697420706C6163657261742073757363697069742E204475697320736F64616C6573207075727573206163206E6962682E204E756C6C6120696E206F64696F206567657420656E696D206C756374757320626C616E6469742E2043757261626974757220756C74726963657320697073756D206E6F6E206E65717565206567657374617320656C656966656E642E20536564207475727069732E2050726F696E20636F6E7365637465747565722E20566976616D7573206D61747469732E20496E20616C69717565742E0A0A4E756E632069642065726F732E20446F6E65632076656E656E617469732C206E756C6C61206574206D6174746973206C75637475732C20616E7465206C656F2073656D706572206A7573746F2C206E6F6E2061646970697363696E67206F64696F20726973757320736564206C616375732E205072616573656E7420766974616520726973757320636F6E677565206C696265726F20636F6E6775652074656D7075732E2050686173656C6C75732061632065726F732E204E756C6C61207665686963756C612C206C6F72656D20696E20616C69717565742073757363697069742C2061726375206572617420656765737461732073656D2C2071756973206C6F626F72746973207175616D20616E7465206575206D617373612E20437572616269747572206E6F6E206D617373612E2053656420626962656E64756D206C6163696E6961206F64696F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20566976616D757320766F6C757470617420626C616E646974206C616375732E2050726F696E20706F7274612C2074656C6C757320757420617563746F72206C616F726565742C206C65637475732065726F73206665726D656E74756D206C65637475732C2069642073616769747469732061726375206A7573746F20696E207475727069732E2050686173656C6C757320636F6E7365717561742E204E616D2070656C6C656E7465737175652C206D69206964207669766572726120636F6E76616C6C69732C206E756E63206C696265726F20706C616365726174206C656F2C20656C656966656E6420706F7274612073656D206E69736C2076697461652073617069656E2E2050656C6C656E746573717565206C6967756C61206C696265726F2C20747269737469717565206E6F6E2C20706F72747469746F722072757472756D2C20706F72747469746F72206E6F6E2C20657261742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E74656765722064696374756D2074656C6C7573206120746F72746F722E20566976616D75732066656C6973206E756E632C206D6F6C6573746965206E6F6E2C2072686F6E63757320717569732C2070686172657472612069642C206475692E20446F6E6563207269737573206D657475732C206672696E67696C6C612076656C2C20616C69717565742065752C20706C6163657261742069642C206E657175652E0A0A53757370656E646973736520697073756D2E20566976616D7573206C65637475732E2053656420766976657272612C206D61737361206567657420636F6E76616C6C6973206D61747469732C207175616D2074757270697320636F6E736563746574756572206E756E632C206567657420706F7375657265206D61676E612073656D2069642076656C69742E20496E206E6563206D61757269732E2041656E65616E206120707572757320736564207175616D206C6F626F72746973206672696E67696C6C612E2050726F696E20756C74726963696573206C6163696E696120616E74652E205365642061646970697363696E67206572617420717569732076656C69742E204E756C6C616D207669746165206E69736C206964206A7573746F20736F6C6C696369747564696E206D6F6C65737469652E204E756C6C6120666163696C6973692E20536564206E65632075726E6120736564206E69736C206672696E67696C6C6120646170696275732E204E756C6C61206174206469616D2E20416C697175616D2065676574206E6962682E204E756E63206163206E6973692073697420616D65742074656C6C757320656765737461732074656D7075732E204E616D207363656C657269737175652075726E61206574206E657175652E20446F6E656320657374206F7263692C207361676974746973206E6F6E2C2076756C70757461746520612C20636F6D6D6F646F2065742C2061756775652E205574206461706962757320746F72746F722E205574206E756E632E20446F6E65632064696374756D2064617069627573206F64696F2E204E616D20756C7472696369657320756C6C616D636F72706572206C6967756C612E2050656C6C656E74657371756520616363756D73616E20766172697573206C656F2E0A0A4D6F72626920657569736D6F64206C616F7265657420657261742E20566976616D7573207175697320697073756D2E204D6F72626920657569736D6F642E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2053757370656E64697373652076656C2070757275732E204E756C6C616D206174206D61676E612E20437572616269747572206C61637573206C6F72656D2C20696163756C697320717569732C2064617069627573206E6F6E2C20766F6C75747061742076656C2C206E756C6C612E20446F6E656320757420617263752072686F6E63757320646F6C6F72207072657469756D2064696374756D2E204E756C6C616D2076656C206D657475732E20557420617263752E2050656C6C656E746573717565206E697369206E756E632C20706C61636572617420656765742C2074696E636964756E742076656C2C207068617265747261206E6F6E2C206E756E632E20496E74656765722074696E636964756E7420756C74726963696573206C65637475732E20496E74656765722073656D7065722C2070757275732073656420756C74726963657320666575676961742C206E756C6C61207065646520736F6C6C696369747564696E20657261742C2076656C20617563746F72206E756C6C6120697073756D2076656C206C65637475732E2041656E65616E206D692E0A0A4E756C6C616D20736564206E697369206574206172637520696D70657264696574206665726D656E74756D2E204D6175726973206E6563206D657475732E20496E20616320646F6C6F722E20496E206D6920617263752C20636F6E6775652061632C207068617265747261206E65632C207363656C657269737175652073697420616D65742C206D61676E612E20437572616269747572206C616375732E2043757261626974757220657420656C69742E20416C697175616D20756C6C616D636F72706572206E756E6320657520656C69742E2053656420636F6E76616C6C697320646F6C6F722061742076656C69742E20566573746962756C756D20646170696275732C20617567756520696420636F6E73656374657475657220706C6163657261742C206E756E63206D6173736120626C616E6469742073617069656E2C20696420616C697175616D20656C6974206E697369206964206D692E2050686173656C6C75732073617069656E206573742C20677261766964612065752C20626962656E64756D2075742C2061646970697363696E6720717569732C206573742E205574206D6F6C6573746965207175616D207669746165206F64696F2E20446F6E65632071756973207269737573206964206572617420666175636962757320736F6C6C696369747564696E2E204E616D2069642066656C69732E204D61757269732073656420656E696D207669746165206C656F20616363756D73616E207072657469756D2E0A0A4E616D206A7573746F2E20446F6E656320747572706973206E69736C2C20636F6D6D6F646F2065742C20696E74657264756D2061632C20636F6E736563746574756572206E6F6E2C206D617373612E2046757363652073656D206D657475732C206C616F72656574206E65632C20706F73756572652069642C20696D7065726469657420696E2C2076656C69742E20446F6E65632076756C707574617465206A7573746F2065676574207475727069732E204E756C6C6120706564652E204D6F7262692074696E636964756E742E20467573636520616C69717565742C207175616D20657420616C697175616D206672696E67696C6C612C20616E746520616E746520696163756C6973206475692C206E656320616C697175616D20617263752070757275732073656420657261742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050686173656C6C7573207375736369706974207175616D206574206573742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B0A0A496E7465676572207365642074656C6C75732E20536564207365642076656C697420756C74726963696573206C656F2072757472756D206C616F726565742E20536564206E6F6E2065726F7320616320707572757320736167697474697320666575676961742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E205365642068656E647265726974206C6967756C612073697420616D6574206E6962682E204D616563656E6173207475727069732E204D6F72626920636F6E7365637465747565722C20646F6C6F722065742061646970697363696E6720696D706572646965742C20616E7465206E65717565206665756769617420646F6C6F722C20617420706F727461207175616D206E657175652071756973206C6967756C612E204D61757269732073656D7065722076656C69742073697420616D657420697073756D2E2050656C6C656E7465737175652074656D7075732C20707572757320696E2072757472756D20636F6E7365717561742C20656E696D2065726174207665686963756C61206D617373612C20696420616363756D73616E206C656F2073617069656E206E65632070757275732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E20646F6C6F722E20496E746567657220666163696C69736973206C696265726F2073697420616D657420706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2055742076617269757320616C697175657420656E696D2E204E756C6C6120666163696C6973692E2043757261626974757220636F6E7365637465747565722C206F64696F206575207072657469756D2074696E636964756E742C206E756E63206E69736920616C6971756574206E657175652C2076656C20696D7065726469657420656C6974206D617373612073697420616D6574207475727069732E2050656C6C656E7465737175652074656D7075732C206F72636920766F6C757470617420626C616E646974206672696E67696C6C612C206F64696F2073656D20706F737565726520616E74652C20766974616520626962656E64756D2075726E61206C6F72656D2076697461652065726F732E205072616573656E7420766976657272612072686F6E63757320617263752E2053656420617563746F722C206573742073697420616D6574206D6F6C6C6973206D6F6C6C69732C207175616D207175616D20677261766964612073617069656E2C20696E20636F6D6D6F646F206D65747573206E756C6C6120617563746F7220656E696D2E20446F6E656320666163696C697369732E0A0A50726F696E2074696E636964756E742C2073617069656E206567657420756C747269636965732061646970697363696E672C20657374206F64696F2064696374756D20617263752C207574206D6F6C6C69732065726174206475692073697420616D65742076656C69742E204D6F726269206573742073656D2C20696E74657264756D2061742C20636F6E67756520612C20656C656D656E74756D2076697461652C206D657475732E2053757370656E64697373652069642061756775652E204D617572697320656E696D2073656D2C2070756C76696E617220656765742C2074656D70757320612C2074656D7075732073697420616D65742C2073617069656E2E20467573636520766573746962756C756D20636F6E736563746574756572206475692E2050656C6C656E74657371756520657261742E20536564206469676E697373696D20706C616365726174206F64696F2E204D616563656E61732073656D7065722072686F6E637573206C65637475732E2050686173656C6C7573207072657469756D2E2044756973206C696265726F20656C69742C20656C656966656E64206E65632C20656765737461732075742C20637572737573207365642C2066656C69732E204E616D206E69736C20617263752C20616C69717565742065742C20666163696C697369732065752C206C75637475732075742C2072697375732E20457469616D20756C7472696365732C20646F6C6F722073656420766F6C7574706174206D616C6573756164612C20747572706973206172637520696D7065726469657420746F72746F722C20657569736D6F6420636F6D6D6F646F206C696265726F206D61737361207574207175616D2E20496E7465676572206D6F6C6573746965207075727573206E6F6E20656C69742E2055742076656E656E617469732073656D70657220746F72746F722E20457469616D20626962656E64756D206567657374617320697073756D2E204D617572697320736F6C6C696369747564696E2073656D206E6563206E6962682E204E756C6C61207072657469756D206D65747573206575206D657475732E2050656C6C656E7465737175652073697420616D65742073656D2E0A0A53757370656E6469737365206163206E6973692E205574206C656F2E20566573746962756C756D2068656E647265726974207072657469756D20646F6C6F722E204E756E632066657567696174206D616C6573756164612070757275732E2043726173206574206E6962682E20437572616269747572206E756E6320657261742C206D616C6573756164612076697461652C206C616F726565742061632C20756C7472696369657320696E2C2070757275732E20566976616D75732074656C6C757320617263752C20736F64616C65732065752C20666163696C6973697320612C206C6163696E6961206E65632C206E756E632E2050656C6C656E7465737175652069642076656C69742E20496E206575206E6962682E204E756E63206E656320657261742E205365642064696374756D206E65717565207574206E69736C2E0A0A4D6F726269206C65637475732074656C6C75732C2074696E636964756E742061632C20706F72747469746F722061632C2074726973746971756520696E2C2065726F732E20446F6E6563206C7563747573206C7563747573206C656F2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2046757363652075742065737420657420656E696D207363656C6572697371756520616363756D73616E2E20446F6E6563206C6967756C612066656C69732C206C6163696E696120717569732C2070656C6C656E74657371756520696E2C2073656D70657220766573746962756C756D2C20656C69742E204D61757269732065676574206F72636920612066656C697320636F6E677565207665686963756C612E20557420736F6C6C696369747564696E2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204E756C6C616D20696420646F6C6F72207574206C6F72656D206469676E697373696D2076656E656E617469732E2053757370656E64697373652076697461652073617069656E2E2050726F696E206E6F6E206D61676E612075742065726F7320766976657272612070756C76696E61722E20446F6E65632071756973206F64696F2E204E756C6C616D206E6F6E20617263752076656C206C6F72656D20737573636970697420616C697175616D2E20416C697175616D2072757472756D2074757270697320696E206C656F2E0A0A5574206C7563747573206E6962682074726973746971756520657261742E2053757370656E646973736520626962656E64756D206F64696F20766974616520746F72746F722E20446F6E6563206C6163696E69612E204372617320736F64616C65732066656C6973206C7563747573206E756C6C612E204E616D20656C656966656E64207361676974746973206C6967756C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E64697373652076656C206E657175652E204D6F72626920616C6971756574207665686963756C61206D61676E612E2041656E65616E206174206F64696F2E20447569732070656C6C656E746573717565206D61676E612E204E756C6C6120617420746F72746F72207574206469616D2064696374756D2066617563696275732E204D617572697320717569732076656C69742E20446F6E6563206E6F6E2074656C6C7573207669746165206C6F72656D206672696E67696C6C6120706F72747469746F722E2046757363652075742073617069656E207175697320746F72746F7220666575676961742073616769747469732E20446F6E656320766976657272612073656D2076697461652073617069656E2E205072616573656E7420736F64616C65732C206C6163757320696E206672696E67696C6C6120766976657272612C206F64696F2061756775652061646970697363696E672075726E612C20766974616520696E74657264756D20616E74652073656D206E6F6E206E6973692E204E756C6C616D20746F72746F72206C6F72656D2C20656C656966656E642061632C206D6F6C6C6973206E6F6E2C206C616F726565742061632C2072697375732E20496E7465676572206F726E617265206C656F20736564206A7573746F2E2051756973717565206375727375732C2073656D206E6F6E20666163696C6973697320626962656E64756D2C206E697369206D69207661726975732066656C69732C206665726D656E74756D2066657567696174206C6F72656D2065726F73206C616F726565742072697375732E0A0A517569737175652073697420616D657420657374206574206C6F72656D207665686963756C61206C6163696E69612E20446F6E6563206E656320746F72746F722E2043726173206F64696F2E204E616D207363656C657269737175652076756C7075746174652075726E612E205072616573656E74206475692E20457469616D206E6563206E69736C206C6F626F7274697320697073756D20616C69717565742074656D7075732E204D616563656E6173207072657469756D20736F6C6C696369747564696E206D61757269732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206175677565206D617373612C20636F6E67756520656765742C20636F6E76616C6C697320656765742C207472697374697175652073697420616D65742C2065726F732E2053656420636F6E736571756174206E6973692065752066656C69732E2050656C6C656E746573717565206A7573746F2E2053757370656E6469737365206E6F6E2061756775652E20496E206469676E697373696D206C6F626F72746973206D61757269732E204D61757269732073616769747469732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E0A0A5365642061646970697363696E672E20446F6E656320612074656C6C75732076697461652065737420637572737573207665686963756C612E204E616D20616E74652073656D2C20736F64616C65732069642C206672696E67696C6C612076656C2C20636F6E64696D656E74756D2076656C2C206E756C6C612E205175697371756520736F64616C65732E20457469616D20696D7065726469657420656C6974206964206F64696F2E20416C697175616D206572617420766F6C75747061742E204D616563656E617320706F7274612074656D706F7220617263752E204E756C6C612073656D2061756775652C2070656C6C656E7465737175652061632C20636F6E7365717561742075742C20636F6E64696D656E74756D20657569736D6F642C2072697375732E2053656420616C697175616D2074696E636964756E74206D692E20496E20696E74657264756D206C6F626F72746973206F7263692E0A0A536564207665686963756C612068656E6472657269742070757275732E20457469616D2061206469616D2E2043757261626974757220636F6E76616C6C69732E2053757370656E64697373652061206E6973692E20446F6E6563206964206D61676E6120696E207175616D20736F6C6C696369747564696E20756C747269636965732E20446F6E656320766976657272612E205175697371756520766F6C757470617420657374207365642073656D2E20416C697175616D206A7573746F2E20566573746962756C756D20746F72746F72206D617373612C20706F72747469746F72207365642C2076617269757320717569732C20696163756C697320717569732C206F64696F2E20416C697175616D2065676574206E657175652E0A0A4D6175726973206E756C6C612E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566573746962756C756D206575207175616D20696E206E6571756520756C7472696365732070656C6C656E7465737175652E204372617320696E20646F6C6F722071756973207175616D207661726975732068656E6472657269742E20416C697175616D206E697369206C616375732C206C6F626F727469732065752C20636F6E76616C6C69732073697420616D65742C20666163696C697369732075742C206D692E20416C697175616D206174206E657175652E204372617320736167697474697320656C656D656E74756D206A7573746F2E20566573746962756C756D207574206C656374757320616C6971756574207075727573206D616C65737561646120766F6C75747061742E2044756973206174206C616375732061646970697363696E67206C696265726F2074696E636964756E7420766573746962756C756D2E204D6F7262692061206C696265726F2E20437261732070757275732E204D6F72626920757420617567756520657420707572757320696E74657264756D207363656C657269737175652E20496E74656765722061206475692E20496E206861632068616269746173736520706C617465612064696374756D73742E2044756973207068617265747261206D657475732065676574206D61757269732E20416C697175616D20696E74657264756D20756C6C616D636F72706572206D617373612E0A0A457469616D206F726E6172652E204E756C6C616D20657569736D6F642E2041656E65616E20636F6E7365717561742067726176696461206C6967756C612E20416C697175616D206573742E2050726F696E207669746165206C616375732E205072616573656E7420612065726F732073697420616D657420647569206C756374757320636F6D6D6F646F2E2050686173656C6C7573207665686963756C612061726375206567657420646F6C6F722E205072616573656E74206665726D656E74756D20636F6E677565206C656F2E20416C697175616D20766F6C7574706174207075727573207574206C6F72656D2E2046757363652068656E64726572697420656E696D206174206C656F2E20416C697175616D2072686F6E637573206E69736C2E20566976616D75732064696374756D2065676573746173206D692E2053757370656E64697373652070656C6C656E74657371756520626962656E64756D20646F6C6F722E2050656C6C656E7465737175652074696E636964756E742C207475727069732073656D7065722070656C6C656E74657371756520636F6E64696D656E74756D2C20697073756D206D6574757320736F64616C6573206C6967756C612C20696420766F6C7574706174206469616D2074757270697320757420656C69742E0A0A5072616573656E7420736564206C616375732E204E616D20656C656966656E64206D6F6C6573746965206D61757269732E20446F6E65632064617069627573206665726D656E74756D206D617373612E20446F6E656320766976657272612066617563696275732070757275732E2043757261626974757220636F6E6775652C206C696265726F20766974616520766976657272612070656C6C656E7465737175652C206469616D2076656C697420736F64616C657320656E696D2C20736564207375736369706974206C6563747573206E697369206E6563206E657175652E20566573746962756C756D206D616C6573756164612C206C616375732061742063757273757320636F6E6775652C2076656C6974206C65637475732074726973746971756520646F6C6F722C2073697420616D657420736F64616C6573206E6571756520697073756D2061206C696265726F2E20566573746962756C756D206574207175616D2E2043757261626974757220706C6163657261742E20437572616269747572206E756E6320617263752C20657569736D6F64206E65632C2076756C7075746174652068656E6472657269742C20616C697175657420656765742C207175616D2E204375726162697475722076656C20656E696D2E2053757370656E646973736520706F74656E74692E0A0A4E756E6320636F6E736571756174206F726369207574206C616375732E2046757363652076656C697420646F6C6F722C2064617069627573207365642C20626C616E6469742073697420616D65742C2072686F6E6375732069642C2072697375732E20447569732075726E61206E6962682C207363656C6572697371756520717569732C206461706962757320612C207363656C65726973717565207365642C206E6962682E20446F6E6563206C75637475732E205574206575206D617572697320637572737573206469616D206C6163696E69612072686F6E6375732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20416C697175616D207665686963756C61206D6F6C6573746965206A7573746F2E204D616563656E617320696D70657264696574207065646520736564206D692E2053757370656E6469737365206E756C6C6120646F6C6F722C2068656E64726572697420656765742C2068656E6472657269742069642C2064696374756D2076656C2C206C656F2E204475697320616363756D73616E2E2043757261626974757220696E2066656C69732E204E756E63206C6F72656D2E205574206C656F20646F6C6F722C206C616F72656574206E65632C2076756C7075746174652061742C20656C656966656E6420696E2C206E756C6C612E2051756973717565206E756E632070757275732C2076617269757320656765742C20616363756D73616E206E65632C20616C69717565742065742C206E6962682E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20437261732061646970697363696E67207669766572726120646F6C6F722E204D617572697320706F72747469746F7220756C7472696365732070757275732E204E756C6C6120666163696C6973692E205072616573656E7420666175636962757320616E7465207669746165206D61757269732E0A0A5072616573656E74206C6163696E6961206C656374757320736564206E69736C2E20496E2074656D70757320636F6E677565206D61757269732E20496E746567657220666163696C69736973206F726E61726520656E696D2E204E756C6C61206964206D617373612E20446F6E656320636F6D6D6F646F206469616D2061742074656C6C75732E204E616D20646170696275732076697665727261206573742E204E616D2074656C6C75732E205072616573656E742061206C696265726F2E20496E206661756369627573206573742065676574206E6962682E204E756C6C612065726F73206F7263692C20696D70657264696574206E6F6E2C20626C616E646974206E6F6E2C2074656D706F7220656765742C206D692E2050656C6C656E74657371756520636F6E76616C6C69732E0A0A517569737175652065676574206D69206163206C656F20657569736D6F642066617563696275732E2050686173656C6C75732072686F6E637573207075727573206964206475692E20566573746962756C756D206D616C65737561646120656C656966656E6420616E74652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050656C6C656E74657371756520626C616E646974206D6174746973206F64696F2E2053757370656E646973736520636F6E7365717561742C206C65637475732061632073656D70657220736F6C6C696369747564696E2C206D692076656C69742064696374756D2061756775652C2061632074656D70757320646F6C6F7220657261742073697420616D6574206475692E2050726F696E2068656E6472657269742C2066656C6973207175697320766F6C757470617420706F73756572652C206469616D206F64696F206D616C657375616461206F64696F2C206120696E74657264756D206F726369206469616D20717569732073617069656E2E2050656C6C656E746573717565206F64696F206F64696F2C20766976657272612076656C2C20677261766964612065752C206D6F6C6573746965207365642C206E756C6C612E2050686173656C6C7573206D617572697320706564652C20636F6D6D6F646F2075742C20657569736D6F642065752C2068656E6472657269742065752C206573742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C6120656C656D656E74756D206C616375732065752061756775652E2053656420657261742E2050726F696E20706F7274612E204D616563656E61732071756973206D692E2050686173656C6C757320617420656E696D206163206A7573746F206772617669646120756C7472696365732E2043726173206C656F2E0A0A496E746567657220757420617263752E20446F6E656320736564206D61676E612E2050726F696E2066656C69732E20496E20696163756C69732C206C6967756C61206964206672696E67696C6C61207072657469756D2C206E696268206469616D20616363756D73616E2074656C6C75732C206567657420616363756D73616E206D657475732064756920766172697573207475727069732E2050686173656C6C7573206F726369206D657475732C20656C656966656E64207365642C2074656D706F722061632C207363656C657269737175652061632C2075726E612E20496E74656765722076697665727261206E657175652061206D61757269732E204D617572697320706F72747469746F7220646F6C6F722065752076656C69742E20496E7465676572206F64696F20656C69742C20766573746962756C756D2075742C20766F6C75747061742069642C2072686F6E63757320636F6D6D6F646F2C2075726E612E20457469616D20706C61636572617420706861726574726120657261742E2055742074656D706F72206573742E20496E7465676572206469676E697373696D20626C616E6469742074656C6C75732E204D6F726269206E69626820646F6C6F722C207363656C657269737175652069642C20636F6D6D6F646F206D616C6573756164612C206D61747469732061742C206D692E20437261732074696E636964756E7420636F6D6D6F646F2070757275732E20496E2074696E636964756E742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D20756C6C616D636F727065722E2055742068656E6472657269742E204D6F72626920756C7472696365732E0A0A5072616573656E7420696163756C69732C2065726F73206163206567657374617320736F64616C65732C2075726E61206C656F206665726D656E74756D206C6967756C612C2073697420616D657420616C697175616D2076656C69742073656D206E6F6E2070757275732E20446F6E65632072757472756D206172637520717569732070757275732E204E616D20706F73756572652C206C6163757320617420636F6E73657175617420706C6163657261742C206E756C6C61207065646520706F7375657265206F7263692C206E6F6E20657569736D6F6420747572706973206475692071756973206E69736C2E2050726F696E20706F7274612061646970697363696E67206E6962682E20446F6E65632074726973746971756520646F6C6F722061742074656C6C75732E20446F6E6563206E65717565206D617373612C20617563746F722069642C2066617563696275732076697461652C20756C6C616D636F727065722076656C2C206E6973692E2050726F696E206D6F6C6573746965206E6571756520736564206D617373612E204E616D2074656D706F722E204D6F72626920616C697175616D2073617069656E2061742074656C6C75732E2046757363652071756973207269737573206574206D69207072657469756D2070756C76696E61722E2046757363652073697420616D6574206C6967756C612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E646973736520657520656E696D2065742066656C6973207363656C65726973717565206C6F626F727469732E205072616573656E7420626962656E64756D2E20566976616D7573207665686963756C612E20496E7465676572206174206E696268207365642076656C69742072686F6E637573206D6F6C65737469652E2043726173206C616375732E2053656420756C6C616D636F727065722065726F732076656C20657261742E20467573636520657520746F72746F722073697420616D6574206469616D20657569736D6F642073616769747469732E204E756E632071756973206C61637573206964206E69626820636F6E76616C6C6973207661726975732E2053757370656E6469737365207669746165206D692E20566573746962756C756D207472697374697175652E20446F6E6563206D616C65737561646120697073756D206964206E657175652E204E756C6C616D20736564206C616375732E204475697320656765737461732C206A7573746F20757420636F6E677565206F726E6172652C2061756775652073617069656E206C7563747573206469616D2C20617420616363756D73616E20657261742073617069656E207574206C696265726F2E2050686173656C6C75732076656C206E756C6C612E2053757370656E646973736520617263752074656C6C75732C20706F72747469746F7220612C2070686172657472612066617563696275732C20616C697175616D2073697420616D65742C206D617373612E204E756C6C6120706F72747469746F722074696E636964756E74206C6F72656D2E204E756E6320646F6C6F72206F64696F2C20736167697474697320696E2C206C6F626F727469732076656C2C20766F6C7574706174207365642C206E6962682E0A0A5175697371756520626C616E646974206C656F2075742073617069656E2074656D70757320666163696C697369732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2041656E65616E20756C7472696369657320706F72747469746F72206A7573746F2E2046757363652072757472756D2065726F732075742075726E612E2050726F696E2071756973207175616D20656765742064756920616C697175616D20616363756D73616E2E20446F6E656320737573636970697420656C656966656E6420656C69742E2050656C6C656E746573717565206D61747469732C2066656C697320736F64616C657320696163756C697320696D706572646965742C206C616375732073656D20636F6E76616C6C69732061756775652C2073697420616D657420616C69717565742061726375207075727573206672696E67696C6C612072697375732E20496E206575206F64696F206964206D61676E61207068617265747261206F726E6172652E20416C697175616D20696E74657264756D2070756C76696E617220697073756D2E20536564206E657175652E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D2073697420616D6574206E6973692E2055742061742061756775652E204D617572697320766F6C757470617420626C616E646974206C6967756C612E204E756C6C61206575206D657475732E20566573746962756C756D206567657420656C69742E205072616573656E7420706F73756572652E20566573746962756C756D2069642073656D206E6F6E206C6563747573206D6F6C6C69732074696E636964756E742E20416C697175616D2069642066656C697320617420616E7465206F726E6172652074656D706F722E204E756C6C61206C61637573207475727069732C20666575676961742076697461652C2063757273757320717569732C20636F6E736563746574756572206E6F6E2C206D61757269732E204675736365206C61637573206D617373612C20706F72747469746F722075742C206D6F6C65737469652075742C2076656E656E6174697320612C206C6F72656D2E205072616573656E742073697420616D6574206F7263692E204D61757269732072686F6E6375732066656C69732076697461652066656C69732061646970697363696E6720696D706572646965742E204D616563656E6173206D6F6C6C6973206469616D206E6563206C656F2E0A0A467573636520656E696D20697073756D2C20756C7472696365732065752C206D6F6C65737469652069642C20656C656D656E74756D2069642C2073617069656E2E20496E746567657220612075726E612E204E616D2076656C6974206C696265726F2C2076656E656E6174697320656765742C2074656D706F722073697420616D65742C20666575676961742076697461652C20616E74652E204675736365206E756E632E205365642073656D706572206E69736C206E65632072697375732E20496E20736564206C696265726F2E2050726F696E20746F72746F72206E657175652C2074696E636964756E742061632C2074656D706F722061632C20706861726574726120717569732C2076656C69742E2044756973206C65637475732061756775652C20756C747269636965732076656C2C20636F6E7365717561742069642C20696163756C69732069642C20616E74652E20566976616D757320617563746F72206D65747573206120616E74652E204375726162697475722061726375206E6973692C20666163696C697369732061742C206C616F7265657420696E2C20636F6E736563746574756572207365642C206D61757269732E205175697371756520706C616365726174206469616D20736564206475692E20566976616D7573207072657469756D20636F6E64696D656E74756D206C6F72656D2E20437572616269747572206C616F726565742E2041656E65616E206F726369206C6967756C612C2063757273757320656765742C206C6163696E6961206E6F6E2C2066617563696275732076656C2C206C6F72656D2E0A0A416C697175616D206572617420766F6C75747061742E204375726162697475722065726F7320646F6C6F722C20636F6E67756520612C20636F6E64696D656E74756D207365642C206C75637475732075742C206E6962682E204D616563656E6173206E6F6E20746F72746F72206E65632074757270697320636F6D6D6F646F2070656C6C656E7465737175652E205072616573656E7420657569736D6F6420706C616365726174206D692E2053757370656E646973736520706F74656E74692E2050686173656C6C7573207574206E65717565207669746165206F726369206D617474697320696163756C69732E20496E746567657220656765742074656C6C75732E20446F6E656320617420616E74652E204E616D206C6163696E6961206C656F206567657420657261742E204D616563656E617320657569736D6F64206D61676E6120636F6E67756520746F72746F722E204D6F726269206E6563206D6173736120657520656E696D206D616C65737561646120736F6C6C696369747564696E2E2053656420616363756D73616E2E204E756C6C616D20697073756D2E205574206F64696F2E20416C697175616D206572617420766F6C75747061742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2050656C6C656E7465737175652069642076656C69742E204E616D206F64696F2073656D2C20616C69717565742075742C2074656D7075732073697420616D65742C20657569736D6F642065742C206E756E632E0A0A50656C6C656E746573717565206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205072616573656E74206D6175726973206E756E632C207661726975732075742C20636F6E76616C6C6973206D6F6C65737469652C206C75637475732073697420616D65742C206C656F2E205365642064696374756D206C6F72656D20657420617263752E204E756E632076656E656E617469732070656C6C656E746573717565206D617373612E204E756C6C6120666163696C6973692E2050686173656C6C757320696E20746F72746F722065676574207269737573207363656C657269737175652076756C7075746174652E20536564206E69626820656C69742C2073616769747469732061632C20636F6E64696D656E74756D206E65632C20636F6E76616C6C69732065742C206A7573746F2E20467573636520766F6C7574706174206D657475732E204E756E6320617563746F722E20566573746962756C756D206C656F2065726F732C2070656C6C656E7465737175652061632C206D6F6C6C697320756C7472696365732C2072686F6E637573206E6F6E2C20646F6C6F722E204D6175726973207665686963756C6120706C616365726174206E69736C2E20566573746962756C756D20626962656E64756D2C2061726375207175697320636F6E67756520656C656D656E74756D2C2076656C6974206E756E6320656C656966656E64207475727069732C206964206C7563747573207269737573206E69736C2073697420616D65742074656C6C75732E2050686173656C6C75732070656465206E657175652C20626C616E646974206E6F6E2C20636F6D6D6F646F2076697461652C20756C7472696369657320656765742C206D61676E612E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120666163696C6973692E20416C697175616D20616320616E74652E20437261732072697375732E204D6F726269206D6175726973206C616375732C20706F73756572652065752C20626C616E6469742065742C2070686172657472612061742C206D692E2050726F696E2061632070757275732E204475697320637572737573206E69736C2072757472756D207175616D2E20416C697175616D2061206F64696F206E6F6E206D61676E612070656C6C656E74657371756520756C747269636965732E204D616563656E6173206163206D6173736120717569732073617069656E20756C6C616D636F727065722074656D7075732E2043726173206375727375732076656C6974207365642073617069656E2E2050726F696E206E756C6C612E20566976616D757320736F64616C657320616C697175616D206E6962682E20457469616D206574206572617420757420616E7465206C6163696E696120657569736D6F642E204675736365206E6973692E2050726F696E2071756973206E756C6C612E0A0A517569737175652076656E656E617469732C2065726F7320736564206C616F7265657420736F6C6C696369747564696E2C206F72636920616E74652070656C6C656E746573717565206E69736C2C2073697420616D65742076697665727261207175616D2065726174206E6F6E2072697375732E20437261732065676574206C696265726F2E2053656420656C6974206D61676E612C2073656D7065722065752C206672696E67696C6C6120696E2C206469676E697373696D20736F64616C65732C20657261742E20566976616D757320666575676961742073656D2076656C206475692E20446F6E656320636F6E76616C6C697320736F6C6C696369747564696E206469616D2E2043726173207365642070757275732E20446F6E65632066656C69732065726F732C2073656D70657220656765742C2074656D706F7220636F6E7365637465747565722C20736167697474697320717569732C206E69736C2E204475697320696E20616E74652E2043726173206E6F6E207475727069732E204E756C6C612074656D706F722076656C697420616C697175657420747572706973206D6F6C657374696520706C6163657261742E2050726F696E20656C656D656E74756D206665726D656E74756D206D61757269732E20566976616D757320736564206F726369206C6163696E69612064756920706C6163657261742076656E656E617469732E20566573746962756C756D20666575676961742C2074656C6C757320696E20766F6C75747061742072757472756D2C206D61676E61206E69736920756C6C616D636F727065722065726F732C2069642070756C76696E6172206E657175652065726174207574206C616375732E20566976616D7573207365642061756775652E204E756C6C6120666163696C6973692E204D616563656E617320616E74652061756775652C20656C656D656E74756D2075742C20736F64616C65732076697461652C20636F6E64696D656E74756D206E65632C206C6F72656D2E20447569732070656465206F7263692C206672696E67696C6C612061742C20656C656966656E64206E65632C207072657469756D20696E2C20657261742E204E616D2073616769747469732C2074757270697320766974616520636F6E76616C6C69732070686172657472612C206F64696F2073656D207363656C65726973717565206C616375732C206E6563206C6F626F7274697320647569206469616D2076656C2065726F732E20496E2073656D7065722067726176696461206E657175652E0A0A496E7465676572206E756E632E205574207072657469756D20697073756D2073697420616D657420656C69742E20496E206E656320617263752E2053656420766573746962756C756D2076756C70757461746520697073756D2E2050656C6C656E7465737175652074696E636964756E742E204E756C6C61206772617669646120646F6C6F7220696E2074656C6C75732E2043726173207665686963756C612C20646F6C6F722075742070656C6C656E74657371756520616C697175616D2C206572617420656E696D20617563746F72206D617373612C207665686963756C61206C6F626F72746973206F64696F2065726F732071756973207175616D2E2050726F696E2064617069627573206E6571756520696E20656E696D2E2050726F696E20656C69742E20496E74656765722072686F6E6375732074696E636964756E7420656C69742E204675736365206C6F72656D206D657475732C2073656D7065722061632C20766F6C75747061742076697461652C20666163696C697369732075742C2074656C6C75732E20446F6E65632076656C20747572706973207669746165206E69736920706861726574726120706F72747469746F722E204D616563656E617320746F72746F722E204675736365206D692E204E756C6C616D206E6563207475727069732E2053656420736F64616C657320766573746962756C756D206E756E632E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A50656C6C656E74657371756520646F6C6F7220646F6C6F722C206C616F726565742065752C20616C697175657420717569732C207363656C657269737175652073697420616D65742C20617263752E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C616D206375727375732075726E61206567657420656C69742E205175697371756520626C616E6469742073617069656E20616320616E74652E2050726F696E206E756C6C612065726F732C206772617669646120766F6C75747061742C20736F64616C65732076656C2C206D6F6C6C69732065752C206D617373612E204E756C6C612074726973746971756520736F6C6C696369747564696E206E69736C2E20437572616269747572207669746165206C6F72656D2076697461652076656C69742065676573746173206F726E6172652E2041656E65616E20656765742065726F732E20416C697175616D206572617420766F6C75747061742E20467573636520612075726E61206964206F64696F20616C697175657420636F6E76616C6C69732E204375726162697475722073697420616D6574206E69736C20706F7375657265206C656F20706F737565726520646170696275732E2044756973206D6574757320657261742C206C75637475732076656C2C2072686F6E6375732061742C20636F6E76616C6C69732073697420616D65742C20656E696D2E20566976616D75732068656E6472657269742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D206567657420656C69742E0A0A4E756C6C616D2061206E756E632E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206D657475732075726E612C2074696E636964756E742065742C206C6163696E69612073697420616D65742C206C6F626F727469732076697461652C206C6967756C612E2050726F696E206574206D6175726973207669746165206D6920616363756D73616E2070656C6C656E7465737175652E20457469616D207175616D2070757275732C2068656E647265726974207365642C20666575676961742076697461652C20657569736D6F6420656765742C20746F72746F722E20557420616C697175616D206D61676E61207669746165206A7573746F2E2053757370656E6469737365206E6F6E206A7573746F2076656C2076656C697420636F6E64696D656E74756D2074656D7075732E20447569732074656D70757320697073756D2076697461652074656C6C75732E2050726F696E20696E206D617373612E20457469616D20756C6C616D636F727065722064696374756D2074656C6C75732E2050726F696E20616C69717565742066656C6973206174206C656F206C616F726565742070756C76696E61722E20566573746962756C756D20617263752070757275732C206D616C6573756164612073697420616D65742C206375727375732065752C20706C6163657261742073697420616D65742C206E756E632E204E616D206D61737361206F64696F2C20736F6C6C696369747564696E20696E2C2061646970697363696E6720612C20616C697175616D206E65632C2072697375732E20416C697175616D20626C616E6469742068656E647265726974206C696265726F2E204D617572697320677261766964612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204375726162697475722061206E6962682E20557420696E74657264756D206665726D656E74756D206E657175652E2050656C6C656E74657371756520736564206E756E632E204D6175726973207665686963756C61206E697369206574206E756E632E205072616573656E74206C6F72656D2E20446F6E65632073656D7065722E20496E7465676572206575206C6163757320696E2065737420616C697175616D2068656E6472657269742E20566573746962756C756D2065676574206E657175652E205365642073656D706572206C75637475732076656C69742E20437572616269747572206E6962682061756775652C20636F6E6775652065752C2068656E6472657269742069642C20636F6E6775652065742C20656E696D2E20496E746567657220706C61636572617420616C697175616D206C65637475732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20566976616D75732076697461652065726F732E20446F6E65632076656C206E69736C2E0A0A496E20766573746962756C756D20666163696C697369732075726E612E2055742072697375732E204D61757269732070686172657472612E2050656C6C656E746573717565206D61747469732E20496E746567657220737573636970697420616C697175616D20697073756D2E204475697320626C616E6469742C2073617069656E20657420756C7472696369657320636F6E64696D656E74756D2C2066656C6973206D6920656C656D656E74756D20706564652C206E6563207361676974746973206D65747573206D61757269732071756973207175616D2E205175697371756520616363756D73616E20617263752076656C206E756C6C612E20437261732073656D2073617069656E2C20706F72747469746F722069642C20756C747269636965732073616769747469732C206C75637475732065752C206E756C6C612E20496E746567657220717569732065726F732E204D6F726269207365642075726E6120612074656C6C7573207665686963756C612076756C7075746174652E20457469616D206E656320617567756520656765742066656C69732073656D706572207472697374697175652E205175697371756520757420646F6C6F722076656C2072697375732064696374756D20636F6E7365717561742E20536564206567657420646F6C6F7220736564206E756E63206C6163696E696120616C69717565742E2053757370656E646973736520616320746F72746F7220696E20697073756D20706F73756572652076656E656E617469732E20536564206567657420657261742E204E756C6C612066617563696275732E2044756973206C616F726565742C206D6173736120706F72747469746F7220616C697175657420656765737461732C20697073756D206C65637475732072686F6E637573207175616D2C20696E2061646970697363696E672065726F732073656D2075742074656C6C75732E2050656C6C656E74657371756520666575676961742074656D707573207175616D2E20566976616D757320696420646F6C6F7220656765742073617069656E20636F6E7365637465747565722074656D706F722E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120696163756C6973206665726D656E74756D206C696265726F2E204375726162697475722066617563696275732C206D61737361206D616C657375616461206375727375732074696E636964756E742C20657261742073656D20656C656966656E64206D61757269732C20736564206672696E67696C6C61206D6920616E74652061632070757275732E204475697320656C656D656E74756D206C65637475732E204E756E63206F726E617265206172637520657520746F72746F722E20566573746962756C756D2076656C20646F6C6F72206174207075727573206C6163696E6961206672696E67696C6C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E616D20696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204D616563656E61732074696E636964756E742C2065726F73206120656765737461732070656C6C656E7465737175652C2072697375732072697375732064696374756D206C696265726F2C20696420616C6971756574206D65747573206A7573746F20696E206D617373612E2050726F696E20612074656C6C75732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205365642070757275732E20536564206E6F6E20706564652E2041656E65616E206D617373612073617069656E2C20736F64616C65732073697420616D65742C20636F6E7365717561742064696374756D2C20656C656966656E642076697461652C20746F72746F722E20446F6E656320756C747269636573206C6163696E696120656C69742E0A0A4D6F7262692061646970697363696E6720736F64616C657320646F6C6F722E20557420756C6C616D636F7270657220756C74726963696573206573742E20496E2076656E656E617469732074656D7075732061756775652E2053757370656E646973736520746F72746F7220646F6C6F722C20616363756D73616E2065742C20737573636970697420612C2074696E636964756E742075742C206C696265726F2E20416C697175616D207363656C65726973717565206D61676E61207365642066656C69732E2051756973717565207574206E756E632061206D61676E612076756C70757461746520706C6163657261742E20416C697175616D2072686F6E637573207665686963756C61206475692E2053656420746F72746F722E204E756C6C616D2073697420616D6574206469616D2E204E756E63207365642065726F732E20536564206574206F64696F2074696E636964756E7420656C6974206772617669646120636F6E76616C6C69732E20437572616269747572207175697320746F72746F722061206C616375732073656D706572207661726975732E204D6175726973206174206175677565206E6F6E206D6920736F6C6C696369747564696E20616C697175616D2E20496E746567657220756C6C616D636F727065722E2050656C6C656E746573717565207375736369706974207175616D206E6F6E2070757275732E20416C697175616D2061632065726F73206174206172637520756C6C616D636F7270657220636F6E7365637465747565722E2053757370656E6469737365207072657469756D206D6174746973206C656F2E0A0A44756973206174206E756E632E2053656420646F6C6F72206573742C207661726975732061632C20706F7274612065742C2074696E636964756E742068656E6472657269742C2072697375732E20566976616D7573207574206D61676E612E205072616573656E74207574206D61757269732E20496E207075727573206C616375732C206D6174746973207365642C20766573746962756C756D206E65632C2074656D706F722061742C206E69736C2E204372617320756C6C616D636F727065722076656E656E617469732074656C6C75732E20557420646F6C6F722E204D616563656E6173206D616C6573756164612C207065646520612070756C76696E6172206D61747469732C2061726375206469616D207665686963756C612072697375732C207175697320706F72747469746F72206175677565206D6173736120696E2076656C69742E204E756E6320636F6E6775652E204D6F7262692076656C6974206D657475732C2072686F6E6375732065742C20616C697175616D20636F6E7365637465747565722C20756C74726963696573206D616C6573756164612C206C6967756C612E205365642076656C6974206E69736C2C2073616769747469732076697461652C20706861726574726120612C20706F7375657265207365642C206D617373612E204E756C6C6120666163696C6973692E20496E207661726975732C206C6967756C61206964206C6F626F7274697320736F64616C65732C206175677565206F726369206665726D656E74756D2074656C6C75732C2065752070756C76696E6172207269737573206C6967756C6120612073617069656E2E204D6F726269206C616F7265657420697073756D206E6F6E206D692E204E616D20637572737573206C6F72656D207574206D692E20566976616D7573206D61676E6120656E696D2C20706F7375657265206E6F6E2C2073656D70657220717569732C20736F64616C65732065752C20617263752E20457469616D206D692070757275732C207072657469756D20666575676961742C20766172697573207365642C2070656C6C656E74657371756520656765742C206C6967756C612E20496E206C656F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E6563207669746165206F726369206575206F72636920736F6C6C696369747564696E20666575676961742E0A0A5072616573656E74207075727573206D617373612C20657569736D6F642076697461652C2074656D707573206E65632C20636F6E7365717561742068656E6472657269742C206D657475732E2041656E65616E2066656C6973206573742C20656765737461732076697461652C20616363756D73616E20656765742C2070656C6C656E74657371756520696E2C2073617069656E2E204475697320646170696275732070656465206E6F6E2073617069656E2E204E756E632075726E612E20496E74656765722076656C206C696265726F2E204475697320617567756520617263752C2064617069627573206E6F6E2C20666163696C697369732076697461652C20706F73756572652075742C2065726F732E20446F6E6563207669746165206E756E632073697420616D6574206172637520696D706572646965742064696374756D2E204D6F72626920656C656966656E642C206C6F72656D20657520636F6E73656374657475657220766573746962756C756D2C206469616D206E756E63206F726E61726520617263752C2061632074656D706F722066656C697320646F6C6F7220656765742065726F732E2050686173656C6C7573206D617373612073656D2C20736F6C6C696369747564696E2061632C20736F64616C657320677261766964612C206C756374757320612C207175616D2E204E616D206E65717565207175616D2C20766976657272612061742C2076656E656E6174697320717569732C207361676974746973206E6F6E2C20656E696D2E0A0A4E756C6C6120666163696C6973692E2050656C6C656E7465737175652065676573746173206C6163696E6961206573742E205365642074696E636964756E742C2070656465207365642074696E636964756E7420766573746962756C756D2C2075726E6120646F6C6F722061646970697363696E672070757275732C207669746165206672696E67696C6C612066656C697320656C697420696E206E6962682E204E756C6C6120736564206E6973692E204D6175726973207375736369706974207363656C6572697371756520617263752E20457469616D206E6F6E20656E696D2076656C2065726F7320616363756D73616E206D616C6573756164612E204E756E632074696E636964756E7420636F6D6D6F646F206D61757269732E20496E2074696E636964756E7420726973757320717569732075726E612E204E756C6C61206469616D20746F72746F722C20616C69717565742065742C2074696E636964756E7420717569732C20736F6C6C696369747564696E2061632C20746F72746F722E2043726173206E69736C206E657175652C2076756C7075746174652073757363697069742C206D6F6C657374696520717569732C2070756C76696E61722061742C206E756C6C612E204E756C6C616D206163206D65747573206E6563206F64696F20706F7375657265207661726975732E2043726173207365642070656465206E65632064756920706F737565726520626962656E64756D2E204475697320657569736D6F6420756C6C616D636F72706572206C696265726F2E20416C697175616D2066617563696275732070756C76696E6172207475727069732E0A0A496E207574206E65717565206964206E756E63206665756769617420636F6D6D6F646F2E20437572616269747572206469676E697373696D2C2066656C697320617420736F6C6C696369747564696E206C6163696E69612C20656E696D20656C6974207375736369706974206E657175652C20736564206C7563747573206C6F72656D20697073756D20696E206C656F2E204475697320646170696275732C206F64696F207175697320617563746F7220636F6D6D6F646F2C206E69736C206F64696F206D61747469732074656C6C75732C206E65632074696E636964756E7420747572706973206469616D20696E20617263752E2043757261626974757220612073656D2E204E756C6C616D20766F6C7574706174206D61676E612E2050656C6C656E7465737175652073616769747469732C206E6571756520636F6E736571756174207072657469756D206375727375732C20646F6C6F72206C6163757320636F6E73656374657475657220617263752C20736564206C616F72656574206573742075726E61206574206D657475732E2053757370656E646973736520706C6163657261742C20647569206120706F7274612074656D706F722C206C6F72656D20647569206C6F626F72746973206E657175652C207365642076656E656E61746973206469616D20656E696D2069642065726F732E20457469616D206574206E69736C206E6F6E206C656374757320666175636962757320636F6E7365637465747565722E204D6F726269207363656C657269737175652C2073656D206E65632074656D70757320756C6C616D636F727065722C20697073756D206469616D2066657567696174206C6F72656D2C2061206672696E67696C6C612073617069656E20656C69742071756973206E6962682E204E756C6C616D206469616D2075726E612C2076697665727261207365642C2070686172657472612072686F6E6375732C2074696E636964756E742076656C2C206F7263692E20496E746567657220616363756D73616E206D617474697320657261742E204E616D2064696374756D2E204D6175726973206E6563206C656F2E204E756C6C6120696163756C69732E204E756C6C61206E69736C206D692C206461706962757320717569732C207665686963756C6120612C2063757273757320656765742C206F64696F2E0A0A50686173656C6C7573206461706962757320657569736D6F64206E6962682E20566976616D757320696D7065726469657420616E746520696E206C6967756C612E2050656C6C656E74657371756520616363756D73616E2E20496E20696D706572646965742C20647569206120617563746F72206672696E67696C6C612C206D65747573206E6973692063757273757320646F6C6F722C2076656C206C7563747573206C6967756C61206C6F72656D207669746165206D61757269732E205072616573656E74206D617474697320766573746962756C756D20656C69742E20416C697175616D20656E696D206C616375732C2070756C76696E6172206E6F6E2C206C6163696E69612073697420616D65742C20656C656966656E64206E6F6E2C2076656C69742E20566573746962756C756D206163206C656F2E204D617572697320696D70657264696574206A7573746F206163206C65637475732E20536564206D6F6C6573746965206C656374757320736564206475692E20536564206665726D656E74756D2074656D707573206D61757269732E204E616D206F726E617265206F7263692061632074656C6C75732E205574206D616C6573756164612C206C61637573206964206C6163696E696120616363756D73616E2C206469616D20656C69742061646970697363696E67206D657475732C20657420626962656E64756D2073617069656E206E69626820626C616E646974206F7263692E2053757370656E646973736520697073756D2074656C6C75732C20736167697474697320717569732C20766573746962756C756D206E6F6E2C2076756C7075746174652065752C2065726F732E205072616573656E74206174206E756C6C612069642070656465207363656C6572697371756520756C747269636965732E204372617320626C616E646974207072657469756D2074656C6C75732E204D616563656E6173206461706962757320636F6E64696D656E74756D2061756775652E2050686173656C6C75732074696E636964756E74207068617265747261206C6F72656D2E204D6F726269206E6F6E2065726F732E205365642074656D706F722C206E69736C20612074696E636964756E742074696E636964756E742C2065726F73206469616D2064696374756D2073656D2C2076656C206469676E697373696D20616E7465206469616D20736564206D61676E612E205072616573656E74206E6F6E206C6967756C61206964206D65747573206D6F6C657374696520636F6E7365637465747565722E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E64697373652076656C206D692E2043757261626974757220616E7465206E756C6C612C2072757472756D20612C20636F6E76616C6C69732076656C2C207665686963756C612061632C206E756E632E204E756E632073616769747469732C20656E696D2073697420616D657420617563746F722072757472756D2C206D617572697320617263752076756C707574617465206E657175652C20657420657569736D6F64206573742066656C6973207175697320616E74652E20566573746962756C756D207475727069732074656C6C75732C2068656E64726572697420696E2C206C6163696E696120636F6D6D6F646F2C20756C6C616D636F7270657220677261766964612C2072697375732E204D61757269732072686F6E637573206C6163696E69612072697375732E204D616563656E617320736F6C6C696369747564696E2065726174207669746165206E756E632E205072616573656E74207072657469756D2070656C6C656E7465737175652061756775652E20446F6E656320696E74657264756D2E205072616573656E742061632065726F732076697461652065726174206C6F626F72746973206672696E67696C6C612E2041656E65616E20636F6E7365717561742074656C6C75732E204E756C6C6120616363756D73616E20626962656E64756D2066656C69732E204D616563656E6173207072657469756D20616E7465206964206E6973692E2041656E65616E206D6920617263752C2073656D706572207365642C206D61747469732065752C2076656E656E617469732073697420616D65742C20617263752E20446F6E656320616C697175657420657569736D6F64206C656F2E2050726F696E206D61676E61206A7573746F2C2074726973746971756520612C2073656D7065722061632C20736F6C6C696369747564696E20612C206C6967756C612E204D6F7262692076656C69742E20416C697175616D2076656C206E6973692E0A0A496E2061206C6F72656D207574206E756E63206665756769617420636F6E6775652E20446F6E6563206665726D656E74756D20626962656E64756D206475692E2050726F696E207661726975732065737420717569732076656C69742E20446F6E656320616C69717565742073656D20616363756D73616E206D692E2053656420706C6163657261742E204E756C6C616D206163206E6973692061206D61737361206C6F626F727469732073757363697069742E204E756E63206964206C656F2E20416C697175616D206574206D617373612E204E756C6C616D20766573746962756C756D20656C656D656E74756D206D657475732E20496E20636F6E736563746574756572206E6973692076656C206A7573746F2E204D616563656E6173206567657420707572757320736564206D61737361207661726975732070656C6C656E7465737175652E2050686173656C6C75732066617563696275732066656C697320717569732066656C69732E2041656E65616E206F64696F20617263752C20626C616E64697420717569732C20666163696C6973697320696E2C20696D706572646965742065752C206C6F72656D2E204E616D20706F73756572652070756C76696E6172206D692E204675736365207472697374697175652C206D617572697320657420636F6E73656374657475657220756C747269636965732C206D6175726973206C65637475732074656D706F72206A7573746F2C206174206672696E67696C6C61206573742065737420736564206E6973692E20517569737175652066617563696275732E2053656420696E20746F72746F722074696E636964756E7420657374206C6163696E696120696163756C69732E204D616563656E61732061206D617373612E2050656C6C656E7465737175652061206E69626820617420707572757320706F7274612068656E6472657269742E0A0A4E756C6C616D207475727069732E2046757363652061632073656D20736564206F64696F2070656C6C656E74657371756520696D706572646965742E2043757261626974757220696E20617263752E205072616573656E74206C61637573206C616375732C20666575676961742069642C2070756C76696E617220696E2C2074696E636964756E74207365642C206E657175652E204D616563656E61732076697665727261206F64696F206567657420746F72746F722E20496E746567657220616C697175616D2C206C6F72656D2072757472756D2076656E656E61746973206469676E697373696D2C206C6967756C61206D61676E61206D616C65737561646120617263752C2076656C2066657567696174206C6F72656D20697073756D2071756973206D617373612E204D6F72626920616E74652E20566573746962756C756D206D6175726973206C696265726F2C20756C6C616D636F7270657220717569732C20756C74726963657320717569732C20666163696C69736973206E6F6E2C206D617373612E204D616563656E617320696D706572646965742E20416C697175616D206572617420766F6C75747061742E2050656C6C656E746573717565206469676E697373696D2067726176696461206C65637475732E20496E206E696268206F64696F2C20617563746F7220656765742C206461706962757320717569732C206469676E697373696D2076656E656E617469732C20617263752E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20447569732070656C6C656E746573717565206C6967756C612071756973206D617373612E2043757261626974757220636F6E64696D656E74756D2C206A7573746F2065676574206F726E617265206C75637475732C206C6F72656D206C6967756C6120736167697474697320706564652C206120706F727461206E756E63206E756E6320696E206E657175652E20517569737175652066656C6973206D61757269732C20636F6E64696D656E74756D2076697461652C20617563746F722076697461652C2074696E636964756E7420717569732C20706564652E204E756E63206C6163696E696120616E746520696E206C656F2E2050656C6C656E746573717565206C696265726F2E2041656E65616E2061206C6967756C61206574206E756E6320766573746962756C756D20636F6E7365637465747565722E0A0A4675736365206F726E6172652E205072616573656E742069642075726E612E20496E74656765722076656E656E617469732C207175616D206E6F6E20736167697474697320616363756D73616E2C20616E7465206E6962682073616769747469732061756775652C20736F6C6C696369747564696E2061646970697363696E6720646F6C6F722076656C697420657520657261742E2050726F696E207175697320656E696D206575207075727573207665686963756C6120616C697175616D2E204E756C6C612076656C20656E696D2076656C20656C697420736F6C6C696369747564696E206672696E67696C6C612E20416C697175616D206572617420766F6C75747061742E205365642073757363697069742066656C6973207574207475727069732E20457469616D2072757472756D20726973757320696D70657264696574206573742E20416C697175616D20612074656C6C75732061742074656C6C757320636F6D6D6F646F20646170696275732E204D61757269732072757472756D206D61676E61206574206F64696F2E20496E20617420646F6C6F722E20437572616269747572207665686963756C61206C656374757320696E20746F72746F722E204675736365206A7573746F2070757275732C206C75637475732076697461652C206D6F6C6C697320696E2C2070686172657472612061632C2070757275732E204E756C6C616D20706F737565726520696E74657264756D206A7573746F2E20437572616269747572207669746165206C616375732076656C206C656F20636F6E6775652070756C76696E61722E0A0A41656E65616E20656C656966656E64206E6962682076617269757320746F72746F722E2053757370656E64697373652076656C2065726F732E2050726F696E206E6563206469616D206120746F72746F7220756C747269636573206F726E6172652E20416C697175616D207363656C657269737175652066657567696174206A7573746F2E20566976616D757320616E74652075726E612C2061646970697363696E672076697461652C20706F72747469746F722065752C20736F64616C65732065742C2066656C69732E2053757370656E646973736520706F74656E74692E20437572616269747572206163206D6173736120696E206E69736C207361676974746973206D6F6C6C69732E204E616D207175616D206C6967756C612C20636F6E73656374657475657220656765742C20696163756C69732061742C207661726975732065752C206C656F2E204475697320646F6C6F72206C6967756C612C2074696E636964756E742061742C20756C6C616D636F72706572207365642C20616363756D73616E20616C697175616D2C206C6967756C612E2050686173656C6C75732076756C7075746174652C206C6F72656D2061742074696E636964756E742070686172657472612C207269737573206C6563747573206C6163696E6961206D61676E612C20717569732072757472756D20656E696D206D61676E612061742073656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E20447569732069642073656D2061206D617572697320736F6C6C696369747564696E2074696E636964756E742E20457469616D2065752070757275732065752061726375206672696E67696C6C612061646970697363696E672E20566976616D7573206F726E6172652074656D707573206469616D2E2050726F696E20747572706973207175616D2C206C6163696E6961206E6F6E2C20656765737461732061742C20636F6D6D6F646F20656765742C20706564652E205072616573656E742076756C70757461746520726973757320696E206573742E204E756C6C6120666163696C6973692E0A0A557420656C656D656E74756D206C6163696E69612070757275732E2050726F696E2076697461652061726375206163206E756C6C6120636F6E76616C6C697320616C697175616D2E204E756C6C6120636F6E6775652C206C696265726F2069642070656C6C656E746573717565206D61747469732C207175616D206C656374757320706F72747469746F72206469616D2C2061207363656C6572697371756520647569206C696265726F20696E2073617069656E2E204E756C6C616D2066656C6973206469616D2C207665686963756C612076656C2C206D6F6C65737469652075742C20766573746962756C756D20616C697175616D2C2073617069656E2E20446F6E656320636F6E76616C6C69732C2065737420757420656C656D656E74756D20766F6C75747061742C206D617572697320697073756D20677261766964612073656D2C20636F6D6D6F646F20666163696C697369732073617069656E206C65637475732073656D706572206C65637475732E205175697371756520706F72747469746F722065726F73207574206E6962682E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20457469616D206D617474697320726973757320736564206F64696F2E20566573746962756C756D206574206F64696F2E20496E206861632068616269746173736520706C617465612064696374756D73742E204E616D20747269737469717565206D61737361207574206C6967756C612E2051756973717565206E6962682074656C6C75732C207665686963756C612073697420616D65742C2061646970697363696E672061742C20636F6E76616C6C6973206E65632C206C6967756C612E20566573746962756C756D207072657469756D2C206D69206E6563206672696E67696C6C6120626962656E64756D2C20647569206E756E6320736F64616C657320706564652C20612073656D706572206D61676E61206E696268206E6F6E206469616D2E20446F6E6563206D61737361206E756E632C20766976657272612076656C2C20636F6E73656374657475657220706F7274612C2064617069627573206E6F6E2C20697073756D2E2044756973206E69736C206D61757269732C206375727375732076656C2C2073656D706572206E6F6E2C20736F6C6C696369747564696E20626962656E64756D2C2066656C69732E20566573746962756C756D206575206E657175652E0A0A43726173206E656320646F6C6F722E20446F6E6563206C616F726565742074656D707573206C65637475732E20437261732073656420746F72746F7220696E74657264756D206C6163757320656C656966656E64206469676E697373696D2E204D616563656E61732073697420616D657420656C69742E204E756C6C616D207175697320646F6C6F722076656C20647569207068617265747261206C75637475732E20496E2073697420616D6574207175616D2073697420616D6574207065646520756C74726963657320756C7472696365732E204D616563656E6173206469616D2E20496E74656765722075726E612E204375726162697475722064696374756D2C2076656C69742073656420706C6163657261742073757363697069742C206572617420747572706973206665726D656E74756D206A7573746F2C2073656420696E74657264756D206E657175652073656D206574206E6962682E20566976616D757320636F6E73657175617420636F6E76616C6C6973206D61676E612E204E616D20616C697175616D2C2065737420616320626962656E64756D20636F6D6D6F646F2C206D61676E61206573742064696374756D206D692C207669746165206D616C65737561646120656C6974206D61676E61207669746165206F64696F2E204D616563656E61732074656D706F722076756C7075746174652074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206475692E20457469616D20616363756D73616E207065646520636F6E67756520746F72746F722E0A0A4D6F7262692074656D706F72206C696265726F206163206C6F72656D2E20496E20616C697175657420766172697573206D61676E612E20496E20617263752E2050686173656C6C7573206F64696F2E2046757363652074696E636964756E7420616C69717565742066656C69732E20517569737175652076656C69742E20536564206C75637475732E20416C697175616D2066657567696174206672696E67696C6C61206D692E20416C697175616D206D6F6C657374696520766976657272612072697375732E2050726F696E20617263752E20566573746962756C756D206C6F626F727469732074656D707573206E6973692E205072616573656E742061206172637520696E2076656C697420766976657272612072757472756D2E0A0A496E20736564206C65637475732E20446F6E656320726973757320646F6C6F722C20626C616E6469742073697420616D65742C20656C656D656E74756D20636F6E76616C6C69732C20706861726574726120717569732C20706564652E20496E7465676572206F726E6172652E2041656E65616E20656765737461732064617069627573206A7573746F2E20536564207175616D206C656F2C20706F73756572652061742C20656C656D656E74756D2076697461652C20636F6D6D6F646F20656765742C206573742E20416C697175616D206D6F6C65737469652072686F6E63757320656E696D2E2043757261626974757220696163756C697320756C74726963657320706564652E204D6F72626920616C69717565742072757472756D206C616375732E20416C697175616D207175616D2E2053656420636F6D6D6F646F2C2074757270697320696E20706861726574726120706F73756572652C206D6920726973757320696D7065726469657420657261742C206120766573746962756C756D206D617373612074656C6C7573207665686963756C612073656D2E204D6175726973206672696E67696C6C6120756C747269636573206E756E632E204E616D206E69736920656E696D2C20656C656966656E642073697420616D65742C20756C747269636573207365642C206665726D656E74756D206E6F6E2C2061756775652E2050726F696E20636F6E677565206C6F626F72746973206E6973692E204D616563656E61732068656E6472657269742E204E616D20736564206E69736C2E204E756E6320656C656D656E74756D206F64696F2065752072697375732E20496E206D657475732E2050686173656C6C75732067726176696461207072657469756D206C6967756C612E204E756C6C61207669746165206E657175652E204E616D206E69736920746F72746F722C206F726E617265206E6F6E2C20626C616E6469742061742C206375727375732065752C20746F72746F722E0A0A4475697320626962656E64756D20697073756D20696E206E756E6320637572737573206D6F6C65737469652E204E756E63206F7263692E204E756C6C616D206E656320616E7465206E6F6E20657374206469676E697373696D20766976657272612E204D617572697320626C616E6469742C2076656C69742069642066657567696174207072657469756D2C20656C6974206D61676E612070656C6C656E74657371756520646F6C6F722C206174207361676974746973206C616375732076656C69742065676573746173206D61676E612E2050656C6C656E746573717565206375727375732C206469616D20636F6E736563746574756572207361676974746973206672696E67696C6C612C20746F72746F72206E6973692061646970697363696E67206E756E632C20657520766172697573206C6163757320726973757320616320656C69742E204D6175726973206964206E6973692071756973206C656F20657569736D6F642076656E656E617469732E2050656C6C656E74657371756520616320616E74652E204D617572697320617263752073617069656E2C2074656D706F722061742C20706F72747469746F722069642C20636F6E64696D656E74756D2075742C206475692E20457469616D206665726D656E74756D20756C747269636965732061756775652E20437261732075742065726F73206174206A7573746F20756C7472696369657320696163756C69732E2044756973206469676E697373696D2C206E69736C20657420666163696C69736973206665726D656E74756D2C2065726174207075727573206D6F6C65737469652074656C6C75732C20717569732074656D70757320697073756D206C656374757320617420656C69742E204E756C6C61207669746165206C6F72656D2E0A0A41656E65616E2076656C2073656D206574206469616D2073656D70657220636F6E6775652E20496E20626962656E64756D206469616D20717569732074656C6C75732E204E756E6320666163696C6973697320756C74726963696573206E6962682E2043726173206E756E6320656E696D2C2066657567696174207365642C20756C7472696365732076697461652C2073616769747469732076697461652C20697073756D2E204675736365207669746165206E756C6C612E20446F6E65632070656C6C656E7465737175652C2076656C697420696E20706F72747469746F7220656C656966656E642C20657374206E65717565206C6F626F727469732076656C69742C2073697420616D65742072757472756D20616E746520746F72746F72206E656320646F6C6F722E20446F6E6563207665686963756C612E204E756C6C6120666163696C6973692E20536564206567657374617320756C747269636573206E6962682E20446F6E656320656C6974206C65637475732C20636F6E76616C6C697320706F72747469746F722C20616C697175657420646170696275732C206665756769617420656765742C206C6967756C612E2053656420636F6E736563746574756572206A7573746F2E204D616563656E617320612073617069656E2073697420616D6574206E6973692064617069627573206C6F626F727469732E20566976616D7573206C7563747573206C6F72656D206E6F6E206E756C6C612E2053656420656765742065726174207669746165206C696265726F20696E74657264756D20706F73756572652E20437261732070756C76696E61722E204E756C6C616D20696D706572646965742C20646F6C6F722074656D706F72206469676E697373696D20626C616E6469742C206475692073617069656E2072686F6E637573206E657175652C206964206D616C657375616461206175677565206D61676E612073697420616D65742075726E612E204475697320736564206D61757269732E0A0A4D6F72626920616363756D73616E2E20536564206D61757269732061756775652C206672696E67696C6C61206E6F6E2C20617563746F722075742C20617563746F722065742C206F7263692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320757420706564652E20446F6E6563207669766572726120656E696D2076656C206C6F72656D2E2050656C6C656E746573717565206E65717565206D61757269732C20696E74657264756D2065752C2076656E656E617469732069642C20636F6E64696D656E74756D2065752C2073617069656E2E20446F6E656320697073756D20617263752C206C6163696E69612061646970697363696E672C206C616F726565742065742C206375727375732076656C2C2076656C69742E205574207361676974746973206D617572697320717569732072697375732E20496E7465676572206575206F64696F207669746165206C61637573207669766572726120616363756D73616E2E204D6F726269206C656F20616E74652C206469676E697373696D207365642C2076617269757320717569732C20766F6C75747061742076697461652C206E6973692E204E756C6C6120706C61636572617420696E74657264756D20656C69742E20446F6E6563206E65717565206475692C2073616769747469732076697461652C20736F6C6C696369747564696E20717569732C20636F6D6D6F646F2076697461652C206E657175652E204E756C6C612071756973206C6967756C61206F726E617265206C6967756C612064696374756D206F726E6172652E204D61757269732072757472756D2072757472756D206E657175652E2041656E65616E207665686963756C612074656D707573206573742E20446F6E656320766172697573207363656C6572697371756520706564652E20446F6E656320706C6163657261742076756C707574617465206C656F2E204E756C6C616D206E756E63206E69736C2C20706F7375657265206E6F6E2C20666575676961742076697461652C2070656C6C656E74657371756520717569732C206D61757269732E20496E20647569206E657175652C2063757273757320656765742C20736167697474697320656765742C20646170696275732076697461652C206D692E2050726F696E2065676574206573742E0A0A467573636520706F727461206573742E204D6175726973206D61676E612E20416C697175616D20697073756D206C616375732C20756C747269636965732069642C20766573746962756C756D206C75637475732C20616363756D73616E2075742C20616E74652E20536564206D61757269732E205365642061646970697363696E67206C656F2073697420616D6574206D61676E612E2053757370656E646973736520706F74656E74692E204E756E63206D6173736120656C69742C206672696E67696C6C6120656765742C20656765737461732076697461652C206C75637475732076697461652C20646F6C6F722E2050686173656C6C75732071756973206E756C6C61206575206E69736920696E74657264756D20736F6C6C696369747564696E2E204E756C6C616D2069642074656C6C75732E20496E746567657220696163756C697320646F6C6F722061632070757275732E205365642076656C206D692E20437572616269747572206E6F6E206D61676E612073697420616D6574206A7573746F20636F6E64696D656E74756D2076756C7075746174652E20517569737175652074696E636964756E742070656465206575206E69736C2E20566976616D7573206C6F626F727469732E204E756E63206D65747573206D657475732C20636F6E677565207365642C2074696E636964756E74207365642C207072657469756D2061742C206F64696F2E20446F6E6563206120617263752E20496E2073656D206A7573746F2C207665686963756C61207365642C207661726975732069642C20766F6C75747061742061742C2072697375732E205072616573656E7420696163756C6973206D617373612E20496E206172637520656C69742C2068656E64726572697420656765742C20756C6C616D636F7270657220696E2C20706F7274612069642C2074656C6C75732E20446F6E65632073616769747469732068656E647265726974206469616D2E0A0A53757370656E646973736520706F74656E74692E20536564206574206469616D206574206175677565207361676974746973206C6F626F727469732E2050686173656C6C757320646F6C6F722E2055742065742061726375206567657420616E74652074656D706F7220706F73756572652E20416C697175616D206665726D656E74756D207363656C65726973717565206475692E204D61757269732061742070757275732E20446F6E656320657261742073656D2C20766573746962756C756D206E65632C2066617563696275732061632C206D617474697320612C206C656F2E2053757370656E64697373652061646970697363696E67206C6163696E69612073656D2E204E756C6C616D206F72636920617263752C2064696374756D2065742C20666175636962757320766976657272612C20646170696275732065742C206E657175652E2043726173206E756E63206469616D2C2061646970697363696E67206E6F6E2C20736F6C6C696369747564696E20696E2C20696E74657264756D2076656C2C206D617373612E204D61757269732073616769747469732C206A7573746F206174207472697374697175652074656D7075732C206D6175726973206D617572697320616C697175616D20616E74652C2073697420616D657420706F7375657265206469616D206475692065676574206C6967756C612E20496E206469676E697373696D2C206E69736C207574206C6163696E696120636F6E64696D656E74756D2C2065726174206A7573746F20706F72747469746F72206E756C6C612C206E6F6E2067726176696461206C6967756C61206D61676E612065676574206D617373612E20566573746962756C756D207669746165206C6967756C61206174206D6920766573746962756C756D2073757363697069742E2044756973206C616F726565742E204E756C6C6120636F6D6D6F646F206C696265726F2073697420616D6574206C6F72656D2E20557420656C656D656E74756D2073656D2E20496E74656765722076656C20646F6C6F722E204E616D20666163696C69736973206D6920717569732073656D20756C7472696365732073616769747469732E205365642071756973207175616D206174206D65747573206D6F6C657374696520626962656E64756D2E0A0A50726F696E2064756920656E696D2C206C6163696E696120612C20666575676961742061632C20706C6163657261742076697461652C20706564652E205175697371756520656765737461732C206C656F206567657420616C697175616D207072657469756D2C206C696265726F206A7573746F2074696E636964756E742065726F732C2075742065676573746173206175677565207065646520656C656D656E74756D206E6962682E20437572616269747572206D6F6C6C697320736F64616C657320656E696D2E20446F6E65632061756775652E2050686173656C6C757320696420697073756D20706F737565726520647569207072657469756D2066617563696275732E204D6175726973206C756374757320616E74652073656D706572206E69736920696E74657264756D2061646970697363696E672E204475697320646170696275732C206F64696F207175697320766976657272612072686F6E6375732C206A7573746F207175616D20626962656E64756D20646F6C6F722C20696420646170696275732076656C697420657261742076656C20657261742E2046757363652073697420616D6574206E69736C2076656E656E61746973207175616D20756C74726963657320636F6E64696D656E74756D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632072686F6E637573207363656C65726973717565206C6967756C612E20566573746962756C756D206D69206F64696F2C20616363756D73616E2065742C2061646970697363696E6720656765742C206F726E6172652075742C207175616D2E204E756C6C616D20626C616E646974206D6F6C6573746965206D61757269732E20437572616269747572206469676E697373696D206D6175726973206574206C6F72656D2E2053757370656E64697373652061206A7573746F2E204E616D206D617474697320666175636962757320617263752E204475697320626C616E64697420656E696D206E6F6E206D617373612E0A0A4E756C6C616D206C6F72656D2E20496E206861632068616269746173736520706C617465612064696374756D73742E204D617572697320636F6E73656374657475657220706F7375657265206D61757269732E204D616563656E61732074696E636964756E74206D617572697320696E2065726F732E204E756C6C61206575206D65747573206575206F72636920736F6C6C696369747564696E2066617563696275732E2053757370656E646973736520616C697175616D206D6175726973206964206573742E204372617320626C616E646974206475692065742075726E612E204E756C6C6120617263752E2053656420612075726E612E204E756C6C612064617069627573207665686963756C6120746F72746F722E20446F6E65632072697375732E20536564207175616D206D657475732C20656765737461732065752C206375727375732075742C2076697665727261206E6F6E2C206F64696F2E205574206A7573746F206A7573746F2C206D616C6573756164612073697420616D65742C20626C616E6469742073757363697069742C206D6F6C657374696520696E2C206A7573746F2E20566573746962756C756D20636F6E7365717561742C207175616D20616320666575676961742074696E636964756E742C20697073756D206C696265726F20656C656966656E64206F64696F2C206E6F6E20656C656966656E64207065646520697073756D206E6F6E20616E74652E204E756C6C616D2061206D657475732E0A0A4E616D206163206E6973692061742066656C697320637572737573206D61747469732E2050656C6C656E74657371756520636F6E7365717561742073656D2071756973206F7263692E20517569737175652074656D7075732E2041656E65616E20696D70657264696574206D6F6C657374696520706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652065752074656C6C75732E204E756C6C61206469616D2065726F732C20736F64616C65732075742C20736F64616C6573206E65632C2074696E636964756E742061632C206E756E632E204E756E63206C6163696E696120666175636962757320697073756D2E20566976616D75732076656C206E6571756520696E2065726174206665726D656E74756D206C75637475732E204E756C6C612065676574206D65747573206E656320617567756520626962656E64756D20706C6163657261742E20566976616D75732074656D7075732E205072616573656E7420636F6E677565206F726E61726520697073756D2E20457469616D206D61747469732066657567696174206A7573746F2E0A0A416C697175616D206475692E2041656E65616E20636F6D6D6F646F20746F72746F72207669746165206E756C6C612E204D6F72626920657420697073756D2E204D617572697320616320697073756D2E204E616D2076656C207269737573207574206C6563747573206D6F6C6C697320766976657272612E2043757261626974757220656C656D656E74756D206D6F6C6C6973206573742E204E756C6C616D20656C69742E20566573746962756C756D207375736369706974207072657469756D20656E696D2E20566573746962756C756D207574206D617373612E2050726F696E206E65632066656C69732E204D616563656E617320677261766964612C2061726375206E656320636F6E7365717561742073616769747469732C2065726F732074656C6C7573207363656C65726973717565206D61757269732C20766974616520616363756D73616E207175616D207175616D207574206E756E632E20496E7465676572206567657420616E74652065752076656C6974206C616F72656574206D616C6573756164612E204E756E632073616769747469732C206D617572697320766974616520706861726574726120766F6C75747061742C2074656C6C75732074656C6C757320656C656966656E642065726F732C2073697420616D65742072757472756D20697073756D206E69736920612076656C69742E205072616573656E7420766172697573206C656F20657520657261742E20566976616D757320636F6E73657175617420706C6163657261742070757275732E20446F6E6563207072657469756D20656C656D656E74756D206E6962682E2050726F696E20617420656C6974206E6F6E2073656D20616C6971756574206D61747469732E2053656420756C6C616D636F7270657220697073756D2073697420616D657420656C69742E0A0A4D617572697320696E206D657475732E2053757370656E6469737365206D61676E61206C6F72656D2C2066617563696275732076656C2C2074696E636964756E7420717569732C207363656C65726973717565206E6F6E2C2074656C6C75732E2046757363652071756973206C6F72656D2E2050726F696E2061206C616375732073697420616D6574206D617572697320696163756C69732070756C76696E61722E2053757370656E64697373652072686F6E6375732065726F73206E6563206D692E205072616573656E7420657569736D6F642C207475727069732076697461652072757472756D207072657469756D2C206F64696F206D6574757320766F6C7574706174206E657175652C20656765742074656D7075732073617069656E206E657175652073656420657261742E20446F6E6563206665726D656E74756D207075727573206174206C65637475732E204E756C6C616D2073656D2E2046757363652076656C206D6920717569732065726174206C6F626F7274697320706F73756572652E2041656E65616E20656765742075726E612E2053757370656E6469737365206C6967756C612E204475697320696E206E6973692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A4375726162697475722076756C707574617465206C656374757320696420706564652E2050686173656C6C75732065752076656C69742E20457469616D2076656E656E617469732061646970697363696E67206E6962682E20416C697175616D206375727375732070756C76696E61722074656C6C75732E20566573746962756C756D206E657175652E204D6175726973206E6563206A7573746F20657420657261742073656D7065722070656C6C656E7465737175652E204675736365206D61747469732064696374756D20646F6C6F722E20457469616D2065676574207075727573206575206D617373612076617269757320656C656D656E74756D2E2050656C6C656E746573717565206D617373612E20557420756C74726963696573206469616D2073656420697073756D2E204E756C6C616D206469616D2E2050656C6C656E746573717565206964206D61676E61206964206C696265726F2074726973746971756520616C697175616D2E0A0A557420656C656966656E642C20707572757320696420706C6163657261742076656E656E617469732C2075726E6120617567756520616C6971756574206C6967756C612C20696E20756C74726963696573206C656F2072697375732065742074656C6C75732E204D6175726973206574206E756C6C612069642075726E61207472697374697175652074656D7075732E20557420666163696C697369732C2075726E6120657520766573746962756C756D2072686F6E6375732C206C616375732065726F7320636F6E736563746574756572206D657475732C2065742072757472756D20647569206C656374757320696E2070757275732E204E756E632076656C206E69736C206E6F6E20697073756D2074696E636964756E74206D6F6C6C69732E204E616D207175616D206C616375732C206F726E6172652076697461652C2072686F6E637573206E6F6E2C20636F6E677565207365642C206F64696F2E2050726F696E206E696268206475692C20706F7274612076656C2C2076656E656E61746973206E6F6E2C2070656C6C656E7465737175652075742C206E6973692E20536564207472697374697175652066656C69732061206D61676E612E2053757370656E646973736520656765742074656C6C75732E2043726173206772617669646120696D706572646965742076656C69742E20496E74656765722068656E6472657269742072697375732E2050726F696E206F7263692E20416C697175616D20756C6C616D636F72706572206D61757269732071756973206D61757269732E204E756E63206C6163696E696120766573746962756C756D206D657475732E20447569732074656C6C75732E204E756C6C616D2066617563696275732C206C656F2061632076756C70757461746520736F6C6C696369747564696E2C206C656F20646F6C6F7220666175636962757320657261742C207175697320626962656E64756D206F726369206F64696F206E6F6E20617263752E0A0A4E756C6C616D20616363756D73616E206D617474697320646F6C6F722E20446F6E6563206574206475692E205072616573656E7420612066656C6973206D6F6C6C6973206C616375732073656D706572206C6163696E69612E204375726162697475722070656C6C656E746573717565206C7563747573206573742E2050726F696E206E756C6C61206475692C20636F6E64696D656E74756D2076656C2C206661756369627573206E6F6E2C20696E74657264756D2061632C20657261742E204D616563656E6173207363656C657269737175652C206C656374757320696420766F6C757470617420616363756D73616E2C2073617069656E20746F72746F722070656C6C656E746573717565206475692C207365642073656D706572206D61676E612073656D207574206C656F2E2050726F696E206E756C6C612E204E756C6C616D206461706962757320756C6C616D636F727065722073656D2E2053757370656E6469737365207665686963756C61206D6574757320696E206E756E632E2050656C6C656E746573717565206E6F6E207175616D2076656C206172637520756C74726963657320756C6C616D636F727065722E2050686173656C6C757320717569732066656C69732073697420616D65742074656C6C757320756C6C616D636F72706572206665726D656E74756D2E20536564207665686963756C6120736F6C6C696369747564696E2075726E612E20437572616269747572207068617265747261207363656C657269737175652072697375732E2050656C6C656E746573717565206964206D617373612071756973206D6574757320616C697175616D20696D706572646965742E20496E206E756E63206C616375732C206665756769617420696E2C206772617669646120656765742C2076656E656E617469732075742C2074656C6C75732E2053757370656E646973736520706F74656E74692E204E616D20636F6E7365717561742061646970697363696E67206475692E20496E206E756C6C61206E6973692C20666575676961742075742C206665726D656E74756D2076656C2C2067726176696461206E65632C20746F72746F722E20496E207365642061756775652E0A0A457469616D20756C6C616D636F7270657220617567756520617420656E696D2E20496E7465676572206469676E697373696D2E20416C697175616D2070756C76696E617220636F6E677565206E756C6C612E204D6F72626920656E696D206D617373612C206672696E67696C6C6120612C20616363756D73616E20656765742C20636F6E64696D656E74756D206E65632C20657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2041656E65616E2070686172657472612E20457469616D20706F72747469746F722070757275732061206D657475732E20416C697175616D20696E74657264756D2073656D2065676574206A7573746F2E205175697371756520766F6C7574706174206C7563747573206573742E2041656E65616E2061756775652E2050686173656C6C757320647569206C65637475732C20756C747269636573206E65632C20636F6D6D6F646F2076656C2C20617563746F722076656C2C206E6973692E20557420756C7472696365732070656C6C656E746573717565206E6973692E20496E74656765722061632076656C69742065742073656D20696D70657264696574206C75637475732E20467573636520766974616520747572706973206964206175677565206D6F6C6C697320636F6E7365637465747565722E0A0A4D616563656E6173206E6563206C616375732E204D616563656E617320636F6E64696D656E74756D206F64696F2065752066656C69732E204D6175726973207574206E69736C207669766572726120657261742066617563696275732061646970697363696E672E20457469616D20656765737461732E204E756E6320657420646F6C6F72207669746165207269737573206469676E697373696D20636F6D6D6F646F2E204D6F726269206C65637475732076656C69742C2074696E636964756E74206E65632C20616C69717565742076656C2C206D61747469732076697461652C206C6967756C612E204D616563656E617320756C747269636965732073656D70657220646F6C6F722E2053757370656E6469737365206D616C6573756164612E20496E7465676572206D617474697320656C69742E20446F6E656320616363756D73616E2C206C6163757320666163696C69736973207661726975732074656D7075732C206E756C6C6120656C697420706F72746120657261742C2065742072757472756D20656C69742073656D2073697420616D6574206475692E0A0A4D616563656E6173206D6F6C6C6973206D69206E6F6E206E756C6C612E20566976616D7573207475727069732E2053757370656E64697373652061206D657475732E20496E2071756973206D6920696E2074757270697320636F6E67756520617563746F722E204D616563656E6173206C616375732E2053757370656E646973736520736F6C6C696369747564696E2E2050686173656C6C757320706F727461206E756E63206E6F6E206E69736C2070756C76696E617220656765737461732E20536564206E756C6C612E20566573746962756C756D206163206D692E204D617572697320756C7472696369657320636F6E64696D656E74756D206E657175652E204E756C6C612074656D707573206A7573746F2076656C206D617373612E204E756C6C6120737573636970697420636F6E67756520617263752E205072616573656E74206964207475727069732E204D6175726973206E69626820706564652C20657569736D6F642073656D7065722C206D6F6C65737469652061632C2072686F6E6375732076697461652C20616E74652E204D616563656E617320657261742066656C69732C207669766572726120736F6C6C696369747564696E2C20736167697474697320656765742C2070656C6C656E746573717565206E65632C206F7263692E20467573636520756C74726963657320636F6E736571756174206C616375732E20416C697175616D2065726174206D61676E612C20666575676961742061742C207669766572726120612C206D6F6C6C6973206E6F6E2C207475727069732E0A0A446F6E6563206D692E204E616D2064696374756D2070656C6C656E7465737175652073656D2E20446F6E6563206D6F6C6C69732072686F6E63757320656C69742E2050686173656C6C75732072686F6E63757320706564652073697420616D65742072697375732E20446F6E656320656765742061756775652E204D616563656E6173206E6F6E206C65637475732E2050686173656C6C757320736F6C6C696369747564696E206E697369206E65632066656C69732E20416C697175616D207072657469756D2C2065737420656765742073656D70657220636F6E76616C6C69732C206E696268206E756E6320736F6C6C696369747564696E2070757275732C2069642074656D706F722070656465206475692076656C206D61676E612E20566976616D7573206163206C6F72656D2E20457469616D206E69736C20746F72746F722C2061646970697363696E672064696374756D2C20656C656D656E74756D20696E2C20666163696C69736973207365642C206E6962682E2050726F696E206D61757269732E2050726F696E2072757472756D206D6173736120656765742073656D2E204375726162697475722074656D706F722061646970697363696E6720656C69742E204375726162697475722070757275732074656C6C75732C206665726D656E74756D20656765742C20616C69717565742076697461652C20636F6E76616C6C69732061632C206D61757269732E0A0A496E746567657220636F6E7365717561742076656C69742065752065726F732074696E636964756E74207665686963756C612E204E756C6C616D206C6F72656D2073617069656E2C2072686F6E637573206E6F6E2C206D617474697320717569732C20756C747269636965732073697420616D65742C20656E696D2E2043757261626974757220636F6D6D6F646F2C206C696265726F20696E20657569736D6F642073757363697069742C2073656D207075727573206672696E67696C6C6120656E696D2C206163206D6F6C657374696520746F72746F72206F7263692065742076656C69742E20446F6E656320706564652E20457469616D20706C61636572617420636F6E64696D656E74756D207475727069732E2050686173656C6C7573206567657374617320656E696D206E6563206D61676E612E20566976616D757320636F6E64696D656E74756D2C206E756C6C612076656C206C7563747573207472697374697175652C2065726F7320726973757320766573746962756C756D206E756C6C612C20696E207665686963756C61206172637520697073756D2061742066656C69732E20446F6E656320616C697175616D20656C69742061742061756775652E205175697371756520612065726F73206575206C6967756C6120616363756D73616E2064696374756D2E20457469616D207665686963756C61207475727069732071756973206C696265726F2E20416C697175616D206E6F6E206D692E20446F6E6563206574206C656F2E2050726F696E206C656F206C696265726F2C20616C697175616D2074696E636964756E742C20636F6E677565206E65632C2061646970697363696E6720706F7274612C20656E696D2E204E756C6C61206C6F626F727469732C20746F72746F722073697420616D657420696D7065726469657420756C6C616D636F727065722C20646F6C6F72206F726369206D616C65737561646120706564652C207365642067726176696461206E6962682075726E612076656C206C6F72656D2E20536564207068617265747261206D616C6573756164612065726F732E205175697371756520657569736D6F6420616C697175657420657261742E2053757370656E646973736520616C6971756574206D61747469732070757275732E0A0A4E756E63206964206E756C6C612071756973206A7573746F20636F6E67756520736F6C6C696369747564696E2E205072616573656E742065726174207475727069732C2072686F6E6375732065752C207072657469756D2065752C2070656C6C656E74657371756520612C206E6962682E20566976616D75732074656D7075732E2043726173206E65632072697375732061742074757270697320696D70657264696574206C6F626F727469732E205574206D61747469732E204D616563656E6173206573742066656C69732C2070656C6C656E746573717565206E6F6E2C20696D70657264696574207365642C20656C656966656E642074696E636964756E742C206C6F72656D2E20496E2074696E636964756E742E205365642076656C206C656F2E20446F6E65632065742075726E6120696E207475727069732068656E64726572697420626C616E6469742E20446F6E656320636F6E64696D656E74756D20616363756D73616E206573742E2055742070686172657472612C206D65747573207669746165206D617474697320636F6E7365637465747565722C206C656F207175616D2076756C707574617465206F64696F2C206E6563206C616F72656574206E6973692076656C697420657520657261742E20496E7465676572206C65637475732061756775652C206567657374617320696E2C20696E74657264756D2065752C2076656E656E617469732076656C2C2073617069656E2E2051756973717565206574206573742076697461652065726F73206C616F72656574206C6F626F727469732E204E756C6C616D207574207269737573206E6F6E206E756C6C6120706C6163657261742061646970697363696E672E205072616573656E7420646170696275732E20457469616D20612066656C69732E20557420736F64616C657320636F6E736571756174206D61757269732E2044756973206C6F72656D2066656C69732C206C756374757320612C2074726973746971756520696E2C206D6F6C65737469652061742C2072697375732E20536564207665686963756C6120626962656E64756D2074656C6C75732E204E616D20636F6E73657175617420657569736D6F64206C616375732E0A0A41656E65616E20746F72746F7220656C69742C2067726176696461206E65632C206665726D656E74756D2065752C206C6F626F727469732069642C20697073756D2E204D616563656E61732065752070757275732E204372617320616320747572706973207574206E69736920696163756C69732072686F6E6375732E204E756C6C61207075727573206D657475732C206469676E697373696D206E65632C2074696E636964756E742076697461652C20646170696275732065752C206E6962682E204675736365206C6F626F727469732C206E756E63206174207669766572726120656C656966656E642C206A7573746F20747572706973207363656C657269737175652065726F732C2061632070656C6C656E746573717565206D65747573206E69736C2061742070757275732E2053656420656C656D656E74756D2074656C6C75732073656420656E696D20696E74657264756D20626C616E6469742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E746567657220756C7472696369657320616C6971756574206F64696F2E204D61757269732065676574206E756E63206120697073756D20756C74726963657320736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2041656E65616E20616363756D73616E2E20446F6E65632073617069656E206C65637475732C20636F6E6775652061742C20706F7274612069642C2068656E6472657269742076697461652C206E69736C2E204375726162697475722076656C207175616D2076656C206E6571756520616363756D73616E206C616F726565742E204D6F7262692073617069656E206573742C207072657469756D20696E2C20636F6E7365637465747565722061632C206D6F6C6C69732075742C206C696265726F2E20446F6E65632074696E636964756E742061646970697363696E67206D657475732E204E756E6320766573746962756C756D20656765737461732061756775652E20446F6E6563207363656C65726973717565206475692075742073656D2E2053757370656E64697373652076656C206D6574757320696420657374206D6F6C657374696520696163756C69732E0A0A566976616D75732070686172657472612C20656C6974206575206D616C65737561646120626C616E6469742C206469616D20746F72746F72206D6F6C6C6973206475692C207365642070756C76696E6172206D61737361206E756E63206574206D61676E612E2053656420706C61636572617420656C697420617563746F7220746F72746F722E204E756C6C6120616320657261742E2050656C6C656E74657371756520636F6E7365637465747565722C2064756920636F6E76616C6C69732074696E636964756E7420636F6E64696D656E74756D2C2073656D206F64696F20766F6C7574706174206C696265726F2C206E6F6E20656C656D656E74756D2066656C6973206E65717565206E6563206F64696F2E204D616563656E61732068656E6472657269742065726F73206964206469616D2E204D61757269732076656C207075727573206163206F72636920636F6E76616C6C697320636F6E76616C6C69732E205365642073697420616D6574206C616375732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20517569737175652064696374756D20766172697573206C616375732E204D61757269732065676574206E69736C2E2053757370656E646973736520706C6163657261742C206E756C6C61206E6F6E206F726E617265206469676E697373696D2C206E69736C206469616D2073616769747469732074656C6C75732C20696E2073656D706572206E69736920646F6C6F72206174206E6962682E204475697320756C6C616D636F7270657220766976657272612066656C69732E20496E746567657220612074656C6C75732E2053757370656E64697373652065676574206E756E632E2041656E65616E206469616D206573742C20616363756D73616E2069642C20737573636970697420696E74657264756D2C206672696E67696C6C612076697461652C206A7573746F2E2050726F696E20706564652E204D616563656E6173206174206E6571756520696E206E6571756520766573746962756C756D20656C656966656E642E0A0A566573746962756C756D206E756C6C61206C6F72656D2C20706F72747469746F7220656765742C20657569736D6F642061632C20616C697175616D2061742C206E69736C2E204D616563656E6173206574206573742065676574206D6173736120766172697573206C6F626F727469732E20496E206D692E204475697320706F72747469746F72206665726D656E74756D2070757275732E20446F6E65632063757273757320696D70657264696574206C6967756C612E204D6F726269206574206C6967756C6120657420616E7465206D6F6C6573746965207665686963756C612E204D61757269732073656420646F6C6F722E2053656420696D706572646965742066656C69732075742073656D2E20536564207669746165206E6571756520656C656D656E74756D206C656F20617563746F72206665726D656E74756D2E2044756973206665756769617420756C6C616D636F7270657220657261742E2041656E65616E2070757275732E204D6F726269206665726D656E74756D20766573746962756C756D206573742E2050656C6C656E7465737175652076656E656E61746973206D61757269732E2050686173656C6C75732070756C76696E61722E20496E746567657220697073756D206C65637475732C20696163756C697320612C206C6163696E69612069642C20616363756D73616E2069642C20617263752E2050686173656C6C7573206174206573742E204675736365206E65717565207175616D2C20756C747269636965732069642C20696163756C69732076656C2C20646170696275732076697461652C206C616375732E20496E206C6F626F7274697320636F6E76616C6C697320616E74652E204E756C6C61206E756E632070757275732C2076756C70757461746520696E2C2068656E6472657269742065742C20626C616E6469742065742C206C6967756C612E0A0A50656C6C656E746573717565206C656F206D657475732C20736167697474697320696E2C206D6F6C65737469652076697461652C2064696374756D20696E2C20706564652E204D6F726269207072657469756D2066656C6973206E6563207175616D2E2050656C6C656E746573717565206D617474697320616E746520736564207175616D20736167697474697320646170696275732E2053757370656E64697373652073617069656E2E205072616573656E7420626962656E64756D20696163756C697320746F72746F722E20447569732061206E69736C2E2041656E65616E206D692E20446F6E65632064696374756D206172637520696E206573742E204D6F72626920696E74657264756D2076756C70757461746520697073756D2E2041656E65616E2073697420616D6574206D61676E61206E6F6E206E69736C2074726973746971756520706F73756572652E2050686173656C6C75732076656C6974206D657475732C2074656D706F722061632C206665726D656E74756D20656765742C20636F6E64696D656E74756D206E6F6E2C2076656C69742E20566573746962756C756D2073697420706F73756572652E0A0A4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204372617320616C6971756574206D61737361206E6563206475692E20437261732061726375206E756E632C2068656E6472657269742061632C20656C656966656E642065752C20756C6C616D636F72706572206E65632C2074656C6C75732E205365642070686172657472612070757275732073697420616D6574207175616D2E20437572616269747572206D6F6C6C69732E204E616D20766974616520706564652E20457469616D207269737573206D617373612C207665686963756C612073697420616D65742C207068617265747261206E65632C20736F6C6C696369747564696E2075742C206475692E20446F6E65632065676573746173206A7573746F206174207175616D2E2050726F696E206E69736C2072697375732C20766573746962756C756D206E65632C207072657469756D2076697461652C207472697374697175652061632C206C6F72656D2E20416C697175616D206572617420766F6C75747061742E204372617320736564206E6962682E2050656C6C656E74657371756520736F6C6C696369747564696E20657569736D6F642061756775652E0A0A457469616D206672696E67696C6C6120736F6C6C696369747564696E206F7263692E204D61757269732063757273757320656C69742071756973206C616375732E204372617320746F72746F722E20496E2061646970697363696E672C206C656374757320696420617563746F7220766573746962756C756D2C206E65717565207065646520616363756D73616E20646F6C6F722C206E6F6E20696D70657264696574206D61676E61206469616D20616363756D73616E2076656C69742E2053757370656E6469737365206174206C696265726F207574206E69736920626C616E6469742073616769747469732E2050686173656C6C7573206E6F6E206D61757269732E20467573636520656C656D656E74756D2073616769747469732073656D2E2053757370656E646973736520616C697175616D20656C656966656E642074656C6C75732E2050726F696E206C6967756C61206C6F72656D2C20696D7065726469657420717569732C2076656E656E617469732069642C20696163756C6973206D6F6C6C69732C206E69736C2E20457469616D20636F6E76616C6C69732070656465206174206D617373612E204D6F72626920616363756D73616E20647569206574206D61757269732E0A0A53656420736564206F7263692E204E756E632070757275732E2053757370656E646973736520706F74656E74692E205574206C7563747573206672696E67696C6C61206D61757269732E20446F6E6563206E6962682E2050686173656C6C757320706F7274612E2050686173656C6C75732073697420616D6574206F64696F20736564206D61676E6120736F64616C65732070686172657472612E2043726173206C65637475732E2053757370656E6469737365206C696265726F20697073756D2C20636F6D6D6F646F206E65632C20666163696C6973697320696E2C207375736369706974206C6F626F727469732C206C6967756C612E2044756973206D61737361206E756C6C612C2073656D7065722065742C20636F6E736571756174206E65632C2070686172657472612065752C20656C69742E20566976616D757320756C7472696369657320616C697175616D206F64696F2E20566573746962756C756D2073697420616D6574206D617373612E2053656420636F6E736571756174206C61637573207365642075726E612E20457469616D2066617563696275732066656C69732076656C206F7263692E2050686173656C6C757320756C6C616D636F727065722E2041656E65616E20636F6E736563746574756572206C61637573206174206C696265726F2E0A0A436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204475697320666163696C697369732C206C6967756C6120766974616520636F6E64696D656E74756D207363656C657269737175652C2076656C6974206F72636920677261766964612066656C69732C2076656C20756C74726963696573207175616D206D69206E6F6E206469616D2E20566976616D757320617563746F72206D65747573206E6F6E206C696265726F2E205072616573656E74206C6967756C61206E6973692C20636F6D6D6F646F20636F6E64696D656E74756D2C206D6F6C65737469652065742C20766976657272612065742C206A7573746F2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566976616D757320736F6C6C696369747564696E2E204E756E6320626C616E6469742063757273757320697073756D2E2041656E65616E206E6563206C6967756C612075742074656C6C757320736F64616C6573206D61747469732E20496E74656765722073656D2E20416C697175616D206964206C6967756C612E2053656420746F72746F72206D61757269732C20626C616E6469742076697461652C206375727375732076656C2C20656C656D656E74756D2065742C206E756C6C612E20416C697175616D207363656C65726973717565206D65747573206574206E69736C2E20447569732061646970697363696E67206D61676E61206174206E657175652E20517569737175652076756C70757461746520656C656966656E64206E756E632E20416C697175616D206567657420656C69742E2050686173656C6C757320647569206F64696F2C20626962656E64756D2073616769747469732C20766573746962756C756D2069642C206469676E697373696D20696D706572646965742C206F7263692E204E756C6C616D2065752066656C6973206E6F6E206E756E63206C6163696E696120736F64616C65732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A53757370656E64697373652070656C6C656E7465737175652C206C696265726F206D617474697320756C7472696369657320616363756D73616E2C20746F72746F7220746F72746F72206D616C6573756164612073656D2C20657420736F64616C6573206C696265726F206F64696F20616320697073756D2E20566976616D75732071756973206D61676E61206E656320657374207375736369706974206C6F626F727469732E20437261732074656D70757320706F7375657265206E756E632E205175697371756520757420656E696D20612066656C697320656765737461732073656D7065722E20536564207068617265747261206D6174746973206E657175652E20467573636520747572706973206E756E632C20636F6E677565207365642C20636F6E736571756174206E6F6E2C20636F6E677565207365642C206E756C6C612E2053757370656E646973736520766172697573206C6F72656D20696420726973757320706F72746120766573746962756C756D2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E204675736365207365642070757275732E20496E20612066656C69732E20496E7465676572206567657374617320617563746F72206F7263692E204D617572697320756C747269636573207375736369706974206E69736C2E204E756C6C616D2070757275732E0A0A437261732074656D706F722061646970697363696E6720697073756D2E2055742071756973206D692E204D616563656E617320696E206A7573746F207574206E756C6C6120636F6E6775652070686172657472612E2050656C6C656E746573717565207574206C696265726F20657520646F6C6F722076656E656E617469732073757363697069742E205072616573656E74206665756769617420636F6E736563746574756572206E6962682E204D6F7262692066617563696275732073656D206E6F6E2066656C69732E20496E2068656E6472657269742061726375206163206D617373612E20496E20616363756D73616E20756C747269636573206D692E2050726F696E206D616C65737561646120617563746F722066656C69732E2043757261626974757220696E74657264756D2E20536564206469616D20697073756D2C20756C7472696369657320696E2C2074656D706F722073697420616D65742C207669766572726120696D706572646965742C20656C69742E204D6F726269206D6F6C6573746965206E6973692E204D617572697320697073756D2E2046757363652064696374756D206D6F6C6C6973206D61676E612E204475697320636F6D6D6F646F206469676E697373696D206E756C6C612E20566573746962756C756D20617567756520656E696D2C20756C7472696369657320717569732C20696163756C6973206E65632C2074696E636964756E742076697461652C206469616D2E204D6175726973206C6163696E69612074656D70757320697073756D2E20536564206174206D61757269732E205574206C6F72656D2E20446F6E6563206C696265726F2E0A0A4475697320696163756C6973206C6163696E6961206C65637475732E2041656E65616E20636F6E76616C6C69732065726F7320616320616E74652E205365642071756973206F726369206E656320726973757320617563746F72206672696E67696C6C612E2050686173656C6C757320666163696C6973697320656C656D656E74756D206E6973692E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E6320706F727461206C61637573206E656320616E74652E204D6F726269206D617572697320657261742C2061646970697363696E6720696E2C2070756C76696E6172206E65632C206C6F626F72746973206E65632C206F64696F2E20557420656C656966656E64206C656374757320736564207175616D2E204E756C6C616D206D6F6C6C69732E20496E206E6F6E20747572706973206574206E69736C2068656E64726572697420626C616E6469742E204475697320656C656D656E74756D2E204E756E63206E6563206C696265726F2E2053757370656E646973736520766573746962756C756D207269737573206E6F6E20706564652E204D6F72626920696D70657264696574206F64696F2073697420616D6574206C696265726F2E2053656420736564206D6173736120766974616520697073756D206D61747469732074696E636964756E742E204E756C6C61206E656320746F72746F72207669746165206C696265726F20766F6C75747061742074656D7075732E20446F6E656320616C697175616D2E0A0A4475697320736564206E756E632E2043757261626974757220747572706973206E756C6C612C207665686963756C61207365642C206C756374757320717569732C20656C656D656E74756D20656765742C2066656C69732E204D616563656E61732065742070757275732E204D616563656E6173206C656F2074656C6C75732C2074696E636964756E7420612C20666163696C697369732076697461652C206C6F626F727469732073697420616D65742C2076656C69742E20446F6E656320636F6E76616C6C69732073617069656E2E204D616563656E6173206D6F6C6C6973206F64696F206575206E6962682E20457469616D20677261766964612E20496E7465676572206D6F6C65737469652C2073617069656E206575206D6F6C6573746965206C6163696E69612C206E756E63206E69626820616C697175616D206C6967756C612C2065752073616769747469732074656C6C7573206572617420736F6C6C696369747564696E206F64696F2E20447569732065742072697375732E2050686173656C6C7573206E697369206E657175652C20706C616365726174206E65632C20636F6E64696D656E74756D206E6F6E2C20756C7472696365732065752C2073656D2E20557420706564652E20457469616D206E756C6C61206D657475732C20766F6C75747061742069642C20636F6E76616C6C6973207365642C2073757363697069742076656C2C2075726E612E20446F6E65632076656C20656C69742E205574206C656F206E657175652C2076656E656E617469732066617563696275732C206C6163696E6961206E65632C2074696E636964756E742065752C20656E696D2E2043726173206964206475692061206C696265726F207068617265747261206469676E697373696D2E20446F6E65632065726F73206C656F2C20706F72746120717569732C206C616F726565742075742C2070656C6C656E74657371756520766F6C75747061742C206C65637475732E0A0A4E756C6C616D20626C616E6469742E20416C697175616D206572617420766F6C75747061742E2046757363652061646970697363696E6720656E696D2E2053757370656E6469737365206E6F6E206475692071756973206C6967756C6120706F72746120766573746962756C756D2E20446F6E65632065752074656C6C75732076656C206C6F72656D207072657469756D20706F72747469746F722E205072616573656E74206C75637475732E20416C697175616D2061632065726F7320696E206D6173736120646170696275732074696E636964756E742E20446F6E6563207574206D61676E612E20457469616D20617563746F72206C616375732073697420616D6574206C616375732E2053656420756C7472696369657320697073756D206E656320656C69742E205175697371756520612065737420696E207075727573207375736369706974207472697374697175652E0A0A41656E65616E20736564206475692076656C20646F6C6F722070756C76696E6172206C616F726565742E20566976616D7573207665686963756C61206C6F72656D20696E20706564652E20566976616D7573206574206469616D2E20496E7465676572206163206F64696F2076656C206469616D2068656E64726572697420626962656E64756D2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204E756C6C612061206E6973692E2050686173656C6C75732074696E636964756E74206475692076697461652061756775652E20447569732066617563696275732C2064756920696E74657264756D206672696E67696C6C612074696E636964756E742C206F64696F20656C697420766573746962756C756D206C696265726F2C206163206D6F6C6573746965206D61676E61206C6563747573206964206C616375732E2041656E65616E206C6967756C612E204E756C6C6120666163696C6973692E0A0A46757363652076656C2073656D2065752076656C6974206672696E67696C6C61206F726E6172652E2053656420666575676961742074696E636964756E742066656C69732E204E756C6C616D2066656C6973206D692C20657569736D6F642073697420616D65742C206D6F6C6C69732061742C20736F64616C657320656765742C2061756775652E204E616D20696D70657264696574206E6962682061742076656C69742E2053656420757420657261742E20496E206475692E204E756C6C6120666163696C6973692E204E756C6C616D206175677565206C696265726F2C2074696E636964756E74206E65632C207072657469756D2065752C2070756C76696E617220696E2C206475692E204D6F7262692076697461652066656C69732E2050656C6C656E7465737175652076656C206A7573746F2076656C2076656C6974207361676974746973206D616C6573756164612E2050726F696E207665686963756C6120626C616E646974206D617373612E20457469616D2074696E636964756E742070686172657472612075726E612E20496E206D65747573206573742C20617563746F72206E65632C20626C616E64697420612C20637572737573206E65632C207175616D2E204D6175726973206163206D657475732061206C696265726F20636F6E6775652066617563696275732E204D6175726973206D617572697320646F6C6F722C20736F64616C657320696E2C206375727375732075742C20736F64616C65732072757472756D2C2065726F732E2051756973717565206D61757269732065726F732C2073616769747469732076697461652C206C6F626F727469732075742C20656C656966656E642069642C206E6973692E0A0A41656E65616E206E657175652E20566573746962756C756D20656765737461732070656C6C656E746573717565206C6967756C612E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2050686173656C6C7573207361676974746973206A7573746F2076656C2072697375732E20536564207072657469756D206E657175652076697461652075726E612E2050656C6C656E74657371756520636F6E677565206C696265726F206964206C6F72656D2E204D6175726973206C656F206C6F72656D2C20626C616E6469742073697420616D65742C20636F6E76616C6C697320717569732C20636F6E736563746574756572207365642C2065726F732E204D61757269732074696E636964756E742C20656E696D2061206772617669646120657569736D6F642C206D61676E61206E756C6C61206665726D656E74756D206C696265726F2C207669766572726120656765737461732076656C6974207175616D20657420746F72746F722E20566976616D757320616C6971756574206D61737361207669746165206A7573746F2E204E756C6C6120636F6E677565206C6163757320616320656C69742E0A0A50686173656C6C757320636F6D6D6F646F207175616D2076656C206C6967756C612E2050726F696E206E6F6E206D657475732061742065726F732070756C76696E6172206C75637475732E204D6175726973206469616D206C6F72656D2C20706F737565726520717569732C20677261766964612065742C2074696E636964756E74206E65632C206C6967756C612E20536564206469616D2E20416C697175616D20656C6974206C65637475732C2068656E6472657269742075742C20696D706572646965742073697420616D65742C207072657469756D2073697420616D65742C20697073756D2E204D6175726973207665686963756C61206E69736C20696E206475692E204375726162697475722065676574207175616D207574206D61676E6120656C656D656E74756D206665726D656E74756D2E204D6175726973207363656C657269737175652E2051756973717565206C616F726565742E20457469616D2074656D707573207475727069732E2050656C6C656E746573717565206175677565207175616D2C2068656E647265726974207365642C2074696E636964756E742061742C2070686172657472612061742C206E69736C2E20416C697175616D206C616375732E2053757370656E646973736520706F74656E74692E2041656E65616E2076656C6974206C696265726F2C20756C74726963657320696E2C206C6163696E69612065752C206C75637475732076656C2C20616E74652E20457469616D2064696374756D206D6920696E2066656C69732E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20467573636520677261766964612064617069627573206E69736C2E2043726173207669746165206E69736C2E0A0A4D616563656E6173206469676E697373696D2C206C6967756C61206E6F6E20706F727461206375727375732C20656E696D206E756E63206D616C6573756164612073656D2C20657520706F72747469746F72206E756C6C612075726E61206575207175616D2E2046757363652065726F732E20416C697175616D2065726F732E204E616D20617563746F722E204E756C6C61206D6F6C657374696520706F727461206573742E2053757370656E646973736520706F74656E74692E20566976616D7573206D6F6C6573746965206C6F72656D2073656420657261742E20536564206567657420697073756D2E20496E746567657220616C697175616D2070756C76696E6172206E756C6C612E204372617320616C69717565742073656D207574206E756E632E2046757363652066617563696275732074656D707573206C65637475732E204372617320736F64616C65732C206E69736920616320666163696C6973697320756C7472696365732C2065726F73206172637520646170696275732073617069656E2C20657420756C747269636573206D61757269732074656C6C7573206E6F6E20646F6C6F722E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20437261732063757273757320766172697573206D657475732E205574207475727069732E20566976616D7573206567657420746F72746F722E0A0A536564206C616F726565742C2076656C6974206E6F6E20616363756D73616E206375727375732C206E756E632075726E6120706F7375657265206A7573746F2C20696E2064696374756D206C6563747573207065646520696420616E74652E20437261732076756C7075746174652E204372617320636F6E677565206475692073656420656C69742E2050726F696E206C616375732073656D2C20756C7472696365732061742C20636F6E73657175617420696E2C2074656D706F7220717569732C206D657475732E2050726F696E2076656C20617263752E204E616D20657569736D6F642068656E64726572697420656C69742E20557420657261742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2053656420706F73756572652E204D6F7262692065726F732075726E612C2073656D7065722061742C2073656D706572206E6F6E2C20636F6E76616C6C697320717569732C2076656C69742E204D616563656E6173206F7263692E20566573746962756C756D206C6F626F7274697320747269737469717565206D657475732E20566573746962756C756D206C6F72656D206E756C6C612C20736F6C6C696369747564696E2076697461652C20636F6E64696D656E74756D20717569732C20617563746F722075742C206475692E20566976616D757320766573746962756C756D206D61676E61207574206E6973692E2043757261626974757220656C656966656E64206475692076656C206E756E632E20437572616269747572206D6175726973206C616375732C206D616C6573756164612073697420616D65742C207375736369706974207365642C2072757472756D206C75637475732C2074656C6C75732E20496E746567657220666163696C697369732075726E61207669746165206C65637475732E0A0A41656E65616E207175616D206C656F2C206C6F626F7274697320717569732C206D616C6573756164612065752C2076756C7075746174652076697461652C206E69736C2E205072616573656E7420656765742065726F732E205574206665726D656E74756D20747572706973206964207175616D2E204E616D20746F72746F722E205072616573656E74206E6563206F7263692E204E756C6C6120626962656E64756D2061646970697363696E672061756775652E20557420636F6D6D6F646F2C206D61676E61206964206D616C65737561646120677261766964612C206175677565206F64696F206D616C657375616461206D692C20706F727461206D616C65737561646120656C697420657374207669746165206469616D2E204D6175726973206E6F6E206E756C6C612E2053757370656E64697373652074696E636964756E742C206E756E6320756C7472696369657320706F7274612076656E656E617469732C206D6920706564652074696E636964756E74206C696265726F2C20656765742076617269757320616E7465206C696265726F207574206C6967756C612E20437572616269747572207072657469756D20706F72747469746F7220746F72746F722E0A0A4D616563656E617320766974616520656C69742065676574206E69736920646170696275732064696374756D2E204E756E6320696E206C696265726F2E204E756C6C612064696374756D206F726369206575206572617420617563746F72206C6F626F727469732E2050686173656C6C75732072697375732E2053757370656E646973736520706F74656E74692E2053757370656E646973736520706F74656E74692E205072616573656E742061646970697363696E6720636F6E73657175617420656C69742E20496E74656765722069642061756775652E205072616573656E7420696E206A7573746F206E6563206D61676E6120646170696275732070756C76696E61722E2044756973206E69736C2E2053757370656E6469737365206163206F64696F2E20566976616D757320696D706572646965742E20446F6E6563206E6F6E2076656C69742073697420616D6574207269737573206469676E697373696D20636F6E6775652E204E616D20616C697175657420706F73756572652076656C69742E2043726173207475727069732E204D6F726269206D616C657375616461206469676E697373696D206D692E0A0A536564206C656F206E657175652C2076617269757320717569732C2076656E656E61746973207365642C207068617265747261207365642C206573742E204D6F72626920626C616E6469742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E20457469616D2073656D7065722070656C6C656E746573717565206D692E2055742076656C206C6F72656D2E204E756E63206D6920746F72746F722C206C616F726565742061742C2066617563696275732065752C2074696E636964756E742073697420616D65742C20657261742E20447569732074656D706F72206D616C65737561646120697073756D2E2050686173656C6C757320616C69717565742E20446F6E656320657420656C69742E2050656C6C656E7465737175652070757275732E20566573746962756C756D2072757472756D2073656D706572206E6962682E204E756C6C6120666163696C6973692E2050686173656C6C757320657420656E696D2073697420616D657420616E746520766573746962756C756D207665686963756C612E2050686173656C6C7573206964206E69736C2E20446F6E6563206D6F6C6C6973206C656F2061742065726F732E204D61757269732070656C6C656E746573717565206E657175652061742070757275732E204D6F726269207175697320646F6C6F7220617420697073756D207363656C6572697371756520736F64616C65732E20457469616D20766F6C7574706174207475727069732061206D657475732E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206C6F72656D206C6F72656D2C20766573746962756C756D2061632C20657569736D6F6420656765742C20756C6C616D636F72706572206469676E697373696D2C2076656C69742E0A0A43756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E204372617320756C7472696365732C206E6962682076656C20616C697175616D20766573746962756C756D2C2065726F7320656E696D2076656E656E61746973206475692C20696420696163756C697320656E696D206E756E632076656C206D617373612E204D6F72626920656C656966656E64206F726369206574206D617373612E20416C697175616D206572617420766F6C75747061742E204E756C6C61206D6F6C6C69732065676573746173207475727069732E20496E20736F64616C6573206E756E63206567657420746F72746F722E2053656420697073756D2065726F732C2074656D706F7220717569732C20616C69717565742076697461652C20696D70657264696574206E6F6E2C206C6F72656D2E2050656C6C656E746573717565207175697320656C6974206964206D69206C756374757320646170696275732E20536564206E756E6320617263752C2072686F6E637573206E65632C20636F6E76616C6C697320717569732C206375727375732061742C206E657175652E204D617572697320636F6E76616C6C697320707572757320617420657261742E2050656C6C656E74657371756520766573746962756C756D2E20566976616D7573206672696E67696C6C6120656C697420617420617263752E204E756C6C616D20616C697175657420656E696D206E656320617263752E204E616D20696420746F72746F722E204E756C6C612071756973206E756E632E20557420617263752E2053757370656E646973736520706F74656E74692E2050656C6C656E74657371756520756C6C616D636F72706572206C6967756C6120696420617263752E0A0A4E616D206E6F6E206C696265726F207669746165206E69736C207363656C65726973717565206672696E67696C6C612E20517569737175652076617269757320616E7465206964206D657475732072686F6E637573206672696E67696C6C612E204E756C6C6120666163696C6973692E205072616573656E7420656C656966656E6420706F72747469746F72206C6967756C612E20457469616D207175697320646F6C6F72206E6F6E20617567756520636F6D6D6F646F20617563746F722E20446F6E65632061206D692E20566573746962756C756D2074656D706F722E20446F6E65632066656C69732075726E612C20617563746F722061742C206375727375732064696374756D2C20677261766964612069642C20617263752E2041656E65616E2064696374756D206D616C65737561646120646F6C6F722E20566976616D7573206D61747469732E2050686173656C6C757320657520706564652E2046757363652061646970697363696E67206A7573746F206672696E67696C6C61206D657475732E20457469616D20616E74652E20496E7465676572206D6F6C6C6973206D617373612071756973206E756E632E20496E74656765722064696374756D206E65717565206C756374757320656E696D2E0A0A536564206575206C696265726F2E20496E74656765722074656D706F72206C6967756C6120696E2076656C69742E2055742074696E636964756E74206C6163696E69612073656D2E204E756C6C616D2076656C2072697375732E2053656420736F64616C657320616E7465206120646F6C6F722E204375726162697475722065726F732E2053656420736F64616C65732E20536564206E6F6E206D657475732E20566573746962756C756D20656C656D656E74756D20666175636962757320616E74652E204E756C6C612076656C206E6962682E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756E63206E6563206C6F72656D20757420697073756D206C6163696E696120696163756C69732E204475697320657261742E20416C697175616D20657261742E204372617320696163756C69732E20496E206861632068616269746173736520706C617465612064696374756D73742E0A0A4E756C6C616D20616E74652E2043726173207669746165206573742E2050656C6C656E7465737175652076656C206D657475732061206C6967756C612064617069627573206D61747469732E2044756973206665756769617420616C69717565742066656C69732E20457469616D206964206E69736C207175697320657374206469676E697373696D20636F6E64696D656E74756D2E2053757370656E646973736520706F74656E74692E204D6F7262692076656C6974206C6F72656D2C206F726E61726520717569732C2070656C6C656E7465737175652076656C2C20706C61636572617420656765742C20746F72746F722E20566573746962756C756D2074696E636964756E74206D6F6C6573746965206C696265726F2E204E756C6C61206E756C6C6120656E696D2C206D616C6573756164612069642C20756C6C616D636F727065722076697461652C2064696374756D2061742C2070757275732E20446F6E6563206469676E697373696D206F64696F20757420656E696D2E2053757370656E6469737365206174206C65637475732E0A0A5072616573656E74206C6F626F727469732061756775652076656C206C65637475732E20557420696E206C6967756C612075742066656C697320636F6E6775652073757363697069742E2051756973717565206469676E697373696D20746F72746F72207574206D692E204675736365206D61676E61206E6973692C20656C656966656E642061632C206F726E6172652076656C2C20706F72747469746F722076697461652C207175616D2E20566573746962756C756D20736F64616C6573206A7573746F2071756973207475727069732E2046757363652075726E61206E6973692C2072686F6E63757320717569732C20636F6E64696D656E74756D2076656C2C2064696374756D2065752C206E756E632E20467573636520736564206E696268207669746165206F64696F20706F73756572652061646970697363696E672E2053656420706F72746120656C6974207175697320646F6C6F722E204E616D206C696265726F206E756C6C612C20617563746F72207365642C2074696E636964756E7420717569732C2066617563696275732073697420616D65742C206D692E2051756973717565206F7263692E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E756C6C616D2069642073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20446F6E65632076656C2065726F732E0A0A566976616D7573206C7563747573206C6F626F72746973206C656F2E2053757370656E64697373652076656C20656C6974206120656E696D20756C6C616D636F7270657220706F73756572652E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E20446F6E656320717569732070656465206D6174746973206C6563747573206D6F6C6C69732061646970697363696E672E2053656420616363756D73616E20706F737565726520657261742E205072616573656E7420657569736D6F642074696E636964756E742066656C69732E20446F6E6563206D692E20557420636F6D6D6F646F2061726375206C6163696E69612074656C6C75732E20416C697175616D2061206C696265726F2071756973206C65637475732073656D70657220766976657272612E20437572616269747572206C6163696E6961206D61757269732061742074656C6C75732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E756E632073697420616D6574206D61676E61206D6F6C6573746965206F726369207375736369706974206672696E67696C6C612E204675736365207072657469756D206D65747573206E6F6E2073656D2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642068656E6472657269742E204E756C6C612066656C69732E2053757370656E646973736520706F74656E74692E20416C697175616D20626C616E64697420747269737469717565206E657175652E20437572616269747572207175697320657261742076656C206E756E6320616363756D73616E206D6F6C6C69732E0A0A447569732073616769747469732C2074656C6C757320757420616C697175616D206672696E67696C6C612C20646F6C6F72206D6920756C6C616D636F72706572206E69736C2C20757420747269737469717565207065646520656C697420736564206D61757269732E204375726162697475722069642066656C69732E20446F6E65632070756C76696E6172206C61637573206574206C65637475732E20416C697175616D2076756C7075746174652076756C707574617465206D657475732E20437572616269747572206D61676E612066656C69732C2061646970697363696E672061632C20616363756D73616E2076656C2C206D6F6C657374696520717569732C207175616D2E204D617572697320656C697420617263752C207072657469756D2076697461652C206D6F6C6C69732073697420616D65742C20736F6C6C696369747564696E2075742C206D692E20446F6E656320696D70657264696574206469676E697373696D206D692E204E756C6C616D2073697420616D657420746F72746F722E20416C697175616D206E65717565206E756C6C612C2076656E656E6174697320612C20706F72746120696E2C20706C6163657261742074656D7075732C206C616375732E205175697371756520766573746962756C756D20647569206574206C616375732E2050726F696E206469676E697373696D20636F6E7365637465747565722070757275732E20457469616D206772617669646120746F72746F7220696E206E756E632E2055742074656D706F722074726973746971756520746F72746F722E20536564206C616F726565742074696E636964756E74207175616D2E20566573746962756C756D20706F7274612074757270697320757420656C69742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20446F6E6563206E696268206475692C2066657567696174206E65632C206C616F726565742069642C206D616C65737561646120656765742C206E6973692E205574206E65717565206D617373612C207665686963756C612065752C20636F6D6D6F646F206E6F6E2C20756C747269636965732076697461652C2070757275732E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204D617572697320657569736D6F642C2066656C69732076656C2074656D706F7220616C69717565742C20746F72746F72206D6175726973206D616C657375616461206E756E632C2076656C206665726D656E74756D2073656D206469616D206964206475692E204E616D2072757472756D2073617069656E2065676574206F64696F2E20416C697175616D20736564206C696265726F206E6F6E206D692066617563696275732074656D7075732E2046757363652068656E6472657269742C206469616D206E6F6E20766F6C75747061742072757472756D2C2065726174206D657475732076656E656E61746973206C6967756C612C206E6F6E207363656C657269737175652070656465206C6967756C612076656C207175616D2E204D6F7262692072686F6E6375732065726F7320616320647569206665756769617420656C656D656E74756D2E2044756973206575206C696265726F2065742074656C6C757320636F6E67756520766976657272612E204D6F726269207175616D207175616D2C20656C656D656E74756D207365642C20756C6C616D636F7270657220696D706572646965742C20636F6D6D6F646F206E6F6E2C206F64696F2E204E616D20616C697175657420656765737461732075726E612E204D6175726973206F64696F2066656C69732C207661726975732065752C206C6163696E69612065752C20636F6E64696D656E74756D20612C206C65637475732E20536564206A7573746F206D617373612C2070756C76696E61722069642C2076617269757320612C20706F72747469746F72206E65632C206C696265726F2E20457469616D207661726975732E2043757261626974757220736F64616C65732C206F64696F20617420706F73756572652073656D7065722C2065726F73206E6962682074696E636964756E74206C65637475732C2076656C2072757472756D2073617069656E206E69736920696E206C6967756C612E2053757370656E6469737365206567657420617263752E2050686173656C6C757320696D70657264696574206573742061632073617069656E2E20446F6E6563206E756C6C6120746F72746F722C20706C6163657261742076656C2C2074656D70757320612C206C6F626F727469732076656C2C206E6962682E20416C697175616D20766172697573206E6973692E204E756C6C6120657420656E696D2E20467573636520636F6E76616C6C6973206C616F72656574206C616375732E0A0A50686173656C6C757320697073756D20646F6C6F722C206D6F6C657374696520717569732C20636F6E64696D656E74756D20696E2C20636F6D6D6F646F2065752C206469616D2E205175697371756520626962656E64756D206C6163696E6961206475692E204E756C6C616D20626C616E6469742076756C707574617465206F7263692E205574206C6163696E6961206D617373612076656C2061756775652E20416C697175616D20677261766964612C207175616D207175697320696D7065726469657420696D706572646965742C2074656C6C7573206469616D20706861726574726120657261742C206174207068617265747261206C61637573206E6962682065676573746173206D61676E612E204E756C6C61207361676974746973206C6F72656D207574206C6F72656D2E204475697320636F6E64696D656E74756D2C2064756920766974616520616C697175616D20706F73756572652C206469616D207175616D20636F6E76616C6C69732076656C69742C2075742067726176696461206C656F20697073756D206E6F6E2072697375732E205574206665726D656E74756D20736F6C6C696369747564696E20657261742E20446F6E6563207361676974746973207363656C657269737175652066656C69732E204E756E6320617263752E20457469616D2074656D7075732C206D61676E612073697420616D657420737573636970697420657569736D6F642C2065726F732073656D2072757472756D206475692C207669746165207361676974746973206E696268207075727573206E6F6E206C616375732E20536564206D6F6C6C69732061726375206567657420646F6C6F722E20446F6E6563206F726E6172652C20617263752073697420616D6574206665726D656E74756D2076756C7075746174652C20726973757320656E696D206665726D656E74756D206C696265726F2C2061206C6163696E696120646F6C6F72206D69206E6F6E2076656C69742E20457469616D206C6F626F72746973207075727573206120656C69742E204E756E63206E756C6C61206475692C206D617474697320717569732C20626962656E64756D20612C20756C7472696365732061632C2061756775652E20496E20616C697175616D207665686963756C61207475727069732E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E0A0A496E7465676572206964206E69736C2E20517569737175652064696374756D20656C656D656E74756D206F64696F2E2041656E65616E206C75637475732E205365642065752073656D206120706564652076756C70757461746520636F6E64696D656E74756D2E2051756973717565206D61676E612E20446F6E656320616C697175616D206D617474697320697073756D2E204375726162697475722064696374756D20736F6C6C696369747564696E2073656D2E20416C697175616D2070756C76696E61722E204E756E6320736F6C6C696369747564696E207269737573206120657261742E20566976616D757320717569732074656C6C75732073697420616D6574206E69626820766573746962756C756D20636F6E7365717561742E204E756C6C61207072657469756D20736F6C6C696369747564696E20646F6C6F722E20416C697175616D20696163756C69732074696E636964756E74207475727069732E2050686173656C6C757320697073756D206C656F2C2076656E656E6174697320696E2C20736167697474697320696E2C206F726E6172652061742C206E756E632E0A0A50656C6C656E74657371756520756C7472696365732C2064756920657520696163756C6973206C75637475732C2074656C6C757320617567756520766F6C75747061742073617069656E2C20696E206469676E697373696D2075726E612066656C6973207574206D692E205365642061726375206475692C206469676E697373696D2069642C20706F72747469746F722075742C20696D706572646965742076697461652C20616E74652E204E756C6C61206475692073656D2C20636F6D6D6F646F206E65632C2073616769747469732065742C206C6163696E69612065742C20706564652E20457469616D20656C656966656E6420647569207574206E69736C2E20446F6E656320616E7465206D61757269732C2074656D7075732073697420616D65742C207661726975732076697461652C206772617669646120717569732C206D692E20496E207363656C657269737175652C2066656C697320766974616520766976657272612073616769747469732C2076656C6974206D6574757320756C74726963696573206E657175652C207175697320696D706572646965742076656C697420656C6974206574206D61676E612E2053757370656E646973736520706F74656E74692E205365642076656C69742065726F732C20657569736D6F64207365642C20636F6E64696D656E74756D206E65632C206661756369627573207365642C2073617069656E2E204E616D20616363756D73616E206C6967756C612073697420616D6574206E657175652E20416C697175616D206572617420766F6C75747061742E0A0A566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B204E616D20657520706564652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B205365642065752066656C69732073656420746F72746F722074656D706F72206665726D656E74756D2E2050686173656C6C757320636F6D6D6F646F2073656D2076656C206E69736C2E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050726F696E206C656374757320656C69742C2070686172657472612073697420616D65742C20616363756D73616E207365642C2074696E636964756E742065742C206D61757269732E204475697320646170696275732070686172657472612073656D2E20496E746567657220696E206A7573746F2E205072616573656E742065726F732E20566573746962756C756D20616320616E74652E20416C697175616D207363656C657269737175652073656D2070656C6C656E746573717565206E69626820636F6E73656374657475657220736F64616C65732E20416C697175616D20636F6E736563746574756572206F64696F2E2044756973206C6563747573206F64696F2C206C75637475732065752C20636F6D6D6F646F20717569732C206D6F6C6C69732076697461652C2076656C69742E2043726173206E6563206E756E63206E6F6E20656C697420696163756C6973206D61747469732E2041656E65616E206A7573746F206E657175652C20736F6C6C696369747564696E20656765742C20756C6C616D636F7270657220656765742C20656765737461732069642C2073656D2E20496E2065752072697375732E2053656420656765737461732E0A0A496E7465676572206174206E657175652E20536564207072657469756D207363656C65726973717565206E756C6C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20467573636520757420706564652E20457469616D207669746165207175616D20612075726E612076617269757320696D706572646965742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2044756973207665686963756C612E20467573636520756C6C616D636F72706572206E696268206E6F6E20657261742E205175697371756520696E206E657175652E205072616573656E74206573742E2050656C6C656E74657371756520617263752E0A0A50726F696E20706F73756572652E2053757370656E646973736520706F74656E74692E20496E74656765722066656C6973206C616375732C20616C697175616D207365642C2076756C70757461746520696E2C206D6F6C6C69732076656C2C2074656C6C75732E20496E7465676572207665686963756C6120626962656E64756D206573742E204E756E63206E6F6E20646F6C6F7220696E2074656C6C7573206D617474697320666163696C697369732E20496E746567657220766573746962756C756D2C20617567756520617420636F6D6D6F646F20616C697175616D2C2064756920657374206D6174746973206C6967756C612C2073697420616D65742061646970697363696E67206F7263692073656D207669746165206D61676E612E205072616573656E7420656E696D2076656C69742C206D616C6573756164612061742C20636F6E677565206E65632C206C756374757320696E2C206A7573746F2E20536564207661726975732E204D6F7262692070686172657472612E20446F6E6563206575206D61737361206E65632074656C6C75732076756C7075746174652070756C76696E61722E20557420636F6D6D6F646F20747572706973206E6F6E2073656D2E20557420636F6E76616C6C697320756C6C616D636F727065722072697375732E20457469616D20696E74657264756D2070656465206964206E6973692E2043726173206D61676E612073617069656E2C20737573636970697420612C206C616F72656574206E6F6E2C2072686F6E6375732065742C2066656C69732E20496E7465676572206F726369206C6F72656D2C20766573746962756C756D2064696374756D2C20756C6C616D636F7270657220612C20706F72747469746F722065742C206475692E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E0A0A4E756E63206574206D61676E612E2053656420626962656E64756D2074656C6C757320696E206469616D2E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E204E616D20766974616520746F72746F722E20496E7465676572206D61676E612E20447569732076656E656E617469732C206C656F2061632074656D706F72206C616F726565742C20656C6974206E756C6C6120706861726574726120706564652C206E6F6E206665726D656E74756D206E756E63206F64696F2061206F64696F2E2050726F696E206E6F6E2076656C69742E2053656420696D706572646965742061756775652071756973206E69736C2E20496E746567657220636F6E64696D656E74756D206E69736C206E6563206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20566976616D757320706C616365726174206C696265726F2E204475697320636F6E6775652064696374756D206D61676E612E20416C697175616D206461706962757320626962656E64756D20656E696D2E204E756E6320656C656966656E6420706564652076656C20697073756D2E0A0A457469616D2076697461652076656C69742E204D61757269732065726174206E756E632C206D616C6573756164612075742C20666575676961742061632C20706C61636572617420636F6E64696D656E74756D2C2061756775652E204E616D20766F6C75747061742E20416C697175616D207665686963756C6120697073756D206964206F64696F2E20566976616D757320736F6C6C696369747564696E207475727069732069642073617069656E2E20467573636520612066656C6973207669746165206F64696F20636F6E76616C6C697320626C616E6469742E204375726162697475722076697461652065726F732069642065726F7320706F727461207072657469756D2E204E756C6C6120696E206D61676E6120656765742075726E61206C6163696E696120636F6E76616C6C69732E20416C697175616D206D61747469732076656E656E617469732070757275732E2053656420736564206D69206567657420657261742074726973746971756520706F7274612E20446F6E656320617563746F7220646F6C6F72206120657261742E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20496E206E6563206C6967756C612E204E756E6320656C656966656E642E20566573746962756C756D2071756973206E697369206567657420656C697420706F72747469746F7220636F6E6775652E204D616563656E61732066617563696275732C206D61676E6120656765742061646970697363696E672074696E636964756E742C20646F6C6F7220616E7465206D616C65737561646120656C69742C206E6F6E20656C656D656E74756D206C616375732074757270697320696E20706564652E0A0A5574206D616C657375616461206D69206E6563206D657475732E205072616573656E7420617563746F72206175677565206163206E69736C20756C7472696369657320666163696C697369732E204E616D2070757275732073617069656E2C2070656C6C656E746573717565206469676E697373696D2C20706F73756572652065752C206375727375732069642C206469616D2E205175697371756520736F6C6C696369747564696E2C20656C697420612070656C6C656E746573717565207363656C657269737175652C206C6F72656D20726973757320617563746F72207175616D2C207175697320636F6E7365717561742074656C6C7573206E657175652069642075726E612E2053757370656E6469737365206469616D20746F72746F722C20656C656966656E64206469676E697373696D2C20656765737461732075742C206C756374757320696E2C20616E74652E204475697320616E74652E204D616563656E6173206C75637475732E20437572616269747572206375727375732070686172657472612075726E612E204D616563656E617320696D706572646965742C2065726174206E6F6E20656C656D656E74756D20657569736D6F642C20746F72746F72206F64696F20657569736D6F64206C65637475732C20616320666163696C697369732073656D206E696268207669746165206E756C6C612E204E756E6320677261766964612E204D6F72626920736F6C6C696369747564696E206F64696F2071756973206C616375732E20416C697175616D2061206E696268206E6F6E2075726E6120706F72746120696D706572646965742E20416C697175616D206572617420766F6C75747061742E20496E20696163756C6973206C6163696E69612076656C69742E20536564206C696265726F206C616375732C207472697374697175652065752C206C6163696E69612061632C20616C697175657420656765742C2075726E612E0A0A457469616D206174206E69736C2E2050686173656C6C7573206661756369627573206C7563747573206C65637475732E20557420706C6163657261742076756C70757461746520646F6C6F722E2050686173656C6C75732076656C2076656C69742E204D6F72626920766976657272612E2050686173656C6C7573206F7263692E20496E7465676572206469676E697373696D206D6174746973206D61757269732E2050656C6C656E74657371756520706F7375657265206C656F20706F7375657265207175616D2E2051756973717565206E6563206D61676E61206174206469616D20766976657272612070656C6C656E7465737175652E2053757370656E64697373652076656C697420617263752C20756C7472696369657320717569732C20636F6E67756520612C2076656E656E6174697320656765742C206C616375732E20496E74656765722073616769747469732068656E64726572697420646F6C6F722E2046757363652074696E636964756E7420616E746520612073656D2E0A0A4D616563656E617320636F6E7365637465747565722C206A7573746F207365642072686F6E6375732076656E656E617469732C206E69626820617263752072757472756D20646F6C6F722C2073656420636F6E64696D656E74756D206C696265726F206C696265726F20657420697073756D2E20566976616D7573206D6174746973206A7573746F207574206C6F72656D2074696E636964756E74206C6F626F727469732E205574206E6F6E2076656C6974206964206E6571756520616C697175657420616363756D73616E2E205365642074656D7075732076697665727261206E756C6C612E2043757261626974757220756C6C616D636F727065722C206E6571756520717569732064617069627573207363656C657269737175652C2066656C6973206469616D2067726176696461206F7263692C206E6F6E20637572737573207175616D206E6571756520766974616520656C69742E20457469616D2070686172657472612074696E636964756E74206C616375732E204475697320657569736D6F64206672696E67696C6C61206573742E20457469616D206F726E6172652074696E636964756E74206C65637475732E2050726F696E20696E207475727069732E204E756E6320626C616E64697420626C616E646974207475727069732E2041656E65616E2075742061756775652E2044756973206F726369206A7573746F2C2074696E636964756E742065752C2072757472756D207365642C2072757472756D2065742C207475727069732E2043757261626974757220666163696C69736973206F64696F20696E20616E74652E20496E206861632068616269746173736520706C617465612064696374756D73742E205365642065726F73206573742C2070656C6C656E7465737175652061742C2074696E636964756E742065752C20756C74726963657320717569732C206D657475732E204D6F7262692073697420616D6574206A7573746F2E204D616563656E617320616320617263752E204D6175726973206469676E697373696D2E0A0A50656C6C656E74657371756520756C747269636965732072757472756D206F7263692E2041656E65616E206F726E6172652E20566976616D75732065752072697375732076656C206D6175726973206C6F626F727469732064696374756D2E205365642065742074757270697320617563746F72206D692072686F6E6375732070756C76696E61722E20536564206E6563206E756E6320612070757275732074656D706F7220766976657272612E2050656C6C656E7465737175652073757363697069742E20446F6E656320747269737469717565207269737573206E6F6E206E6962682E20457469616D206E69736C206D61676E612C20736F6C6C696369747564696E2075742C20756C7472696365732073697420616D65742C20656765737461732065752C206E756C6C612E20416C697175616D206572617420766F6C75747061742E20566573746962756C756D2070686172657472612E2053656420656765737461732C206D657475732073697420616D6574206C6F626F7274697320636F6E7365717561742C206572617420656C697420696D70657264696574206C696265726F2C20657520696E74657264756D207175616D206D61737361206567657420646F6C6F722E2053757370656E6469737365207669746165206F64696F2E2050726F696E20626C616E646974206D617572697320696163756C6973206D657475732E0A0A566976616D757320766573746962756C756D2E20457469616D206574206E69736C2E20416C697175616D20696E206469616D2076656C20656C697420706C6163657261742073757363697069742E204475697320736F64616C6573207075727573206163206E6962682E204E756C6C6120696E206F64696F206567657420656E696D206C756374757320626C616E6469742E2043757261626974757220756C74726963657320697073756D206E6F6E206E65717565206567657374617320656C656966656E642E20536564207475727069732E2050726F696E20636F6E7365637465747565722E20566976616D7573206D61747469732E20496E20616C69717565742E0A0A4E756E632069642065726F732E20446F6E65632076656E656E617469732C206E756C6C61206574206D6174746973206C75637475732C20616E7465206C656F2073656D706572206A7573746F2C206E6F6E2061646970697363696E67206F64696F20726973757320736564206C616375732E205072616573656E7420766974616520726973757320636F6E677565206C696265726F20636F6E6775652074656D7075732E2050686173656C6C75732061632065726F732E204E756C6C61207665686963756C612C206C6F72656D20696E20616C69717565742073757363697069742C2061726375206572617420656765737461732073656D2C2071756973206C6F626F72746973207175616D20616E7465206575206D617373612E20437572616269747572206E6F6E206D617373612E2053656420626962656E64756D206C6163696E6961206F64696F2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20566976616D757320766F6C757470617420626C616E646974206C616375732E2050726F696E20706F7274612C2074656C6C757320757420617563746F72206C616F726565742C206C65637475732065726F73206665726D656E74756D206C65637475732C2069642073616769747469732061726375206A7573746F20696E207475727069732E2050686173656C6C757320636F6E7365717561742E204E616D2070656C6C656E7465737175652C206D69206964207669766572726120636F6E76616C6C69732C206E756E63206C696265726F20706C616365726174206C656F2C20656C656966656E6420706F7274612073656D206E69736C2076697461652073617069656E2E2050656C6C656E746573717565206C6967756C61206C696265726F2C20747269737469717565206E6F6E2C20706F72747469746F722072757472756D2C20706F72747469746F72206E6F6E2C20657261742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E74656765722064696374756D2074656C6C7573206120746F72746F722E20566976616D75732066656C6973206E756E632C206D6F6C6573746965206E6F6E2C2072686F6E63757320717569732C2070686172657472612069642C206475692E20446F6E6563207269737573206D657475732C206672696E67696C6C612076656C2C20616C69717565742065752C20706C6163657261742069642C206E657175652E0A0A53757370656E646973736520697073756D2E20566976616D7573206C65637475732E2053656420766976657272612C206D61737361206567657420636F6E76616C6C6973206D61747469732C207175616D2074757270697320636F6E736563746574756572206E756E632C206567657420706F7375657265206D61676E612073656D2069642076656C69742E20496E206E6563206D61757269732E2041656E65616E206120707572757320736564207175616D206C6F626F72746973206672696E67696C6C612E2050726F696E20756C74726963696573206C6163696E696120616E74652E205365642061646970697363696E67206572617420717569732076656C69742E204E756C6C616D207669746165206E69736C206964206A7573746F20736F6C6C696369747564696E206D6F6C65737469652E204E756C6C6120666163696C6973692E20536564206E65632075726E6120736564206E69736C206672696E67696C6C6120646170696275732E204E756C6C61206174206469616D2E20416C697175616D2065676574206E6962682E204E756E63206163206E6973692073697420616D65742074656C6C757320656765737461732074656D7075732E204E616D207363656C657269737175652075726E61206574206E657175652E20446F6E656320657374206F7263692C207361676974746973206E6F6E2C2076756C70757461746520612C20636F6D6D6F646F2065742C2061756775652E205574206461706962757320746F72746F722E205574206E756E632E20446F6E65632064696374756D2064617069627573206F64696F2E204E616D20756C7472696369657320756C6C616D636F72706572206C6967756C612E2050656C6C656E74657371756520616363756D73616E20766172697573206C656F2E0A0A4D6F72626920657569736D6F64206C616F7265657420657261742E20566976616D7573207175697320697073756D2E204D6F72626920657569736D6F642E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E2053757370656E64697373652076656C2070757275732E204E756C6C616D206174206D61676E612E20437572616269747572206C61637573206C6F72656D2C20696163756C697320717569732C2064617069627573206E6F6E2C20766F6C75747061742076656C2C206E756C6C612E20446F6E656320757420617263752072686F6E63757320646F6C6F72207072657469756D2064696374756D2E204E756C6C616D2076656C206D657475732E20557420617263752E2050656C6C656E746573717565206E697369206E756E632C20706C61636572617420656765742C2074696E636964756E742076656C2C207068617265747261206E6F6E2C206E756E632E20496E74656765722074696E636964756E7420756C74726963696573206C65637475732E20496E74656765722073656D7065722C2070757275732073656420756C74726963657320666575676961742C206E756C6C61207065646520736F6C6C696369747564696E20657261742C2076656C20617563746F72206E756C6C6120697073756D2076656C206C65637475732E2041656E65616E206D692E0A0A4E756C6C616D20736564206E697369206574206172637520696D70657264696574206665726D656E74756D2E204D6175726973206E6563206D657475732E20496E20616320646F6C6F722E20496E206D6920617263752C20636F6E6775652061632C207068617265747261206E65632C207363656C657269737175652073697420616D65742C206D61676E612E20437572616269747572206C616375732E2043757261626974757220657420656C69742E20416C697175616D20756C6C616D636F72706572206E756E6320657520656C69742E2053656420636F6E76616C6C697320646F6C6F722061742076656C69742E20566573746962756C756D20646170696275732C20617567756520696420636F6E73656374657475657220706C6163657261742C206E756E63206D6173736120626C616E6469742073617069656E2C20696420616C697175616D20656C6974206E697369206964206D692E2050686173656C6C75732073617069656E206573742C20677261766964612065752C20626962656E64756D2075742C2061646970697363696E6720717569732C206573742E205574206D6F6C6573746965207175616D207669746165206F64696F2E20446F6E65632071756973207269737573206964206572617420666175636962757320736F6C6C696369747564696E2E204E616D2069642066656C69732E204D61757269732073656420656E696D207669746165206C656F20616363756D73616E207072657469756D2E0A0A4E616D206A7573746F2E20446F6E656320747572706973206E69736C2C20636F6D6D6F646F2065742C20696E74657264756D2061632C20636F6E736563746574756572206E6F6E2C206D617373612E2046757363652073656D206D657475732C206C616F72656574206E65632C20706F73756572652069642C20696D7065726469657420696E2C2076656C69742E20446F6E65632076756C707574617465206A7573746F2065676574207475727069732E204E756C6C6120706564652E204D6F7262692074696E636964756E742E20467573636520616C69717565742C207175616D20657420616C697175616D206672696E67696C6C612C20616E746520616E746520696163756C6973206475692C206E656320616C697175616D20617263752070757275732073656420657261742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2050686173656C6C7573207375736369706974207175616D206574206573742E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B0A0A496E7465676572207365642074656C6C75732E20536564207365642076656C697420756C74726963696573206C656F2072757472756D206C616F726565742E20536564206E6F6E2065726F7320616320707572757320736167697474697320666575676961742E204C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747565722061646970697363696E6720656C69742E205365642068656E647265726974206C6967756C612073697420616D6574206E6962682E204D616563656E6173207475727069732E204D6F72626920636F6E7365637465747565722C20646F6C6F722065742061646970697363696E6720696D706572646965742C20616E7465206E65717565206665756769617420646F6C6F722C20617420706F727461207175616D206E657175652071756973206C6967756C612E204D61757269732073656D7065722076656C69742073697420616D657420697073756D2E2050656C6C656E7465737175652074656D7075732C20707572757320696E2072757472756D20636F6E7365717561742C20656E696D2065726174207665686963756C61206D617373612C20696420616363756D73616E206C656F2073617069656E206E65632070757275732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20496E20646F6C6F722E20496E746567657220666163696C69736973206C696265726F2073697420616D657420706564652E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2055742076617269757320616C697175657420656E696D2E204E756C6C6120666163696C6973692E2043757261626974757220636F6E7365637465747565722C206F64696F206575207072657469756D2074696E636964756E742C206E756E63206E69736920616C6971756574206E657175652C2076656C20696D7065726469657420656C6974206D617373612073697420616D6574207475727069732E2050656C6C656E7465737175652074656D7075732C206F72636920766F6C757470617420626C616E646974206672696E67696C6C612C206F64696F2073656D20706F737565726520616E74652C20766974616520626962656E64756D2075726E61206C6F72656D2076697461652065726F732E205072616573656E7420766976657272612072686F6E63757320617263752E2053656420617563746F722C206573742073697420616D6574206D6F6C6C6973206D6F6C6C69732C207175616D207175616D20677261766964612073617069656E2C20696E20636F6D6D6F646F206D65747573206E756C6C6120617563746F7220656E696D2E20446F6E656320666163696C697369732E0A0A50726F696E2074696E636964756E742C2073617069656E206567657420756C747269636965732061646970697363696E672C20657374206F64696F2064696374756D20617263752C207574206D6F6C6C69732065726174206475692073697420616D65742076656C69742E204D6F726269206573742073656D2C20696E74657264756D2061742C20636F6E67756520612C20656C656D656E74756D2076697461652C206D657475732E2053757370656E64697373652069642061756775652E204D617572697320656E696D2073656D2C2070756C76696E617220656765742C2074656D70757320612C2074656D7075732073697420616D65742C2073617069656E2E20467573636520766573746962756C756D20636F6E736563746574756572206475692E2050656C6C656E74657371756520657261742E20536564206469676E697373696D20706C616365726174206F64696F2E204D616563656E61732073656D7065722072686F6E637573206C65637475732E2050686173656C6C7573207072657469756D2E2044756973206C696265726F20656C69742C20656C656966656E64206E65632C20656765737461732075742C20637572737573207365642C2066656C69732E204E616D206E69736C20617263752C20616C69717565742065742C20666163696C697369732065752C206C75637475732075742C2072697375732E20457469616D20756C7472696365732C20646F6C6F722073656420766F6C7574706174206D616C6573756164612C20747572706973206172637520696D7065726469657420746F72746F722C20657569736D6F6420636F6D6D6F646F206C696265726F206D61737361207574207175616D2E20496E7465676572206D6F6C6573746965207075727573206E6F6E20656C69742E2055742076656E656E617469732073656D70657220746F72746F722E20457469616D20626962656E64756D206567657374617320697073756D2E204D617572697320736F6C6C696369747564696E2073656D206E6563206E6962682E204E756C6C61207072657469756D206D65747573206575206D657475732E2050656C6C656E7465737175652073697420616D65742073656D2E0A0A53757370656E6469737365206163206E6973692E205574206C656F2E20566573746962756C756D2068656E647265726974207072657469756D20646F6C6F722E204E756E632066657567696174206D616C6573756164612070757275732E2043726173206574206E6962682E20437572616269747572206E756E6320657261742C206D616C6573756164612076697461652C206C616F726565742061632C20756C7472696369657320696E2C2070757275732E20566976616D75732074656C6C757320617263752C20736F64616C65732065752C20666163696C6973697320612C206C6163696E6961206E65632C206E756E632E2050656C6C656E7465737175652069642076656C69742E20496E206575206E6962682E204E756E63206E656320657261742E205365642064696374756D206E65717565207574206E69736C2E0A0A4D6F726269206C65637475732074656C6C75732C2074696E636964756E742061632C20706F72747469746F722061632C2074726973746971756520696E2C2065726F732E20446F6E6563206C7563747573206C7563747573206C656F2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2046757363652075742065737420657420656E696D207363656C6572697371756520616363756D73616E2E20446F6E6563206C6967756C612066656C69732C206C6163696E696120717569732C2070656C6C656E74657371756520696E2C2073656D70657220766573746962756C756D2C20656C69742E204D61757269732065676574206F72636920612066656C697320636F6E677565207665686963756C612E20557420736F6C6C696369747564696E2E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E204E756C6C616D20696420646F6C6F72207574206C6F72656D206469676E697373696D2076656E656E617469732E2053757370656E64697373652076697461652073617069656E2E2050726F696E206E6F6E206D61676E612075742065726F7320766976657272612070756C76696E61722E20446F6E65632071756973206F64696F2E204E756C6C616D206E6F6E20617263752076656C206C6F72656D20737573636970697420616C697175616D2E20416C697175616D2072757472756D2074757270697320696E206C656F2E0A0A5574206C7563747573206E6962682074726973746971756520657261742E2053757370656E646973736520626962656E64756D206F64696F20766974616520746F72746F722E20446F6E6563206C6163696E69612E204372617320736F64616C65732066656C6973206C7563747573206E756C6C612E204E616D20656C656966656E64207361676974746973206C6967756C612E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E64697373652076656C206E657175652E204D6F72626920616C6971756574207665686963756C61206D61676E612E2041656E65616E206174206F64696F2E20447569732070656C6C656E746573717565206D61676E612E204E756C6C6120617420746F72746F72207574206469616D2064696374756D2066617563696275732E204D617572697320717569732076656C69742E20446F6E6563206E6F6E2074656C6C7573207669746165206C6F72656D206672696E67696C6C6120706F72747469746F722E2046757363652075742073617069656E207175697320746F72746F7220666575676961742073616769747469732E20446F6E656320766976657272612073656D2076697461652073617069656E2E205072616573656E7420736F64616C65732C206C6163757320696E206672696E67696C6C6120766976657272612C206F64696F2061756775652061646970697363696E672075726E612C20766974616520696E74657264756D20616E74652073656D206E6F6E206E6973692E204E756C6C616D20746F72746F72206C6F72656D2C20656C656966656E642061632C206D6F6C6C6973206E6F6E2C206C616F726565742061632C2072697375732E20496E7465676572206F726E617265206C656F20736564206A7573746F2E2051756973717565206375727375732C2073656D206E6F6E20666163696C6973697320626962656E64756D2C206E697369206D69207661726975732066656C69732C206665726D656E74756D2066657567696174206C6F72656D2065726F73206C616F726565742072697375732E0A0A517569737175652073697420616D657420657374206574206C6F72656D207665686963756C61206C6163696E69612E20446F6E6563206E656320746F72746F722E2043726173206F64696F2E204E616D207363656C657269737175652076756C7075746174652075726E612E205072616573656E74206475692E20457469616D206E6563206E69736C206C6F626F7274697320697073756D20616C69717565742074656D7075732E204D616563656E6173207072657469756D20736F6C6C696369747564696E206D61757269732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050686173656C6C7573206175677565206D617373612C20636F6E67756520656765742C20636F6E76616C6C697320656765742C207472697374697175652073697420616D65742C2065726F732E2053656420636F6E736571756174206E6973692065752066656C69732E2050656C6C656E746573717565206A7573746F2E2053757370656E6469737365206E6F6E2061756775652E20496E206469676E697373696D206C6F626F72746973206D61757269732E204D61757269732073616769747469732E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E0A0A5365642061646970697363696E672E20446F6E656320612074656C6C75732076697461652065737420637572737573207665686963756C612E204E616D20616E74652073656D2C20736F64616C65732069642C206672696E67696C6C612076656C2C20636F6E64696D656E74756D2076656C2C206E756C6C612E205175697371756520736F64616C65732E20457469616D20696D7065726469657420656C6974206964206F64696F2E20416C697175616D206572617420766F6C75747061742E204D616563656E617320706F7274612074656D706F7220617263752E204E756C6C612073656D2061756775652C2070656C6C656E7465737175652061632C20636F6E7365717561742075742C20636F6E64696D656E74756D20657569736D6F642C2072697375732E2053656420616C697175616D2074696E636964756E74206D692E20496E20696E74657264756D206C6F626F72746973206F7263692E0A0A536564207665686963756C612068656E6472657269742070757275732E20457469616D2061206469616D2E2043757261626974757220636F6E76616C6C69732E2053757370656E64697373652061206E6973692E20446F6E6563206964206D61676E6120696E207175616D20736F6C6C696369747564696E20756C747269636965732E20446F6E656320766976657272612E205175697371756520766F6C757470617420657374207365642073656D2E20416C697175616D206A7573746F2E20566573746962756C756D20746F72746F72206D617373612C20706F72747469746F72207365642C2076617269757320717569732C20696163756C697320717569732C206F64696F2E20416C697175616D2065676574206E657175652E0A0A4D6175726973206E756C6C612E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20566573746962756C756D206575207175616D20696E206E6571756520756C7472696365732070656C6C656E7465737175652E204372617320696E20646F6C6F722071756973207175616D207661726975732068656E6472657269742E20416C697175616D206E697369206C616375732C206C6F626F727469732065752C20636F6E76616C6C69732073697420616D65742C20666163696C697369732075742C206D692E20416C697175616D206174206E657175652E204372617320736167697474697320656C656D656E74756D206A7573746F2E20566573746962756C756D207574206C656374757320616C6971756574207075727573206D616C65737561646120766F6C75747061742E2044756973206174206C616375732061646970697363696E67206C696265726F2074696E636964756E7420766573746962756C756D2E204D6F7262692061206C696265726F2E20437261732070757275732E204D6F72626920757420617567756520657420707572757320696E74657264756D207363656C657269737175652E20496E74656765722061206475692E20496E206861632068616269746173736520706C617465612064696374756D73742E2044756973207068617265747261206D657475732065676574206D61757269732E20416C697175616D20696E74657264756D20756C6C616D636F72706572206D617373612E0A0A457469616D206F726E6172652E204E756C6C616D20657569736D6F642E2041656E65616E20636F6E7365717561742067726176696461206C6967756C612E20416C697175616D206573742E2050726F696E207669746165206C616375732E205072616573656E7420612065726F732073697420616D657420647569206C756374757320636F6D6D6F646F2E2050686173656C6C7573207665686963756C612061726375206567657420646F6C6F722E205072616573656E74206665726D656E74756D20636F6E677565206C656F2E20416C697175616D20766F6C7574706174207075727573207574206C6F72656D2E2046757363652068656E64726572697420656E696D206174206C656F2E20416C697175616D2072686F6E637573206E69736C2E20566976616D75732064696374756D2065676573746173206D692E2053757370656E64697373652070656C6C656E74657371756520626962656E64756D20646F6C6F722E2050656C6C656E7465737175652074696E636964756E742C207475727069732073656D7065722070656C6C656E74657371756520636F6E64696D656E74756D2C20697073756D206D6574757320736F64616C6573206C6967756C612C20696420766F6C7574706174206469616D2074757270697320757420656C69742E0A0A5072616573656E7420736564206C616375732E204E616D20656C656966656E64206D6F6C6573746965206D61757269732E20446F6E65632064617069627573206665726D656E74756D206D617373612E20446F6E656320766976657272612066617563696275732070757275732E2043757261626974757220636F6E6775652C206C696265726F20766974616520766976657272612070656C6C656E7465737175652C206469616D2076656C697420736F64616C657320656E696D2C20736564207375736369706974206C6563747573206E697369206E6563206E657175652E20566573746962756C756D206D616C6573756164612C206C616375732061742063757273757320636F6E6775652C2076656C6974206C65637475732074726973746971756520646F6C6F722C2073697420616D657420736F64616C6573206E6571756520697073756D2061206C696265726F2E20566573746962756C756D206574207175616D2E2043757261626974757220706C6163657261742E20437572616269747572206E756E6320617263752C20657569736D6F64206E65632C2076756C7075746174652068656E6472657269742C20616C697175657420656765742C207175616D2E204375726162697475722076656C20656E696D2E2053757370656E646973736520706F74656E74692E0A0A4E756E6320636F6E736571756174206F726369207574206C616375732E2046757363652076656C697420646F6C6F722C2064617069627573207365642C20626C616E6469742073697420616D65742C2072686F6E6375732069642C2072697375732E20447569732075726E61206E6962682C207363656C6572697371756520717569732C206461706962757320612C207363656C65726973717565207365642C206E6962682E20446F6E6563206C75637475732E205574206575206D617572697320637572737573206469616D206C6163696E69612072686F6E6375732E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B20416C697175616D207665686963756C61206D6F6C6573746965206A7573746F2E204D616563656E617320696D70657264696574207065646520736564206D692E2053757370656E6469737365206E756C6C6120646F6C6F722C2068656E64726572697420656765742C2068656E6472657269742069642C2064696374756D2076656C2C206C656F2E204475697320616363756D73616E2E2043757261626974757220696E2066656C69732E204E756E63206C6F72656D2E205574206C656F20646F6C6F722C206C616F72656574206E65632C2076756C7075746174652061742C20656C656966656E6420696E2C206E756C6C612E2051756973717565206E756E632070757275732C2076617269757320656765742C20616363756D73616E206E65632C20616C69717565742065742C206E6962682E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E20437261732061646970697363696E67207669766572726120646F6C6F722E204D617572697320706F72747469746F7220756C7472696365732070757275732E204E756C6C6120666163696C6973692E205072616573656E7420666175636962757320616E7465207669746165206D61757269732E0A0A5072616573656E74206C6163696E6961206C656374757320736564206E69736C2E20496E2074656D70757320636F6E677565206D61757269732E20496E746567657220666163696C69736973206F726E61726520656E696D2E204E756C6C61206964206D617373612E20446F6E656320636F6D6D6F646F206469616D2061742074656C6C75732E204E616D20646170696275732076697665727261206573742E204E616D2074656C6C75732E205072616573656E742061206C696265726F2E20496E206661756369627573206573742065676574206E6962682E204E756C6C612065726F73206F7263692C20696D70657264696574206E6F6E2C20626C616E646974206E6F6E2C2074656D706F7220656765742C206D692E2050656C6C656E74657371756520636F6E76616C6C69732E0A0A517569737175652065676574206D69206163206C656F20657569736D6F642066617563696275732E2050686173656C6C75732072686F6E637573207075727573206964206475692E20566573746962756C756D206D616C65737561646120656C656966656E6420616E74652E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2050656C6C656E74657371756520626C616E646974206D6174746973206F64696F2E2053757370656E646973736520636F6E7365717561742C206C65637475732061632073656D70657220736F6C6C696369747564696E2C206D692076656C69742064696374756D2061756775652C2061632074656D70757320646F6C6F7220657261742073697420616D6574206475692E2050726F696E2068656E6472657269742C2066656C6973207175697320766F6C757470617420706F73756572652C206469616D206F64696F206D616C657375616461206F64696F2C206120696E74657264756D206F726369206469616D20717569732073617069656E2E2050656C6C656E746573717565206F64696F206F64696F2C20766976657272612076656C2C20677261766964612065752C206D6F6C6573746965207365642C206E756C6C612E2050686173656C6C7573206D617572697320706564652C20636F6D6D6F646F2075742C20657569736D6F642065752C2068656E6472657269742065752C206573742E20496E206861632068616269746173736520706C617465612064696374756D73742E204E756C6C6120656C656D656E74756D206C616375732065752061756775652E2053656420657261742E2050726F696E20706F7274612E204D616563656E61732071756973206D692E2050686173656C6C757320617420656E696D206163206A7573746F206772617669646120756C7472696365732E2043726173206C656F2E0A0A496E746567657220757420617263752E20446F6E656320736564206D61676E612E2050726F696E2066656C69732E20496E20696163756C69732C206C6967756C61206964206672696E67696C6C61207072657469756D2C206E696268206469616D20616363756D73616E2074656C6C75732C206567657420616363756D73616E206D657475732064756920766172697573207475727069732E2050686173656C6C7573206F726369206D657475732C20656C656966656E64207365642C2074656D706F722061632C207363656C657269737175652061632C2075726E612E20496E74656765722076697665727261206E657175652061206D61757269732E204D617572697320706F72747469746F7220646F6C6F722065752076656C69742E20496E7465676572206F64696F20656C69742C20766573746962756C756D2075742C20766F6C75747061742069642C2072686F6E63757320636F6D6D6F646F2C2075726E612E20457469616D20706C61636572617420706861726574726120657261742E2055742074656D706F72206573742E20496E7465676572206469676E697373696D20626C616E6469742074656C6C75732E204D6F726269206E69626820646F6C6F722C207363656C657269737175652069642C20636F6D6D6F646F206D616C6573756164612C206D61747469732061742C206D692E20437261732074696E636964756E7420636F6D6D6F646F2070757275732E20496E2074696E636964756E742E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D20756C6C616D636F727065722E2055742068656E6472657269742E204D6F72626920756C7472696365732E0A0A5072616573656E7420696163756C69732C2065726F73206163206567657374617320736F64616C65732C2075726E61206C656F206665726D656E74756D206C6967756C612C2073697420616D657420616C697175616D2076656C69742073656D206E6F6E2070757275732E20446F6E65632072757472756D206172637520717569732070757275732E204E616D20706F73756572652C206C6163757320617420636F6E73657175617420706C6163657261742C206E756C6C61207065646520706F7375657265206F7263692C206E6F6E20657569736D6F6420747572706973206475692071756973206E69736C2E2050726F696E20706F7274612061646970697363696E67206E6962682E20446F6E65632074726973746971756520646F6C6F722061742074656C6C75732E20446F6E6563206E65717565206D617373612C20617563746F722069642C2066617563696275732076697461652C20756C6C616D636F727065722076656C2C206E6973692E2050726F696E206D6F6C6573746965206E6571756520736564206D617373612E204E616D2074656D706F722E204D6F72626920616C697175616D2073617069656E2061742074656C6C75732E2046757363652071756973207269737573206574206D69207072657469756D2070756C76696E61722E2046757363652073697420616D6574206C6967756C612E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2053757370656E646973736520657520656E696D2065742066656C6973207363656C65726973717565206C6F626F727469732E205072616573656E7420626962656E64756D2E20566976616D7573207665686963756C612E20496E7465676572206174206E696268207365642076656C69742072686F6E637573206D6F6C65737469652E2043726173206C616375732E2053656420756C6C616D636F727065722065726F732076656C20657261742E20467573636520657520746F72746F722073697420616D6574206469616D20657569736D6F642073616769747469732E204E756E632071756973206C61637573206964206E69626820636F6E76616C6C6973207661726975732E2053757370656E6469737365207669746165206D692E20566573746962756C756D207472697374697175652E20446F6E6563206D616C65737561646120697073756D206964206E657175652E204E756C6C616D20736564206C616375732E204475697320656765737461732C206A7573746F20757420636F6E677565206F726E6172652C2061756775652073617069656E206C7563747573206469616D2C20617420616363756D73616E20657261742073617069656E207574206C696265726F2E2050686173656C6C75732076656C206E756C6C612E2053757370656E646973736520617263752074656C6C75732C20706F72747469746F7220612C2070686172657472612066617563696275732C20616C697175616D2073697420616D65742C206D617373612E204E756C6C6120706F72747469746F722074696E636964756E74206C6F72656D2E204E756E6320646F6C6F72206F64696F2C20736167697474697320696E2C206C6F626F727469732076656C2C20766F6C7574706174207365642C206E6962682E0A0A5175697371756520626C616E646974206C656F2075742073617069656E2074656D70757320666163696C697369732E2050656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E2041656E65616E20756C7472696369657320706F72747469746F72206A7573746F2E2046757363652072757472756D2065726F732075742075726E612E2050726F696E2071756973207175616D20656765742064756920616C697175616D20616363756D73616E2E20446F6E656320737573636970697420656C656966656E6420656C69742E2050656C6C656E746573717565206D61747469732C2066656C697320736F64616C657320696163756C697320696D706572646965742C206C616375732073656D20636F6E76616C6C69732061756775652C2073697420616D657420616C69717565742061726375207075727573206672696E67696C6C612072697375732E20496E206575206F64696F206964206D61676E61207068617265747261206F726E6172652E20416C697175616D20696E74657264756D2070756C76696E617220697073756D2E20536564206E657175652E0A0A50656C6C656E746573717565206861626974616E74206D6F726269207472697374697175652073656E6563747573206574206E65747573206574206D616C6573756164612066616D65732061632074757270697320656765737461732E20457469616D2073697420616D6574206E6973692E2055742061742061756775652E204D617572697320766F6C757470617420626C616E646974206C6967756C612E204E756C6C61206575206D657475732E20566573746962756C756D206567657420656C69742E205072616573656E7420706F73756572652E20566573746962756C756D2069642073656D206E6F6E206C6563747573206D6F6C6C69732074696E636964756E742E20416C697175616D2069642066656C697320617420616E7465206F726E6172652074656D706F722E204E756C6C61206C61637573207475727069732C20666575676961742076697461652C2063757273757320717569732C20636F6E736563746574756572206E6F6E2C206D61757269732E204675736365206C61637573206D617373612C20706F72747469746F722075742C206D6F6C65737469652075742C2076656E656E6174697320612C206C6F72656D2E205072616573656E742073697420616D6574206F7263692E204D61757269732072686F6E6375732066656C69732076697461652066656C69732061646970697363696E6720696D706572646965742E204D616563656E6173206D6F6C6C6973206469616D206E6563206C656F2E0A0A467573636520656E696D20697073756D2C20756C7472696365732065752C206D6F6C65737469652069642C20656C656D656E74756D2069642C2073617069656E2E20496E746567657220612075726E612E204E616D2076656C6974206C696265726F2C2076656E656E6174697320656765742C2074656D706F722073697420616D65742C20666575676961742076697461652C20616E74652E204675736365206E756E632E205365642073656D706572206E69736C206E65632072697375732E20496E20736564206C696265726F2E2050726F696E20746F72746F72206E657175652C2074696E636964756E742061632C2074656D706F722061632C20706861726574726120717569732C2076656C69742E2044756973206C65637475732061756775652C20756C747269636965732076656C2C20636F6E7365717561742069642C20696163756C69732069642C20616E74652E20566976616D757320617563746F72206D65747573206120616E74652E204375726162697475722061726375206E6973692C20666163696C697369732061742C206C616F7265657420696E2C20636F6E736563746574756572207365642C206D61757269732E205175697371756520706C616365726174206469616D20736564206475692E20566976616D7573207072657469756D20636F6E64696D656E74756D206C6F72656D2E20437572616269747572206C616F726565742E2041656E65616E206F726369206C6967756C612C2063757273757320656765742C206C6163696E6961206E6F6E2C2066617563696275732076656C2C206C6F72656D2E0A0A416C697175616D206572617420766F6C75747061742E204375726162697475722065726F7320646F6C6F722C20636F6E67756520612C20636F6E64696D656E74756D207365642C206C75637475732075742C206E6962682E204D616563656E6173206E6F6E20746F72746F72206E65632074757270697320636F6D6D6F646F2070656C6C656E7465737175652E205072616573656E7420657569736D6F6420706C616365726174206D692E2053757370656E646973736520706F74656E74692E2050686173656C6C7573207574206E65717565207669746165206F726369206D617474697320696163756C69732E20496E746567657220656765742074656C6C75732E20446F6E656320617420616E74652E204E616D206C6163696E6961206C656F206567657420657261742E204D616563656E617320657569736D6F64206D61676E6120636F6E67756520746F72746F722E204D6F726269206E6563206D6173736120657520656E696D206D616C65737561646120736F6C6C696369747564696E2E2053656420616363756D73616E2E204E756C6C616D20697073756D2E205574206F64696F2E20416C697175616D206572617420766F6C75747061742E20436C61737320617074656E742074616369746920736F63696F737175206164206C69746F726120746F727175656E742070657220636F6E75626961206E6F737472612C2070657220696E636570746F732068696D656E61656F732E2050656C6C656E7465737175652069642076656C69742E204E616D206F64696F2073656D2C20616C69717565742075742C2074656D7075732073697420616D65742C20657569736D6F642065742C206E756E632E0A0A50656C6C656E746573717565206C696265726F2E2043756D20736F63696973206E61746F7175652070656E617469627573206574206D61676E6973206469732070617274757269656E74206D6F6E7465732C206E61736365747572207269646963756C7573206D75732E205072616573656E74206D6175726973206E756E632C207661726975732075742C20636F6E76616C6C6973206D6F6C65737469652C206C75637475732073697420616D65742C206C656F2E205365642064696374756D206C6F72656D20657420617263752E204E756E632076656E656E617469732070656C6C656E746573717565206D617373612E204E756C6C6120666163696C6973692E2050686173656C6C757320696E20746F72746F722065676574207269737573207363656C657269737175652076756C7075746174652E20536564206E69626820656C69742C2073616769747469732061632C20636F6E64696D656E74756D206E65632C20636F6E76616C6C69732065742C206A7573746F2E20467573636520766F6C7574706174206D657475732E204E756E6320617563746F722E20566573746962756C756D206C656F2065726F732C2070656C6C656E7465737175652061632C206D6F6C6C697320756C7472696365732C2072686F6E637573206E6F6E2C20646F6C6F722E204D6175726973207665686963756C6120706C616365726174206E69736C2E20566573746962756C756D20626962656E64756D2C2061726375207175697320636F6E67756520656C656D656E74756D2C2076656C6974206E756E6320656C656966656E64207475727069732C206964206C7563747573207269737573206E69736C2073697420616D65742074656C6C75732E2050686173656C6C75732070656465206E657175652C20626C616E646974206E6F6E2C20636F6D6D6F646F2076697461652C20756C7472696369657320656765742C206D61676E612E20416C697175616D206572617420766F6C75747061742E0A0A4E756C6C6120666163696C6973692E20416C697175616D20616320616E74652E20437261732072697375732E204D6F726269206D6175726973206C616375732C20706F73756572652065752C20626C616E6469742065742C2070686172657472612061742C206D692E2050726F696E2061632070757275732E204475697320637572737573206E69736C2072757472756D207175616D2E20416C697175616D2061206F64696F206E6F6E206D61676E612070656C6C656E74657371756520756C747269636965732E204D616563656E6173206163206D6173736120717569732073617069656E20756C6C616D636F727065722074656D7075732E2043726173206375727375732076656C6974207365642073617069656E2E2050726F696E206E756C6C612E20566976616D757320736F64616C657320616C697175616D206E6962682E20457469616D206574206572617420757420616E7465206C6163696E696120657569736D6F642E204675736365206E6973692E2050726F696E2071756973206E756C6C612E0A0A517569737175652076656E656E617469732C2065726F7320736564206C616F7265657420736F6C6C696369747564696E2C206F72636920616E74652070656C6C656E746573717565206E69736C2C2073697420616D65742076697665727261207175616D2065726174206E6F6E2072697375732E20437261732065676574206C696265726F2E2053656420656C6974206D61676E612C2073656D7065722065752C206672696E67696C6C6120696E2C206469676E697373696D20736F64616C65732C20657261742E20566976616D757320666575676961742073656D2076656C206475692E20446F6E656320636F6E76616C6C697320736F6C6C696369747564696E206469616D2E2043726173207365642070757275732E20446F6E65632066656C69732065726F732C2073656D70657220656765742C2074656D706F7220636F6E7365637465747565722C20736167697474697320717569732C206E69736C2E204475697320696E20616E74652E2043726173206E6F6E207475727069732E204E756C6C612074656D706F722076656C697420616C697175657420747572706973206D6F6C657374696520706C6163657261742E2050726F696E20656C656D656E74756D206665726D656E74756D206D61757269732E20566976616D757320736564206F726369206C6163696E69612064756920706C6163657261742076656E656E617469732E20566573746962756C756D20666575676961742C2074656C6C757320696E20766F6C75747061742072757472756D2C206D61676E61206E69736920756C6C616D636F727065722065726F732C2069642070756C76696E6172206E657175652065726174207574206C616375732E20566976616D7573207365642061756775652E204E756C6C6120666163696C6973692E204D616563656E617320616E74652061756775652C20656C656D656E74756D2075742C20736F64616C65732076697461652C20636F6E64696D656E74756D206E65632C206C6F72656D2E20447569732070656465206F7263692C206672696E67696C6C612061742C20656C656966656E64206E65632C207072657469756D20696E2C20657261742E204E616D2073616769747469732C2074757270697320766974616520636F6E76616C6C69732070686172657472612C206F64696F2073656D207363656C65726973717565206C616375732C206E6563206C6F626F7274697320647569206469616D2076656C2065726F732E20496E2073656D7065722067726176696461206E657175652E0A0A496E7465676572206E756E632E205574207072657469756D20697073756D2073697420616D657420656C69742E20496E206E656320617263752E2053656420766573746962756C756D2076756C70757461746520697073756D2E2050656C6C656E7465737175652074696E636964756E742E204E756C6C61206772617669646120646F6C6F7220696E2074656C6C75732E2043726173207665686963756C612C20646F6C6F722075742070656C6C656E74657371756520616C697175616D2C206572617420656E696D20617563746F72206D617373612C207665686963756C61206C6F626F72746973206F64696F2065726F732071756973207175616D2E2050726F696E2064617069627573206E6571756520696E20656E696D2E2050726F696E20656C69742E20496E74656765722072686F6E6375732074696E636964756E7420656C69742E204675736365206C6F72656D206D657475732C2073656D7065722061632C20766F6C75747061742076697461652C20666163696C697369732075742C2074656C6C75732E20446F6E65632076656C20747572706973207669746165206E69736920706861726574726120706F72747469746F722E204D616563656E617320746F72746F722E204675736365206D692E204E756C6C616D206E6563 \ No newline at end of file
diff --git a/core/src/test/resources/org/ldaptive/io/plaintext.txt b/core/src/test/resources/org/ldaptive/io/plaintext.txt new file mode 100644 index 0000000..5977465 --- /dev/null +++ b/core/src/test/resources/org/ldaptive/io/plaintext.txt
@@ -0,0 +1,3273 @@ +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras aliquet massa nec dui. Cras arcu nunc, hendrerit ac, eleifend eu, ullamcorper nec, tellus. Sed pharetra purus sit amet quam. Curabitur mollis. Nam vitae pede. Etiam risus massa, vehicula sit amet, pharetra nec, sollicitudin ut, dui. Donec egestas justo at quam. Proin nisl risus, vestibulum nec, pretium vitae, tristique ac, lorem. Aliquam erat volutpat. Cras sed nibh. Pellentesque sollicitudin euismod augue. + +Etiam fringilla sollicitudin orci. Mauris cursus elit quis lacus. Cras tortor. In adipiscing, lectus id auctor vestibulum, neque pede accumsan dolor, non imperdiet magna diam accumsan velit. Suspendisse at libero ut nisi blandit sagittis. Phasellus non mauris. Fusce elementum sagittis sem. Suspendisse aliquam eleifend tellus. Proin ligula lorem, imperdiet quis, venenatis id, iaculis mollis, nisl. Etiam convallis pede at massa. Morbi accumsan dui et mauris. + +Sed sed orci. Nunc purus. Suspendisse potenti. Ut luctus fringilla mauris. Donec nibh. Phasellus porta. Phasellus sit amet odio sed magna sodales pharetra. Cras lectus. Suspendisse libero ipsum, commodo nec, facilisis in, suscipit lobortis, ligula. Duis massa nulla, semper et, consequat nec, pharetra eu, elit. Vivamus ultricies aliquam odio. Vestibulum sit amet massa. Sed consequat lacus sed urna. Etiam faucibus felis vel orci. Phasellus ullamcorper. Aenean consectetuer lacus at libero. + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis facilisis, ligula vitae condimentum scelerisque, velit orci gravida felis, vel ultricies quam mi non diam. Vivamus auctor metus non libero. Praesent ligula nisi, commodo condimentum, molestie et, viverra et, justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus sollicitudin. Nunc blandit cursus ipsum. Aenean nec ligula ut tellus sodales mattis. Integer sem. Aliquam id ligula. Sed tortor mauris, blandit vitae, cursus vel, elementum et, nulla. Aliquam scelerisque metus et nisl. Duis adipiscing magna at neque. Quisque vulputate eleifend nunc. Aliquam eget elit. Phasellus dui odio, bibendum sagittis, vestibulum id, dignissim imperdiet, orci. Nullam eu felis non nunc lacinia sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Suspendisse pellentesque, libero mattis ultricies accumsan, tortor tortor malesuada sem, et sodales libero odio ac ipsum. Vivamus quis magna nec est suscipit lobortis. Cras tempus posuere nunc. Quisque ut enim a felis egestas semper. Sed pharetra mattis neque. Fusce turpis nunc, congue sed, consequat non, congue sed, nulla. Suspendisse varius lorem id risus porta vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce sed purus. In a felis. Integer egestas auctor orci. Mauris ultrices suscipit nisl. Nullam purus. + +Cras tempor adipiscing ipsum. Ut quis mi. Maecenas in justo ut nulla congue pharetra. Pellentesque ut libero eu dolor venenatis suscipit. Praesent feugiat consectetuer nibh. Morbi faucibus sem non felis. In hendrerit arcu ac massa. In accumsan ultrices mi. Proin malesuada auctor felis. Curabitur interdum. Sed diam ipsum, ultricies in, tempor sit amet, viverra imperdiet, elit. Morbi molestie nisi. Mauris ipsum. Fusce dictum mollis magna. Duis commodo dignissim nulla. Vestibulum augue enim, ultricies quis, iaculis nec, tincidunt vitae, diam. Mauris lacinia tempus ipsum. Sed at mauris. Ut lorem. Donec libero. + +Duis iaculis lacinia lectus. Aenean convallis eros ac ante. Sed quis orci nec risus auctor fringilla. Phasellus facilisis elementum nisi. In hac habitasse platea dictumst. Nunc porta lacus nec ante. Morbi mauris erat, adipiscing in, pulvinar nec, lobortis nec, odio. Ut eleifend lectus sed quam. Nullam mollis. In non turpis et nisl hendrerit blandit. Duis elementum. Nunc nec libero. Suspendisse vestibulum risus non pede. Morbi imperdiet odio sit amet libero. Sed sed massa vitae ipsum mattis tincidunt. Nulla nec tortor vitae libero volutpat tempus. Donec aliquam. + +Duis sed nunc. Curabitur turpis nulla, vehicula sed, luctus quis, elementum eget, felis. Maecenas et purus. Maecenas leo tellus, tincidunt a, facilisis vitae, lobortis sit amet, velit. Donec convallis sapien. Maecenas mollis odio eu nibh. Etiam gravida. Integer molestie, sapien eu molestie lacinia, nunc nibh aliquam ligula, eu sagittis tellus erat sollicitudin odio. Duis et risus. Phasellus nisi neque, placerat nec, condimentum non, ultrices eu, sem. Ut pede. Etiam nulla metus, volutpat id, convallis sed, suscipit vel, urna. Donec vel elit. Ut leo neque, venenatis faucibus, lacinia nec, tincidunt eu, enim. Cras id dui a libero pharetra dignissim. Donec eros leo, porta quis, laoreet ut, pellentesque volutpat, lectus. + +Nullam blandit. Aliquam erat volutpat. Fusce adipiscing enim. Suspendisse non dui quis ligula porta vestibulum. Donec eu tellus vel lorem pretium porttitor. Praesent luctus. Aliquam ac eros in massa dapibus tincidunt. Donec ut magna. Etiam auctor lacus sit amet lacus. Sed ultricies ipsum nec elit. Quisque a est in purus suscipit tristique. + +Aenean sed dui vel dolor pulvinar laoreet. Vivamus vehicula lorem in pede. Vivamus et diam. Integer ac odio vel diam hendrerit bibendum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a nisi. Phasellus tincidunt dui vitae augue. Duis faucibus, dui interdum fringilla tincidunt, odio elit vestibulum libero, ac molestie magna lectus id lacus. Aenean ligula. Nulla facilisi. + +Fusce vel sem eu velit fringilla ornare. Sed feugiat tincidunt felis. Nullam felis mi, euismod sit amet, mollis at, sodales eget, augue. Nam imperdiet nibh at velit. Sed ut erat. In dui. Nulla facilisi. Nullam augue libero, tincidunt nec, pretium eu, pulvinar in, dui. Morbi vitae felis. Pellentesque vel justo vel velit sagittis malesuada. Proin vehicula blandit massa. Etiam tincidunt pharetra urna. In metus est, auctor nec, blandit a, cursus nec, quam. Mauris ac metus a libero congue faucibus. Mauris mauris dolor, sodales in, cursus ut, sodales rutrum, eros. Quisque mauris eros, sagittis vitae, lobortis ut, eleifend id, nisi. + +Aenean neque. Vestibulum egestas pellentesque ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus sagittis justo vel risus. Sed pretium neque vitae urna. Pellentesque congue libero id lorem. Mauris leo lorem, blandit sit amet, convallis quis, consectetuer sed, eros. Mauris tincidunt, enim a gravida euismod, magna nulla fermentum libero, viverra egestas velit quam et tortor. Vivamus aliquet massa vitae justo. Nulla congue lacus ac elit. + +Phasellus commodo quam vel ligula. Proin non metus at eros pulvinar luctus. Mauris diam lorem, posuere quis, gravida et, tincidunt nec, ligula. Sed diam. Aliquam elit lectus, hendrerit ut, imperdiet sit amet, pretium sit amet, ipsum. Mauris vehicula nisl in dui. Curabitur eget quam ut magna elementum fermentum. Mauris scelerisque. Quisque laoreet. Etiam tempus turpis. Pellentesque augue quam, hendrerit sed, tincidunt at, pharetra at, nisl. Aliquam lacus. Suspendisse potenti. Aenean velit libero, ultrices in, lacinia eu, luctus vel, ante. Etiam dictum mi in felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce gravida dapibus nisl. Cras vitae nisl. + +Maecenas dignissim, ligula non porta cursus, enim nunc malesuada sem, eu porttitor nulla urna eu quam. Fusce eros. Aliquam eros. Nam auctor. Nulla molestie porta est. Suspendisse potenti. Vivamus molestie lorem sed erat. Sed eget ipsum. Integer aliquam pulvinar nulla. Cras aliquet sem ut nunc. Fusce faucibus tempus lectus. Cras sodales, nisi ac facilisis ultrices, eros arcu dapibus sapien, et ultrices mauris tellus non dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras cursus varius metus. Ut turpis. Vivamus eget tortor. + +Sed laoreet, velit non accumsan cursus, nunc urna posuere justo, in dictum lectus pede id ante. Cras vulputate. Cras congue dui sed elit. Proin lacus sem, ultrices at, consequat in, tempor quis, metus. Proin vel arcu. Nam euismod hendrerit elit. Ut erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed posuere. Morbi eros urna, semper at, semper non, convallis quis, velit. Maecenas orci. Vestibulum lobortis tristique metus. Vestibulum lorem nulla, sollicitudin vitae, condimentum quis, auctor ut, dui. Vivamus vestibulum magna ut nisi. Curabitur eleifend dui vel nunc. Curabitur mauris lacus, malesuada sit amet, suscipit sed, rutrum luctus, tellus. Integer facilisis urna vitae lectus. + +Aenean quam leo, lobortis quis, malesuada eu, vulputate vitae, nisl. Praesent eget eros. Ut fermentum turpis id quam. Nam tortor. Praesent nec orci. Nulla bibendum adipiscing augue. Ut commodo, magna id malesuada gravida, augue odio malesuada mi, porta malesuada elit est vitae diam. Mauris non nulla. Suspendisse tincidunt, nunc ultricies porta venenatis, mi pede tincidunt libero, eget varius ante libero ut ligula. Curabitur pretium porttitor tortor. + +Maecenas vitae elit eget nisi dapibus dictum. Nunc in libero. Nulla dictum orci eu erat auctor lobortis. Phasellus risus. Suspendisse potenti. Suspendisse potenti. Praesent adipiscing consequat elit. Integer id augue. Praesent in justo nec magna dapibus pulvinar. Duis nisl. Suspendisse ac odio. Vivamus imperdiet. Donec non velit sit amet risus dignissim congue. Nam aliquet posuere velit. Cras turpis. Morbi malesuada dignissim mi. + +Sed leo neque, varius quis, venenatis sed, pharetra sed, est. Morbi blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam semper pellentesque mi. Ut vel lorem. Nunc mi tortor, laoreet at, faucibus eu, tincidunt sit amet, erat. Duis tempor malesuada ipsum. Phasellus aliquet. Donec et elit. Pellentesque purus. Vestibulum rutrum semper nibh. Nulla facilisi. Phasellus et enim sit amet ante vestibulum vehicula. Phasellus id nisl. Donec mollis leo at eros. Mauris pellentesque neque at purus. Morbi quis dolor at ipsum scelerisque sodales. Etiam volutpat turpis a metus. In hac habitasse platea dictumst. Nunc lorem lorem, vestibulum ac, euismod eget, ullamcorper dignissim, velit. + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ultrices, nibh vel aliquam vestibulum, eros enim venenatis dui, id iaculis enim nunc vel massa. Morbi eleifend orci et massa. Aliquam erat volutpat. Nulla mollis egestas turpis. In sodales nunc eget tortor. Sed ipsum eros, tempor quis, aliquet vitae, imperdiet non, lorem. Pellentesque quis elit id mi luctus dapibus. Sed nunc arcu, rhoncus nec, convallis quis, cursus at, neque. Mauris convallis purus at erat. Pellentesque vestibulum. Vivamus fringilla elit at arcu. Nullam aliquet enim nec arcu. Nam id tortor. Nulla quis nunc. Ut arcu. Suspendisse potenti. Pellentesque ullamcorper ligula id arcu. + +Nam non libero vitae nisl scelerisque fringilla. Quisque varius ante id metus rhoncus fringilla. Nulla facilisi. Praesent eleifend porttitor ligula. Etiam quis dolor non augue commodo auctor. Donec a mi. Vestibulum tempor. Donec felis urna, auctor at, cursus dictum, gravida id, arcu. Aenean dictum malesuada dolor. Vivamus mattis. Phasellus eu pede. Fusce adipiscing justo fringilla metus. Etiam ante. Integer mollis massa quis nunc. Integer dictum neque luctus enim. + +Sed eu libero. Integer tempor ligula in velit. Ut tincidunt lacinia sem. Nullam vel risus. Sed sodales ante a dolor. Curabitur eros. Sed sodales. Sed non metus. Vestibulum elementum faucibus ante. Nulla vel nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In hac habitasse platea dictumst. Nunc nec lorem ut ipsum lacinia iaculis. Duis erat. Aliquam erat. Cras iaculis. In hac habitasse platea dictumst. + +Nullam ante. Cras vitae est. Pellentesque vel metus a ligula dapibus mattis. Duis feugiat aliquet felis. Etiam id nisl quis est dignissim condimentum. Suspendisse potenti. Morbi velit lorem, ornare quis, pellentesque vel, placerat eget, tortor. Vestibulum tincidunt molestie libero. Nulla nulla enim, malesuada id, ullamcorper vitae, dictum at, purus. Donec dignissim odio ut enim. Suspendisse at lectus. + +Praesent lobortis augue vel lectus. Ut in ligula ut felis congue suscipit. Quisque dignissim tortor ut mi. Fusce magna nisi, eleifend ac, ornare vel, porttitor vitae, quam. Vestibulum sodales justo quis turpis. Fusce urna nisi, rhoncus quis, condimentum vel, dictum eu, nunc. Fusce sed nibh vitae odio posuere adipiscing. Sed porta elit quis dolor. Nam libero nulla, auctor sed, tincidunt quis, faucibus sit amet, mi. Quisque orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam id sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vel eros. + +Vivamus luctus lobortis leo. Suspendisse vel elit a enim ullamcorper posuere. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec quis pede mattis lectus mollis adipiscing. Sed accumsan posuere erat. Praesent euismod tincidunt felis. Donec mi. Ut commodo arcu lacinia tellus. Aliquam a libero quis lectus semper viverra. Curabitur lacinia mauris at tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sit amet magna molestie orci suscipit fringilla. Fusce pretium metus non sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed hendrerit. Nulla felis. Suspendisse potenti. Aliquam blandit tristique neque. Curabitur quis erat vel nunc accumsan mollis. + +Duis sagittis, tellus ut aliquam fringilla, dolor mi ullamcorper nisl, ut tristique pede elit sed mauris. Curabitur id felis. Donec pulvinar lacus et lectus. Aliquam vulputate vulputate metus. Curabitur magna felis, adipiscing ac, accumsan vel, molestie quis, quam. Mauris elit arcu, pretium vitae, mollis sit amet, sollicitudin ut, mi. Donec imperdiet dignissim mi. Nullam sit amet tortor. Aliquam neque nulla, venenatis a, porta in, placerat tempus, lacus. Quisque vestibulum dui et lacus. Proin dignissim consectetuer purus. Etiam gravida tortor in nunc. Ut tempor tristique tortor. Sed laoreet tincidunt quam. Vestibulum porta turpis ut elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nibh dui, feugiat nec, laoreet id, malesuada eget, nisi. Ut neque massa, vehicula eu, commodo non, ultricies vitae, purus. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris euismod, felis vel tempor aliquet, tortor mauris malesuada nunc, vel fermentum sem diam id dui. Nam rutrum sapien eget odio. Aliquam sed libero non mi faucibus tempus. Fusce hendrerit, diam non volutpat rutrum, erat metus venenatis ligula, non scelerisque pede ligula vel quam. Morbi rhoncus eros ac dui feugiat elementum. Duis eu libero et tellus congue viverra. Morbi quam quam, elementum sed, ullamcorper imperdiet, commodo non, odio. Nam aliquet egestas urna. Mauris odio felis, varius eu, lacinia eu, condimentum a, lectus. Sed justo massa, pulvinar id, varius a, porttitor nec, libero. Etiam varius. Curabitur sodales, odio at posuere semper, eros nibh tincidunt lectus, vel rutrum sapien nisi in ligula. Suspendisse eget arcu. Phasellus imperdiet est ac sapien. Donec nulla tortor, placerat vel, tempus a, lobortis vel, nibh. Aliquam varius nisi. Nulla et enim. Fusce convallis laoreet lacus. + +Phasellus ipsum dolor, molestie quis, condimentum in, commodo eu, diam. Quisque bibendum lacinia dui. Nullam blandit vulputate orci. Ut lacinia massa vel augue. Aliquam gravida, quam quis imperdiet imperdiet, tellus diam pharetra erat, at pharetra lacus nibh egestas magna. Nulla sagittis lorem ut lorem. Duis condimentum, dui vitae aliquam posuere, diam quam convallis velit, ut gravida leo ipsum non risus. Ut fermentum sollicitudin erat. Donec sagittis scelerisque felis. Nunc arcu. Etiam tempus, magna sit amet suscipit euismod, eros sem rutrum dui, vitae sagittis nibh purus non lacus. Sed mollis arcu eget dolor. Donec ornare, arcu sit amet fermentum vulputate, risus enim fermentum libero, a lacinia dolor mi non velit. Etiam lobortis purus a elit. Nunc nulla dui, mattis quis, bibendum a, ultrices ac, augue. In aliquam vehicula turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Integer id nisl. Quisque dictum elementum odio. Aenean luctus. Sed eu sem a pede vulputate condimentum. Quisque magna. Donec aliquam mattis ipsum. Curabitur dictum sollicitudin sem. Aliquam pulvinar. Nunc sollicitudin risus a erat. Vivamus quis tellus sit amet nibh vestibulum consequat. Nulla pretium sollicitudin dolor. Aliquam iaculis tincidunt turpis. Phasellus ipsum leo, venenatis in, sagittis in, ornare at, nunc. + +Pellentesque ultrices, dui eu iaculis luctus, tellus augue volutpat sapien, in dignissim urna felis ut mi. Sed arcu dui, dignissim id, porttitor ut, imperdiet vitae, ante. Nulla dui sem, commodo nec, sagittis et, lacinia et, pede. Etiam eleifend dui ut nisl. Donec ante mauris, tempus sit amet, varius vitae, gravida quis, mi. In scelerisque, felis vitae viverra sagittis, velit metus ultricies neque, quis imperdiet velit elit et magna. Suspendisse potenti. Sed velit eros, euismod sed, condimentum nec, faucibus sed, sapien. Nam accumsan ligula sit amet neque. Aliquam erat volutpat. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam eu pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed eu felis sed tortor tempor fermentum. Phasellus commodo sem vel nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lectus elit, pharetra sit amet, accumsan sed, tincidunt et, mauris. Duis dapibus pharetra sem. Integer in justo. Praesent eros. Vestibulum ac ante. Aliquam scelerisque sem pellentesque nibh consectetuer sodales. Aliquam consectetuer odio. Duis lectus odio, luctus eu, commodo quis, mollis vitae, velit. Cras nec nunc non elit iaculis mattis. Aenean justo neque, sollicitudin eget, ullamcorper eget, egestas id, sem. In eu risus. Sed egestas. + +Integer at neque. Sed pretium scelerisque nulla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce ut pede. Etiam vitae quam a urna varius imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vehicula. Fusce ullamcorper nibh non erat. Quisque in neque. Praesent est. Pellentesque arcu. + +Proin posuere. Suspendisse potenti. Integer felis lacus, aliquam sed, vulputate in, mollis vel, tellus. Integer vehicula bibendum est. Nunc non dolor in tellus mattis facilisis. Integer vestibulum, augue at commodo aliquam, dui est mattis ligula, sit amet adipiscing orci sem vitae magna. Praesent enim velit, malesuada at, congue nec, luctus in, justo. Sed varius. Morbi pharetra. Donec eu massa nec tellus vulputate pulvinar. Ut commodo turpis non sem. Ut convallis ullamcorper risus. Etiam interdum pede id nisi. Cras magna sapien, suscipit a, laoreet non, rhoncus et, felis. Integer orci lorem, vestibulum dictum, ullamcorper a, porttitor et, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc et magna. Sed bibendum tellus in diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vitae tortor. Integer magna. Duis venenatis, leo ac tempor laoreet, elit nulla pharetra pede, non fermentum nunc odio a odio. Proin non velit. Sed imperdiet augue quis nisl. Integer condimentum nisl nec libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus placerat libero. Duis congue dictum magna. Aliquam dapibus bibendum enim. Nunc eleifend pede vel ipsum. + +Etiam vitae velit. Mauris erat nunc, malesuada ut, feugiat ac, placerat condimentum, augue. Nam volutpat. Aliquam vehicula ipsum id odio. Vivamus sollicitudin turpis id sapien. Fusce a felis vitae odio convallis blandit. Curabitur vitae eros id eros porta pretium. Nulla in magna eget urna lacinia convallis. Aliquam mattis venenatis purus. Sed sed mi eget erat tristique porta. Donec auctor dolor a erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In nec ligula. Nunc eleifend. Vestibulum quis nisi eget elit porttitor congue. Maecenas faucibus, magna eget adipiscing tincidunt, dolor ante malesuada elit, non elementum lacus turpis in pede. + +Ut malesuada mi nec metus. Praesent auctor augue ac nisl ultricies facilisis. Nam purus sapien, pellentesque dignissim, posuere eu, cursus id, diam. Quisque sollicitudin, elit a pellentesque scelerisque, lorem risus auctor quam, quis consequat tellus neque id urna. Suspendisse diam tortor, eleifend dignissim, egestas ut, luctus in, ante. Duis ante. Maecenas luctus. Curabitur cursus pharetra urna. Maecenas imperdiet, erat non elementum euismod, tortor odio euismod lectus, ac facilisis sem nibh vitae nulla. Nunc gravida. Morbi sollicitudin odio quis lacus. Aliquam a nibh non urna porta imperdiet. Aliquam erat volutpat. In iaculis lacinia velit. Sed libero lacus, tristique eu, lacinia ac, aliquet eget, urna. + +Etiam at nisl. Phasellus faucibus luctus lectus. Ut placerat vulputate dolor. Phasellus vel velit. Morbi viverra. Phasellus orci. Integer dignissim mattis mauris. Pellentesque posuere leo posuere quam. Quisque nec magna at diam viverra pellentesque. Suspendisse velit arcu, ultricies quis, congue a, venenatis eget, lacus. Integer sagittis hendrerit dolor. Fusce tincidunt ante a sem. + +Maecenas consectetuer, justo sed rhoncus venenatis, nibh arcu rutrum dolor, sed condimentum libero libero et ipsum. Vivamus mattis justo ut lorem tincidunt lobortis. Ut non velit id neque aliquet accumsan. Sed tempus viverra nulla. Curabitur ullamcorper, neque quis dapibus scelerisque, felis diam gravida orci, non cursus quam neque vitae elit. Etiam pharetra tincidunt lacus. Duis euismod fringilla est. Etiam ornare tincidunt lectus. Proin in turpis. Nunc blandit blandit turpis. Aenean ut augue. Duis orci justo, tincidunt eu, rutrum sed, rutrum et, turpis. Curabitur facilisis odio in ante. In hac habitasse platea dictumst. Sed eros est, pellentesque at, tincidunt eu, ultrices quis, metus. Morbi sit amet justo. Maecenas ac arcu. Mauris dignissim. + +Pellentesque ultricies rutrum orci. Aenean ornare. Vivamus eu risus vel mauris lobortis dictum. Sed et turpis auctor mi rhoncus pulvinar. Sed nec nunc a purus tempor viverra. Pellentesque suscipit. Donec tristique risus non nibh. Etiam nisl magna, sollicitudin ut, ultrices sit amet, egestas eu, nulla. Aliquam erat volutpat. Vestibulum pharetra. Sed egestas, metus sit amet lobortis consequat, erat elit imperdiet libero, eu interdum quam massa eget dolor. Suspendisse vitae odio. Proin blandit mauris iaculis metus. + +Vivamus vestibulum. Etiam et nisl. Aliquam in diam vel elit placerat suscipit. Duis sodales purus ac nibh. Nulla in odio eget enim luctus blandit. Curabitur ultrices ipsum non neque egestas eleifend. Sed turpis. Proin consectetuer. Vivamus mattis. In aliquet. + +Nunc id eros. Donec venenatis, nulla et mattis luctus, ante leo semper justo, non adipiscing odio risus sed lacus. Praesent vitae risus congue libero congue tempus. Phasellus ac eros. Nulla vehicula, lorem in aliquet suscipit, arcu erat egestas sem, quis lobortis quam ante eu massa. Curabitur non massa. Sed bibendum lacinia odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus volutpat blandit lacus. Proin porta, tellus ut auctor laoreet, lectus eros fermentum lectus, id sagittis arcu justo in turpis. Phasellus consequat. Nam pellentesque, mi id viverra convallis, nunc libero placerat leo, eleifend porta sem nisl vitae sapien. Pellentesque ligula libero, tristique non, porttitor rutrum, porttitor non, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer dictum tellus a tortor. Vivamus felis nunc, molestie non, rhoncus quis, pharetra id, dui. Donec risus metus, fringilla vel, aliquet eu, placerat id, neque. + +Suspendisse ipsum. Vivamus lectus. Sed viverra, massa eget convallis mattis, quam turpis consectetuer nunc, eget posuere magna sem id velit. In nec mauris. Aenean a purus sed quam lobortis fringilla. Proin ultricies lacinia ante. Sed adipiscing erat quis velit. Nullam vitae nisl id justo sollicitudin molestie. Nulla facilisi. Sed nec urna sed nisl fringilla dapibus. Nulla at diam. Aliquam eget nibh. Nunc ac nisi sit amet tellus egestas tempus. Nam scelerisque urna et neque. Donec est orci, sagittis non, vulputate a, commodo et, augue. Ut dapibus tortor. Ut nunc. Donec dictum dapibus odio. Nam ultricies ullamcorper ligula. Pellentesque accumsan varius leo. + +Morbi euismod laoreet erat. Vivamus quis ipsum. Morbi euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel purus. Nullam at magna. Curabitur lacus lorem, iaculis quis, dapibus non, volutpat vel, nulla. Donec ut arcu rhoncus dolor pretium dictum. Nullam vel metus. Ut arcu. Pellentesque nisi nunc, placerat eget, tincidunt vel, pharetra non, nunc. Integer tincidunt ultricies lectus. Integer semper, purus sed ultrices feugiat, nulla pede sollicitudin erat, vel auctor nulla ipsum vel lectus. Aenean mi. + +Nullam sed nisi et arcu imperdiet fermentum. Mauris nec metus. In ac dolor. In mi arcu, congue ac, pharetra nec, scelerisque sit amet, magna. Curabitur lacus. Curabitur et elit. Aliquam ullamcorper nunc eu elit. Sed convallis dolor at velit. Vestibulum dapibus, augue id consectetuer placerat, nunc massa blandit sapien, id aliquam elit nisi id mi. Phasellus sapien est, gravida eu, bibendum ut, adipiscing quis, est. Ut molestie quam vitae odio. Donec quis risus id erat faucibus sollicitudin. Nam id felis. Mauris sed enim vitae leo accumsan pretium. + +Nam justo. Donec turpis nisl, commodo et, interdum ac, consectetuer non, massa. Fusce sem metus, laoreet nec, posuere id, imperdiet in, velit. Donec vulputate justo eget turpis. Nulla pede. Morbi tincidunt. Fusce aliquet, quam et aliquam fringilla, ante ante iaculis dui, nec aliquam arcu purus sed erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus suscipit quam et est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; + +Integer sed tellus. Sed sed velit ultricies leo rutrum laoreet. Sed non eros ac purus sagittis feugiat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed hendrerit ligula sit amet nibh. Maecenas turpis. Morbi consectetuer, dolor et adipiscing imperdiet, ante neque feugiat dolor, at porta quam neque quis ligula. Mauris semper velit sit amet ipsum. Pellentesque tempus, purus in rutrum consequat, enim erat vehicula massa, id accumsan leo sapien nec purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In dolor. Integer facilisis libero sit amet pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut varius aliquet enim. Nulla facilisi. Curabitur consectetuer, odio eu pretium tincidunt, nunc nisi aliquet neque, vel imperdiet elit massa sit amet turpis. Pellentesque tempus, orci volutpat blandit fringilla, odio sem posuere ante, vitae bibendum urna lorem vitae eros. Praesent viverra rhoncus arcu. Sed auctor, est sit amet mollis mollis, quam quam gravida sapien, in commodo metus nulla auctor enim. Donec facilisis. + +Proin tincidunt, sapien eget ultricies adipiscing, est odio dictum arcu, ut mollis erat dui sit amet velit. Morbi est sem, interdum at, congue a, elementum vitae, metus. Suspendisse id augue. Mauris enim sem, pulvinar eget, tempus a, tempus sit amet, sapien. Fusce vestibulum consectetuer dui. Pellentesque erat. Sed dignissim placerat odio. Maecenas semper rhoncus lectus. Phasellus pretium. Duis libero elit, eleifend nec, egestas ut, cursus sed, felis. Nam nisl arcu, aliquet et, facilisis eu, luctus ut, risus. Etiam ultrices, dolor sed volutpat malesuada, turpis arcu imperdiet tortor, euismod commodo libero massa ut quam. Integer molestie purus non elit. Ut venenatis semper tortor. Etiam bibendum egestas ipsum. Mauris sollicitudin sem nec nibh. Nulla pretium metus eu metus. Pellentesque sit amet sem. + +Suspendisse ac nisi. Ut leo. Vestibulum hendrerit pretium dolor. Nunc feugiat malesuada purus. Cras et nibh. Curabitur nunc erat, malesuada vitae, laoreet ac, ultricies in, purus. Vivamus tellus arcu, sodales eu, facilisis a, lacinia nec, nunc. Pellentesque id velit. In eu nibh. Nunc nec erat. Sed dictum neque ut nisl. + +Morbi lectus tellus, tincidunt ac, porttitor ac, tristique in, eros. Donec luctus luctus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ut est et enim scelerisque accumsan. Donec ligula felis, lacinia quis, pellentesque in, semper vestibulum, elit. Mauris eget orci a felis congue vehicula. Ut sollicitudin. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam id dolor ut lorem dignissim venenatis. Suspendisse vitae sapien. Proin non magna ut eros viverra pulvinar. Donec quis odio. Nullam non arcu vel lorem suscipit aliquam. Aliquam rutrum turpis in leo. + +Ut luctus nibh tristique erat. Suspendisse bibendum odio vitae tortor. Donec lacinia. Cras sodales felis luctus nulla. Nam eleifend sagittis ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse vel neque. Morbi aliquet vehicula magna. Aenean at odio. Duis pellentesque magna. Nulla at tortor ut diam dictum faucibus. Mauris quis velit. Donec non tellus vitae lorem fringilla porttitor. Fusce ut sapien quis tortor feugiat sagittis. Donec viverra sem vitae sapien. Praesent sodales, lacus in fringilla viverra, odio augue adipiscing urna, vitae interdum ante sem non nisi. Nullam tortor lorem, eleifend ac, mollis non, laoreet ac, risus. Integer ornare leo sed justo. Quisque cursus, sem non facilisis bibendum, nisi mi varius felis, fermentum feugiat lorem eros laoreet risus. + +Quisque sit amet est et lorem vehicula lacinia. Donec nec tortor. Cras odio. Nam scelerisque vulputate urna. Praesent dui. Etiam nec nisl lobortis ipsum aliquet tempus. Maecenas pretium sollicitudin mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus augue massa, congue eget, convallis eget, tristique sit amet, eros. Sed consequat nisi eu felis. Pellentesque justo. Suspendisse non augue. In dignissim lobortis mauris. Mauris sagittis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + +Sed adipiscing. Donec a tellus vitae est cursus vehicula. Nam ante sem, sodales id, fringilla vel, condimentum vel, nulla. Quisque sodales. Etiam imperdiet elit id odio. Aliquam erat volutpat. Maecenas porta tempor arcu. Nulla sem augue, pellentesque ac, consequat ut, condimentum euismod, risus. Sed aliquam tincidunt mi. In interdum lobortis orci. + +Sed vehicula hendrerit purus. Etiam a diam. Curabitur convallis. Suspendisse a nisi. Donec id magna in quam sollicitudin ultricies. Donec viverra. Quisque volutpat est sed sem. Aliquam justo. Vestibulum tortor massa, porttitor sed, varius quis, iaculis quis, odio. Aliquam eget neque. + +Mauris nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum eu quam in neque ultrices pellentesque. Cras in dolor quis quam varius hendrerit. Aliquam nisi lacus, lobortis eu, convallis sit amet, facilisis ut, mi. Aliquam at neque. Cras sagittis elementum justo. Vestibulum ut lectus aliquet purus malesuada volutpat. Duis at lacus adipiscing libero tincidunt vestibulum. Morbi a libero. Cras purus. Morbi ut augue et purus interdum scelerisque. Integer a dui. In hac habitasse platea dictumst. Duis pharetra metus eget mauris. Aliquam interdum ullamcorper massa. + +Etiam ornare. Nullam euismod. Aenean consequat gravida ligula. Aliquam est. Proin vitae lacus. Praesent a eros sit amet dui luctus commodo. Phasellus vehicula arcu eget dolor. Praesent fermentum congue leo. Aliquam volutpat purus ut lorem. Fusce hendrerit enim at leo. Aliquam rhoncus nisl. Vivamus dictum egestas mi. Suspendisse pellentesque bibendum dolor. Pellentesque tincidunt, turpis semper pellentesque condimentum, ipsum metus sodales ligula, id volutpat diam turpis ut elit. + +Praesent sed lacus. Nam eleifend molestie mauris. Donec dapibus fermentum massa. Donec viverra faucibus purus. Curabitur congue, libero vitae viverra pellentesque, diam velit sodales enim, sed suscipit lectus nisi nec neque. Vestibulum malesuada, lacus at cursus congue, velit lectus tristique dolor, sit amet sodales neque ipsum a libero. Vestibulum et quam. Curabitur placerat. Curabitur nunc arcu, euismod nec, vulputate hendrerit, aliquet eget, quam. Curabitur vel enim. Suspendisse potenti. + +Nunc consequat orci ut lacus. Fusce velit dolor, dapibus sed, blandit sit amet, rhoncus id, risus. Duis urna nibh, scelerisque quis, dapibus a, scelerisque sed, nibh. Donec luctus. Ut eu mauris cursus diam lacinia rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam vehicula molestie justo. Maecenas imperdiet pede sed mi. Suspendisse nulla dolor, hendrerit eget, hendrerit id, dictum vel, leo. Duis accumsan. Curabitur in felis. Nunc lorem. Ut leo dolor, laoreet nec, vulputate at, eleifend in, nulla. Quisque nunc purus, varius eget, accumsan nec, aliquet et, nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras adipiscing viverra dolor. Mauris porttitor ultrices purus. Nulla facilisi. Praesent faucibus ante vitae mauris. + +Praesent lacinia lectus sed nisl. In tempus congue mauris. Integer facilisis ornare enim. Nulla id massa. Donec commodo diam at tellus. Nam dapibus viverra est. Nam tellus. Praesent a libero. In faucibus est eget nibh. Nulla eros orci, imperdiet non, blandit non, tempor eget, mi. Pellentesque convallis. + +Quisque eget mi ac leo euismod faucibus. Phasellus rhoncus purus id dui. Vestibulum malesuada eleifend ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque blandit mattis odio. Suspendisse consequat, lectus ac semper sollicitudin, mi velit dictum augue, ac tempus dolor erat sit amet dui. Proin hendrerit, felis quis volutpat posuere, diam odio malesuada odio, a interdum orci diam quis sapien. Pellentesque odio odio, viverra vel, gravida eu, molestie sed, nulla. Phasellus mauris pede, commodo ut, euismod eu, hendrerit eu, est. In hac habitasse platea dictumst. Nulla elementum lacus eu augue. Sed erat. Proin porta. Maecenas quis mi. Phasellus at enim ac justo gravida ultrices. Cras leo. + +Integer ut arcu. Donec sed magna. Proin felis. In iaculis, ligula id fringilla pretium, nibh diam accumsan tellus, eget accumsan metus dui varius turpis. Phasellus orci metus, eleifend sed, tempor ac, scelerisque ac, urna. Integer viverra neque a mauris. Mauris porttitor dolor eu velit. Integer odio elit, vestibulum ut, volutpat id, rhoncus commodo, urna. Etiam placerat pharetra erat. Ut tempor est. Integer dignissim blandit tellus. Morbi nibh dolor, scelerisque id, commodo malesuada, mattis at, mi. Cras tincidunt commodo purus. In tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ullamcorper. Ut hendrerit. Morbi ultrices. + +Praesent iaculis, eros ac egestas sodales, urna leo fermentum ligula, sit amet aliquam velit sem non purus. Donec rutrum arcu quis purus. Nam posuere, lacus at consequat placerat, nulla pede posuere orci, non euismod turpis dui quis nisl. Proin porta adipiscing nibh. Donec tristique dolor at tellus. Donec neque massa, auctor id, faucibus vitae, ullamcorper vel, nisi. Proin molestie neque sed massa. Nam tempor. Morbi aliquam sapien at tellus. Fusce quis risus et mi pretium pulvinar. Fusce sit amet ligula. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse eu enim et felis scelerisque lobortis. Praesent bibendum. Vivamus vehicula. Integer at nibh sed velit rhoncus molestie. Cras lacus. Sed ullamcorper eros vel erat. Fusce eu tortor sit amet diam euismod sagittis. Nunc quis lacus id nibh convallis varius. Suspendisse vitae mi. Vestibulum tristique. Donec malesuada ipsum id neque. Nullam sed lacus. Duis egestas, justo ut congue ornare, augue sapien luctus diam, at accumsan erat sapien ut libero. Phasellus vel nulla. Suspendisse arcu tellus, porttitor a, pharetra faucibus, aliquam sit amet, massa. Nulla porttitor tincidunt lorem. Nunc dolor odio, sagittis in, lobortis vel, volutpat sed, nibh. + +Quisque blandit leo ut sapien tempus facilisis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean ultricies porttitor justo. Fusce rutrum eros ut urna. Proin quis quam eget dui aliquam accumsan. Donec suscipit eleifend elit. Pellentesque mattis, felis sodales iaculis imperdiet, lacus sem convallis augue, sit amet aliquet arcu purus fringilla risus. In eu odio id magna pharetra ornare. Aliquam interdum pulvinar ipsum. Sed neque. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam sit amet nisi. Ut at augue. Mauris volutpat blandit ligula. Nulla eu metus. Vestibulum eget elit. Praesent posuere. Vestibulum id sem non lectus mollis tincidunt. Aliquam id felis at ante ornare tempor. Nulla lacus turpis, feugiat vitae, cursus quis, consectetuer non, mauris. Fusce lacus massa, porttitor ut, molestie ut, venenatis a, lorem. Praesent sit amet orci. Mauris rhoncus felis vitae felis adipiscing imperdiet. Maecenas mollis diam nec leo. + +Fusce enim ipsum, ultrices eu, molestie id, elementum id, sapien. Integer a urna. Nam velit libero, venenatis eget, tempor sit amet, feugiat vitae, ante. Fusce nunc. Sed semper nisl nec risus. In sed libero. Proin tortor neque, tincidunt ac, tempor ac, pharetra quis, velit. Duis lectus augue, ultricies vel, consequat id, iaculis id, ante. Vivamus auctor metus a ante. Curabitur arcu nisi, facilisis at, laoreet in, consectetuer sed, mauris. Quisque placerat diam sed dui. Vivamus pretium condimentum lorem. Curabitur laoreet. Aenean orci ligula, cursus eget, lacinia non, faucibus vel, lorem. + +Aliquam erat volutpat. Curabitur eros dolor, congue a, condimentum sed, luctus ut, nibh. Maecenas non tortor nec turpis commodo pellentesque. Praesent euismod placerat mi. Suspendisse potenti. Phasellus ut neque vitae orci mattis iaculis. Integer eget tellus. Donec at ante. Nam lacinia leo eget erat. Maecenas euismod magna congue tortor. Morbi nec massa eu enim malesuada sollicitudin. Sed accumsan. Nullam ipsum. Ut odio. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque id velit. Nam odio sem, aliquet ut, tempus sit amet, euismod et, nunc. + +Pellentesque libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent mauris nunc, varius ut, convallis molestie, luctus sit amet, leo. Sed dictum lorem et arcu. Nunc venenatis pellentesque massa. Nulla facilisi. Phasellus in tortor eget risus scelerisque vulputate. Sed nibh elit, sagittis ac, condimentum nec, convallis et, justo. Fusce volutpat metus. Nunc auctor. Vestibulum leo eros, pellentesque ac, mollis ultrices, rhoncus non, dolor. Mauris vehicula placerat nisl. Vestibulum bibendum, arcu quis congue elementum, velit nunc eleifend turpis, id luctus risus nisl sit amet tellus. Phasellus pede neque, blandit non, commodo vitae, ultricies eget, magna. Aliquam erat volutpat. + +Nulla facilisi. Aliquam ac ante. Cras risus. Morbi mauris lacus, posuere eu, blandit et, pharetra at, mi. Proin ac purus. Duis cursus nisl rutrum quam. Aliquam a odio non magna pellentesque ultricies. Maecenas ac massa quis sapien ullamcorper tempus. Cras cursus velit sed sapien. Proin nulla. Vivamus sodales aliquam nibh. Etiam et erat ut ante lacinia euismod. Fusce nisi. Proin quis nulla. + +Quisque venenatis, eros sed laoreet sollicitudin, orci ante pellentesque nisl, sit amet viverra quam erat non risus. Cras eget libero. Sed elit magna, semper eu, fringilla in, dignissim sodales, erat. Vivamus feugiat sem vel dui. Donec convallis sollicitudin diam. Cras sed purus. Donec felis eros, semper eget, tempor consectetuer, sagittis quis, nisl. Duis in ante. Cras non turpis. Nulla tempor velit aliquet turpis molestie placerat. Proin elementum fermentum mauris. Vivamus sed orci lacinia dui placerat venenatis. Vestibulum feugiat, tellus in volutpat rutrum, magna nisi ullamcorper eros, id pulvinar neque erat ut lacus. Vivamus sed augue. Nulla facilisi. Maecenas ante augue, elementum ut, sodales vitae, condimentum nec, lorem. Duis pede orci, fringilla at, eleifend nec, pretium in, erat. Nam sagittis, turpis vitae convallis pharetra, odio sem scelerisque lacus, nec lobortis dui diam vel eros. In semper gravida neque. + +Integer nunc. Ut pretium ipsum sit amet elit. In nec arcu. Sed vestibulum vulputate ipsum. Pellentesque tincidunt. Nulla gravida dolor in tellus. Cras vehicula, dolor ut pellentesque aliquam, erat enim auctor massa, vehicula lobortis odio eros quis quam. Proin dapibus neque in enim. Proin elit. Integer rhoncus tincidunt elit. Fusce lorem metus, semper ac, volutpat vitae, facilisis ut, tellus. Donec vel turpis vitae nisi pharetra porttitor. Maecenas tortor. Fusce mi. Nullam nec turpis. Sed sodales vestibulum nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Pellentesque dolor dolor, laoreet eu, aliquet quis, scelerisque sit amet, arcu. In hac habitasse platea dictumst. Nullam cursus urna eget elit. Quisque blandit sapien ac ante. Proin nulla eros, gravida volutpat, sodales vel, mollis eu, massa. Nulla tristique sollicitudin nisl. Curabitur vitae lorem vitae velit egestas ornare. Aenean eget eros. Aliquam erat volutpat. Fusce a urna id odio aliquet convallis. Curabitur sit amet nisl posuere leo posuere dapibus. Duis metus erat, luctus vel, rhoncus at, convallis sit amet, enim. Vivamus hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam eget elit. + +Nullam a nunc. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In metus urna, tincidunt et, lacinia sit amet, lobortis vitae, ligula. Proin et mauris vitae mi accumsan pellentesque. Etiam quam purus, hendrerit sed, feugiat vitae, euismod eget, tortor. Ut aliquam magna vitae justo. Suspendisse non justo vel velit condimentum tempus. Duis tempus ipsum vitae tellus. Proin in massa. Etiam ullamcorper dictum tellus. Proin aliquet felis at leo laoreet pulvinar. Vestibulum arcu purus, malesuada sit amet, cursus eu, placerat sit amet, nunc. Nam massa odio, sollicitudin in, adipiscing a, aliquam nec, risus. Aliquam blandit hendrerit libero. Mauris gravida. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur a nibh. Ut interdum fermentum neque. Pellentesque sed nunc. Mauris vehicula nisi et nunc. Praesent lorem. Donec semper. Integer eu lacus in est aliquam hendrerit. Vestibulum eget neque. Sed semper luctus velit. Curabitur nibh augue, congue eu, hendrerit id, congue et, enim. Integer placerat aliquam lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae eros. Donec vel nisl. + +In vestibulum facilisis urna. Ut risus. Mauris pharetra. Pellentesque mattis. Integer suscipit aliquam ipsum. Duis blandit, sapien et ultricies condimentum, felis mi elementum pede, nec sagittis metus mauris quis quam. Quisque accumsan arcu vel nulla. Cras sem sapien, porttitor id, ultricies sagittis, luctus eu, nulla. Integer quis eros. Morbi sed urna a tellus vehicula vulputate. Etiam nec augue eget felis semper tristique. Quisque ut dolor vel risus dictum consequat. Sed eget dolor sed nunc lacinia aliquet. Suspendisse ac tortor in ipsum posuere venenatis. Sed eget erat. Nulla faucibus. Duis laoreet, massa porttitor aliquet egestas, ipsum lectus rhoncus quam, in adipiscing eros sem ut tellus. Pellentesque feugiat tempus quam. Vivamus id dolor eget sapien consectetuer tempor. Aliquam erat volutpat. + +Nulla iaculis fermentum libero. Curabitur faucibus, massa malesuada cursus tincidunt, erat sem eleifend mauris, sed fringilla mi ante ac purus. Duis elementum lectus. Nunc ornare arcu eu tortor. Vestibulum vel dolor at purus lacinia fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas tincidunt, eros a egestas pellentesque, risus risus dictum libero, id aliquet metus justo in massa. Proin a tellus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed purus. Sed non pede. Aenean massa sapien, sodales sit amet, consequat dictum, eleifend vitae, tortor. Donec ultrices lacinia elit. + +Morbi adipiscing sodales dolor. Ut ullamcorper ultricies est. In venenatis tempus augue. Suspendisse tortor dolor, accumsan et, suscipit a, tincidunt ut, libero. Aliquam scelerisque magna sed felis. Quisque ut nunc a magna vulputate placerat. Aliquam rhoncus vehicula dui. Sed tortor. Nullam sit amet diam. Nunc sed eros. Sed et odio tincidunt elit gravida convallis. Curabitur quis tortor a lacus semper varius. Mauris at augue non mi sollicitudin aliquam. Integer ullamcorper. Pellentesque suscipit quam non purus. Aliquam ac eros at arcu ullamcorper consectetuer. Suspendisse pretium mattis leo. + +Duis at nunc. Sed dolor est, varius ac, porta et, tincidunt hendrerit, risus. Vivamus ut magna. Praesent ut mauris. In purus lacus, mattis sed, vestibulum nec, tempor at, nisl. Cras ullamcorper venenatis tellus. Ut dolor. Maecenas malesuada, pede a pulvinar mattis, arcu diam vehicula risus, quis porttitor augue massa in velit. Nunc congue. Morbi velit metus, rhoncus et, aliquam consectetuer, ultricies malesuada, ligula. Sed velit nisl, sagittis vitae, pharetra a, posuere sed, massa. Nulla facilisi. In varius, ligula id lobortis sodales, augue orci fermentum tellus, eu pulvinar risus ligula a sapien. Morbi laoreet ipsum non mi. Nam cursus lorem ut mi. Vivamus magna enim, posuere non, semper quis, sodales eu, arcu. Etiam mi purus, pretium feugiat, varius sed, pellentesque eget, ligula. In leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vitae orci eu orci sollicitudin feugiat. + +Praesent purus massa, euismod vitae, tempus nec, consequat hendrerit, metus. Aenean felis est, egestas vitae, accumsan eget, pellentesque in, sapien. Duis dapibus pede non sapien. Nunc urna. Integer vel libero. Duis augue arcu, dapibus non, facilisis vitae, posuere ut, eros. Donec vitae nunc sit amet arcu imperdiet dictum. Morbi eleifend, lorem eu consectetuer vestibulum, diam nunc ornare arcu, ac tempor felis dolor eget eros. Phasellus massa sem, sollicitudin ac, sodales gravida, luctus a, quam. Nam neque quam, viverra at, venenatis quis, sagittis non, enim. + +Nulla facilisi. Pellentesque egestas lacinia est. Sed tincidunt, pede sed tincidunt vestibulum, urna dolor adipiscing purus, vitae fringilla felis elit in nibh. Nulla sed nisi. Mauris suscipit scelerisque arcu. Etiam non enim vel eros accumsan malesuada. Nunc tincidunt commodo mauris. In tincidunt risus quis urna. Nulla diam tortor, aliquet et, tincidunt quis, sollicitudin ac, tortor. Cras nisl neque, vulputate suscipit, molestie quis, pulvinar at, nulla. Nullam ac metus nec odio posuere varius. Cras sed pede nec dui posuere bibendum. Duis euismod ullamcorper libero. Aliquam faucibus pulvinar turpis. + +In ut neque id nunc feugiat commodo. Curabitur dignissim, felis at sollicitudin lacinia, enim elit suscipit neque, sed luctus lorem ipsum in leo. Duis dapibus, odio quis auctor commodo, nisl odio mattis tellus, nec tincidunt turpis diam in arcu. Curabitur a sem. Nullam volutpat magna. Pellentesque sagittis, neque consequat pretium cursus, dolor lacus consectetuer arcu, sed laoreet est urna et metus. Suspendisse placerat, dui a porta tempor, lorem dui lobortis neque, sed venenatis diam enim id eros. Etiam et nisl non lectus faucibus consectetuer. Morbi scelerisque, sem nec tempus ullamcorper, ipsum diam feugiat lorem, a fringilla sapien elit quis nibh. Nullam diam urna, viverra sed, pharetra rhoncus, tincidunt vel, orci. Integer accumsan mattis erat. Nam dictum. Mauris nec leo. Nulla iaculis. Nulla nisl mi, dapibus quis, vehicula a, cursus eget, odio. + +Phasellus dapibus euismod nibh. Vivamus imperdiet ante in ligula. Pellentesque accumsan. In imperdiet, dui a auctor fringilla, metus nisi cursus dolor, vel luctus ligula lorem vitae mauris. Praesent mattis vestibulum elit. Aliquam enim lacus, pulvinar non, lacinia sit amet, eleifend non, velit. Vestibulum ac leo. Mauris imperdiet justo ac lectus. Sed molestie lectus sed dui. Sed fermentum tempus mauris. Nam ornare orci ac tellus. Ut malesuada, lacus id lacinia accumsan, diam elit adipiscing metus, et bibendum sapien nibh blandit orci. Suspendisse ipsum tellus, sagittis quis, vestibulum non, vulputate eu, eros. Praesent at nulla id pede scelerisque ultricies. Cras blandit pretium tellus. Maecenas dapibus condimentum augue. Phasellus tincidunt pharetra lorem. Morbi non eros. Sed tempor, nisl a tincidunt tincidunt, eros diam dictum sem, vel dignissim ante diam sed magna. Praesent non ligula id metus molestie consectetuer. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse vel mi. Curabitur ante nulla, rutrum a, convallis vel, vehicula ac, nunc. Nunc sagittis, enim sit amet auctor rutrum, mauris arcu vulputate neque, et euismod est felis quis ante. Vestibulum turpis tellus, hendrerit in, lacinia commodo, ullamcorper gravida, risus. Mauris rhoncus lacinia risus. Maecenas sollicitudin erat vitae nunc. Praesent pretium pellentesque augue. Donec interdum. Praesent ac eros vitae erat lobortis fringilla. Aenean consequat tellus. Nulla accumsan bibendum felis. Maecenas pretium ante id nisi. Aenean mi arcu, semper sed, mattis eu, venenatis sit amet, arcu. Donec aliquet euismod leo. Proin magna justo, tristique a, semper ac, sollicitudin a, ligula. Morbi velit. Aliquam vel nisi. + +In a lorem ut nunc feugiat congue. Donec fermentum bibendum dui. Proin varius est quis velit. Donec aliquet sem accumsan mi. Sed placerat. Nullam ac nisi a massa lobortis suscipit. Nunc id leo. Aliquam et massa. Nullam vestibulum elementum metus. In consectetuer nisi vel justo. Maecenas eget purus sed massa varius pellentesque. Phasellus faucibus felis quis felis. Aenean odio arcu, blandit quis, facilisis in, imperdiet eu, lorem. Nam posuere pulvinar mi. Fusce tristique, mauris et consectetuer ultricies, mauris lectus tempor justo, at fringilla est est sed nisi. Quisque faucibus. Sed in tortor tincidunt est lacinia iaculis. Maecenas a massa. Pellentesque a nibh at purus porta hendrerit. + +Nullam turpis. Fusce ac sem sed odio pellentesque imperdiet. Curabitur in arcu. Praesent lacus lacus, feugiat id, pulvinar in, tincidunt sed, neque. Maecenas viverra odio eget tortor. Integer aliquam, lorem rutrum venenatis dignissim, ligula magna malesuada arcu, vel feugiat lorem ipsum quis massa. Morbi ante. Vestibulum mauris libero, ullamcorper quis, ultrices quis, facilisis non, massa. Maecenas imperdiet. Aliquam erat volutpat. Pellentesque dignissim gravida lectus. In nibh odio, auctor eget, dapibus quis, dignissim venenatis, arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis pellentesque ligula quis massa. Curabitur condimentum, justo eget ornare luctus, lorem ligula sagittis pede, a porta nunc nunc in neque. Quisque felis mauris, condimentum vitae, auctor vitae, tincidunt quis, pede. Nunc lacinia ante in leo. Pellentesque libero. Aenean a ligula et nunc vestibulum consectetuer. + +Fusce ornare. Praesent id urna. Integer venenatis, quam non sagittis accumsan, ante nibh sagittis augue, sollicitudin adipiscing dolor velit eu erat. Proin quis enim eu purus vehicula aliquam. Nulla vel enim vel elit sollicitudin fringilla. Aliquam erat volutpat. Sed suscipit felis ut turpis. Etiam rutrum risus imperdiet est. Aliquam a tellus at tellus commodo dapibus. Mauris rutrum magna et odio. In at dolor. Curabitur vehicula lectus in tortor. Fusce justo purus, luctus vitae, mollis in, pharetra ac, purus. Nullam posuere interdum justo. Curabitur vitae lacus vel leo congue pulvinar. + +Aenean eleifend nibh varius tortor. Suspendisse vel eros. Proin nec diam a tortor ultrices ornare. Aliquam scelerisque feugiat justo. Vivamus ante urna, adipiscing vitae, porttitor eu, sodales et, felis. Suspendisse potenti. Curabitur ac massa in nisl sagittis mollis. Nam quam ligula, consectetuer eget, iaculis at, varius eu, leo. Duis dolor ligula, tincidunt at, ullamcorper sed, accumsan aliquam, ligula. Phasellus vulputate, lorem at tincidunt pharetra, risus lectus lacinia magna, quis rutrum enim magna at sem. In hac habitasse platea dictumst. Duis id sem a mauris sollicitudin tincidunt. Etiam eu purus eu arcu fringilla adipiscing. Vivamus ornare tempus diam. Proin turpis quam, lacinia non, egestas at, commodo eget, pede. Praesent vulputate risus in est. Nulla facilisi. + +Ut elementum lacinia purus. Proin vitae arcu ac nulla convallis aliquam. Nulla congue, libero id pellentesque mattis, quam lectus porttitor diam, a scelerisque dui libero in sapien. Nullam felis diam, vehicula vel, molestie ut, vestibulum aliquam, sapien. Donec convallis, est ut elementum volutpat, mauris ipsum gravida sem, commodo facilisis sapien lectus semper lectus. Quisque porttitor eros ut nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam mattis risus sed odio. Vestibulum et odio. In hac habitasse platea dictumst. Nam tristique massa ut ligula. Quisque nibh tellus, vehicula sit amet, adipiscing at, convallis nec, ligula. Vestibulum pretium, mi nec fringilla bibendum, dui nunc sodales pede, a semper magna nibh non diam. Donec massa nunc, viverra vel, consectetuer porta, dapibus non, ipsum. Duis nisl mauris, cursus vel, semper non, sollicitudin bibendum, felis. Vestibulum eu neque. + +Cras nec dolor. Donec laoreet tempus lectus. Cras sed tortor interdum lacus eleifend dignissim. Maecenas sit amet elit. Nullam quis dolor vel dui pharetra luctus. In sit amet quam sit amet pede ultrices ultrices. Maecenas diam. Integer urna. Curabitur dictum, velit sed placerat suscipit, erat turpis fermentum justo, sed interdum neque sem et nibh. Vivamus consequat convallis magna. Nam aliquam, est ac bibendum commodo, magna est dictum mi, vitae malesuada elit magna vitae odio. Maecenas tempor vulputate tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus dui. Etiam accumsan pede congue tortor. + +Morbi tempor libero ac lorem. In aliquet varius magna. In arcu. Phasellus odio. Fusce tincidunt aliquet felis. Quisque velit. Sed luctus. Aliquam feugiat fringilla mi. Aliquam molestie viverra risus. Proin arcu. Vestibulum lobortis tempus nisi. Praesent a arcu in velit viverra rutrum. + +In sed lectus. Donec risus dolor, blandit sit amet, elementum convallis, pharetra quis, pede. Integer ornare. Aenean egestas dapibus justo. Sed quam leo, posuere at, elementum vitae, commodo eget, est. Aliquam molestie rhoncus enim. Curabitur iaculis ultrices pede. Morbi aliquet rutrum lacus. Aliquam quam. Sed commodo, turpis in pharetra posuere, mi risus imperdiet erat, a vestibulum massa tellus vehicula sem. Mauris fringilla ultrices nunc. Nam nisi enim, eleifend sit amet, ultrices sed, fermentum non, augue. Proin congue lobortis nisi. Maecenas hendrerit. Nam sed nisl. Nunc elementum odio eu risus. In metus. Phasellus gravida pretium ligula. Nulla vitae neque. Nam nisi tortor, ornare non, blandit at, cursus eu, tortor. + +Duis bibendum ipsum in nunc cursus molestie. Nunc orci. Nullam nec ante non est dignissim viverra. Mauris blandit, velit id feugiat pretium, elit magna pellentesque dolor, at sagittis lacus velit egestas magna. Pellentesque cursus, diam consectetuer sagittis fringilla, tortor nisi adipiscing nunc, eu varius lacus risus ac elit. Mauris id nisi quis leo euismod venenatis. Pellentesque ac ante. Mauris arcu sapien, tempor at, porttitor id, condimentum ut, dui. Etiam fermentum ultricies augue. Cras ut eros at justo ultricies iaculis. Duis dignissim, nisl et facilisis fermentum, erat purus molestie tellus, quis tempus ipsum lectus at elit. Nulla vitae lorem. + +Aenean vel sem et diam semper congue. In bibendum diam quis tellus. Nunc facilisis ultricies nibh. Cras nunc enim, feugiat sed, ultrices vitae, sagittis vitae, ipsum. Fusce vitae nulla. Donec pellentesque, velit in porttitor eleifend, est neque lobortis velit, sit amet rutrum ante tortor nec dolor. Donec vehicula. Nulla facilisi. Sed egestas ultrices nibh. Donec elit lectus, convallis porttitor, aliquet dapibus, feugiat eget, ligula. Sed consectetuer justo. Maecenas a sapien sit amet nisi dapibus lobortis. Vivamus luctus lorem non nulla. Sed eget erat vitae libero interdum posuere. Cras pulvinar. Nullam imperdiet, dolor tempor dignissim blandit, dui sapien rhoncus neque, id malesuada augue magna sit amet urna. Duis sed mauris. + +Morbi accumsan. Sed mauris augue, fringilla non, auctor ut, auctor et, orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus ut pede. Donec viverra enim vel lorem. Pellentesque neque mauris, interdum eu, venenatis id, condimentum eu, sapien. Donec ipsum arcu, lacinia adipiscing, laoreet et, cursus vel, velit. Ut sagittis mauris quis risus. Integer eu odio vitae lacus viverra accumsan. Morbi leo ante, dignissim sed, varius quis, volutpat vitae, nisi. Nulla placerat interdum elit. Donec neque dui, sagittis vitae, sollicitudin quis, commodo vitae, neque. Nulla quis ligula ornare ligula dictum ornare. Mauris rutrum rutrum neque. Aenean vehicula tempus est. Donec varius scelerisque pede. Donec placerat vulputate leo. Nullam nunc nisl, posuere non, feugiat vitae, pellentesque quis, mauris. In dui neque, cursus eget, sagittis eget, dapibus vitae, mi. Proin eget est. + +Fusce porta est. Mauris magna. Aliquam ipsum lacus, ultricies id, vestibulum luctus, accumsan ut, ante. Sed mauris. Sed adipiscing leo sit amet magna. Suspendisse potenti. Nunc massa elit, fringilla eget, egestas vitae, luctus vitae, dolor. Phasellus quis nulla eu nisi interdum sollicitudin. Nullam id tellus. Integer iaculis dolor ac purus. Sed vel mi. Curabitur non magna sit amet justo condimentum vulputate. Quisque tincidunt pede eu nisl. Vivamus lobortis. Nunc metus metus, congue sed, tincidunt sed, pretium at, odio. Donec a arcu. In sem justo, vehicula sed, varius id, volutpat at, risus. Praesent iaculis massa. In arcu elit, hendrerit eget, ullamcorper in, porta id, tellus. Donec sagittis hendrerit diam. + +Suspendisse potenti. Sed et diam et augue sagittis lobortis. Phasellus dolor. Ut et arcu eget ante tempor posuere. Aliquam fermentum scelerisque dui. Mauris at purus. Donec erat sem, vestibulum nec, faucibus ac, mattis a, leo. Suspendisse adipiscing lacinia sem. Nullam orci arcu, dictum et, faucibus viverra, dapibus et, neque. Cras nunc diam, adipiscing non, sollicitudin in, interdum vel, massa. Mauris sagittis, justo at tristique tempus, mauris mauris aliquam ante, sit amet posuere diam dui eget ligula. In dignissim, nisl ut lacinia condimentum, erat justo porttitor nulla, non gravida ligula magna eget massa. Vestibulum vitae ligula at mi vestibulum suscipit. Duis laoreet. Nulla commodo libero sit amet lorem. Ut elementum sem. Integer vel dolor. Nam facilisis mi quis sem ultrices sagittis. Sed quis quam at metus molestie bibendum. + +Proin dui enim, lacinia a, feugiat ac, placerat vitae, pede. Quisque egestas, leo eget aliquam pretium, libero justo tincidunt eros, ut egestas augue pede elementum nibh. Curabitur mollis sodales enim. Donec augue. Phasellus id ipsum posuere dui pretium faucibus. Mauris luctus ante semper nisi interdum adipiscing. Duis dapibus, odio quis viverra rhoncus, justo quam bibendum dolor, id dapibus velit erat vel erat. Fusce sit amet nisl venenatis quam ultrices condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec rhoncus scelerisque ligula. Vestibulum mi odio, accumsan et, adipiscing eget, ornare ut, quam. Nullam blandit molestie mauris. Curabitur dignissim mauris et lorem. Suspendisse a justo. Nam mattis faucibus arcu. Duis blandit enim non massa. + +Nullam lorem. In hac habitasse platea dictumst. Mauris consectetuer posuere mauris. Maecenas tincidunt mauris in eros. Nulla eu metus eu orci sollicitudin faucibus. Suspendisse aliquam mauris id est. Cras blandit dui et urna. Nulla arcu. Sed a urna. Nulla dapibus vehicula tortor. Donec risus. Sed quam metus, egestas eu, cursus ut, viverra non, odio. Ut justo justo, malesuada sit amet, blandit suscipit, molestie in, justo. Vestibulum consequat, quam ac feugiat tincidunt, ipsum libero eleifend odio, non eleifend pede ipsum non ante. Nullam a metus. + +Nam ac nisi at felis cursus mattis. Pellentesque consequat sem quis orci. Quisque tempus. Aenean imperdiet molestie pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eu tellus. Nulla diam eros, sodales ut, sodales nec, tincidunt ac, nunc. Nunc lacinia faucibus ipsum. Vivamus vel neque in erat fermentum luctus. Nulla eget metus nec augue bibendum placerat. Vivamus tempus. Praesent congue ornare ipsum. Etiam mattis feugiat justo. + +Aliquam dui. Aenean commodo tortor vitae nulla. Morbi et ipsum. Mauris ac ipsum. Nam vel risus ut lectus mollis viverra. Curabitur elementum mollis est. Nullam elit. Vestibulum suscipit pretium enim. Vestibulum ut massa. Proin nec felis. Maecenas gravida, arcu nec consequat sagittis, eros tellus scelerisque mauris, vitae accumsan quam quam ut nunc. Integer eget ante eu velit laoreet malesuada. Nunc sagittis, mauris vitae pharetra volutpat, tellus tellus eleifend eros, sit amet rutrum ipsum nisi a velit. Praesent varius leo eu erat. Vivamus consequat placerat purus. Donec pretium elementum nibh. Proin at elit non sem aliquet mattis. Sed ullamcorper ipsum sit amet elit. + +Mauris in metus. Suspendisse magna lorem, faucibus vel, tincidunt quis, scelerisque non, tellus. Fusce quis lorem. Proin a lacus sit amet mauris iaculis pulvinar. Suspendisse rhoncus eros nec mi. Praesent euismod, turpis vitae rutrum pretium, odio metus volutpat neque, eget tempus sapien neque sed erat. Donec fermentum purus at lectus. Nullam sem. Fusce vel mi quis erat lobortis posuere. Aenean eget urna. Suspendisse ligula. Duis in nisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Curabitur vulputate lectus id pede. Phasellus eu velit. Etiam venenatis adipiscing nibh. Aliquam cursus pulvinar tellus. Vestibulum neque. Mauris nec justo et erat semper pellentesque. Fusce mattis dictum dolor. Etiam eget purus eu massa varius elementum. Pellentesque massa. Ut ultricies diam sed ipsum. Nullam diam. Pellentesque id magna id libero tristique aliquam. + +Ut eleifend, purus id placerat venenatis, urna augue aliquet ligula, in ultricies leo risus et tellus. Mauris et nulla id urna tristique tempus. Ut facilisis, urna eu vestibulum rhoncus, lacus eros consectetuer metus, et rutrum dui lectus in purus. Nunc vel nisl non ipsum tincidunt mollis. Nam quam lacus, ornare vitae, rhoncus non, congue sed, odio. Proin nibh dui, porta vel, venenatis non, pellentesque ut, nisi. Sed tristique felis a magna. Suspendisse eget tellus. Cras gravida imperdiet velit. Integer hendrerit risus. Proin orci. Aliquam ullamcorper mauris quis mauris. Nunc lacinia vestibulum metus. Duis tellus. Nullam faucibus, leo ac vulputate sollicitudin, leo dolor faucibus erat, quis bibendum orci odio non arcu. + +Nullam accumsan mattis dolor. Donec et dui. Praesent a felis mollis lacus semper lacinia. Curabitur pellentesque luctus est. Proin nulla dui, condimentum vel, faucibus non, interdum ac, erat. Maecenas scelerisque, lectus id volutpat accumsan, sapien tortor pellentesque dui, sed semper magna sem ut leo. Proin nulla. Nullam dapibus ullamcorper sem. Suspendisse vehicula metus in nunc. Pellentesque non quam vel arcu ultrices ullamcorper. Phasellus quis felis sit amet tellus ullamcorper fermentum. Sed vehicula sollicitudin urna. Curabitur pharetra scelerisque risus. Pellentesque id massa quis metus aliquam imperdiet. In nunc lacus, feugiat in, gravida eget, venenatis ut, tellus. Suspendisse potenti. Nam consequat adipiscing dui. In nulla nisi, feugiat ut, fermentum vel, gravida nec, tortor. In sed augue. + +Etiam ullamcorper augue at enim. Integer dignissim. Aliquam pulvinar congue nulla. Morbi enim massa, fringilla a, accumsan eget, condimentum nec, erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean pharetra. Etiam porttitor purus a metus. Aliquam interdum sem eget justo. Quisque volutpat luctus est. Aenean augue. Phasellus dui lectus, ultrices nec, commodo vel, auctor vel, nisi. Ut ultrices pellentesque nisi. Integer ac velit et sem imperdiet luctus. Fusce vitae turpis id augue mollis consectetuer. + +Maecenas nec lacus. Maecenas condimentum odio eu felis. Mauris ut nisl viverra erat faucibus adipiscing. Etiam egestas. Nunc et dolor vitae risus dignissim commodo. Morbi lectus velit, tincidunt nec, aliquet vel, mattis vitae, ligula. Maecenas ultricies semper dolor. Suspendisse malesuada. Integer mattis elit. Donec accumsan, lacus facilisis varius tempus, nulla elit porta erat, et rutrum elit sem sit amet dui. + +Maecenas mollis mi non nulla. Vivamus turpis. Suspendisse a metus. In quis mi in turpis congue auctor. Maecenas lacus. Suspendisse sollicitudin. Phasellus porta nunc non nisl pulvinar egestas. Sed nulla. Vestibulum ac mi. Mauris ultricies condimentum neque. Nulla tempus justo vel massa. Nulla suscipit congue arcu. Praesent id turpis. Mauris nibh pede, euismod semper, molestie ac, rhoncus vitae, ante. Maecenas erat felis, viverra sollicitudin, sagittis eget, pellentesque nec, orci. Fusce ultrices consequat lacus. Aliquam erat magna, feugiat at, viverra a, mollis non, turpis. + +Donec mi. Nam dictum pellentesque sem. Donec mollis rhoncus elit. Phasellus rhoncus pede sit amet risus. Donec eget augue. Maecenas non lectus. Phasellus sollicitudin nisi nec felis. Aliquam pretium, est eget semper convallis, nibh nunc sollicitudin purus, id tempor pede dui vel magna. Vivamus ac lorem. Etiam nisl tortor, adipiscing dictum, elementum in, facilisis sed, nibh. Proin mauris. Proin rutrum massa eget sem. Curabitur tempor adipiscing elit. Curabitur purus tellus, fermentum eget, aliquet vitae, convallis ac, mauris. + +Integer consequat velit eu eros tincidunt vehicula. Nullam lorem sapien, rhoncus non, mattis quis, ultricies sit amet, enim. Curabitur commodo, libero in euismod suscipit, sem purus fringilla enim, ac molestie tortor orci et velit. Donec pede. Etiam placerat condimentum turpis. Phasellus egestas enim nec magna. Vivamus condimentum, nulla vel luctus tristique, eros risus vestibulum nulla, in vehicula arcu ipsum at felis. Donec aliquam elit at augue. Quisque a eros eu ligula accumsan dictum. Etiam vehicula turpis quis libero. Aliquam non mi. Donec et leo. Proin leo libero, aliquam tincidunt, congue nec, adipiscing porta, enim. Nulla lobortis, tortor sit amet imperdiet ullamcorper, dolor orci malesuada pede, sed gravida nibh urna vel lorem. Sed pharetra malesuada eros. Quisque euismod aliquet erat. Suspendisse aliquet mattis purus. + +Nunc id nulla quis justo congue sollicitudin. Praesent erat turpis, rhoncus eu, pretium eu, pellentesque a, nibh. Vivamus tempus. Cras nec risus at turpis imperdiet lobortis. Ut mattis. Maecenas est felis, pellentesque non, imperdiet sed, eleifend tincidunt, lorem. In tincidunt. Sed vel leo. Donec et urna in turpis hendrerit blandit. Donec condimentum accumsan est. Ut pharetra, metus vitae mattis consectetuer, leo quam vulputate odio, nec laoreet nisi velit eu erat. Integer lectus augue, egestas in, interdum eu, venenatis vel, sapien. Quisque et est vitae eros laoreet lobortis. Nullam ut risus non nulla placerat adipiscing. Praesent dapibus. Etiam a felis. Ut sodales consequat mauris. Duis lorem felis, luctus a, tristique in, molestie at, risus. Sed vehicula bibendum tellus. Nam consequat euismod lacus. + +Aenean tortor elit, gravida nec, fermentum eu, lobortis id, ipsum. Maecenas eu purus. Cras ac turpis ut nisi iaculis rhoncus. Nulla purus metus, dignissim nec, tincidunt vitae, dapibus eu, nibh. Fusce lobortis, nunc at viverra eleifend, justo turpis scelerisque eros, ac pellentesque metus nisl at purus. Sed elementum tellus sed enim interdum blandit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer ultricies aliquet odio. Mauris eget nunc a ipsum ultrices sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean accumsan. Donec sapien lectus, congue at, porta id, hendrerit vitae, nisl. Curabitur vel quam vel neque accumsan laoreet. Morbi sapien est, pretium in, consectetuer ac, mollis ut, libero. Donec tincidunt adipiscing metus. Nunc vestibulum egestas augue. Donec scelerisque dui ut sem. Suspendisse vel metus id est molestie iaculis. + +Vivamus pharetra, elit eu malesuada blandit, diam tortor mollis dui, sed pulvinar massa nunc et magna. Sed placerat elit auctor tortor. Nulla ac erat. Pellentesque consectetuer, dui convallis tincidunt condimentum, sem odio volutpat libero, non elementum felis neque nec odio. Maecenas hendrerit eros id diam. Mauris vel purus ac orci convallis convallis. Sed sit amet lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque dictum varius lacus. Mauris eget nisl. Suspendisse placerat, nulla non ornare dignissim, nisl diam sagittis tellus, in semper nisi dolor at nibh. Duis ullamcorper viverra felis. Integer a tellus. Suspendisse eget nunc. Aenean diam est, accumsan id, suscipit interdum, fringilla vitae, justo. Proin pede. Maecenas at neque in neque vestibulum eleifend. + +Vestibulum nulla lorem, porttitor eget, euismod ac, aliquam at, nisl. Maecenas et est eget massa varius lobortis. In mi. Duis porttitor fermentum purus. Donec cursus imperdiet ligula. Morbi et ligula et ante molestie vehicula. Mauris sed dolor. Sed imperdiet felis ut sem. Sed vitae neque elementum leo auctor fermentum. Duis feugiat ullamcorper erat. Aenean purus. Morbi fermentum vestibulum est. Pellentesque venenatis mauris. Phasellus pulvinar. Integer ipsum lectus, iaculis a, lacinia id, accumsan id, arcu. Phasellus at est. Fusce neque quam, ultricies id, iaculis vel, dapibus vitae, lacus. In lobortis convallis ante. Nulla nunc purus, vulputate in, hendrerit et, blandit et, ligula. + +Pellentesque leo metus, sagittis in, molestie vitae, dictum in, pede. Morbi pretium felis nec quam. Pellentesque mattis ante sed quam sagittis dapibus. Suspendisse sapien. Praesent bibendum iaculis tortor. Duis a nisl. Aenean mi. Donec dictum arcu in est. Morbi interdum vulputate ipsum. Aenean sit amet magna non nisl tristique posuere. Phasellus velit metus, tempor ac, fermentum eget, condimentum non, velit. Vestibulum sit posuere. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras aliquet massa nec dui. Cras arcu nunc, hendrerit ac, eleifend eu, ullamcorper nec, tellus. Sed pharetra purus sit amet quam. Curabitur mollis. Nam vitae pede. Etiam risus massa, vehicula sit amet, pharetra nec, sollicitudin ut, dui. Donec egestas justo at quam. Proin nisl risus, vestibulum nec, pretium vitae, tristique ac, lorem. Aliquam erat volutpat. Cras sed nibh. Pellentesque sollicitudin euismod augue. + +Etiam fringilla sollicitudin orci. Mauris cursus elit quis lacus. Cras tortor. In adipiscing, lectus id auctor vestibulum, neque pede accumsan dolor, non imperdiet magna diam accumsan velit. Suspendisse at libero ut nisi blandit sagittis. Phasellus non mauris. Fusce elementum sagittis sem. Suspendisse aliquam eleifend tellus. Proin ligula lorem, imperdiet quis, venenatis id, iaculis mollis, nisl. Etiam convallis pede at massa. Morbi accumsan dui et mauris. + +Sed sed orci. Nunc purus. Suspendisse potenti. Ut luctus fringilla mauris. Donec nibh. Phasellus porta. Phasellus sit amet odio sed magna sodales pharetra. Cras lectus. Suspendisse libero ipsum, commodo nec, facilisis in, suscipit lobortis, ligula. Duis massa nulla, semper et, consequat nec, pharetra eu, elit. Vivamus ultricies aliquam odio. Vestibulum sit amet massa. Sed consequat lacus sed urna. Etiam faucibus felis vel orci. Phasellus ullamcorper. Aenean consectetuer lacus at libero. + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis facilisis, ligula vitae condimentum scelerisque, velit orci gravida felis, vel ultricies quam mi non diam. Vivamus auctor metus non libero. Praesent ligula nisi, commodo condimentum, molestie et, viverra et, justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus sollicitudin. Nunc blandit cursus ipsum. Aenean nec ligula ut tellus sodales mattis. Integer sem. Aliquam id ligula. Sed tortor mauris, blandit vitae, cursus vel, elementum et, nulla. Aliquam scelerisque metus et nisl. Duis adipiscing magna at neque. Quisque vulputate eleifend nunc. Aliquam eget elit. Phasellus dui odio, bibendum sagittis, vestibulum id, dignissim imperdiet, orci. Nullam eu felis non nunc lacinia sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Suspendisse pellentesque, libero mattis ultricies accumsan, tortor tortor malesuada sem, et sodales libero odio ac ipsum. Vivamus quis magna nec est suscipit lobortis. Cras tempus posuere nunc. Quisque ut enim a felis egestas semper. Sed pharetra mattis neque. Fusce turpis nunc, congue sed, consequat non, congue sed, nulla. Suspendisse varius lorem id risus porta vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce sed purus. In a felis. Integer egestas auctor orci. Mauris ultrices suscipit nisl. Nullam purus. + +Cras tempor adipiscing ipsum. Ut quis mi. Maecenas in justo ut nulla congue pharetra. Pellentesque ut libero eu dolor venenatis suscipit. Praesent feugiat consectetuer nibh. Morbi faucibus sem non felis. In hendrerit arcu ac massa. In accumsan ultrices mi. Proin malesuada auctor felis. Curabitur interdum. Sed diam ipsum, ultricies in, tempor sit amet, viverra imperdiet, elit. Morbi molestie nisi. Mauris ipsum. Fusce dictum mollis magna. Duis commodo dignissim nulla. Vestibulum augue enim, ultricies quis, iaculis nec, tincidunt vitae, diam. Mauris lacinia tempus ipsum. Sed at mauris. Ut lorem. Donec libero. + +Duis iaculis lacinia lectus. Aenean convallis eros ac ante. Sed quis orci nec risus auctor fringilla. Phasellus facilisis elementum nisi. In hac habitasse platea dictumst. Nunc porta lacus nec ante. Morbi mauris erat, adipiscing in, pulvinar nec, lobortis nec, odio. Ut eleifend lectus sed quam. Nullam mollis. In non turpis et nisl hendrerit blandit. Duis elementum. Nunc nec libero. Suspendisse vestibulum risus non pede. Morbi imperdiet odio sit amet libero. Sed sed massa vitae ipsum mattis tincidunt. Nulla nec tortor vitae libero volutpat tempus. Donec aliquam. + +Duis sed nunc. Curabitur turpis nulla, vehicula sed, luctus quis, elementum eget, felis. Maecenas et purus. Maecenas leo tellus, tincidunt a, facilisis vitae, lobortis sit amet, velit. Donec convallis sapien. Maecenas mollis odio eu nibh. Etiam gravida. Integer molestie, sapien eu molestie lacinia, nunc nibh aliquam ligula, eu sagittis tellus erat sollicitudin odio. Duis et risus. Phasellus nisi neque, placerat nec, condimentum non, ultrices eu, sem. Ut pede. Etiam nulla metus, volutpat id, convallis sed, suscipit vel, urna. Donec vel elit. Ut leo neque, venenatis faucibus, lacinia nec, tincidunt eu, enim. Cras id dui a libero pharetra dignissim. Donec eros leo, porta quis, laoreet ut, pellentesque volutpat, lectus. + +Nullam blandit. Aliquam erat volutpat. Fusce adipiscing enim. Suspendisse non dui quis ligula porta vestibulum. Donec eu tellus vel lorem pretium porttitor. Praesent luctus. Aliquam ac eros in massa dapibus tincidunt. Donec ut magna. Etiam auctor lacus sit amet lacus. Sed ultricies ipsum nec elit. Quisque a est in purus suscipit tristique. + +Aenean sed dui vel dolor pulvinar laoreet. Vivamus vehicula lorem in pede. Vivamus et diam. Integer ac odio vel diam hendrerit bibendum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a nisi. Phasellus tincidunt dui vitae augue. Duis faucibus, dui interdum fringilla tincidunt, odio elit vestibulum libero, ac molestie magna lectus id lacus. Aenean ligula. Nulla facilisi. + +Fusce vel sem eu velit fringilla ornare. Sed feugiat tincidunt felis. Nullam felis mi, euismod sit amet, mollis at, sodales eget, augue. Nam imperdiet nibh at velit. Sed ut erat. In dui. Nulla facilisi. Nullam augue libero, tincidunt nec, pretium eu, pulvinar in, dui. Morbi vitae felis. Pellentesque vel justo vel velit sagittis malesuada. Proin vehicula blandit massa. Etiam tincidunt pharetra urna. In metus est, auctor nec, blandit a, cursus nec, quam. Mauris ac metus a libero congue faucibus. Mauris mauris dolor, sodales in, cursus ut, sodales rutrum, eros. Quisque mauris eros, sagittis vitae, lobortis ut, eleifend id, nisi. + +Aenean neque. Vestibulum egestas pellentesque ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus sagittis justo vel risus. Sed pretium neque vitae urna. Pellentesque congue libero id lorem. Mauris leo lorem, blandit sit amet, convallis quis, consectetuer sed, eros. Mauris tincidunt, enim a gravida euismod, magna nulla fermentum libero, viverra egestas velit quam et tortor. Vivamus aliquet massa vitae justo. Nulla congue lacus ac elit. + +Phasellus commodo quam vel ligula. Proin non metus at eros pulvinar luctus. Mauris diam lorem, posuere quis, gravida et, tincidunt nec, ligula. Sed diam. Aliquam elit lectus, hendrerit ut, imperdiet sit amet, pretium sit amet, ipsum. Mauris vehicula nisl in dui. Curabitur eget quam ut magna elementum fermentum. Mauris scelerisque. Quisque laoreet. Etiam tempus turpis. Pellentesque augue quam, hendrerit sed, tincidunt at, pharetra at, nisl. Aliquam lacus. Suspendisse potenti. Aenean velit libero, ultrices in, lacinia eu, luctus vel, ante. Etiam dictum mi in felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce gravida dapibus nisl. Cras vitae nisl. + +Maecenas dignissim, ligula non porta cursus, enim nunc malesuada sem, eu porttitor nulla urna eu quam. Fusce eros. Aliquam eros. Nam auctor. Nulla molestie porta est. Suspendisse potenti. Vivamus molestie lorem sed erat. Sed eget ipsum. Integer aliquam pulvinar nulla. Cras aliquet sem ut nunc. Fusce faucibus tempus lectus. Cras sodales, nisi ac facilisis ultrices, eros arcu dapibus sapien, et ultrices mauris tellus non dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras cursus varius metus. Ut turpis. Vivamus eget tortor. + +Sed laoreet, velit non accumsan cursus, nunc urna posuere justo, in dictum lectus pede id ante. Cras vulputate. Cras congue dui sed elit. Proin lacus sem, ultrices at, consequat in, tempor quis, metus. Proin vel arcu. Nam euismod hendrerit elit. Ut erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed posuere. Morbi eros urna, semper at, semper non, convallis quis, velit. Maecenas orci. Vestibulum lobortis tristique metus. Vestibulum lorem nulla, sollicitudin vitae, condimentum quis, auctor ut, dui. Vivamus vestibulum magna ut nisi. Curabitur eleifend dui vel nunc. Curabitur mauris lacus, malesuada sit amet, suscipit sed, rutrum luctus, tellus. Integer facilisis urna vitae lectus. + +Aenean quam leo, lobortis quis, malesuada eu, vulputate vitae, nisl. Praesent eget eros. Ut fermentum turpis id quam. Nam tortor. Praesent nec orci. Nulla bibendum adipiscing augue. Ut commodo, magna id malesuada gravida, augue odio malesuada mi, porta malesuada elit est vitae diam. Mauris non nulla. Suspendisse tincidunt, nunc ultricies porta venenatis, mi pede tincidunt libero, eget varius ante libero ut ligula. Curabitur pretium porttitor tortor. + +Maecenas vitae elit eget nisi dapibus dictum. Nunc in libero. Nulla dictum orci eu erat auctor lobortis. Phasellus risus. Suspendisse potenti. Suspendisse potenti. Praesent adipiscing consequat elit. Integer id augue. Praesent in justo nec magna dapibus pulvinar. Duis nisl. Suspendisse ac odio. Vivamus imperdiet. Donec non velit sit amet risus dignissim congue. Nam aliquet posuere velit. Cras turpis. Morbi malesuada dignissim mi. + +Sed leo neque, varius quis, venenatis sed, pharetra sed, est. Morbi blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam semper pellentesque mi. Ut vel lorem. Nunc mi tortor, laoreet at, faucibus eu, tincidunt sit amet, erat. Duis tempor malesuada ipsum. Phasellus aliquet. Donec et elit. Pellentesque purus. Vestibulum rutrum semper nibh. Nulla facilisi. Phasellus et enim sit amet ante vestibulum vehicula. Phasellus id nisl. Donec mollis leo at eros. Mauris pellentesque neque at purus. Morbi quis dolor at ipsum scelerisque sodales. Etiam volutpat turpis a metus. In hac habitasse platea dictumst. Nunc lorem lorem, vestibulum ac, euismod eget, ullamcorper dignissim, velit. + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ultrices, nibh vel aliquam vestibulum, eros enim venenatis dui, id iaculis enim nunc vel massa. Morbi eleifend orci et massa. Aliquam erat volutpat. Nulla mollis egestas turpis. In sodales nunc eget tortor. Sed ipsum eros, tempor quis, aliquet vitae, imperdiet non, lorem. Pellentesque quis elit id mi luctus dapibus. Sed nunc arcu, rhoncus nec, convallis quis, cursus at, neque. Mauris convallis purus at erat. Pellentesque vestibulum. Vivamus fringilla elit at arcu. Nullam aliquet enim nec arcu. Nam id tortor. Nulla quis nunc. Ut arcu. Suspendisse potenti. Pellentesque ullamcorper ligula id arcu. + +Nam non libero vitae nisl scelerisque fringilla. Quisque varius ante id metus rhoncus fringilla. Nulla facilisi. Praesent eleifend porttitor ligula. Etiam quis dolor non augue commodo auctor. Donec a mi. Vestibulum tempor. Donec felis urna, auctor at, cursus dictum, gravida id, arcu. Aenean dictum malesuada dolor. Vivamus mattis. Phasellus eu pede. Fusce adipiscing justo fringilla metus. Etiam ante. Integer mollis massa quis nunc. Integer dictum neque luctus enim. + +Sed eu libero. Integer tempor ligula in velit. Ut tincidunt lacinia sem. Nullam vel risus. Sed sodales ante a dolor. Curabitur eros. Sed sodales. Sed non metus. Vestibulum elementum faucibus ante. Nulla vel nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In hac habitasse platea dictumst. Nunc nec lorem ut ipsum lacinia iaculis. Duis erat. Aliquam erat. Cras iaculis. In hac habitasse platea dictumst. + +Nullam ante. Cras vitae est. Pellentesque vel metus a ligula dapibus mattis. Duis feugiat aliquet felis. Etiam id nisl quis est dignissim condimentum. Suspendisse potenti. Morbi velit lorem, ornare quis, pellentesque vel, placerat eget, tortor. Vestibulum tincidunt molestie libero. Nulla nulla enim, malesuada id, ullamcorper vitae, dictum at, purus. Donec dignissim odio ut enim. Suspendisse at lectus. + +Praesent lobortis augue vel lectus. Ut in ligula ut felis congue suscipit. Quisque dignissim tortor ut mi. Fusce magna nisi, eleifend ac, ornare vel, porttitor vitae, quam. Vestibulum sodales justo quis turpis. Fusce urna nisi, rhoncus quis, condimentum vel, dictum eu, nunc. Fusce sed nibh vitae odio posuere adipiscing. Sed porta elit quis dolor. Nam libero nulla, auctor sed, tincidunt quis, faucibus sit amet, mi. Quisque orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam id sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vel eros. + +Vivamus luctus lobortis leo. Suspendisse vel elit a enim ullamcorper posuere. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec quis pede mattis lectus mollis adipiscing. Sed accumsan posuere erat. Praesent euismod tincidunt felis. Donec mi. Ut commodo arcu lacinia tellus. Aliquam a libero quis lectus semper viverra. Curabitur lacinia mauris at tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sit amet magna molestie orci suscipit fringilla. Fusce pretium metus non sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed hendrerit. Nulla felis. Suspendisse potenti. Aliquam blandit tristique neque. Curabitur quis erat vel nunc accumsan mollis. + +Duis sagittis, tellus ut aliquam fringilla, dolor mi ullamcorper nisl, ut tristique pede elit sed mauris. Curabitur id felis. Donec pulvinar lacus et lectus. Aliquam vulputate vulputate metus. Curabitur magna felis, adipiscing ac, accumsan vel, molestie quis, quam. Mauris elit arcu, pretium vitae, mollis sit amet, sollicitudin ut, mi. Donec imperdiet dignissim mi. Nullam sit amet tortor. Aliquam neque nulla, venenatis a, porta in, placerat tempus, lacus. Quisque vestibulum dui et lacus. Proin dignissim consectetuer purus. Etiam gravida tortor in nunc. Ut tempor tristique tortor. Sed laoreet tincidunt quam. Vestibulum porta turpis ut elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nibh dui, feugiat nec, laoreet id, malesuada eget, nisi. Ut neque massa, vehicula eu, commodo non, ultricies vitae, purus. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris euismod, felis vel tempor aliquet, tortor mauris malesuada nunc, vel fermentum sem diam id dui. Nam rutrum sapien eget odio. Aliquam sed libero non mi faucibus tempus. Fusce hendrerit, diam non volutpat rutrum, erat metus venenatis ligula, non scelerisque pede ligula vel quam. Morbi rhoncus eros ac dui feugiat elementum. Duis eu libero et tellus congue viverra. Morbi quam quam, elementum sed, ullamcorper imperdiet, commodo non, odio. Nam aliquet egestas urna. Mauris odio felis, varius eu, lacinia eu, condimentum a, lectus. Sed justo massa, pulvinar id, varius a, porttitor nec, libero. Etiam varius. Curabitur sodales, odio at posuere semper, eros nibh tincidunt lectus, vel rutrum sapien nisi in ligula. Suspendisse eget arcu. Phasellus imperdiet est ac sapien. Donec nulla tortor, placerat vel, tempus a, lobortis vel, nibh. Aliquam varius nisi. Nulla et enim. Fusce convallis laoreet lacus. + +Phasellus ipsum dolor, molestie quis, condimentum in, commodo eu, diam. Quisque bibendum lacinia dui. Nullam blandit vulputate orci. Ut lacinia massa vel augue. Aliquam gravida, quam quis imperdiet imperdiet, tellus diam pharetra erat, at pharetra lacus nibh egestas magna. Nulla sagittis lorem ut lorem. Duis condimentum, dui vitae aliquam posuere, diam quam convallis velit, ut gravida leo ipsum non risus. Ut fermentum sollicitudin erat. Donec sagittis scelerisque felis. Nunc arcu. Etiam tempus, magna sit amet suscipit euismod, eros sem rutrum dui, vitae sagittis nibh purus non lacus. Sed mollis arcu eget dolor. Donec ornare, arcu sit amet fermentum vulputate, risus enim fermentum libero, a lacinia dolor mi non velit. Etiam lobortis purus a elit. Nunc nulla dui, mattis quis, bibendum a, ultrices ac, augue. In aliquam vehicula turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Integer id nisl. Quisque dictum elementum odio. Aenean luctus. Sed eu sem a pede vulputate condimentum. Quisque magna. Donec aliquam mattis ipsum. Curabitur dictum sollicitudin sem. Aliquam pulvinar. Nunc sollicitudin risus a erat. Vivamus quis tellus sit amet nibh vestibulum consequat. Nulla pretium sollicitudin dolor. Aliquam iaculis tincidunt turpis. Phasellus ipsum leo, venenatis in, sagittis in, ornare at, nunc. + +Pellentesque ultrices, dui eu iaculis luctus, tellus augue volutpat sapien, in dignissim urna felis ut mi. Sed arcu dui, dignissim id, porttitor ut, imperdiet vitae, ante. Nulla dui sem, commodo nec, sagittis et, lacinia et, pede. Etiam eleifend dui ut nisl. Donec ante mauris, tempus sit amet, varius vitae, gravida quis, mi. In scelerisque, felis vitae viverra sagittis, velit metus ultricies neque, quis imperdiet velit elit et magna. Suspendisse potenti. Sed velit eros, euismod sed, condimentum nec, faucibus sed, sapien. Nam accumsan ligula sit amet neque. Aliquam erat volutpat. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam eu pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed eu felis sed tortor tempor fermentum. Phasellus commodo sem vel nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lectus elit, pharetra sit amet, accumsan sed, tincidunt et, mauris. Duis dapibus pharetra sem. Integer in justo. Praesent eros. Vestibulum ac ante. Aliquam scelerisque sem pellentesque nibh consectetuer sodales. Aliquam consectetuer odio. Duis lectus odio, luctus eu, commodo quis, mollis vitae, velit. Cras nec nunc non elit iaculis mattis. Aenean justo neque, sollicitudin eget, ullamcorper eget, egestas id, sem. In eu risus. Sed egestas. + +Integer at neque. Sed pretium scelerisque nulla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce ut pede. Etiam vitae quam a urna varius imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vehicula. Fusce ullamcorper nibh non erat. Quisque in neque. Praesent est. Pellentesque arcu. + +Proin posuere. Suspendisse potenti. Integer felis lacus, aliquam sed, vulputate in, mollis vel, tellus. Integer vehicula bibendum est. Nunc non dolor in tellus mattis facilisis. Integer vestibulum, augue at commodo aliquam, dui est mattis ligula, sit amet adipiscing orci sem vitae magna. Praesent enim velit, malesuada at, congue nec, luctus in, justo. Sed varius. Morbi pharetra. Donec eu massa nec tellus vulputate pulvinar. Ut commodo turpis non sem. Ut convallis ullamcorper risus. Etiam interdum pede id nisi. Cras magna sapien, suscipit a, laoreet non, rhoncus et, felis. Integer orci lorem, vestibulum dictum, ullamcorper a, porttitor et, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc et magna. Sed bibendum tellus in diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vitae tortor. Integer magna. Duis venenatis, leo ac tempor laoreet, elit nulla pharetra pede, non fermentum nunc odio a odio. Proin non velit. Sed imperdiet augue quis nisl. Integer condimentum nisl nec libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus placerat libero. Duis congue dictum magna. Aliquam dapibus bibendum enim. Nunc eleifend pede vel ipsum. + +Etiam vitae velit. Mauris erat nunc, malesuada ut, feugiat ac, placerat condimentum, augue. Nam volutpat. Aliquam vehicula ipsum id odio. Vivamus sollicitudin turpis id sapien. Fusce a felis vitae odio convallis blandit. Curabitur vitae eros id eros porta pretium. Nulla in magna eget urna lacinia convallis. Aliquam mattis venenatis purus. Sed sed mi eget erat tristique porta. Donec auctor dolor a erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In nec ligula. Nunc eleifend. Vestibulum quis nisi eget elit porttitor congue. Maecenas faucibus, magna eget adipiscing tincidunt, dolor ante malesuada elit, non elementum lacus turpis in pede. + +Ut malesuada mi nec metus. Praesent auctor augue ac nisl ultricies facilisis. Nam purus sapien, pellentesque dignissim, posuere eu, cursus id, diam. Quisque sollicitudin, elit a pellentesque scelerisque, lorem risus auctor quam, quis consequat tellus neque id urna. Suspendisse diam tortor, eleifend dignissim, egestas ut, luctus in, ante. Duis ante. Maecenas luctus. Curabitur cursus pharetra urna. Maecenas imperdiet, erat non elementum euismod, tortor odio euismod lectus, ac facilisis sem nibh vitae nulla. Nunc gravida. Morbi sollicitudin odio quis lacus. Aliquam a nibh non urna porta imperdiet. Aliquam erat volutpat. In iaculis lacinia velit. Sed libero lacus, tristique eu, lacinia ac, aliquet eget, urna. + +Etiam at nisl. Phasellus faucibus luctus lectus. Ut placerat vulputate dolor. Phasellus vel velit. Morbi viverra. Phasellus orci. Integer dignissim mattis mauris. Pellentesque posuere leo posuere quam. Quisque nec magna at diam viverra pellentesque. Suspendisse velit arcu, ultricies quis, congue a, venenatis eget, lacus. Integer sagittis hendrerit dolor. Fusce tincidunt ante a sem. + +Maecenas consectetuer, justo sed rhoncus venenatis, nibh arcu rutrum dolor, sed condimentum libero libero et ipsum. Vivamus mattis justo ut lorem tincidunt lobortis. Ut non velit id neque aliquet accumsan. Sed tempus viverra nulla. Curabitur ullamcorper, neque quis dapibus scelerisque, felis diam gravida orci, non cursus quam neque vitae elit. Etiam pharetra tincidunt lacus. Duis euismod fringilla est. Etiam ornare tincidunt lectus. Proin in turpis. Nunc blandit blandit turpis. Aenean ut augue. Duis orci justo, tincidunt eu, rutrum sed, rutrum et, turpis. Curabitur facilisis odio in ante. In hac habitasse platea dictumst. Sed eros est, pellentesque at, tincidunt eu, ultrices quis, metus. Morbi sit amet justo. Maecenas ac arcu. Mauris dignissim. + +Pellentesque ultricies rutrum orci. Aenean ornare. Vivamus eu risus vel mauris lobortis dictum. Sed et turpis auctor mi rhoncus pulvinar. Sed nec nunc a purus tempor viverra. Pellentesque suscipit. Donec tristique risus non nibh. Etiam nisl magna, sollicitudin ut, ultrices sit amet, egestas eu, nulla. Aliquam erat volutpat. Vestibulum pharetra. Sed egestas, metus sit amet lobortis consequat, erat elit imperdiet libero, eu interdum quam massa eget dolor. Suspendisse vitae odio. Proin blandit mauris iaculis metus. + +Vivamus vestibulum. Etiam et nisl. Aliquam in diam vel elit placerat suscipit. Duis sodales purus ac nibh. Nulla in odio eget enim luctus blandit. Curabitur ultrices ipsum non neque egestas eleifend. Sed turpis. Proin consectetuer. Vivamus mattis. In aliquet. + +Nunc id eros. Donec venenatis, nulla et mattis luctus, ante leo semper justo, non adipiscing odio risus sed lacus. Praesent vitae risus congue libero congue tempus. Phasellus ac eros. Nulla vehicula, lorem in aliquet suscipit, arcu erat egestas sem, quis lobortis quam ante eu massa. Curabitur non massa. Sed bibendum lacinia odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus volutpat blandit lacus. Proin porta, tellus ut auctor laoreet, lectus eros fermentum lectus, id sagittis arcu justo in turpis. Phasellus consequat. Nam pellentesque, mi id viverra convallis, nunc libero placerat leo, eleifend porta sem nisl vitae sapien. Pellentesque ligula libero, tristique non, porttitor rutrum, porttitor non, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer dictum tellus a tortor. Vivamus felis nunc, molestie non, rhoncus quis, pharetra id, dui. Donec risus metus, fringilla vel, aliquet eu, placerat id, neque. + +Suspendisse ipsum. Vivamus lectus. Sed viverra, massa eget convallis mattis, quam turpis consectetuer nunc, eget posuere magna sem id velit. In nec mauris. Aenean a purus sed quam lobortis fringilla. Proin ultricies lacinia ante. Sed adipiscing erat quis velit. Nullam vitae nisl id justo sollicitudin molestie. Nulla facilisi. Sed nec urna sed nisl fringilla dapibus. Nulla at diam. Aliquam eget nibh. Nunc ac nisi sit amet tellus egestas tempus. Nam scelerisque urna et neque. Donec est orci, sagittis non, vulputate a, commodo et, augue. Ut dapibus tortor. Ut nunc. Donec dictum dapibus odio. Nam ultricies ullamcorper ligula. Pellentesque accumsan varius leo. + +Morbi euismod laoreet erat. Vivamus quis ipsum. Morbi euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel purus. Nullam at magna. Curabitur lacus lorem, iaculis quis, dapibus non, volutpat vel, nulla. Donec ut arcu rhoncus dolor pretium dictum. Nullam vel metus. Ut arcu. Pellentesque nisi nunc, placerat eget, tincidunt vel, pharetra non, nunc. Integer tincidunt ultricies lectus. Integer semper, purus sed ultrices feugiat, nulla pede sollicitudin erat, vel auctor nulla ipsum vel lectus. Aenean mi. + +Nullam sed nisi et arcu imperdiet fermentum. Mauris nec metus. In ac dolor. In mi arcu, congue ac, pharetra nec, scelerisque sit amet, magna. Curabitur lacus. Curabitur et elit. Aliquam ullamcorper nunc eu elit. Sed convallis dolor at velit. Vestibulum dapibus, augue id consectetuer placerat, nunc massa blandit sapien, id aliquam elit nisi id mi. Phasellus sapien est, gravida eu, bibendum ut, adipiscing quis, est. Ut molestie quam vitae odio. Donec quis risus id erat faucibus sollicitudin. Nam id felis. Mauris sed enim vitae leo accumsan pretium. + +Nam justo. Donec turpis nisl, commodo et, interdum ac, consectetuer non, massa. Fusce sem metus, laoreet nec, posuere id, imperdiet in, velit. Donec vulputate justo eget turpis. Nulla pede. Morbi tincidunt. Fusce aliquet, quam et aliquam fringilla, ante ante iaculis dui, nec aliquam arcu purus sed erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus suscipit quam et est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; + +Integer sed tellus. Sed sed velit ultricies leo rutrum laoreet. Sed non eros ac purus sagittis feugiat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed hendrerit ligula sit amet nibh. Maecenas turpis. Morbi consectetuer, dolor et adipiscing imperdiet, ante neque feugiat dolor, at porta quam neque quis ligula. Mauris semper velit sit amet ipsum. Pellentesque tempus, purus in rutrum consequat, enim erat vehicula massa, id accumsan leo sapien nec purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In dolor. Integer facilisis libero sit amet pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut varius aliquet enim. Nulla facilisi. Curabitur consectetuer, odio eu pretium tincidunt, nunc nisi aliquet neque, vel imperdiet elit massa sit amet turpis. Pellentesque tempus, orci volutpat blandit fringilla, odio sem posuere ante, vitae bibendum urna lorem vitae eros. Praesent viverra rhoncus arcu. Sed auctor, est sit amet mollis mollis, quam quam gravida sapien, in commodo metus nulla auctor enim. Donec facilisis. + +Proin tincidunt, sapien eget ultricies adipiscing, est odio dictum arcu, ut mollis erat dui sit amet velit. Morbi est sem, interdum at, congue a, elementum vitae, metus. Suspendisse id augue. Mauris enim sem, pulvinar eget, tempus a, tempus sit amet, sapien. Fusce vestibulum consectetuer dui. Pellentesque erat. Sed dignissim placerat odio. Maecenas semper rhoncus lectus. Phasellus pretium. Duis libero elit, eleifend nec, egestas ut, cursus sed, felis. Nam nisl arcu, aliquet et, facilisis eu, luctus ut, risus. Etiam ultrices, dolor sed volutpat malesuada, turpis arcu imperdiet tortor, euismod commodo libero massa ut quam. Integer molestie purus non elit. Ut venenatis semper tortor. Etiam bibendum egestas ipsum. Mauris sollicitudin sem nec nibh. Nulla pretium metus eu metus. Pellentesque sit amet sem. + +Suspendisse ac nisi. Ut leo. Vestibulum hendrerit pretium dolor. Nunc feugiat malesuada purus. Cras et nibh. Curabitur nunc erat, malesuada vitae, laoreet ac, ultricies in, purus. Vivamus tellus arcu, sodales eu, facilisis a, lacinia nec, nunc. Pellentesque id velit. In eu nibh. Nunc nec erat. Sed dictum neque ut nisl. + +Morbi lectus tellus, tincidunt ac, porttitor ac, tristique in, eros. Donec luctus luctus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ut est et enim scelerisque accumsan. Donec ligula felis, lacinia quis, pellentesque in, semper vestibulum, elit. Mauris eget orci a felis congue vehicula. Ut sollicitudin. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam id dolor ut lorem dignissim venenatis. Suspendisse vitae sapien. Proin non magna ut eros viverra pulvinar. Donec quis odio. Nullam non arcu vel lorem suscipit aliquam. Aliquam rutrum turpis in leo. + +Ut luctus nibh tristique erat. Suspendisse bibendum odio vitae tortor. Donec lacinia. Cras sodales felis luctus nulla. Nam eleifend sagittis ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse vel neque. Morbi aliquet vehicula magna. Aenean at odio. Duis pellentesque magna. Nulla at tortor ut diam dictum faucibus. Mauris quis velit. Donec non tellus vitae lorem fringilla porttitor. Fusce ut sapien quis tortor feugiat sagittis. Donec viverra sem vitae sapien. Praesent sodales, lacus in fringilla viverra, odio augue adipiscing urna, vitae interdum ante sem non nisi. Nullam tortor lorem, eleifend ac, mollis non, laoreet ac, risus. Integer ornare leo sed justo. Quisque cursus, sem non facilisis bibendum, nisi mi varius felis, fermentum feugiat lorem eros laoreet risus. + +Quisque sit amet est et lorem vehicula lacinia. Donec nec tortor. Cras odio. Nam scelerisque vulputate urna. Praesent dui. Etiam nec nisl lobortis ipsum aliquet tempus. Maecenas pretium sollicitudin mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus augue massa, congue eget, convallis eget, tristique sit amet, eros. Sed consequat nisi eu felis. Pellentesque justo. Suspendisse non augue. In dignissim lobortis mauris. Mauris sagittis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + +Sed adipiscing. Donec a tellus vitae est cursus vehicula. Nam ante sem, sodales id, fringilla vel, condimentum vel, nulla. Quisque sodales. Etiam imperdiet elit id odio. Aliquam erat volutpat. Maecenas porta tempor arcu. Nulla sem augue, pellentesque ac, consequat ut, condimentum euismod, risus. Sed aliquam tincidunt mi. In interdum lobortis orci. + +Sed vehicula hendrerit purus. Etiam a diam. Curabitur convallis. Suspendisse a nisi. Donec id magna in quam sollicitudin ultricies. Donec viverra. Quisque volutpat est sed sem. Aliquam justo. Vestibulum tortor massa, porttitor sed, varius quis, iaculis quis, odio. Aliquam eget neque. + +Mauris nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum eu quam in neque ultrices pellentesque. Cras in dolor quis quam varius hendrerit. Aliquam nisi lacus, lobortis eu, convallis sit amet, facilisis ut, mi. Aliquam at neque. Cras sagittis elementum justo. Vestibulum ut lectus aliquet purus malesuada volutpat. Duis at lacus adipiscing libero tincidunt vestibulum. Morbi a libero. Cras purus. Morbi ut augue et purus interdum scelerisque. Integer a dui. In hac habitasse platea dictumst. Duis pharetra metus eget mauris. Aliquam interdum ullamcorper massa. + +Etiam ornare. Nullam euismod. Aenean consequat gravida ligula. Aliquam est. Proin vitae lacus. Praesent a eros sit amet dui luctus commodo. Phasellus vehicula arcu eget dolor. Praesent fermentum congue leo. Aliquam volutpat purus ut lorem. Fusce hendrerit enim at leo. Aliquam rhoncus nisl. Vivamus dictum egestas mi. Suspendisse pellentesque bibendum dolor. Pellentesque tincidunt, turpis semper pellentesque condimentum, ipsum metus sodales ligula, id volutpat diam turpis ut elit. + +Praesent sed lacus. Nam eleifend molestie mauris. Donec dapibus fermentum massa. Donec viverra faucibus purus. Curabitur congue, libero vitae viverra pellentesque, diam velit sodales enim, sed suscipit lectus nisi nec neque. Vestibulum malesuada, lacus at cursus congue, velit lectus tristique dolor, sit amet sodales neque ipsum a libero. Vestibulum et quam. Curabitur placerat. Curabitur nunc arcu, euismod nec, vulputate hendrerit, aliquet eget, quam. Curabitur vel enim. Suspendisse potenti. + +Nunc consequat orci ut lacus. Fusce velit dolor, dapibus sed, blandit sit amet, rhoncus id, risus. Duis urna nibh, scelerisque quis, dapibus a, scelerisque sed, nibh. Donec luctus. Ut eu mauris cursus diam lacinia rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam vehicula molestie justo. Maecenas imperdiet pede sed mi. Suspendisse nulla dolor, hendrerit eget, hendrerit id, dictum vel, leo. Duis accumsan. Curabitur in felis. Nunc lorem. Ut leo dolor, laoreet nec, vulputate at, eleifend in, nulla. Quisque nunc purus, varius eget, accumsan nec, aliquet et, nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras adipiscing viverra dolor. Mauris porttitor ultrices purus. Nulla facilisi. Praesent faucibus ante vitae mauris. + +Praesent lacinia lectus sed nisl. In tempus congue mauris. Integer facilisis ornare enim. Nulla id massa. Donec commodo diam at tellus. Nam dapibus viverra est. Nam tellus. Praesent a libero. In faucibus est eget nibh. Nulla eros orci, imperdiet non, blandit non, tempor eget, mi. Pellentesque convallis. + +Quisque eget mi ac leo euismod faucibus. Phasellus rhoncus purus id dui. Vestibulum malesuada eleifend ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque blandit mattis odio. Suspendisse consequat, lectus ac semper sollicitudin, mi velit dictum augue, ac tempus dolor erat sit amet dui. Proin hendrerit, felis quis volutpat posuere, diam odio malesuada odio, a interdum orci diam quis sapien. Pellentesque odio odio, viverra vel, gravida eu, molestie sed, nulla. Phasellus mauris pede, commodo ut, euismod eu, hendrerit eu, est. In hac habitasse platea dictumst. Nulla elementum lacus eu augue. Sed erat. Proin porta. Maecenas quis mi. Phasellus at enim ac justo gravida ultrices. Cras leo. + +Integer ut arcu. Donec sed magna. Proin felis. In iaculis, ligula id fringilla pretium, nibh diam accumsan tellus, eget accumsan metus dui varius turpis. Phasellus orci metus, eleifend sed, tempor ac, scelerisque ac, urna. Integer viverra neque a mauris. Mauris porttitor dolor eu velit. Integer odio elit, vestibulum ut, volutpat id, rhoncus commodo, urna. Etiam placerat pharetra erat. Ut tempor est. Integer dignissim blandit tellus. Morbi nibh dolor, scelerisque id, commodo malesuada, mattis at, mi. Cras tincidunt commodo purus. In tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ullamcorper. Ut hendrerit. Morbi ultrices. + +Praesent iaculis, eros ac egestas sodales, urna leo fermentum ligula, sit amet aliquam velit sem non purus. Donec rutrum arcu quis purus. Nam posuere, lacus at consequat placerat, nulla pede posuere orci, non euismod turpis dui quis nisl. Proin porta adipiscing nibh. Donec tristique dolor at tellus. Donec neque massa, auctor id, faucibus vitae, ullamcorper vel, nisi. Proin molestie neque sed massa. Nam tempor. Morbi aliquam sapien at tellus. Fusce quis risus et mi pretium pulvinar. Fusce sit amet ligula. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse eu enim et felis scelerisque lobortis. Praesent bibendum. Vivamus vehicula. Integer at nibh sed velit rhoncus molestie. Cras lacus. Sed ullamcorper eros vel erat. Fusce eu tortor sit amet diam euismod sagittis. Nunc quis lacus id nibh convallis varius. Suspendisse vitae mi. Vestibulum tristique. Donec malesuada ipsum id neque. Nullam sed lacus. Duis egestas, justo ut congue ornare, augue sapien luctus diam, at accumsan erat sapien ut libero. Phasellus vel nulla. Suspendisse arcu tellus, porttitor a, pharetra faucibus, aliquam sit amet, massa. Nulla porttitor tincidunt lorem. Nunc dolor odio, sagittis in, lobortis vel, volutpat sed, nibh. + +Quisque blandit leo ut sapien tempus facilisis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean ultricies porttitor justo. Fusce rutrum eros ut urna. Proin quis quam eget dui aliquam accumsan. Donec suscipit eleifend elit. Pellentesque mattis, felis sodales iaculis imperdiet, lacus sem convallis augue, sit amet aliquet arcu purus fringilla risus. In eu odio id magna pharetra ornare. Aliquam interdum pulvinar ipsum. Sed neque. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam sit amet nisi. Ut at augue. Mauris volutpat blandit ligula. Nulla eu metus. Vestibulum eget elit. Praesent posuere. Vestibulum id sem non lectus mollis tincidunt. Aliquam id felis at ante ornare tempor. Nulla lacus turpis, feugiat vitae, cursus quis, consectetuer non, mauris. Fusce lacus massa, porttitor ut, molestie ut, venenatis a, lorem. Praesent sit amet orci. Mauris rhoncus felis vitae felis adipiscing imperdiet. Maecenas mollis diam nec leo. + +Fusce enim ipsum, ultrices eu, molestie id, elementum id, sapien. Integer a urna. Nam velit libero, venenatis eget, tempor sit amet, feugiat vitae, ante. Fusce nunc. Sed semper nisl nec risus. In sed libero. Proin tortor neque, tincidunt ac, tempor ac, pharetra quis, velit. Duis lectus augue, ultricies vel, consequat id, iaculis id, ante. Vivamus auctor metus a ante. Curabitur arcu nisi, facilisis at, laoreet in, consectetuer sed, mauris. Quisque placerat diam sed dui. Vivamus pretium condimentum lorem. Curabitur laoreet. Aenean orci ligula, cursus eget, lacinia non, faucibus vel, lorem. + +Aliquam erat volutpat. Curabitur eros dolor, congue a, condimentum sed, luctus ut, nibh. Maecenas non tortor nec turpis commodo pellentesque. Praesent euismod placerat mi. Suspendisse potenti. Phasellus ut neque vitae orci mattis iaculis. Integer eget tellus. Donec at ante. Nam lacinia leo eget erat. Maecenas euismod magna congue tortor. Morbi nec massa eu enim malesuada sollicitudin. Sed accumsan. Nullam ipsum. Ut odio. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque id velit. Nam odio sem, aliquet ut, tempus sit amet, euismod et, nunc. + +Pellentesque libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent mauris nunc, varius ut, convallis molestie, luctus sit amet, leo. Sed dictum lorem et arcu. Nunc venenatis pellentesque massa. Nulla facilisi. Phasellus in tortor eget risus scelerisque vulputate. Sed nibh elit, sagittis ac, condimentum nec, convallis et, justo. Fusce volutpat metus. Nunc auctor. Vestibulum leo eros, pellentesque ac, mollis ultrices, rhoncus non, dolor. Mauris vehicula placerat nisl. Vestibulum bibendum, arcu quis congue elementum, velit nunc eleifend turpis, id luctus risus nisl sit amet tellus. Phasellus pede neque, blandit non, commodo vitae, ultricies eget, magna. Aliquam erat volutpat. + +Nulla facilisi. Aliquam ac ante. Cras risus. Morbi mauris lacus, posuere eu, blandit et, pharetra at, mi. Proin ac purus. Duis cursus nisl rutrum quam. Aliquam a odio non magna pellentesque ultricies. Maecenas ac massa quis sapien ullamcorper tempus. Cras cursus velit sed sapien. Proin nulla. Vivamus sodales aliquam nibh. Etiam et erat ut ante lacinia euismod. Fusce nisi. Proin quis nulla. + +Quisque venenatis, eros sed laoreet sollicitudin, orci ante pellentesque nisl, sit amet viverra quam erat non risus. Cras eget libero. Sed elit magna, semper eu, fringilla in, dignissim sodales, erat. Vivamus feugiat sem vel dui. Donec convallis sollicitudin diam. Cras sed purus. Donec felis eros, semper eget, tempor consectetuer, sagittis quis, nisl. Duis in ante. Cras non turpis. Nulla tempor velit aliquet turpis molestie placerat. Proin elementum fermentum mauris. Vivamus sed orci lacinia dui placerat venenatis. Vestibulum feugiat, tellus in volutpat rutrum, magna nisi ullamcorper eros, id pulvinar neque erat ut lacus. Vivamus sed augue. Nulla facilisi. Maecenas ante augue, elementum ut, sodales vitae, condimentum nec, lorem. Duis pede orci, fringilla at, eleifend nec, pretium in, erat. Nam sagittis, turpis vitae convallis pharetra, odio sem scelerisque lacus, nec lobortis dui diam vel eros. In semper gravida neque. + +Integer nunc. Ut pretium ipsum sit amet elit. In nec arcu. Sed vestibulum vulputate ipsum. Pellentesque tincidunt. Nulla gravida dolor in tellus. Cras vehicula, dolor ut pellentesque aliquam, erat enim auctor massa, vehicula lobortis odio eros quis quam. Proin dapibus neque in enim. Proin elit. Integer rhoncus tincidunt elit. Fusce lorem metus, semper ac, volutpat vitae, facilisis ut, tellus. Donec vel turpis vitae nisi pharetra porttitor. Maecenas tortor. Fusce mi. Nullam nec turpis. Sed sodales vestibulum nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Pellentesque dolor dolor, laoreet eu, aliquet quis, scelerisque sit amet, arcu. In hac habitasse platea dictumst. Nullam cursus urna eget elit. Quisque blandit sapien ac ante. Proin nulla eros, gravida volutpat, sodales vel, mollis eu, massa. Nulla tristique sollicitudin nisl. Curabitur vitae lorem vitae velit egestas ornare. Aenean eget eros. Aliquam erat volutpat. Fusce a urna id odio aliquet convallis. Curabitur sit amet nisl posuere leo posuere dapibus. Duis metus erat, luctus vel, rhoncus at, convallis sit amet, enim. Vivamus hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam eget elit. + +Nullam a nunc. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In metus urna, tincidunt et, lacinia sit amet, lobortis vitae, ligula. Proin et mauris vitae mi accumsan pellentesque. Etiam quam purus, hendrerit sed, feugiat vitae, euismod eget, tortor. Ut aliquam magna vitae justo. Suspendisse non justo vel velit condimentum tempus. Duis tempus ipsum vitae tellus. Proin in massa. Etiam ullamcorper dictum tellus. Proin aliquet felis at leo laoreet pulvinar. Vestibulum arcu purus, malesuada sit amet, cursus eu, placerat sit amet, nunc. Nam massa odio, sollicitudin in, adipiscing a, aliquam nec, risus. Aliquam blandit hendrerit libero. Mauris gravida. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur a nibh. Ut interdum fermentum neque. Pellentesque sed nunc. Mauris vehicula nisi et nunc. Praesent lorem. Donec semper. Integer eu lacus in est aliquam hendrerit. Vestibulum eget neque. Sed semper luctus velit. Curabitur nibh augue, congue eu, hendrerit id, congue et, enim. Integer placerat aliquam lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae eros. Donec vel nisl. + +In vestibulum facilisis urna. Ut risus. Mauris pharetra. Pellentesque mattis. Integer suscipit aliquam ipsum. Duis blandit, sapien et ultricies condimentum, felis mi elementum pede, nec sagittis metus mauris quis quam. Quisque accumsan arcu vel nulla. Cras sem sapien, porttitor id, ultricies sagittis, luctus eu, nulla. Integer quis eros. Morbi sed urna a tellus vehicula vulputate. Etiam nec augue eget felis semper tristique. Quisque ut dolor vel risus dictum consequat. Sed eget dolor sed nunc lacinia aliquet. Suspendisse ac tortor in ipsum posuere venenatis. Sed eget erat. Nulla faucibus. Duis laoreet, massa porttitor aliquet egestas, ipsum lectus rhoncus quam, in adipiscing eros sem ut tellus. Pellentesque feugiat tempus quam. Vivamus id dolor eget sapien consectetuer tempor. Aliquam erat volutpat. + +Nulla iaculis fermentum libero. Curabitur faucibus, massa malesuada cursus tincidunt, erat sem eleifend mauris, sed fringilla mi ante ac purus. Duis elementum lectus. Nunc ornare arcu eu tortor. Vestibulum vel dolor at purus lacinia fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas tincidunt, eros a egestas pellentesque, risus risus dictum libero, id aliquet metus justo in massa. Proin a tellus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed purus. Sed non pede. Aenean massa sapien, sodales sit amet, consequat dictum, eleifend vitae, tortor. Donec ultrices lacinia elit. + +Morbi adipiscing sodales dolor. Ut ullamcorper ultricies est. In venenatis tempus augue. Suspendisse tortor dolor, accumsan et, suscipit a, tincidunt ut, libero. Aliquam scelerisque magna sed felis. Quisque ut nunc a magna vulputate placerat. Aliquam rhoncus vehicula dui. Sed tortor. Nullam sit amet diam. Nunc sed eros. Sed et odio tincidunt elit gravida convallis. Curabitur quis tortor a lacus semper varius. Mauris at augue non mi sollicitudin aliquam. Integer ullamcorper. Pellentesque suscipit quam non purus. Aliquam ac eros at arcu ullamcorper consectetuer. Suspendisse pretium mattis leo. + +Duis at nunc. Sed dolor est, varius ac, porta et, tincidunt hendrerit, risus. Vivamus ut magna. Praesent ut mauris. In purus lacus, mattis sed, vestibulum nec, tempor at, nisl. Cras ullamcorper venenatis tellus. Ut dolor. Maecenas malesuada, pede a pulvinar mattis, arcu diam vehicula risus, quis porttitor augue massa in velit. Nunc congue. Morbi velit metus, rhoncus et, aliquam consectetuer, ultricies malesuada, ligula. Sed velit nisl, sagittis vitae, pharetra a, posuere sed, massa. Nulla facilisi. In varius, ligula id lobortis sodales, augue orci fermentum tellus, eu pulvinar risus ligula a sapien. Morbi laoreet ipsum non mi. Nam cursus lorem ut mi. Vivamus magna enim, posuere non, semper quis, sodales eu, arcu. Etiam mi purus, pretium feugiat, varius sed, pellentesque eget, ligula. In leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vitae orci eu orci sollicitudin feugiat. + +Praesent purus massa, euismod vitae, tempus nec, consequat hendrerit, metus. Aenean felis est, egestas vitae, accumsan eget, pellentesque in, sapien. Duis dapibus pede non sapien. Nunc urna. Integer vel libero. Duis augue arcu, dapibus non, facilisis vitae, posuere ut, eros. Donec vitae nunc sit amet arcu imperdiet dictum. Morbi eleifend, lorem eu consectetuer vestibulum, diam nunc ornare arcu, ac tempor felis dolor eget eros. Phasellus massa sem, sollicitudin ac, sodales gravida, luctus a, quam. Nam neque quam, viverra at, venenatis quis, sagittis non, enim. + +Nulla facilisi. Pellentesque egestas lacinia est. Sed tincidunt, pede sed tincidunt vestibulum, urna dolor adipiscing purus, vitae fringilla felis elit in nibh. Nulla sed nisi. Mauris suscipit scelerisque arcu. Etiam non enim vel eros accumsan malesuada. Nunc tincidunt commodo mauris. In tincidunt risus quis urna. Nulla diam tortor, aliquet et, tincidunt quis, sollicitudin ac, tortor. Cras nisl neque, vulputate suscipit, molestie quis, pulvinar at, nulla. Nullam ac metus nec odio posuere varius. Cras sed pede nec dui posuere bibendum. Duis euismod ullamcorper libero. Aliquam faucibus pulvinar turpis. + +In ut neque id nunc feugiat commodo. Curabitur dignissim, felis at sollicitudin lacinia, enim elit suscipit neque, sed luctus lorem ipsum in leo. Duis dapibus, odio quis auctor commodo, nisl odio mattis tellus, nec tincidunt turpis diam in arcu. Curabitur a sem. Nullam volutpat magna. Pellentesque sagittis, neque consequat pretium cursus, dolor lacus consectetuer arcu, sed laoreet est urna et metus. Suspendisse placerat, dui a porta tempor, lorem dui lobortis neque, sed venenatis diam enim id eros. Etiam et nisl non lectus faucibus consectetuer. Morbi scelerisque, sem nec tempus ullamcorper, ipsum diam feugiat lorem, a fringilla sapien elit quis nibh. Nullam diam urna, viverra sed, pharetra rhoncus, tincidunt vel, orci. Integer accumsan mattis erat. Nam dictum. Mauris nec leo. Nulla iaculis. Nulla nisl mi, dapibus quis, vehicula a, cursus eget, odio. + +Phasellus dapibus euismod nibh. Vivamus imperdiet ante in ligula. Pellentesque accumsan. In imperdiet, dui a auctor fringilla, metus nisi cursus dolor, vel luctus ligula lorem vitae mauris. Praesent mattis vestibulum elit. Aliquam enim lacus, pulvinar non, lacinia sit amet, eleifend non, velit. Vestibulum ac leo. Mauris imperdiet justo ac lectus. Sed molestie lectus sed dui. Sed fermentum tempus mauris. Nam ornare orci ac tellus. Ut malesuada, lacus id lacinia accumsan, diam elit adipiscing metus, et bibendum sapien nibh blandit orci. Suspendisse ipsum tellus, sagittis quis, vestibulum non, vulputate eu, eros. Praesent at nulla id pede scelerisque ultricies. Cras blandit pretium tellus. Maecenas dapibus condimentum augue. Phasellus tincidunt pharetra lorem. Morbi non eros. Sed tempor, nisl a tincidunt tincidunt, eros diam dictum sem, vel dignissim ante diam sed magna. Praesent non ligula id metus molestie consectetuer. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse vel mi. Curabitur ante nulla, rutrum a, convallis vel, vehicula ac, nunc. Nunc sagittis, enim sit amet auctor rutrum, mauris arcu vulputate neque, et euismod est felis quis ante. Vestibulum turpis tellus, hendrerit in, lacinia commodo, ullamcorper gravida, risus. Mauris rhoncus lacinia risus. Maecenas sollicitudin erat vitae nunc. Praesent pretium pellentesque augue. Donec interdum. Praesent ac eros vitae erat lobortis fringilla. Aenean consequat tellus. Nulla accumsan bibendum felis. Maecenas pretium ante id nisi. Aenean mi arcu, semper sed, mattis eu, venenatis sit amet, arcu. Donec aliquet euismod leo. Proin magna justo, tristique a, semper ac, sollicitudin a, ligula. Morbi velit. Aliquam vel nisi. + +In a lorem ut nunc feugiat congue. Donec fermentum bibendum dui. Proin varius est quis velit. Donec aliquet sem accumsan mi. Sed placerat. Nullam ac nisi a massa lobortis suscipit. Nunc id leo. Aliquam et massa. Nullam vestibulum elementum metus. In consectetuer nisi vel justo. Maecenas eget purus sed massa varius pellentesque. Phasellus faucibus felis quis felis. Aenean odio arcu, blandit quis, facilisis in, imperdiet eu, lorem. Nam posuere pulvinar mi. Fusce tristique, mauris et consectetuer ultricies, mauris lectus tempor justo, at fringilla est est sed nisi. Quisque faucibus. Sed in tortor tincidunt est lacinia iaculis. Maecenas a massa. Pellentesque a nibh at purus porta hendrerit. + +Nullam turpis. Fusce ac sem sed odio pellentesque imperdiet. Curabitur in arcu. Praesent lacus lacus, feugiat id, pulvinar in, tincidunt sed, neque. Maecenas viverra odio eget tortor. Integer aliquam, lorem rutrum venenatis dignissim, ligula magna malesuada arcu, vel feugiat lorem ipsum quis massa. Morbi ante. Vestibulum mauris libero, ullamcorper quis, ultrices quis, facilisis non, massa. Maecenas imperdiet. Aliquam erat volutpat. Pellentesque dignissim gravida lectus. In nibh odio, auctor eget, dapibus quis, dignissim venenatis, arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis pellentesque ligula quis massa. Curabitur condimentum, justo eget ornare luctus, lorem ligula sagittis pede, a porta nunc nunc in neque. Quisque felis mauris, condimentum vitae, auctor vitae, tincidunt quis, pede. Nunc lacinia ante in leo. Pellentesque libero. Aenean a ligula et nunc vestibulum consectetuer. + +Fusce ornare. Praesent id urna. Integer venenatis, quam non sagittis accumsan, ante nibh sagittis augue, sollicitudin adipiscing dolor velit eu erat. Proin quis enim eu purus vehicula aliquam. Nulla vel enim vel elit sollicitudin fringilla. Aliquam erat volutpat. Sed suscipit felis ut turpis. Etiam rutrum risus imperdiet est. Aliquam a tellus at tellus commodo dapibus. Mauris rutrum magna et odio. In at dolor. Curabitur vehicula lectus in tortor. Fusce justo purus, luctus vitae, mollis in, pharetra ac, purus. Nullam posuere interdum justo. Curabitur vitae lacus vel leo congue pulvinar. + +Aenean eleifend nibh varius tortor. Suspendisse vel eros. Proin nec diam a tortor ultrices ornare. Aliquam scelerisque feugiat justo. Vivamus ante urna, adipiscing vitae, porttitor eu, sodales et, felis. Suspendisse potenti. Curabitur ac massa in nisl sagittis mollis. Nam quam ligula, consectetuer eget, iaculis at, varius eu, leo. Duis dolor ligula, tincidunt at, ullamcorper sed, accumsan aliquam, ligula. Phasellus vulputate, lorem at tincidunt pharetra, risus lectus lacinia magna, quis rutrum enim magna at sem. In hac habitasse platea dictumst. Duis id sem a mauris sollicitudin tincidunt. Etiam eu purus eu arcu fringilla adipiscing. Vivamus ornare tempus diam. Proin turpis quam, lacinia non, egestas at, commodo eget, pede. Praesent vulputate risus in est. Nulla facilisi. + +Ut elementum lacinia purus. Proin vitae arcu ac nulla convallis aliquam. Nulla congue, libero id pellentesque mattis, quam lectus porttitor diam, a scelerisque dui libero in sapien. Nullam felis diam, vehicula vel, molestie ut, vestibulum aliquam, sapien. Donec convallis, est ut elementum volutpat, mauris ipsum gravida sem, commodo facilisis sapien lectus semper lectus. Quisque porttitor eros ut nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam mattis risus sed odio. Vestibulum et odio. In hac habitasse platea dictumst. Nam tristique massa ut ligula. Quisque nibh tellus, vehicula sit amet, adipiscing at, convallis nec, ligula. Vestibulum pretium, mi nec fringilla bibendum, dui nunc sodales pede, a semper magna nibh non diam. Donec massa nunc, viverra vel, consectetuer porta, dapibus non, ipsum. Duis nisl mauris, cursus vel, semper non, sollicitudin bibendum, felis. Vestibulum eu neque. + +Cras nec dolor. Donec laoreet tempus lectus. Cras sed tortor interdum lacus eleifend dignissim. Maecenas sit amet elit. Nullam quis dolor vel dui pharetra luctus. In sit amet quam sit amet pede ultrices ultrices. Maecenas diam. Integer urna. Curabitur dictum, velit sed placerat suscipit, erat turpis fermentum justo, sed interdum neque sem et nibh. Vivamus consequat convallis magna. Nam aliquam, est ac bibendum commodo, magna est dictum mi, vitae malesuada elit magna vitae odio. Maecenas tempor vulputate tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus dui. Etiam accumsan pede congue tortor. + +Morbi tempor libero ac lorem. In aliquet varius magna. In arcu. Phasellus odio. Fusce tincidunt aliquet felis. Quisque velit. Sed luctus. Aliquam feugiat fringilla mi. Aliquam molestie viverra risus. Proin arcu. Vestibulum lobortis tempus nisi. Praesent a arcu in velit viverra rutrum. + +In sed lectus. Donec risus dolor, blandit sit amet, elementum convallis, pharetra quis, pede. Integer ornare. Aenean egestas dapibus justo. Sed quam leo, posuere at, elementum vitae, commodo eget, est. Aliquam molestie rhoncus enim. Curabitur iaculis ultrices pede. Morbi aliquet rutrum lacus. Aliquam quam. Sed commodo, turpis in pharetra posuere, mi risus imperdiet erat, a vestibulum massa tellus vehicula sem. Mauris fringilla ultrices nunc. Nam nisi enim, eleifend sit amet, ultrices sed, fermentum non, augue. Proin congue lobortis nisi. Maecenas hendrerit. Nam sed nisl. Nunc elementum odio eu risus. In metus. Phasellus gravida pretium ligula. Nulla vitae neque. Nam nisi tortor, ornare non, blandit at, cursus eu, tortor. + +Duis bibendum ipsum in nunc cursus molestie. Nunc orci. Nullam nec ante non est dignissim viverra. Mauris blandit, velit id feugiat pretium, elit magna pellentesque dolor, at sagittis lacus velit egestas magna. Pellentesque cursus, diam consectetuer sagittis fringilla, tortor nisi adipiscing nunc, eu varius lacus risus ac elit. Mauris id nisi quis leo euismod venenatis. Pellentesque ac ante. Mauris arcu sapien, tempor at, porttitor id, condimentum ut, dui. Etiam fermentum ultricies augue. Cras ut eros at justo ultricies iaculis. Duis dignissim, nisl et facilisis fermentum, erat purus molestie tellus, quis tempus ipsum lectus at elit. Nulla vitae lorem. + +Aenean vel sem et diam semper congue. In bibendum diam quis tellus. Nunc facilisis ultricies nibh. Cras nunc enim, feugiat sed, ultrices vitae, sagittis vitae, ipsum. Fusce vitae nulla. Donec pellentesque, velit in porttitor eleifend, est neque lobortis velit, sit amet rutrum ante tortor nec dolor. Donec vehicula. Nulla facilisi. Sed egestas ultrices nibh. Donec elit lectus, convallis porttitor, aliquet dapibus, feugiat eget, ligula. Sed consectetuer justo. Maecenas a sapien sit amet nisi dapibus lobortis. Vivamus luctus lorem non nulla. Sed eget erat vitae libero interdum posuere. Cras pulvinar. Nullam imperdiet, dolor tempor dignissim blandit, dui sapien rhoncus neque, id malesuada augue magna sit amet urna. Duis sed mauris. + +Morbi accumsan. Sed mauris augue, fringilla non, auctor ut, auctor et, orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus ut pede. Donec viverra enim vel lorem. Pellentesque neque mauris, interdum eu, venenatis id, condimentum eu, sapien. Donec ipsum arcu, lacinia adipiscing, laoreet et, cursus vel, velit. Ut sagittis mauris quis risus. Integer eu odio vitae lacus viverra accumsan. Morbi leo ante, dignissim sed, varius quis, volutpat vitae, nisi. Nulla placerat interdum elit. Donec neque dui, sagittis vitae, sollicitudin quis, commodo vitae, neque. Nulla quis ligula ornare ligula dictum ornare. Mauris rutrum rutrum neque. Aenean vehicula tempus est. Donec varius scelerisque pede. Donec placerat vulputate leo. Nullam nunc nisl, posuere non, feugiat vitae, pellentesque quis, mauris. In dui neque, cursus eget, sagittis eget, dapibus vitae, mi. Proin eget est. + +Fusce porta est. Mauris magna. Aliquam ipsum lacus, ultricies id, vestibulum luctus, accumsan ut, ante. Sed mauris. Sed adipiscing leo sit amet magna. Suspendisse potenti. Nunc massa elit, fringilla eget, egestas vitae, luctus vitae, dolor. Phasellus quis nulla eu nisi interdum sollicitudin. Nullam id tellus. Integer iaculis dolor ac purus. Sed vel mi. Curabitur non magna sit amet justo condimentum vulputate. Quisque tincidunt pede eu nisl. Vivamus lobortis. Nunc metus metus, congue sed, tincidunt sed, pretium at, odio. Donec a arcu. In sem justo, vehicula sed, varius id, volutpat at, risus. Praesent iaculis massa. In arcu elit, hendrerit eget, ullamcorper in, porta id, tellus. Donec sagittis hendrerit diam. + +Suspendisse potenti. Sed et diam et augue sagittis lobortis. Phasellus dolor. Ut et arcu eget ante tempor posuere. Aliquam fermentum scelerisque dui. Mauris at purus. Donec erat sem, vestibulum nec, faucibus ac, mattis a, leo. Suspendisse adipiscing lacinia sem. Nullam orci arcu, dictum et, faucibus viverra, dapibus et, neque. Cras nunc diam, adipiscing non, sollicitudin in, interdum vel, massa. Mauris sagittis, justo at tristique tempus, mauris mauris aliquam ante, sit amet posuere diam dui eget ligula. In dignissim, nisl ut lacinia condimentum, erat justo porttitor nulla, non gravida ligula magna eget massa. Vestibulum vitae ligula at mi vestibulum suscipit. Duis laoreet. Nulla commodo libero sit amet lorem. Ut elementum sem. Integer vel dolor. Nam facilisis mi quis sem ultrices sagittis. Sed quis quam at metus molestie bibendum. + +Proin dui enim, lacinia a, feugiat ac, placerat vitae, pede. Quisque egestas, leo eget aliquam pretium, libero justo tincidunt eros, ut egestas augue pede elementum nibh. Curabitur mollis sodales enim. Donec augue. Phasellus id ipsum posuere dui pretium faucibus. Mauris luctus ante semper nisi interdum adipiscing. Duis dapibus, odio quis viverra rhoncus, justo quam bibendum dolor, id dapibus velit erat vel erat. Fusce sit amet nisl venenatis quam ultrices condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec rhoncus scelerisque ligula. Vestibulum mi odio, accumsan et, adipiscing eget, ornare ut, quam. Nullam blandit molestie mauris. Curabitur dignissim mauris et lorem. Suspendisse a justo. Nam mattis faucibus arcu. Duis blandit enim non massa. + +Nullam lorem. In hac habitasse platea dictumst. Mauris consectetuer posuere mauris. Maecenas tincidunt mauris in eros. Nulla eu metus eu orci sollicitudin faucibus. Suspendisse aliquam mauris id est. Cras blandit dui et urna. Nulla arcu. Sed a urna. Nulla dapibus vehicula tortor. Donec risus. Sed quam metus, egestas eu, cursus ut, viverra non, odio. Ut justo justo, malesuada sit amet, blandit suscipit, molestie in, justo. Vestibulum consequat, quam ac feugiat tincidunt, ipsum libero eleifend odio, non eleifend pede ipsum non ante. Nullam a metus. + +Nam ac nisi at felis cursus mattis. Pellentesque consequat sem quis orci. Quisque tempus. Aenean imperdiet molestie pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eu tellus. Nulla diam eros, sodales ut, sodales nec, tincidunt ac, nunc. Nunc lacinia faucibus ipsum. Vivamus vel neque in erat fermentum luctus. Nulla eget metus nec augue bibendum placerat. Vivamus tempus. Praesent congue ornare ipsum. Etiam mattis feugiat justo. + +Aliquam dui. Aenean commodo tortor vitae nulla. Morbi et ipsum. Mauris ac ipsum. Nam vel risus ut lectus mollis viverra. Curabitur elementum mollis est. Nullam elit. Vestibulum suscipit pretium enim. Vestibulum ut massa. Proin nec felis. Maecenas gravida, arcu nec consequat sagittis, eros tellus scelerisque mauris, vitae accumsan quam quam ut nunc. Integer eget ante eu velit laoreet malesuada. Nunc sagittis, mauris vitae pharetra volutpat, tellus tellus eleifend eros, sit amet rutrum ipsum nisi a velit. Praesent varius leo eu erat. Vivamus consequat placerat purus. Donec pretium elementum nibh. Proin at elit non sem aliquet mattis. Sed ullamcorper ipsum sit amet elit. + +Mauris in metus. Suspendisse magna lorem, faucibus vel, tincidunt quis, scelerisque non, tellus. Fusce quis lorem. Proin a lacus sit amet mauris iaculis pulvinar. Suspendisse rhoncus eros nec mi. Praesent euismod, turpis vitae rutrum pretium, odio metus volutpat neque, eget tempus sapien neque sed erat. Donec fermentum purus at lectus. Nullam sem. Fusce vel mi quis erat lobortis posuere. Aenean eget urna. Suspendisse ligula. Duis in nisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Curabitur vulputate lectus id pede. Phasellus eu velit. Etiam venenatis adipiscing nibh. Aliquam cursus pulvinar tellus. Vestibulum neque. Mauris nec justo et erat semper pellentesque. Fusce mattis dictum dolor. Etiam eget purus eu massa varius elementum. Pellentesque massa. Ut ultricies diam sed ipsum. Nullam diam. Pellentesque id magna id libero tristique aliquam. + +Ut eleifend, purus id placerat venenatis, urna augue aliquet ligula, in ultricies leo risus et tellus. Mauris et nulla id urna tristique tempus. Ut facilisis, urna eu vestibulum rhoncus, lacus eros consectetuer metus, et rutrum dui lectus in purus. Nunc vel nisl non ipsum tincidunt mollis. Nam quam lacus, ornare vitae, rhoncus non, congue sed, odio. Proin nibh dui, porta vel, venenatis non, pellentesque ut, nisi. Sed tristique felis a magna. Suspendisse eget tellus. Cras gravida imperdiet velit. Integer hendrerit risus. Proin orci. Aliquam ullamcorper mauris quis mauris. Nunc lacinia vestibulum metus. Duis tellus. Nullam faucibus, leo ac vulputate sollicitudin, leo dolor faucibus erat, quis bibendum orci odio non arcu. + +Nullam accumsan mattis dolor. Donec et dui. Praesent a felis mollis lacus semper lacinia. Curabitur pellentesque luctus est. Proin nulla dui, condimentum vel, faucibus non, interdum ac, erat. Maecenas scelerisque, lectus id volutpat accumsan, sapien tortor pellentesque dui, sed semper magna sem ut leo. Proin nulla. Nullam dapibus ullamcorper sem. Suspendisse vehicula metus in nunc. Pellentesque non quam vel arcu ultrices ullamcorper. Phasellus quis felis sit amet tellus ullamcorper fermentum. Sed vehicula sollicitudin urna. Curabitur pharetra scelerisque risus. Pellentesque id massa quis metus aliquam imperdiet. In nunc lacus, feugiat in, gravida eget, venenatis ut, tellus. Suspendisse potenti. Nam consequat adipiscing dui. In nulla nisi, feugiat ut, fermentum vel, gravida nec, tortor. In sed augue. + +Etiam ullamcorper augue at enim. Integer dignissim. Aliquam pulvinar congue nulla. Morbi enim massa, fringilla a, accumsan eget, condimentum nec, erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean pharetra. Etiam porttitor purus a metus. Aliquam interdum sem eget justo. Quisque volutpat luctus est. Aenean augue. Phasellus dui lectus, ultrices nec, commodo vel, auctor vel, nisi. Ut ultrices pellentesque nisi. Integer ac velit et sem imperdiet luctus. Fusce vitae turpis id augue mollis consectetuer. + +Maecenas nec lacus. Maecenas condimentum odio eu felis. Mauris ut nisl viverra erat faucibus adipiscing. Etiam egestas. Nunc et dolor vitae risus dignissim commodo. Morbi lectus velit, tincidunt nec, aliquet vel, mattis vitae, ligula. Maecenas ultricies semper dolor. Suspendisse malesuada. Integer mattis elit. Donec accumsan, lacus facilisis varius tempus, nulla elit porta erat, et rutrum elit sem sit amet dui. + +Maecenas mollis mi non nulla. Vivamus turpis. Suspendisse a metus. In quis mi in turpis congue auctor. Maecenas lacus. Suspendisse sollicitudin. Phasellus porta nunc non nisl pulvinar egestas. Sed nulla. Vestibulum ac mi. Mauris ultricies condimentum neque. Nulla tempus justo vel massa. Nulla suscipit congue arcu. Praesent id turpis. Mauris nibh pede, euismod semper, molestie ac, rhoncus vitae, ante. Maecenas erat felis, viverra sollicitudin, sagittis eget, pellentesque nec, orci. Fusce ultrices consequat lacus. Aliquam erat magna, feugiat at, viverra a, mollis non, turpis. + +Donec mi. Nam dictum pellentesque sem. Donec mollis rhoncus elit. Phasellus rhoncus pede sit amet risus. Donec eget augue. Maecenas non lectus. Phasellus sollicitudin nisi nec felis. Aliquam pretium, est eget semper convallis, nibh nunc sollicitudin purus, id tempor pede dui vel magna. Vivamus ac lorem. Etiam nisl tortor, adipiscing dictum, elementum in, facilisis sed, nibh. Proin mauris. Proin rutrum massa eget sem. Curabitur tempor adipiscing elit. Curabitur purus tellus, fermentum eget, aliquet vitae, convallis ac, mauris. + +Integer consequat velit eu eros tincidunt vehicula. Nullam lorem sapien, rhoncus non, mattis quis, ultricies sit amet, enim. Curabitur commodo, libero in euismod suscipit, sem purus fringilla enim, ac molestie tortor orci et velit. Donec pede. Etiam placerat condimentum turpis. Phasellus egestas enim nec magna. Vivamus condimentum, nulla vel luctus tristique, eros risus vestibulum nulla, in vehicula arcu ipsum at felis. Donec aliquam elit at augue. Quisque a eros eu ligula accumsan dictum. Etiam vehicula turpis quis libero. Aliquam non mi. Donec et leo. Proin leo libero, aliquam tincidunt, congue nec, adipiscing porta, enim. Nulla lobortis, tortor sit amet imperdiet ullamcorper, dolor orci malesuada pede, sed gravida nibh urna vel lorem. Sed pharetra malesuada eros. Quisque euismod aliquet erat. Suspendisse aliquet mattis purus. + +Nunc id nulla quis justo congue sollicitudin. Praesent erat turpis, rhoncus eu, pretium eu, pellentesque a, nibh. Vivamus tempus. Cras nec risus at turpis imperdiet lobortis. Ut mattis. Maecenas est felis, pellentesque non, imperdiet sed, eleifend tincidunt, lorem. In tincidunt. Sed vel leo. Donec et urna in turpis hendrerit blandit. Donec condimentum accumsan est. Ut pharetra, metus vitae mattis consectetuer, leo quam vulputate odio, nec laoreet nisi velit eu erat. Integer lectus augue, egestas in, interdum eu, venenatis vel, sapien. Quisque et est vitae eros laoreet lobortis. Nullam ut risus non nulla placerat adipiscing. Praesent dapibus. Etiam a felis. Ut sodales consequat mauris. Duis lorem felis, luctus a, tristique in, molestie at, risus. Sed vehicula bibendum tellus. Nam consequat euismod lacus. + +Aenean tortor elit, gravida nec, fermentum eu, lobortis id, ipsum. Maecenas eu purus. Cras ac turpis ut nisi iaculis rhoncus. Nulla purus metus, dignissim nec, tincidunt vitae, dapibus eu, nibh. Fusce lobortis, nunc at viverra eleifend, justo turpis scelerisque eros, ac pellentesque metus nisl at purus. Sed elementum tellus sed enim interdum blandit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer ultricies aliquet odio. Mauris eget nunc a ipsum ultrices sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean accumsan. Donec sapien lectus, congue at, porta id, hendrerit vitae, nisl. Curabitur vel quam vel neque accumsan laoreet. Morbi sapien est, pretium in, consectetuer ac, mollis ut, libero. Donec tincidunt adipiscing metus. Nunc vestibulum egestas augue. Donec scelerisque dui ut sem. Suspendisse vel metus id est molestie iaculis. + +Vivamus pharetra, elit eu malesuada blandit, diam tortor mollis dui, sed pulvinar massa nunc et magna. Sed placerat elit auctor tortor. Nulla ac erat. Pellentesque consectetuer, dui convallis tincidunt condimentum, sem odio volutpat libero, non elementum felis neque nec odio. Maecenas hendrerit eros id diam. Mauris vel purus ac orci convallis convallis. Sed sit amet lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque dictum varius lacus. Mauris eget nisl. Suspendisse placerat, nulla non ornare dignissim, nisl diam sagittis tellus, in semper nisi dolor at nibh. Duis ullamcorper viverra felis. Integer a tellus. Suspendisse eget nunc. Aenean diam est, accumsan id, suscipit interdum, fringilla vitae, justo. Proin pede. Maecenas at neque in neque vestibulum eleifend. + +Vestibulum nulla lorem, porttitor eget, euismod ac, aliquam at, nisl. Maecenas et est eget massa varius lobortis. In mi. Duis porttitor fermentum purus. Donec cursus imperdiet ligula. Morbi et ligula et ante molestie vehicula. Mauris sed dolor. Sed imperdiet felis ut sem. Sed vitae neque elementum leo auctor fermentum. Duis feugiat ullamcorper erat. Aenean purus. Morbi fermentum vestibulum est. Pellentesque venenatis mauris. Phasellus pulvinar. Integer ipsum lectus, iaculis a, lacinia id, accumsan id, arcu. Phasellus at est. Fusce neque quam, ultricies id, iaculis vel, dapibus vitae, lacus. In lobortis convallis ante. Nulla nunc purus, vulputate in, hendrerit et, blandit et, ligula. + +Pellentesque leo metus, sagittis in, molestie vitae, dictum in, pede. Morbi pretium felis nec quam. Pellentesque mattis ante sed quam sagittis dapibus. Suspendisse sapien. Praesent bibendum iaculis tortor. Duis a nisl. Aenean mi. Donec dictum arcu in est. Morbi interdum vulputate ipsum. Aenean sit amet magna non nisl tristique posuere. Phasellus velit metus, tempor ac, fermentum eget, condimentum non, velit. Vestibulum sit posuere. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras aliquet massa nec dui. Cras arcu nunc, hendrerit ac, eleifend eu, ullamcorper nec, tellus. Sed pharetra purus sit amet quam. Curabitur mollis. Nam vitae pede. Etiam risus massa, vehicula sit amet, pharetra nec, sollicitudin ut, dui. Donec egestas justo at quam. Proin nisl risus, vestibulum nec, pretium vitae, tristique ac, lorem. Aliquam erat volutpat. Cras sed nibh. Pellentesque sollicitudin euismod augue. + +Etiam fringilla sollicitudin orci. Mauris cursus elit quis lacus. Cras tortor. In adipiscing, lectus id auctor vestibulum, neque pede accumsan dolor, non imperdiet magna diam accumsan velit. Suspendisse at libero ut nisi blandit sagittis. Phasellus non mauris. Fusce elementum sagittis sem. Suspendisse aliquam eleifend tellus. Proin ligula lorem, imperdiet quis, venenatis id, iaculis mollis, nisl. Etiam convallis pede at massa. Morbi accumsan dui et mauris. + +Sed sed orci. Nunc purus. Suspendisse potenti. Ut luctus fringilla mauris. Donec nibh. Phasellus porta. Phasellus sit amet odio sed magna sodales pharetra. Cras lectus. Suspendisse libero ipsum, commodo nec, facilisis in, suscipit lobortis, ligula. Duis massa nulla, semper et, consequat nec, pharetra eu, elit. Vivamus ultricies aliquam odio. Vestibulum sit amet massa. Sed consequat lacus sed urna. Etiam faucibus felis vel orci. Phasellus ullamcorper. Aenean consectetuer lacus at libero. + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis facilisis, ligula vitae condimentum scelerisque, velit orci gravida felis, vel ultricies quam mi non diam. Vivamus auctor metus non libero. Praesent ligula nisi, commodo condimentum, molestie et, viverra et, justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus sollicitudin. Nunc blandit cursus ipsum. Aenean nec ligula ut tellus sodales mattis. Integer sem. Aliquam id ligula. Sed tortor mauris, blandit vitae, cursus vel, elementum et, nulla. Aliquam scelerisque metus et nisl. Duis adipiscing magna at neque. Quisque vulputate eleifend nunc. Aliquam eget elit. Phasellus dui odio, bibendum sagittis, vestibulum id, dignissim imperdiet, orci. Nullam eu felis non nunc lacinia sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Suspendisse pellentesque, libero mattis ultricies accumsan, tortor tortor malesuada sem, et sodales libero odio ac ipsum. Vivamus quis magna nec est suscipit lobortis. Cras tempus posuere nunc. Quisque ut enim a felis egestas semper. Sed pharetra mattis neque. Fusce turpis nunc, congue sed, consequat non, congue sed, nulla. Suspendisse varius lorem id risus porta vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce sed purus. In a felis. Integer egestas auctor orci. Mauris ultrices suscipit nisl. Nullam purus. + +Cras tempor adipiscing ipsum. Ut quis mi. Maecenas in justo ut nulla congue pharetra. Pellentesque ut libero eu dolor venenatis suscipit. Praesent feugiat consectetuer nibh. Morbi faucibus sem non felis. In hendrerit arcu ac massa. In accumsan ultrices mi. Proin malesuada auctor felis. Curabitur interdum. Sed diam ipsum, ultricies in, tempor sit amet, viverra imperdiet, elit. Morbi molestie nisi. Mauris ipsum. Fusce dictum mollis magna. Duis commodo dignissim nulla. Vestibulum augue enim, ultricies quis, iaculis nec, tincidunt vitae, diam. Mauris lacinia tempus ipsum. Sed at mauris. Ut lorem. Donec libero. + +Duis iaculis lacinia lectus. Aenean convallis eros ac ante. Sed quis orci nec risus auctor fringilla. Phasellus facilisis elementum nisi. In hac habitasse platea dictumst. Nunc porta lacus nec ante. Morbi mauris erat, adipiscing in, pulvinar nec, lobortis nec, odio. Ut eleifend lectus sed quam. Nullam mollis. In non turpis et nisl hendrerit blandit. Duis elementum. Nunc nec libero. Suspendisse vestibulum risus non pede. Morbi imperdiet odio sit amet libero. Sed sed massa vitae ipsum mattis tincidunt. Nulla nec tortor vitae libero volutpat tempus. Donec aliquam. + +Duis sed nunc. Curabitur turpis nulla, vehicula sed, luctus quis, elementum eget, felis. Maecenas et purus. Maecenas leo tellus, tincidunt a, facilisis vitae, lobortis sit amet, velit. Donec convallis sapien. Maecenas mollis odio eu nibh. Etiam gravida. Integer molestie, sapien eu molestie lacinia, nunc nibh aliquam ligula, eu sagittis tellus erat sollicitudin odio. Duis et risus. Phasellus nisi neque, placerat nec, condimentum non, ultrices eu, sem. Ut pede. Etiam nulla metus, volutpat id, convallis sed, suscipit vel, urna. Donec vel elit. Ut leo neque, venenatis faucibus, lacinia nec, tincidunt eu, enim. Cras id dui a libero pharetra dignissim. Donec eros leo, porta quis, laoreet ut, pellentesque volutpat, lectus. + +Nullam blandit. Aliquam erat volutpat. Fusce adipiscing enim. Suspendisse non dui quis ligula porta vestibulum. Donec eu tellus vel lorem pretium porttitor. Praesent luctus. Aliquam ac eros in massa dapibus tincidunt. Donec ut magna. Etiam auctor lacus sit amet lacus. Sed ultricies ipsum nec elit. Quisque a est in purus suscipit tristique. + +Aenean sed dui vel dolor pulvinar laoreet. Vivamus vehicula lorem in pede. Vivamus et diam. Integer ac odio vel diam hendrerit bibendum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a nisi. Phasellus tincidunt dui vitae augue. Duis faucibus, dui interdum fringilla tincidunt, odio elit vestibulum libero, ac molestie magna lectus id lacus. Aenean ligula. Nulla facilisi. + +Fusce vel sem eu velit fringilla ornare. Sed feugiat tincidunt felis. Nullam felis mi, euismod sit amet, mollis at, sodales eget, augue. Nam imperdiet nibh at velit. Sed ut erat. In dui. Nulla facilisi. Nullam augue libero, tincidunt nec, pretium eu, pulvinar in, dui. Morbi vitae felis. Pellentesque vel justo vel velit sagittis malesuada. Proin vehicula blandit massa. Etiam tincidunt pharetra urna. In metus est, auctor nec, blandit a, cursus nec, quam. Mauris ac metus a libero congue faucibus. Mauris mauris dolor, sodales in, cursus ut, sodales rutrum, eros. Quisque mauris eros, sagittis vitae, lobortis ut, eleifend id, nisi. + +Aenean neque. Vestibulum egestas pellentesque ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus sagittis justo vel risus. Sed pretium neque vitae urna. Pellentesque congue libero id lorem. Mauris leo lorem, blandit sit amet, convallis quis, consectetuer sed, eros. Mauris tincidunt, enim a gravida euismod, magna nulla fermentum libero, viverra egestas velit quam et tortor. Vivamus aliquet massa vitae justo. Nulla congue lacus ac elit. + +Phasellus commodo quam vel ligula. Proin non metus at eros pulvinar luctus. Mauris diam lorem, posuere quis, gravida et, tincidunt nec, ligula. Sed diam. Aliquam elit lectus, hendrerit ut, imperdiet sit amet, pretium sit amet, ipsum. Mauris vehicula nisl in dui. Curabitur eget quam ut magna elementum fermentum. Mauris scelerisque. Quisque laoreet. Etiam tempus turpis. Pellentesque augue quam, hendrerit sed, tincidunt at, pharetra at, nisl. Aliquam lacus. Suspendisse potenti. Aenean velit libero, ultrices in, lacinia eu, luctus vel, ante. Etiam dictum mi in felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce gravida dapibus nisl. Cras vitae nisl. + +Maecenas dignissim, ligula non porta cursus, enim nunc malesuada sem, eu porttitor nulla urna eu quam. Fusce eros. Aliquam eros. Nam auctor. Nulla molestie porta est. Suspendisse potenti. Vivamus molestie lorem sed erat. Sed eget ipsum. Integer aliquam pulvinar nulla. Cras aliquet sem ut nunc. Fusce faucibus tempus lectus. Cras sodales, nisi ac facilisis ultrices, eros arcu dapibus sapien, et ultrices mauris tellus non dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras cursus varius metus. Ut turpis. Vivamus eget tortor. + +Sed laoreet, velit non accumsan cursus, nunc urna posuere justo, in dictum lectus pede id ante. Cras vulputate. Cras congue dui sed elit. Proin lacus sem, ultrices at, consequat in, tempor quis, metus. Proin vel arcu. Nam euismod hendrerit elit. Ut erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed posuere. Morbi eros urna, semper at, semper non, convallis quis, velit. Maecenas orci. Vestibulum lobortis tristique metus. Vestibulum lorem nulla, sollicitudin vitae, condimentum quis, auctor ut, dui. Vivamus vestibulum magna ut nisi. Curabitur eleifend dui vel nunc. Curabitur mauris lacus, malesuada sit amet, suscipit sed, rutrum luctus, tellus. Integer facilisis urna vitae lectus. + +Aenean quam leo, lobortis quis, malesuada eu, vulputate vitae, nisl. Praesent eget eros. Ut fermentum turpis id quam. Nam tortor. Praesent nec orci. Nulla bibendum adipiscing augue. Ut commodo, magna id malesuada gravida, augue odio malesuada mi, porta malesuada elit est vitae diam. Mauris non nulla. Suspendisse tincidunt, nunc ultricies porta venenatis, mi pede tincidunt libero, eget varius ante libero ut ligula. Curabitur pretium porttitor tortor. + +Maecenas vitae elit eget nisi dapibus dictum. Nunc in libero. Nulla dictum orci eu erat auctor lobortis. Phasellus risus. Suspendisse potenti. Suspendisse potenti. Praesent adipiscing consequat elit. Integer id augue. Praesent in justo nec magna dapibus pulvinar. Duis nisl. Suspendisse ac odio. Vivamus imperdiet. Donec non velit sit amet risus dignissim congue. Nam aliquet posuere velit. Cras turpis. Morbi malesuada dignissim mi. + +Sed leo neque, varius quis, venenatis sed, pharetra sed, est. Morbi blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam semper pellentesque mi. Ut vel lorem. Nunc mi tortor, laoreet at, faucibus eu, tincidunt sit amet, erat. Duis tempor malesuada ipsum. Phasellus aliquet. Donec et elit. Pellentesque purus. Vestibulum rutrum semper nibh. Nulla facilisi. Phasellus et enim sit amet ante vestibulum vehicula. Phasellus id nisl. Donec mollis leo at eros. Mauris pellentesque neque at purus. Morbi quis dolor at ipsum scelerisque sodales. Etiam volutpat turpis a metus. In hac habitasse platea dictumst. Nunc lorem lorem, vestibulum ac, euismod eget, ullamcorper dignissim, velit. + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ultrices, nibh vel aliquam vestibulum, eros enim venenatis dui, id iaculis enim nunc vel massa. Morbi eleifend orci et massa. Aliquam erat volutpat. Nulla mollis egestas turpis. In sodales nunc eget tortor. Sed ipsum eros, tempor quis, aliquet vitae, imperdiet non, lorem. Pellentesque quis elit id mi luctus dapibus. Sed nunc arcu, rhoncus nec, convallis quis, cursus at, neque. Mauris convallis purus at erat. Pellentesque vestibulum. Vivamus fringilla elit at arcu. Nullam aliquet enim nec arcu. Nam id tortor. Nulla quis nunc. Ut arcu. Suspendisse potenti. Pellentesque ullamcorper ligula id arcu. + +Nam non libero vitae nisl scelerisque fringilla. Quisque varius ante id metus rhoncus fringilla. Nulla facilisi. Praesent eleifend porttitor ligula. Etiam quis dolor non augue commodo auctor. Donec a mi. Vestibulum tempor. Donec felis urna, auctor at, cursus dictum, gravida id, arcu. Aenean dictum malesuada dolor. Vivamus mattis. Phasellus eu pede. Fusce adipiscing justo fringilla metus. Etiam ante. Integer mollis massa quis nunc. Integer dictum neque luctus enim. + +Sed eu libero. Integer tempor ligula in velit. Ut tincidunt lacinia sem. Nullam vel risus. Sed sodales ante a dolor. Curabitur eros. Sed sodales. Sed non metus. Vestibulum elementum faucibus ante. Nulla vel nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In hac habitasse platea dictumst. Nunc nec lorem ut ipsum lacinia iaculis. Duis erat. Aliquam erat. Cras iaculis. In hac habitasse platea dictumst. + +Nullam ante. Cras vitae est. Pellentesque vel metus a ligula dapibus mattis. Duis feugiat aliquet felis. Etiam id nisl quis est dignissim condimentum. Suspendisse potenti. Morbi velit lorem, ornare quis, pellentesque vel, placerat eget, tortor. Vestibulum tincidunt molestie libero. Nulla nulla enim, malesuada id, ullamcorper vitae, dictum at, purus. Donec dignissim odio ut enim. Suspendisse at lectus. + +Praesent lobortis augue vel lectus. Ut in ligula ut felis congue suscipit. Quisque dignissim tortor ut mi. Fusce magna nisi, eleifend ac, ornare vel, porttitor vitae, quam. Vestibulum sodales justo quis turpis. Fusce urna nisi, rhoncus quis, condimentum vel, dictum eu, nunc. Fusce sed nibh vitae odio posuere adipiscing. Sed porta elit quis dolor. Nam libero nulla, auctor sed, tincidunt quis, faucibus sit amet, mi. Quisque orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam id sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vel eros. + +Vivamus luctus lobortis leo. Suspendisse vel elit a enim ullamcorper posuere. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec quis pede mattis lectus mollis adipiscing. Sed accumsan posuere erat. Praesent euismod tincidunt felis. Donec mi. Ut commodo arcu lacinia tellus. Aliquam a libero quis lectus semper viverra. Curabitur lacinia mauris at tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sit amet magna molestie orci suscipit fringilla. Fusce pretium metus non sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed hendrerit. Nulla felis. Suspendisse potenti. Aliquam blandit tristique neque. Curabitur quis erat vel nunc accumsan mollis. + +Duis sagittis, tellus ut aliquam fringilla, dolor mi ullamcorper nisl, ut tristique pede elit sed mauris. Curabitur id felis. Donec pulvinar lacus et lectus. Aliquam vulputate vulputate metus. Curabitur magna felis, adipiscing ac, accumsan vel, molestie quis, quam. Mauris elit arcu, pretium vitae, mollis sit amet, sollicitudin ut, mi. Donec imperdiet dignissim mi. Nullam sit amet tortor. Aliquam neque nulla, venenatis a, porta in, placerat tempus, lacus. Quisque vestibulum dui et lacus. Proin dignissim consectetuer purus. Etiam gravida tortor in nunc. Ut tempor tristique tortor. Sed laoreet tincidunt quam. Vestibulum porta turpis ut elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nibh dui, feugiat nec, laoreet id, malesuada eget, nisi. Ut neque massa, vehicula eu, commodo non, ultricies vitae, purus. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris euismod, felis vel tempor aliquet, tortor mauris malesuada nunc, vel fermentum sem diam id dui. Nam rutrum sapien eget odio. Aliquam sed libero non mi faucibus tempus. Fusce hendrerit, diam non volutpat rutrum, erat metus venenatis ligula, non scelerisque pede ligula vel quam. Morbi rhoncus eros ac dui feugiat elementum. Duis eu libero et tellus congue viverra. Morbi quam quam, elementum sed, ullamcorper imperdiet, commodo non, odio. Nam aliquet egestas urna. Mauris odio felis, varius eu, lacinia eu, condimentum a, lectus. Sed justo massa, pulvinar id, varius a, porttitor nec, libero. Etiam varius. Curabitur sodales, odio at posuere semper, eros nibh tincidunt lectus, vel rutrum sapien nisi in ligula. Suspendisse eget arcu. Phasellus imperdiet est ac sapien. Donec nulla tortor, placerat vel, tempus a, lobortis vel, nibh. Aliquam varius nisi. Nulla et enim. Fusce convallis laoreet lacus. + +Phasellus ipsum dolor, molestie quis, condimentum in, commodo eu, diam. Quisque bibendum lacinia dui. Nullam blandit vulputate orci. Ut lacinia massa vel augue. Aliquam gravida, quam quis imperdiet imperdiet, tellus diam pharetra erat, at pharetra lacus nibh egestas magna. Nulla sagittis lorem ut lorem. Duis condimentum, dui vitae aliquam posuere, diam quam convallis velit, ut gravida leo ipsum non risus. Ut fermentum sollicitudin erat. Donec sagittis scelerisque felis. Nunc arcu. Etiam tempus, magna sit amet suscipit euismod, eros sem rutrum dui, vitae sagittis nibh purus non lacus. Sed mollis arcu eget dolor. Donec ornare, arcu sit amet fermentum vulputate, risus enim fermentum libero, a lacinia dolor mi non velit. Etiam lobortis purus a elit. Nunc nulla dui, mattis quis, bibendum a, ultrices ac, augue. In aliquam vehicula turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Integer id nisl. Quisque dictum elementum odio. Aenean luctus. Sed eu sem a pede vulputate condimentum. Quisque magna. Donec aliquam mattis ipsum. Curabitur dictum sollicitudin sem. Aliquam pulvinar. Nunc sollicitudin risus a erat. Vivamus quis tellus sit amet nibh vestibulum consequat. Nulla pretium sollicitudin dolor. Aliquam iaculis tincidunt turpis. Phasellus ipsum leo, venenatis in, sagittis in, ornare at, nunc. + +Pellentesque ultrices, dui eu iaculis luctus, tellus augue volutpat sapien, in dignissim urna felis ut mi. Sed arcu dui, dignissim id, porttitor ut, imperdiet vitae, ante. Nulla dui sem, commodo nec, sagittis et, lacinia et, pede. Etiam eleifend dui ut nisl. Donec ante mauris, tempus sit amet, varius vitae, gravida quis, mi. In scelerisque, felis vitae viverra sagittis, velit metus ultricies neque, quis imperdiet velit elit et magna. Suspendisse potenti. Sed velit eros, euismod sed, condimentum nec, faucibus sed, sapien. Nam accumsan ligula sit amet neque. Aliquam erat volutpat. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam eu pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed eu felis sed tortor tempor fermentum. Phasellus commodo sem vel nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lectus elit, pharetra sit amet, accumsan sed, tincidunt et, mauris. Duis dapibus pharetra sem. Integer in justo. Praesent eros. Vestibulum ac ante. Aliquam scelerisque sem pellentesque nibh consectetuer sodales. Aliquam consectetuer odio. Duis lectus odio, luctus eu, commodo quis, mollis vitae, velit. Cras nec nunc non elit iaculis mattis. Aenean justo neque, sollicitudin eget, ullamcorper eget, egestas id, sem. In eu risus. Sed egestas. + +Integer at neque. Sed pretium scelerisque nulla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce ut pede. Etiam vitae quam a urna varius imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vehicula. Fusce ullamcorper nibh non erat. Quisque in neque. Praesent est. Pellentesque arcu. + +Proin posuere. Suspendisse potenti. Integer felis lacus, aliquam sed, vulputate in, mollis vel, tellus. Integer vehicula bibendum est. Nunc non dolor in tellus mattis facilisis. Integer vestibulum, augue at commodo aliquam, dui est mattis ligula, sit amet adipiscing orci sem vitae magna. Praesent enim velit, malesuada at, congue nec, luctus in, justo. Sed varius. Morbi pharetra. Donec eu massa nec tellus vulputate pulvinar. Ut commodo turpis non sem. Ut convallis ullamcorper risus. Etiam interdum pede id nisi. Cras magna sapien, suscipit a, laoreet non, rhoncus et, felis. Integer orci lorem, vestibulum dictum, ullamcorper a, porttitor et, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc et magna. Sed bibendum tellus in diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vitae tortor. Integer magna. Duis venenatis, leo ac tempor laoreet, elit nulla pharetra pede, non fermentum nunc odio a odio. Proin non velit. Sed imperdiet augue quis nisl. Integer condimentum nisl nec libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus placerat libero. Duis congue dictum magna. Aliquam dapibus bibendum enim. Nunc eleifend pede vel ipsum. + +Etiam vitae velit. Mauris erat nunc, malesuada ut, feugiat ac, placerat condimentum, augue. Nam volutpat. Aliquam vehicula ipsum id odio. Vivamus sollicitudin turpis id sapien. Fusce a felis vitae odio convallis blandit. Curabitur vitae eros id eros porta pretium. Nulla in magna eget urna lacinia convallis. Aliquam mattis venenatis purus. Sed sed mi eget erat tristique porta. Donec auctor dolor a erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In nec ligula. Nunc eleifend. Vestibulum quis nisi eget elit porttitor congue. Maecenas faucibus, magna eget adipiscing tincidunt, dolor ante malesuada elit, non elementum lacus turpis in pede. + +Ut malesuada mi nec metus. Praesent auctor augue ac nisl ultricies facilisis. Nam purus sapien, pellentesque dignissim, posuere eu, cursus id, diam. Quisque sollicitudin, elit a pellentesque scelerisque, lorem risus auctor quam, quis consequat tellus neque id urna. Suspendisse diam tortor, eleifend dignissim, egestas ut, luctus in, ante. Duis ante. Maecenas luctus. Curabitur cursus pharetra urna. Maecenas imperdiet, erat non elementum euismod, tortor odio euismod lectus, ac facilisis sem nibh vitae nulla. Nunc gravida. Morbi sollicitudin odio quis lacus. Aliquam a nibh non urna porta imperdiet. Aliquam erat volutpat. In iaculis lacinia velit. Sed libero lacus, tristique eu, lacinia ac, aliquet eget, urna. + +Etiam at nisl. Phasellus faucibus luctus lectus. Ut placerat vulputate dolor. Phasellus vel velit. Morbi viverra. Phasellus orci. Integer dignissim mattis mauris. Pellentesque posuere leo posuere quam. Quisque nec magna at diam viverra pellentesque. Suspendisse velit arcu, ultricies quis, congue a, venenatis eget, lacus. Integer sagittis hendrerit dolor. Fusce tincidunt ante a sem. + +Maecenas consectetuer, justo sed rhoncus venenatis, nibh arcu rutrum dolor, sed condimentum libero libero et ipsum. Vivamus mattis justo ut lorem tincidunt lobortis. Ut non velit id neque aliquet accumsan. Sed tempus viverra nulla. Curabitur ullamcorper, neque quis dapibus scelerisque, felis diam gravida orci, non cursus quam neque vitae elit. Etiam pharetra tincidunt lacus. Duis euismod fringilla est. Etiam ornare tincidunt lectus. Proin in turpis. Nunc blandit blandit turpis. Aenean ut augue. Duis orci justo, tincidunt eu, rutrum sed, rutrum et, turpis. Curabitur facilisis odio in ante. In hac habitasse platea dictumst. Sed eros est, pellentesque at, tincidunt eu, ultrices quis, metus. Morbi sit amet justo. Maecenas ac arcu. Mauris dignissim. + +Pellentesque ultricies rutrum orci. Aenean ornare. Vivamus eu risus vel mauris lobortis dictum. Sed et turpis auctor mi rhoncus pulvinar. Sed nec nunc a purus tempor viverra. Pellentesque suscipit. Donec tristique risus non nibh. Etiam nisl magna, sollicitudin ut, ultrices sit amet, egestas eu, nulla. Aliquam erat volutpat. Vestibulum pharetra. Sed egestas, metus sit amet lobortis consequat, erat elit imperdiet libero, eu interdum quam massa eget dolor. Suspendisse vitae odio. Proin blandit mauris iaculis metus. + +Vivamus vestibulum. Etiam et nisl. Aliquam in diam vel elit placerat suscipit. Duis sodales purus ac nibh. Nulla in odio eget enim luctus blandit. Curabitur ultrices ipsum non neque egestas eleifend. Sed turpis. Proin consectetuer. Vivamus mattis. In aliquet. + +Nunc id eros. Donec venenatis, nulla et mattis luctus, ante leo semper justo, non adipiscing odio risus sed lacus. Praesent vitae risus congue libero congue tempus. Phasellus ac eros. Nulla vehicula, lorem in aliquet suscipit, arcu erat egestas sem, quis lobortis quam ante eu massa. Curabitur non massa. Sed bibendum lacinia odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus volutpat blandit lacus. Proin porta, tellus ut auctor laoreet, lectus eros fermentum lectus, id sagittis arcu justo in turpis. Phasellus consequat. Nam pellentesque, mi id viverra convallis, nunc libero placerat leo, eleifend porta sem nisl vitae sapien. Pellentesque ligula libero, tristique non, porttitor rutrum, porttitor non, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer dictum tellus a tortor. Vivamus felis nunc, molestie non, rhoncus quis, pharetra id, dui. Donec risus metus, fringilla vel, aliquet eu, placerat id, neque. + +Suspendisse ipsum. Vivamus lectus. Sed viverra, massa eget convallis mattis, quam turpis consectetuer nunc, eget posuere magna sem id velit. In nec mauris. Aenean a purus sed quam lobortis fringilla. Proin ultricies lacinia ante. Sed adipiscing erat quis velit. Nullam vitae nisl id justo sollicitudin molestie. Nulla facilisi. Sed nec urna sed nisl fringilla dapibus. Nulla at diam. Aliquam eget nibh. Nunc ac nisi sit amet tellus egestas tempus. Nam scelerisque urna et neque. Donec est orci, sagittis non, vulputate a, commodo et, augue. Ut dapibus tortor. Ut nunc. Donec dictum dapibus odio. Nam ultricies ullamcorper ligula. Pellentesque accumsan varius leo. + +Morbi euismod laoreet erat. Vivamus quis ipsum. Morbi euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel purus. Nullam at magna. Curabitur lacus lorem, iaculis quis, dapibus non, volutpat vel, nulla. Donec ut arcu rhoncus dolor pretium dictum. Nullam vel metus. Ut arcu. Pellentesque nisi nunc, placerat eget, tincidunt vel, pharetra non, nunc. Integer tincidunt ultricies lectus. Integer semper, purus sed ultrices feugiat, nulla pede sollicitudin erat, vel auctor nulla ipsum vel lectus. Aenean mi. + +Nullam sed nisi et arcu imperdiet fermentum. Mauris nec metus. In ac dolor. In mi arcu, congue ac, pharetra nec, scelerisque sit amet, magna. Curabitur lacus. Curabitur et elit. Aliquam ullamcorper nunc eu elit. Sed convallis dolor at velit. Vestibulum dapibus, augue id consectetuer placerat, nunc massa blandit sapien, id aliquam elit nisi id mi. Phasellus sapien est, gravida eu, bibendum ut, adipiscing quis, est. Ut molestie quam vitae odio. Donec quis risus id erat faucibus sollicitudin. Nam id felis. Mauris sed enim vitae leo accumsan pretium. + +Nam justo. Donec turpis nisl, commodo et, interdum ac, consectetuer non, massa. Fusce sem metus, laoreet nec, posuere id, imperdiet in, velit. Donec vulputate justo eget turpis. Nulla pede. Morbi tincidunt. Fusce aliquet, quam et aliquam fringilla, ante ante iaculis dui, nec aliquam arcu purus sed erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus suscipit quam et est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; + +Integer sed tellus. Sed sed velit ultricies leo rutrum laoreet. Sed non eros ac purus sagittis feugiat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed hendrerit ligula sit amet nibh. Maecenas turpis. Morbi consectetuer, dolor et adipiscing imperdiet, ante neque feugiat dolor, at porta quam neque quis ligula. Mauris semper velit sit amet ipsum. Pellentesque tempus, purus in rutrum consequat, enim erat vehicula massa, id accumsan leo sapien nec purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In dolor. Integer facilisis libero sit amet pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut varius aliquet enim. Nulla facilisi. Curabitur consectetuer, odio eu pretium tincidunt, nunc nisi aliquet neque, vel imperdiet elit massa sit amet turpis. Pellentesque tempus, orci volutpat blandit fringilla, odio sem posuere ante, vitae bibendum urna lorem vitae eros. Praesent viverra rhoncus arcu. Sed auctor, est sit amet mollis mollis, quam quam gravida sapien, in commodo metus nulla auctor enim. Donec facilisis. + +Proin tincidunt, sapien eget ultricies adipiscing, est odio dictum arcu, ut mollis erat dui sit amet velit. Morbi est sem, interdum at, congue a, elementum vitae, metus. Suspendisse id augue. Mauris enim sem, pulvinar eget, tempus a, tempus sit amet, sapien. Fusce vestibulum consectetuer dui. Pellentesque erat. Sed dignissim placerat odio. Maecenas semper rhoncus lectus. Phasellus pretium. Duis libero elit, eleifend nec, egestas ut, cursus sed, felis. Nam nisl arcu, aliquet et, facilisis eu, luctus ut, risus. Etiam ultrices, dolor sed volutpat malesuada, turpis arcu imperdiet tortor, euismod commodo libero massa ut quam. Integer molestie purus non elit. Ut venenatis semper tortor. Etiam bibendum egestas ipsum. Mauris sollicitudin sem nec nibh. Nulla pretium metus eu metus. Pellentesque sit amet sem. + +Suspendisse ac nisi. Ut leo. Vestibulum hendrerit pretium dolor. Nunc feugiat malesuada purus. Cras et nibh. Curabitur nunc erat, malesuada vitae, laoreet ac, ultricies in, purus. Vivamus tellus arcu, sodales eu, facilisis a, lacinia nec, nunc. Pellentesque id velit. In eu nibh. Nunc nec erat. Sed dictum neque ut nisl. + +Morbi lectus tellus, tincidunt ac, porttitor ac, tristique in, eros. Donec luctus luctus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ut est et enim scelerisque accumsan. Donec ligula felis, lacinia quis, pellentesque in, semper vestibulum, elit. Mauris eget orci a felis congue vehicula. Ut sollicitudin. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam id dolor ut lorem dignissim venenatis. Suspendisse vitae sapien. Proin non magna ut eros viverra pulvinar. Donec quis odio. Nullam non arcu vel lorem suscipit aliquam. Aliquam rutrum turpis in leo. + +Ut luctus nibh tristique erat. Suspendisse bibendum odio vitae tortor. Donec lacinia. Cras sodales felis luctus nulla. Nam eleifend sagittis ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse vel neque. Morbi aliquet vehicula magna. Aenean at odio. Duis pellentesque magna. Nulla at tortor ut diam dictum faucibus. Mauris quis velit. Donec non tellus vitae lorem fringilla porttitor. Fusce ut sapien quis tortor feugiat sagittis. Donec viverra sem vitae sapien. Praesent sodales, lacus in fringilla viverra, odio augue adipiscing urna, vitae interdum ante sem non nisi. Nullam tortor lorem, eleifend ac, mollis non, laoreet ac, risus. Integer ornare leo sed justo. Quisque cursus, sem non facilisis bibendum, nisi mi varius felis, fermentum feugiat lorem eros laoreet risus. + +Quisque sit amet est et lorem vehicula lacinia. Donec nec tortor. Cras odio. Nam scelerisque vulputate urna. Praesent dui. Etiam nec nisl lobortis ipsum aliquet tempus. Maecenas pretium sollicitudin mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus augue massa, congue eget, convallis eget, tristique sit amet, eros. Sed consequat nisi eu felis. Pellentesque justo. Suspendisse non augue. In dignissim lobortis mauris. Mauris sagittis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + +Sed adipiscing. Donec a tellus vitae est cursus vehicula. Nam ante sem, sodales id, fringilla vel, condimentum vel, nulla. Quisque sodales. Etiam imperdiet elit id odio. Aliquam erat volutpat. Maecenas porta tempor arcu. Nulla sem augue, pellentesque ac, consequat ut, condimentum euismod, risus. Sed aliquam tincidunt mi. In interdum lobortis orci. + +Sed vehicula hendrerit purus. Etiam a diam. Curabitur convallis. Suspendisse a nisi. Donec id magna in quam sollicitudin ultricies. Donec viverra. Quisque volutpat est sed sem. Aliquam justo. Vestibulum tortor massa, porttitor sed, varius quis, iaculis quis, odio. Aliquam eget neque. + +Mauris nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum eu quam in neque ultrices pellentesque. Cras in dolor quis quam varius hendrerit. Aliquam nisi lacus, lobortis eu, convallis sit amet, facilisis ut, mi. Aliquam at neque. Cras sagittis elementum justo. Vestibulum ut lectus aliquet purus malesuada volutpat. Duis at lacus adipiscing libero tincidunt vestibulum. Morbi a libero. Cras purus. Morbi ut augue et purus interdum scelerisque. Integer a dui. In hac habitasse platea dictumst. Duis pharetra metus eget mauris. Aliquam interdum ullamcorper massa. + +Etiam ornare. Nullam euismod. Aenean consequat gravida ligula. Aliquam est. Proin vitae lacus. Praesent a eros sit amet dui luctus commodo. Phasellus vehicula arcu eget dolor. Praesent fermentum congue leo. Aliquam volutpat purus ut lorem. Fusce hendrerit enim at leo. Aliquam rhoncus nisl. Vivamus dictum egestas mi. Suspendisse pellentesque bibendum dolor. Pellentesque tincidunt, turpis semper pellentesque condimentum, ipsum metus sodales ligula, id volutpat diam turpis ut elit. + +Praesent sed lacus. Nam eleifend molestie mauris. Donec dapibus fermentum massa. Donec viverra faucibus purus. Curabitur congue, libero vitae viverra pellentesque, diam velit sodales enim, sed suscipit lectus nisi nec neque. Vestibulum malesuada, lacus at cursus congue, velit lectus tristique dolor, sit amet sodales neque ipsum a libero. Vestibulum et quam. Curabitur placerat. Curabitur nunc arcu, euismod nec, vulputate hendrerit, aliquet eget, quam. Curabitur vel enim. Suspendisse potenti. + +Nunc consequat orci ut lacus. Fusce velit dolor, dapibus sed, blandit sit amet, rhoncus id, risus. Duis urna nibh, scelerisque quis, dapibus a, scelerisque sed, nibh. Donec luctus. Ut eu mauris cursus diam lacinia rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam vehicula molestie justo. Maecenas imperdiet pede sed mi. Suspendisse nulla dolor, hendrerit eget, hendrerit id, dictum vel, leo. Duis accumsan. Curabitur in felis. Nunc lorem. Ut leo dolor, laoreet nec, vulputate at, eleifend in, nulla. Quisque nunc purus, varius eget, accumsan nec, aliquet et, nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras adipiscing viverra dolor. Mauris porttitor ultrices purus. Nulla facilisi. Praesent faucibus ante vitae mauris. + +Praesent lacinia lectus sed nisl. In tempus congue mauris. Integer facilisis ornare enim. Nulla id massa. Donec commodo diam at tellus. Nam dapibus viverra est. Nam tellus. Praesent a libero. In faucibus est eget nibh. Nulla eros orci, imperdiet non, blandit non, tempor eget, mi. Pellentesque convallis. + +Quisque eget mi ac leo euismod faucibus. Phasellus rhoncus purus id dui. Vestibulum malesuada eleifend ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque blandit mattis odio. Suspendisse consequat, lectus ac semper sollicitudin, mi velit dictum augue, ac tempus dolor erat sit amet dui. Proin hendrerit, felis quis volutpat posuere, diam odio malesuada odio, a interdum orci diam quis sapien. Pellentesque odio odio, viverra vel, gravida eu, molestie sed, nulla. Phasellus mauris pede, commodo ut, euismod eu, hendrerit eu, est. In hac habitasse platea dictumst. Nulla elementum lacus eu augue. Sed erat. Proin porta. Maecenas quis mi. Phasellus at enim ac justo gravida ultrices. Cras leo. + +Integer ut arcu. Donec sed magna. Proin felis. In iaculis, ligula id fringilla pretium, nibh diam accumsan tellus, eget accumsan metus dui varius turpis. Phasellus orci metus, eleifend sed, tempor ac, scelerisque ac, urna. Integer viverra neque a mauris. Mauris porttitor dolor eu velit. Integer odio elit, vestibulum ut, volutpat id, rhoncus commodo, urna. Etiam placerat pharetra erat. Ut tempor est. Integer dignissim blandit tellus. Morbi nibh dolor, scelerisque id, commodo malesuada, mattis at, mi. Cras tincidunt commodo purus. In tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ullamcorper. Ut hendrerit. Morbi ultrices. + +Praesent iaculis, eros ac egestas sodales, urna leo fermentum ligula, sit amet aliquam velit sem non purus. Donec rutrum arcu quis purus. Nam posuere, lacus at consequat placerat, nulla pede posuere orci, non euismod turpis dui quis nisl. Proin porta adipiscing nibh. Donec tristique dolor at tellus. Donec neque massa, auctor id, faucibus vitae, ullamcorper vel, nisi. Proin molestie neque sed massa. Nam tempor. Morbi aliquam sapien at tellus. Fusce quis risus et mi pretium pulvinar. Fusce sit amet ligula. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse eu enim et felis scelerisque lobortis. Praesent bibendum. Vivamus vehicula. Integer at nibh sed velit rhoncus molestie. Cras lacus. Sed ullamcorper eros vel erat. Fusce eu tortor sit amet diam euismod sagittis. Nunc quis lacus id nibh convallis varius. Suspendisse vitae mi. Vestibulum tristique. Donec malesuada ipsum id neque. Nullam sed lacus. Duis egestas, justo ut congue ornare, augue sapien luctus diam, at accumsan erat sapien ut libero. Phasellus vel nulla. Suspendisse arcu tellus, porttitor a, pharetra faucibus, aliquam sit amet, massa. Nulla porttitor tincidunt lorem. Nunc dolor odio, sagittis in, lobortis vel, volutpat sed, nibh. + +Quisque blandit leo ut sapien tempus facilisis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean ultricies porttitor justo. Fusce rutrum eros ut urna. Proin quis quam eget dui aliquam accumsan. Donec suscipit eleifend elit. Pellentesque mattis, felis sodales iaculis imperdiet, lacus sem convallis augue, sit amet aliquet arcu purus fringilla risus. In eu odio id magna pharetra ornare. Aliquam interdum pulvinar ipsum. Sed neque. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam sit amet nisi. Ut at augue. Mauris volutpat blandit ligula. Nulla eu metus. Vestibulum eget elit. Praesent posuere. Vestibulum id sem non lectus mollis tincidunt. Aliquam id felis at ante ornare tempor. Nulla lacus turpis, feugiat vitae, cursus quis, consectetuer non, mauris. Fusce lacus massa, porttitor ut, molestie ut, venenatis a, lorem. Praesent sit amet orci. Mauris rhoncus felis vitae felis adipiscing imperdiet. Maecenas mollis diam nec leo. + +Fusce enim ipsum, ultrices eu, molestie id, elementum id, sapien. Integer a urna. Nam velit libero, venenatis eget, tempor sit amet, feugiat vitae, ante. Fusce nunc. Sed semper nisl nec risus. In sed libero. Proin tortor neque, tincidunt ac, tempor ac, pharetra quis, velit. Duis lectus augue, ultricies vel, consequat id, iaculis id, ante. Vivamus auctor metus a ante. Curabitur arcu nisi, facilisis at, laoreet in, consectetuer sed, mauris. Quisque placerat diam sed dui. Vivamus pretium condimentum lorem. Curabitur laoreet. Aenean orci ligula, cursus eget, lacinia non, faucibus vel, lorem. + +Aliquam erat volutpat. Curabitur eros dolor, congue a, condimentum sed, luctus ut, nibh. Maecenas non tortor nec turpis commodo pellentesque. Praesent euismod placerat mi. Suspendisse potenti. Phasellus ut neque vitae orci mattis iaculis. Integer eget tellus. Donec at ante. Nam lacinia leo eget erat. Maecenas euismod magna congue tortor. Morbi nec massa eu enim malesuada sollicitudin. Sed accumsan. Nullam ipsum. Ut odio. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque id velit. Nam odio sem, aliquet ut, tempus sit amet, euismod et, nunc. + +Pellentesque libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent mauris nunc, varius ut, convallis molestie, luctus sit amet, leo. Sed dictum lorem et arcu. Nunc venenatis pellentesque massa. Nulla facilisi. Phasellus in tortor eget risus scelerisque vulputate. Sed nibh elit, sagittis ac, condimentum nec, convallis et, justo. Fusce volutpat metus. Nunc auctor. Vestibulum leo eros, pellentesque ac, mollis ultrices, rhoncus non, dolor. Mauris vehicula placerat nisl. Vestibulum bibendum, arcu quis congue elementum, velit nunc eleifend turpis, id luctus risus nisl sit amet tellus. Phasellus pede neque, blandit non, commodo vitae, ultricies eget, magna. Aliquam erat volutpat. + +Nulla facilisi. Aliquam ac ante. Cras risus. Morbi mauris lacus, posuere eu, blandit et, pharetra at, mi. Proin ac purus. Duis cursus nisl rutrum quam. Aliquam a odio non magna pellentesque ultricies. Maecenas ac massa quis sapien ullamcorper tempus. Cras cursus velit sed sapien. Proin nulla. Vivamus sodales aliquam nibh. Etiam et erat ut ante lacinia euismod. Fusce nisi. Proin quis nulla. + +Quisque venenatis, eros sed laoreet sollicitudin, orci ante pellentesque nisl, sit amet viverra quam erat non risus. Cras eget libero. Sed elit magna, semper eu, fringilla in, dignissim sodales, erat. Vivamus feugiat sem vel dui. Donec convallis sollicitudin diam. Cras sed purus. Donec felis eros, semper eget, tempor consectetuer, sagittis quis, nisl. Duis in ante. Cras non turpis. Nulla tempor velit aliquet turpis molestie placerat. Proin elementum fermentum mauris. Vivamus sed orci lacinia dui placerat venenatis. Vestibulum feugiat, tellus in volutpat rutrum, magna nisi ullamcorper eros, id pulvinar neque erat ut lacus. Vivamus sed augue. Nulla facilisi. Maecenas ante augue, elementum ut, sodales vitae, condimentum nec, lorem. Duis pede orci, fringilla at, eleifend nec, pretium in, erat. Nam sagittis, turpis vitae convallis pharetra, odio sem scelerisque lacus, nec lobortis dui diam vel eros. In semper gravida neque. + +Integer nunc. Ut pretium ipsum sit amet elit. In nec arcu. Sed vestibulum vulputate ipsum. Pellentesque tincidunt. Nulla gravida dolor in tellus. Cras vehicula, dolor ut pellentesque aliquam, erat enim auctor massa, vehicula lobortis odio eros quis quam. Proin dapibus neque in enim. Proin elit. Integer rhoncus tincidunt elit. Fusce lorem metus, semper ac, volutpat vitae, facilisis ut, tellus. Donec vel turpis vitae nisi pharetra porttitor. Maecenas tortor. Fusce mi. Nullam nec turpis. Sed sodales vestibulum nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Pellentesque dolor dolor, laoreet eu, aliquet quis, scelerisque sit amet, arcu. In hac habitasse platea dictumst. Nullam cursus urna eget elit. Quisque blandit sapien ac ante. Proin nulla eros, gravida volutpat, sodales vel, mollis eu, massa. Nulla tristique sollicitudin nisl. Curabitur vitae lorem vitae velit egestas ornare. Aenean eget eros. Aliquam erat volutpat. Fusce a urna id odio aliquet convallis. Curabitur sit amet nisl posuere leo posuere dapibus. Duis metus erat, luctus vel, rhoncus at, convallis sit amet, enim. Vivamus hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam eget elit. + +Nullam a nunc. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In metus urna, tincidunt et, lacinia sit amet, lobortis vitae, ligula. Proin et mauris vitae mi accumsan pellentesque. Etiam quam purus, hendrerit sed, feugiat vitae, euismod eget, tortor. Ut aliquam magna vitae justo. Suspendisse non justo vel velit condimentum tempus. Duis tempus ipsum vitae tellus. Proin in massa. Etiam ullamcorper dictum tellus. Proin aliquet felis at leo laoreet pulvinar. Vestibulum arcu purus, malesuada sit amet, cursus eu, placerat sit amet, nunc. Nam massa odio, sollicitudin in, adipiscing a, aliquam nec, risus. Aliquam blandit hendrerit libero. Mauris gravida. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur a nibh. Ut interdum fermentum neque. Pellentesque sed nunc. Mauris vehicula nisi et nunc. Praesent lorem. Donec semper. Integer eu lacus in est aliquam hendrerit. Vestibulum eget neque. Sed semper luctus velit. Curabitur nibh augue, congue eu, hendrerit id, congue et, enim. Integer placerat aliquam lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae eros. Donec vel nisl. + +In vestibulum facilisis urna. Ut risus. Mauris pharetra. Pellentesque mattis. Integer suscipit aliquam ipsum. Duis blandit, sapien et ultricies condimentum, felis mi elementum pede, nec sagittis metus mauris quis quam. Quisque accumsan arcu vel nulla. Cras sem sapien, porttitor id, ultricies sagittis, luctus eu, nulla. Integer quis eros. Morbi sed urna a tellus vehicula vulputate. Etiam nec augue eget felis semper tristique. Quisque ut dolor vel risus dictum consequat. Sed eget dolor sed nunc lacinia aliquet. Suspendisse ac tortor in ipsum posuere venenatis. Sed eget erat. Nulla faucibus. Duis laoreet, massa porttitor aliquet egestas, ipsum lectus rhoncus quam, in adipiscing eros sem ut tellus. Pellentesque feugiat tempus quam. Vivamus id dolor eget sapien consectetuer tempor. Aliquam erat volutpat. + +Nulla iaculis fermentum libero. Curabitur faucibus, massa malesuada cursus tincidunt, erat sem eleifend mauris, sed fringilla mi ante ac purus. Duis elementum lectus. Nunc ornare arcu eu tortor. Vestibulum vel dolor at purus lacinia fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas tincidunt, eros a egestas pellentesque, risus risus dictum libero, id aliquet metus justo in massa. Proin a tellus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed purus. Sed non pede. Aenean massa sapien, sodales sit amet, consequat dictum, eleifend vitae, tortor. Donec ultrices lacinia elit. + +Morbi adipiscing sodales dolor. Ut ullamcorper ultricies est. In venenatis tempus augue. Suspendisse tortor dolor, accumsan et, suscipit a, tincidunt ut, libero. Aliquam scelerisque magna sed felis. Quisque ut nunc a magna vulputate placerat. Aliquam rhoncus vehicula dui. Sed tortor. Nullam sit amet diam. Nunc sed eros. Sed et odio tincidunt elit gravida convallis. Curabitur quis tortor a lacus semper varius. Mauris at augue non mi sollicitudin aliquam. Integer ullamcorper. Pellentesque suscipit quam non purus. Aliquam ac eros at arcu ullamcorper consectetuer. Suspendisse pretium mattis leo. + +Duis at nunc. Sed dolor est, varius ac, porta et, tincidunt hendrerit, risus. Vivamus ut magna. Praesent ut mauris. In purus lacus, mattis sed, vestibulum nec, tempor at, nisl. Cras ullamcorper venenatis tellus. Ut dolor. Maecenas malesuada, pede a pulvinar mattis, arcu diam vehicula risus, quis porttitor augue massa in velit. Nunc congue. Morbi velit metus, rhoncus et, aliquam consectetuer, ultricies malesuada, ligula. Sed velit nisl, sagittis vitae, pharetra a, posuere sed, massa. Nulla facilisi. In varius, ligula id lobortis sodales, augue orci fermentum tellus, eu pulvinar risus ligula a sapien. Morbi laoreet ipsum non mi. Nam cursus lorem ut mi. Vivamus magna enim, posuere non, semper quis, sodales eu, arcu. Etiam mi purus, pretium feugiat, varius sed, pellentesque eget, ligula. In leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vitae orci eu orci sollicitudin feugiat. + +Praesent purus massa, euismod vitae, tempus nec, consequat hendrerit, metus. Aenean felis est, egestas vitae, accumsan eget, pellentesque in, sapien. Duis dapibus pede non sapien. Nunc urna. Integer vel libero. Duis augue arcu, dapibus non, facilisis vitae, posuere ut, eros. Donec vitae nunc sit amet arcu imperdiet dictum. Morbi eleifend, lorem eu consectetuer vestibulum, diam nunc ornare arcu, ac tempor felis dolor eget eros. Phasellus massa sem, sollicitudin ac, sodales gravida, luctus a, quam. Nam neque quam, viverra at, venenatis quis, sagittis non, enim. + +Nulla facilisi. Pellentesque egestas lacinia est. Sed tincidunt, pede sed tincidunt vestibulum, urna dolor adipiscing purus, vitae fringilla felis elit in nibh. Nulla sed nisi. Mauris suscipit scelerisque arcu. Etiam non enim vel eros accumsan malesuada. Nunc tincidunt commodo mauris. In tincidunt risus quis urna. Nulla diam tortor, aliquet et, tincidunt quis, sollicitudin ac, tortor. Cras nisl neque, vulputate suscipit, molestie quis, pulvinar at, nulla. Nullam ac metus nec odio posuere varius. Cras sed pede nec dui posuere bibendum. Duis euismod ullamcorper libero. Aliquam faucibus pulvinar turpis. + +In ut neque id nunc feugiat commodo. Curabitur dignissim, felis at sollicitudin lacinia, enim elit suscipit neque, sed luctus lorem ipsum in leo. Duis dapibus, odio quis auctor commodo, nisl odio mattis tellus, nec tincidunt turpis diam in arcu. Curabitur a sem. Nullam volutpat magna. Pellentesque sagittis, neque consequat pretium cursus, dolor lacus consectetuer arcu, sed laoreet est urna et metus. Suspendisse placerat, dui a porta tempor, lorem dui lobortis neque, sed venenatis diam enim id eros. Etiam et nisl non lectus faucibus consectetuer. Morbi scelerisque, sem nec tempus ullamcorper, ipsum diam feugiat lorem, a fringilla sapien elit quis nibh. Nullam diam urna, viverra sed, pharetra rhoncus, tincidunt vel, orci. Integer accumsan mattis erat. Nam dictum. Mauris nec leo. Nulla iaculis. Nulla nisl mi, dapibus quis, vehicula a, cursus eget, odio. + +Phasellus dapibus euismod nibh. Vivamus imperdiet ante in ligula. Pellentesque accumsan. In imperdiet, dui a auctor fringilla, metus nisi cursus dolor, vel luctus ligula lorem vitae mauris. Praesent mattis vestibulum elit. Aliquam enim lacus, pulvinar non, lacinia sit amet, eleifend non, velit. Vestibulum ac leo. Mauris imperdiet justo ac lectus. Sed molestie lectus sed dui. Sed fermentum tempus mauris. Nam ornare orci ac tellus. Ut malesuada, lacus id lacinia accumsan, diam elit adipiscing metus, et bibendum sapien nibh blandit orci. Suspendisse ipsum tellus, sagittis quis, vestibulum non, vulputate eu, eros. Praesent at nulla id pede scelerisque ultricies. Cras blandit pretium tellus. Maecenas dapibus condimentum augue. Phasellus tincidunt pharetra lorem. Morbi non eros. Sed tempor, nisl a tincidunt tincidunt, eros diam dictum sem, vel dignissim ante diam sed magna. Praesent non ligula id metus molestie consectetuer. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse vel mi. Curabitur ante nulla, rutrum a, convallis vel, vehicula ac, nunc. Nunc sagittis, enim sit amet auctor rutrum, mauris arcu vulputate neque, et euismod est felis quis ante. Vestibulum turpis tellus, hendrerit in, lacinia commodo, ullamcorper gravida, risus. Mauris rhoncus lacinia risus. Maecenas sollicitudin erat vitae nunc. Praesent pretium pellentesque augue. Donec interdum. Praesent ac eros vitae erat lobortis fringilla. Aenean consequat tellus. Nulla accumsan bibendum felis. Maecenas pretium ante id nisi. Aenean mi arcu, semper sed, mattis eu, venenatis sit amet, arcu. Donec aliquet euismod leo. Proin magna justo, tristique a, semper ac, sollicitudin a, ligula. Morbi velit. Aliquam vel nisi. + +In a lorem ut nunc feugiat congue. Donec fermentum bibendum dui. Proin varius est quis velit. Donec aliquet sem accumsan mi. Sed placerat. Nullam ac nisi a massa lobortis suscipit. Nunc id leo. Aliquam et massa. Nullam vestibulum elementum metus. In consectetuer nisi vel justo. Maecenas eget purus sed massa varius pellentesque. Phasellus faucibus felis quis felis. Aenean odio arcu, blandit quis, facilisis in, imperdiet eu, lorem. Nam posuere pulvinar mi. Fusce tristique, mauris et consectetuer ultricies, mauris lectus tempor justo, at fringilla est est sed nisi. Quisque faucibus. Sed in tortor tincidunt est lacinia iaculis. Maecenas a massa. Pellentesque a nibh at purus porta hendrerit. + +Nullam turpis. Fusce ac sem sed odio pellentesque imperdiet. Curabitur in arcu. Praesent lacus lacus, feugiat id, pulvinar in, tincidunt sed, neque. Maecenas viverra odio eget tortor. Integer aliquam, lorem rutrum venenatis dignissim, ligula magna malesuada arcu, vel feugiat lorem ipsum quis massa. Morbi ante. Vestibulum mauris libero, ullamcorper quis, ultrices quis, facilisis non, massa. Maecenas imperdiet. Aliquam erat volutpat. Pellentesque dignissim gravida lectus. In nibh odio, auctor eget, dapibus quis, dignissim venenatis, arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis pellentesque ligula quis massa. Curabitur condimentum, justo eget ornare luctus, lorem ligula sagittis pede, a porta nunc nunc in neque. Quisque felis mauris, condimentum vitae, auctor vitae, tincidunt quis, pede. Nunc lacinia ante in leo. Pellentesque libero. Aenean a ligula et nunc vestibulum consectetuer. + +Fusce ornare. Praesent id urna. Integer venenatis, quam non sagittis accumsan, ante nibh sagittis augue, sollicitudin adipiscing dolor velit eu erat. Proin quis enim eu purus vehicula aliquam. Nulla vel enim vel elit sollicitudin fringilla. Aliquam erat volutpat. Sed suscipit felis ut turpis. Etiam rutrum risus imperdiet est. Aliquam a tellus at tellus commodo dapibus. Mauris rutrum magna et odio. In at dolor. Curabitur vehicula lectus in tortor. Fusce justo purus, luctus vitae, mollis in, pharetra ac, purus. Nullam posuere interdum justo. Curabitur vitae lacus vel leo congue pulvinar. + +Aenean eleifend nibh varius tortor. Suspendisse vel eros. Proin nec diam a tortor ultrices ornare. Aliquam scelerisque feugiat justo. Vivamus ante urna, adipiscing vitae, porttitor eu, sodales et, felis. Suspendisse potenti. Curabitur ac massa in nisl sagittis mollis. Nam quam ligula, consectetuer eget, iaculis at, varius eu, leo. Duis dolor ligula, tincidunt at, ullamcorper sed, accumsan aliquam, ligula. Phasellus vulputate, lorem at tincidunt pharetra, risus lectus lacinia magna, quis rutrum enim magna at sem. In hac habitasse platea dictumst. Duis id sem a mauris sollicitudin tincidunt. Etiam eu purus eu arcu fringilla adipiscing. Vivamus ornare tempus diam. Proin turpis quam, lacinia non, egestas at, commodo eget, pede. Praesent vulputate risus in est. Nulla facilisi. + +Ut elementum lacinia purus. Proin vitae arcu ac nulla convallis aliquam. Nulla congue, libero id pellentesque mattis, quam lectus porttitor diam, a scelerisque dui libero in sapien. Nullam felis diam, vehicula vel, molestie ut, vestibulum aliquam, sapien. Donec convallis, est ut elementum volutpat, mauris ipsum gravida sem, commodo facilisis sapien lectus semper lectus. Quisque porttitor eros ut nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam mattis risus sed odio. Vestibulum et odio. In hac habitasse platea dictumst. Nam tristique massa ut ligula. Quisque nibh tellus, vehicula sit amet, adipiscing at, convallis nec, ligula. Vestibulum pretium, mi nec fringilla bibendum, dui nunc sodales pede, a semper magna nibh non diam. Donec massa nunc, viverra vel, consectetuer porta, dapibus non, ipsum. Duis nisl mauris, cursus vel, semper non, sollicitudin bibendum, felis. Vestibulum eu neque. + +Cras nec dolor. Donec laoreet tempus lectus. Cras sed tortor interdum lacus eleifend dignissim. Maecenas sit amet elit. Nullam quis dolor vel dui pharetra luctus. In sit amet quam sit amet pede ultrices ultrices. Maecenas diam. Integer urna. Curabitur dictum, velit sed placerat suscipit, erat turpis fermentum justo, sed interdum neque sem et nibh. Vivamus consequat convallis magna. Nam aliquam, est ac bibendum commodo, magna est dictum mi, vitae malesuada elit magna vitae odio. Maecenas tempor vulputate tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus dui. Etiam accumsan pede congue tortor. + +Morbi tempor libero ac lorem. In aliquet varius magna. In arcu. Phasellus odio. Fusce tincidunt aliquet felis. Quisque velit. Sed luctus. Aliquam feugiat fringilla mi. Aliquam molestie viverra risus. Proin arcu. Vestibulum lobortis tempus nisi. Praesent a arcu in velit viverra rutrum. + +In sed lectus. Donec risus dolor, blandit sit amet, elementum convallis, pharetra quis, pede. Integer ornare. Aenean egestas dapibus justo. Sed quam leo, posuere at, elementum vitae, commodo eget, est. Aliquam molestie rhoncus enim. Curabitur iaculis ultrices pede. Morbi aliquet rutrum lacus. Aliquam quam. Sed commodo, turpis in pharetra posuere, mi risus imperdiet erat, a vestibulum massa tellus vehicula sem. Mauris fringilla ultrices nunc. Nam nisi enim, eleifend sit amet, ultrices sed, fermentum non, augue. Proin congue lobortis nisi. Maecenas hendrerit. Nam sed nisl. Nunc elementum odio eu risus. In metus. Phasellus gravida pretium ligula. Nulla vitae neque. Nam nisi tortor, ornare non, blandit at, cursus eu, tortor. + +Duis bibendum ipsum in nunc cursus molestie. Nunc orci. Nullam nec ante non est dignissim viverra. Mauris blandit, velit id feugiat pretium, elit magna pellentesque dolor, at sagittis lacus velit egestas magna. Pellentesque cursus, diam consectetuer sagittis fringilla, tortor nisi adipiscing nunc, eu varius lacus risus ac elit. Mauris id nisi quis leo euismod venenatis. Pellentesque ac ante. Mauris arcu sapien, tempor at, porttitor id, condimentum ut, dui. Etiam fermentum ultricies augue. Cras ut eros at justo ultricies iaculis. Duis dignissim, nisl et facilisis fermentum, erat purus molestie tellus, quis tempus ipsum lectus at elit. Nulla vitae lorem. + +Aenean vel sem et diam semper congue. In bibendum diam quis tellus. Nunc facilisis ultricies nibh. Cras nunc enim, feugiat sed, ultrices vitae, sagittis vitae, ipsum. Fusce vitae nulla. Donec pellentesque, velit in porttitor eleifend, est neque lobortis velit, sit amet rutrum ante tortor nec dolor. Donec vehicula. Nulla facilisi. Sed egestas ultrices nibh. Donec elit lectus, convallis porttitor, aliquet dapibus, feugiat eget, ligula. Sed consectetuer justo. Maecenas a sapien sit amet nisi dapibus lobortis. Vivamus luctus lorem non nulla. Sed eget erat vitae libero interdum posuere. Cras pulvinar. Nullam imperdiet, dolor tempor dignissim blandit, dui sapien rhoncus neque, id malesuada augue magna sit amet urna. Duis sed mauris. + +Morbi accumsan. Sed mauris augue, fringilla non, auctor ut, auctor et, orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus ut pede. Donec viverra enim vel lorem. Pellentesque neque mauris, interdum eu, venenatis id, condimentum eu, sapien. Donec ipsum arcu, lacinia adipiscing, laoreet et, cursus vel, velit. Ut sagittis mauris quis risus. Integer eu odio vitae lacus viverra accumsan. Morbi leo ante, dignissim sed, varius quis, volutpat vitae, nisi. Nulla placerat interdum elit. Donec neque dui, sagittis vitae, sollicitudin quis, commodo vitae, neque. Nulla quis ligula ornare ligula dictum ornare. Mauris rutrum rutrum neque. Aenean vehicula tempus est. Donec varius scelerisque pede. Donec placerat vulputate leo. Nullam nunc nisl, posuere non, feugiat vitae, pellentesque quis, mauris. In dui neque, cursus eget, sagittis eget, dapibus vitae, mi. Proin eget est. + +Fusce porta est. Mauris magna. Aliquam ipsum lacus, ultricies id, vestibulum luctus, accumsan ut, ante. Sed mauris. Sed adipiscing leo sit amet magna. Suspendisse potenti. Nunc massa elit, fringilla eget, egestas vitae, luctus vitae, dolor. Phasellus quis nulla eu nisi interdum sollicitudin. Nullam id tellus. Integer iaculis dolor ac purus. Sed vel mi. Curabitur non magna sit amet justo condimentum vulputate. Quisque tincidunt pede eu nisl. Vivamus lobortis. Nunc metus metus, congue sed, tincidunt sed, pretium at, odio. Donec a arcu. In sem justo, vehicula sed, varius id, volutpat at, risus. Praesent iaculis massa. In arcu elit, hendrerit eget, ullamcorper in, porta id, tellus. Donec sagittis hendrerit diam. + +Suspendisse potenti. Sed et diam et augue sagittis lobortis. Phasellus dolor. Ut et arcu eget ante tempor posuere. Aliquam fermentum scelerisque dui. Mauris at purus. Donec erat sem, vestibulum nec, faucibus ac, mattis a, leo. Suspendisse adipiscing lacinia sem. Nullam orci arcu, dictum et, faucibus viverra, dapibus et, neque. Cras nunc diam, adipiscing non, sollicitudin in, interdum vel, massa. Mauris sagittis, justo at tristique tempus, mauris mauris aliquam ante, sit amet posuere diam dui eget ligula. In dignissim, nisl ut lacinia condimentum, erat justo porttitor nulla, non gravida ligula magna eget massa. Vestibulum vitae ligula at mi vestibulum suscipit. Duis laoreet. Nulla commodo libero sit amet lorem. Ut elementum sem. Integer vel dolor. Nam facilisis mi quis sem ultrices sagittis. Sed quis quam at metus molestie bibendum. + +Proin dui enim, lacinia a, feugiat ac, placerat vitae, pede. Quisque egestas, leo eget aliquam pretium, libero justo tincidunt eros, ut egestas augue pede elementum nibh. Curabitur mollis sodales enim. Donec augue. Phasellus id ipsum posuere dui pretium faucibus. Mauris luctus ante semper nisi interdum adipiscing. Duis dapibus, odio quis viverra rhoncus, justo quam bibendum dolor, id dapibus velit erat vel erat. Fusce sit amet nisl venenatis quam ultrices condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec rhoncus scelerisque ligula. Vestibulum mi odio, accumsan et, adipiscing eget, ornare ut, quam. Nullam blandit molestie mauris. Curabitur dignissim mauris et lorem. Suspendisse a justo. Nam mattis faucibus arcu. Duis blandit enim non massa. + +Nullam lorem. In hac habitasse platea dictumst. Mauris consectetuer posuere mauris. Maecenas tincidunt mauris in eros. Nulla eu metus eu orci sollicitudin faucibus. Suspendisse aliquam mauris id est. Cras blandit dui et urna. Nulla arcu. Sed a urna. Nulla dapibus vehicula tortor. Donec risus. Sed quam metus, egestas eu, cursus ut, viverra non, odio. Ut justo justo, malesuada sit amet, blandit suscipit, molestie in, justo. Vestibulum consequat, quam ac feugiat tincidunt, ipsum libero eleifend odio, non eleifend pede ipsum non ante. Nullam a metus. + +Nam ac nisi at felis cursus mattis. Pellentesque consequat sem quis orci. Quisque tempus. Aenean imperdiet molestie pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eu tellus. Nulla diam eros, sodales ut, sodales nec, tincidunt ac, nunc. Nunc lacinia faucibus ipsum. Vivamus vel neque in erat fermentum luctus. Nulla eget metus nec augue bibendum placerat. Vivamus tempus. Praesent congue ornare ipsum. Etiam mattis feugiat justo. + +Aliquam dui. Aenean commodo tortor vitae nulla. Morbi et ipsum. Mauris ac ipsum. Nam vel risus ut lectus mollis viverra. Curabitur elementum mollis est. Nullam elit. Vestibulum suscipit pretium enim. Vestibulum ut massa. Proin nec felis. Maecenas gravida, arcu nec consequat sagittis, eros tellus scelerisque mauris, vitae accumsan quam quam ut nunc. Integer eget ante eu velit laoreet malesuada. Nunc sagittis, mauris vitae pharetra volutpat, tellus tellus eleifend eros, sit amet rutrum ipsum nisi a velit. Praesent varius leo eu erat. Vivamus consequat placerat purus. Donec pretium elementum nibh. Proin at elit non sem aliquet mattis. Sed ullamcorper ipsum sit amet elit. + +Mauris in metus. Suspendisse magna lorem, faucibus vel, tincidunt quis, scelerisque non, tellus. Fusce quis lorem. Proin a lacus sit amet mauris iaculis pulvinar. Suspendisse rhoncus eros nec mi. Praesent euismod, turpis vitae rutrum pretium, odio metus volutpat neque, eget tempus sapien neque sed erat. Donec fermentum purus at lectus. Nullam sem. Fusce vel mi quis erat lobortis posuere. Aenean eget urna. Suspendisse ligula. Duis in nisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Curabitur vulputate lectus id pede. Phasellus eu velit. Etiam venenatis adipiscing nibh. Aliquam cursus pulvinar tellus. Vestibulum neque. Mauris nec justo et erat semper pellentesque. Fusce mattis dictum dolor. Etiam eget purus eu massa varius elementum. Pellentesque massa. Ut ultricies diam sed ipsum. Nullam diam. Pellentesque id magna id libero tristique aliquam. + +Ut eleifend, purus id placerat venenatis, urna augue aliquet ligula, in ultricies leo risus et tellus. Mauris et nulla id urna tristique tempus. Ut facilisis, urna eu vestibulum rhoncus, lacus eros consectetuer metus, et rutrum dui lectus in purus. Nunc vel nisl non ipsum tincidunt mollis. Nam quam lacus, ornare vitae, rhoncus non, congue sed, odio. Proin nibh dui, porta vel, venenatis non, pellentesque ut, nisi. Sed tristique felis a magna. Suspendisse eget tellus. Cras gravida imperdiet velit. Integer hendrerit risus. Proin orci. Aliquam ullamcorper mauris quis mauris. Nunc lacinia vestibulum metus. Duis tellus. Nullam faucibus, leo ac vulputate sollicitudin, leo dolor faucibus erat, quis bibendum orci odio non arcu. + +Nullam accumsan mattis dolor. Donec et dui. Praesent a felis mollis lacus semper lacinia. Curabitur pellentesque luctus est. Proin nulla dui, condimentum vel, faucibus non, interdum ac, erat. Maecenas scelerisque, lectus id volutpat accumsan, sapien tortor pellentesque dui, sed semper magna sem ut leo. Proin nulla. Nullam dapibus ullamcorper sem. Suspendisse vehicula metus in nunc. Pellentesque non quam vel arcu ultrices ullamcorper. Phasellus quis felis sit amet tellus ullamcorper fermentum. Sed vehicula sollicitudin urna. Curabitur pharetra scelerisque risus. Pellentesque id massa quis metus aliquam imperdiet. In nunc lacus, feugiat in, gravida eget, venenatis ut, tellus. Suspendisse potenti. Nam consequat adipiscing dui. In nulla nisi, feugiat ut, fermentum vel, gravida nec, tortor. In sed augue. + +Etiam ullamcorper augue at enim. Integer dignissim. Aliquam pulvinar congue nulla. Morbi enim massa, fringilla a, accumsan eget, condimentum nec, erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean pharetra. Etiam porttitor purus a metus. Aliquam interdum sem eget justo. Quisque volutpat luctus est. Aenean augue. Phasellus dui lectus, ultrices nec, commodo vel, auctor vel, nisi. Ut ultrices pellentesque nisi. Integer ac velit et sem imperdiet luctus. Fusce vitae turpis id augue mollis consectetuer. + +Maecenas nec lacus. Maecenas condimentum odio eu felis. Mauris ut nisl viverra erat faucibus adipiscing. Etiam egestas. Nunc et dolor vitae risus dignissim commodo. Morbi lectus velit, tincidunt nec, aliquet vel, mattis vitae, ligula. Maecenas ultricies semper dolor. Suspendisse malesuada. Integer mattis elit. Donec accumsan, lacus facilisis varius tempus, nulla elit porta erat, et rutrum elit sem sit amet dui. + +Maecenas mollis mi non nulla. Vivamus turpis. Suspendisse a metus. In quis mi in turpis congue auctor. Maecenas lacus. Suspendisse sollicitudin. Phasellus porta nunc non nisl pulvinar egestas. Sed nulla. Vestibulum ac mi. Mauris ultricies condimentum neque. Nulla tempus justo vel massa. Nulla suscipit congue arcu. Praesent id turpis. Mauris nibh pede, euismod semper, molestie ac, rhoncus vitae, ante. Maecenas erat felis, viverra sollicitudin, sagittis eget, pellentesque nec, orci. Fusce ultrices consequat lacus. Aliquam erat magna, feugiat at, viverra a, mollis non, turpis. + +Donec mi. Nam dictum pellentesque sem. Donec mollis rhoncus elit. Phasellus rhoncus pede sit amet risus. Donec eget augue. Maecenas non lectus. Phasellus sollicitudin nisi nec felis. Aliquam pretium, est eget semper convallis, nibh nunc sollicitudin purus, id tempor pede dui vel magna. Vivamus ac lorem. Etiam nisl tortor, adipiscing dictum, elementum in, facilisis sed, nibh. Proin mauris. Proin rutrum massa eget sem. Curabitur tempor adipiscing elit. Curabitur purus tellus, fermentum eget, aliquet vitae, convallis ac, mauris. + +Integer consequat velit eu eros tincidunt vehicula. Nullam lorem sapien, rhoncus non, mattis quis, ultricies sit amet, enim. Curabitur commodo, libero in euismod suscipit, sem purus fringilla enim, ac molestie tortor orci et velit. Donec pede. Etiam placerat condimentum turpis. Phasellus egestas enim nec magna. Vivamus condimentum, nulla vel luctus tristique, eros risus vestibulum nulla, in vehicula arcu ipsum at felis. Donec aliquam elit at augue. Quisque a eros eu ligula accumsan dictum. Etiam vehicula turpis quis libero. Aliquam non mi. Donec et leo. Proin leo libero, aliquam tincidunt, congue nec, adipiscing porta, enim. Nulla lobortis, tortor sit amet imperdiet ullamcorper, dolor orci malesuada pede, sed gravida nibh urna vel lorem. Sed pharetra malesuada eros. Quisque euismod aliquet erat. Suspendisse aliquet mattis purus. + +Nunc id nulla quis justo congue sollicitudin. Praesent erat turpis, rhoncus eu, pretium eu, pellentesque a, nibh. Vivamus tempus. Cras nec risus at turpis imperdiet lobortis. Ut mattis. Maecenas est felis, pellentesque non, imperdiet sed, eleifend tincidunt, lorem. In tincidunt. Sed vel leo. Donec et urna in turpis hendrerit blandit. Donec condimentum accumsan est. Ut pharetra, metus vitae mattis consectetuer, leo quam vulputate odio, nec laoreet nisi velit eu erat. Integer lectus augue, egestas in, interdum eu, venenatis vel, sapien. Quisque et est vitae eros laoreet lobortis. Nullam ut risus non nulla placerat adipiscing. Praesent dapibus. Etiam a felis. Ut sodales consequat mauris. Duis lorem felis, luctus a, tristique in, molestie at, risus. Sed vehicula bibendum tellus. Nam consequat euismod lacus. + +Aenean tortor elit, gravida nec, fermentum eu, lobortis id, ipsum. Maecenas eu purus. Cras ac turpis ut nisi iaculis rhoncus. Nulla purus metus, dignissim nec, tincidunt vitae, dapibus eu, nibh. Fusce lobortis, nunc at viverra eleifend, justo turpis scelerisque eros, ac pellentesque metus nisl at purus. Sed elementum tellus sed enim interdum blandit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer ultricies aliquet odio. Mauris eget nunc a ipsum ultrices sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean accumsan. Donec sapien lectus, congue at, porta id, hendrerit vitae, nisl. Curabitur vel quam vel neque accumsan laoreet. Morbi sapien est, pretium in, consectetuer ac, mollis ut, libero. Donec tincidunt adipiscing metus. Nunc vestibulum egestas augue. Donec scelerisque dui ut sem. Suspendisse vel metus id est molestie iaculis. + +Vivamus pharetra, elit eu malesuada blandit, diam tortor mollis dui, sed pulvinar massa nunc et magna. Sed placerat elit auctor tortor. Nulla ac erat. Pellentesque consectetuer, dui convallis tincidunt condimentum, sem odio volutpat libero, non elementum felis neque nec odio. Maecenas hendrerit eros id diam. Mauris vel purus ac orci convallis convallis. Sed sit amet lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque dictum varius lacus. Mauris eget nisl. Suspendisse placerat, nulla non ornare dignissim, nisl diam sagittis tellus, in semper nisi dolor at nibh. Duis ullamcorper viverra felis. Integer a tellus. Suspendisse eget nunc. Aenean diam est, accumsan id, suscipit interdum, fringilla vitae, justo. Proin pede. Maecenas at neque in neque vestibulum eleifend. + +Vestibulum nulla lorem, porttitor eget, euismod ac, aliquam at, nisl. Maecenas et est eget massa varius lobortis. In mi. Duis porttitor fermentum purus. Donec cursus imperdiet ligula. Morbi et ligula et ante molestie vehicula. Mauris sed dolor. Sed imperdiet felis ut sem. Sed vitae neque elementum leo auctor fermentum. Duis feugiat ullamcorper erat. Aenean purus. Morbi fermentum vestibulum est. Pellentesque venenatis mauris. Phasellus pulvinar. Integer ipsum lectus, iaculis a, lacinia id, accumsan id, arcu. Phasellus at est. Fusce neque quam, ultricies id, iaculis vel, dapibus vitae, lacus. In lobortis convallis ante. Nulla nunc purus, vulputate in, hendrerit et, blandit et, ligula. + +Pellentesque leo metus, sagittis in, molestie vitae, dictum in, pede. Morbi pretium felis nec quam. Pellentesque mattis ante sed quam sagittis dapibus. Suspendisse sapien. Praesent bibendum iaculis tortor. Duis a nisl. Aenean mi. Donec dictum arcu in est. Morbi interdum vulputate ipsum. Aenean sit amet magna non nisl tristique posuere. Phasellus velit metus, tempor ac, fermentum eget, condimentum non, velit. Vestibulum sit posuere. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras aliquet massa nec dui. Cras arcu nunc, hendrerit ac, eleifend eu, ullamcorper nec, tellus. Sed pharetra purus sit amet quam. Curabitur mollis. Nam vitae pede. Etiam risus massa, vehicula sit amet, pharetra nec, sollicitudin ut, dui. Donec egestas justo at quam. Proin nisl risus, vestibulum nec, pretium vitae, tristique ac, lorem. Aliquam erat volutpat. Cras sed nibh. Pellentesque sollicitudin euismod augue. + +Etiam fringilla sollicitudin orci. Mauris cursus elit quis lacus. Cras tortor. In adipiscing, lectus id auctor vestibulum, neque pede accumsan dolor, non imperdiet magna diam accumsan velit. Suspendisse at libero ut nisi blandit sagittis. Phasellus non mauris. Fusce elementum sagittis sem. Suspendisse aliquam eleifend tellus. Proin ligula lorem, imperdiet quis, venenatis id, iaculis mollis, nisl. Etiam convallis pede at massa. Morbi accumsan dui et mauris. + +Sed sed orci. Nunc purus. Suspendisse potenti. Ut luctus fringilla mauris. Donec nibh. Phasellus porta. Phasellus sit amet odio sed magna sodales pharetra. Cras lectus. Suspendisse libero ipsum, commodo nec, facilisis in, suscipit lobortis, ligula. Duis massa nulla, semper et, consequat nec, pharetra eu, elit. Vivamus ultricies aliquam odio. Vestibulum sit amet massa. Sed consequat lacus sed urna. Etiam faucibus felis vel orci. Phasellus ullamcorper. Aenean consectetuer lacus at libero. + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis facilisis, ligula vitae condimentum scelerisque, velit orci gravida felis, vel ultricies quam mi non diam. Vivamus auctor metus non libero. Praesent ligula nisi, commodo condimentum, molestie et, viverra et, justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus sollicitudin. Nunc blandit cursus ipsum. Aenean nec ligula ut tellus sodales mattis. Integer sem. Aliquam id ligula. Sed tortor mauris, blandit vitae, cursus vel, elementum et, nulla. Aliquam scelerisque metus et nisl. Duis adipiscing magna at neque. Quisque vulputate eleifend nunc. Aliquam eget elit. Phasellus dui odio, bibendum sagittis, vestibulum id, dignissim imperdiet, orci. Nullam eu felis non nunc lacinia sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Suspendisse pellentesque, libero mattis ultricies accumsan, tortor tortor malesuada sem, et sodales libero odio ac ipsum. Vivamus quis magna nec est suscipit lobortis. Cras tempus posuere nunc. Quisque ut enim a felis egestas semper. Sed pharetra mattis neque. Fusce turpis nunc, congue sed, consequat non, congue sed, nulla. Suspendisse varius lorem id risus porta vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce sed purus. In a felis. Integer egestas auctor orci. Mauris ultrices suscipit nisl. Nullam purus. + +Cras tempor adipiscing ipsum. Ut quis mi. Maecenas in justo ut nulla congue pharetra. Pellentesque ut libero eu dolor venenatis suscipit. Praesent feugiat consectetuer nibh. Morbi faucibus sem non felis. In hendrerit arcu ac massa. In accumsan ultrices mi. Proin malesuada auctor felis. Curabitur interdum. Sed diam ipsum, ultricies in, tempor sit amet, viverra imperdiet, elit. Morbi molestie nisi. Mauris ipsum. Fusce dictum mollis magna. Duis commodo dignissim nulla. Vestibulum augue enim, ultricies quis, iaculis nec, tincidunt vitae, diam. Mauris lacinia tempus ipsum. Sed at mauris. Ut lorem. Donec libero. + +Duis iaculis lacinia lectus. Aenean convallis eros ac ante. Sed quis orci nec risus auctor fringilla. Phasellus facilisis elementum nisi. In hac habitasse platea dictumst. Nunc porta lacus nec ante. Morbi mauris erat, adipiscing in, pulvinar nec, lobortis nec, odio. Ut eleifend lectus sed quam. Nullam mollis. In non turpis et nisl hendrerit blandit. Duis elementum. Nunc nec libero. Suspendisse vestibulum risus non pede. Morbi imperdiet odio sit amet libero. Sed sed massa vitae ipsum mattis tincidunt. Nulla nec tortor vitae libero volutpat tempus. Donec aliquam. + +Duis sed nunc. Curabitur turpis nulla, vehicula sed, luctus quis, elementum eget, felis. Maecenas et purus. Maecenas leo tellus, tincidunt a, facilisis vitae, lobortis sit amet, velit. Donec convallis sapien. Maecenas mollis odio eu nibh. Etiam gravida. Integer molestie, sapien eu molestie lacinia, nunc nibh aliquam ligula, eu sagittis tellus erat sollicitudin odio. Duis et risus. Phasellus nisi neque, placerat nec, condimentum non, ultrices eu, sem. Ut pede. Etiam nulla metus, volutpat id, convallis sed, suscipit vel, urna. Donec vel elit. Ut leo neque, venenatis faucibus, lacinia nec, tincidunt eu, enim. Cras id dui a libero pharetra dignissim. Donec eros leo, porta quis, laoreet ut, pellentesque volutpat, lectus. + +Nullam blandit. Aliquam erat volutpat. Fusce adipiscing enim. Suspendisse non dui quis ligula porta vestibulum. Donec eu tellus vel lorem pretium porttitor. Praesent luctus. Aliquam ac eros in massa dapibus tincidunt. Donec ut magna. Etiam auctor lacus sit amet lacus. Sed ultricies ipsum nec elit. Quisque a est in purus suscipit tristique. + +Aenean sed dui vel dolor pulvinar laoreet. Vivamus vehicula lorem in pede. Vivamus et diam. Integer ac odio vel diam hendrerit bibendum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a nisi. Phasellus tincidunt dui vitae augue. Duis faucibus, dui interdum fringilla tincidunt, odio elit vestibulum libero, ac molestie magna lectus id lacus. Aenean ligula. Nulla facilisi. + +Fusce vel sem eu velit fringilla ornare. Sed feugiat tincidunt felis. Nullam felis mi, euismod sit amet, mollis at, sodales eget, augue. Nam imperdiet nibh at velit. Sed ut erat. In dui. Nulla facilisi. Nullam augue libero, tincidunt nec, pretium eu, pulvinar in, dui. Morbi vitae felis. Pellentesque vel justo vel velit sagittis malesuada. Proin vehicula blandit massa. Etiam tincidunt pharetra urna. In metus est, auctor nec, blandit a, cursus nec, quam. Mauris ac metus a libero congue faucibus. Mauris mauris dolor, sodales in, cursus ut, sodales rutrum, eros. Quisque mauris eros, sagittis vitae, lobortis ut, eleifend id, nisi. + +Aenean neque. Vestibulum egestas pellentesque ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus sagittis justo vel risus. Sed pretium neque vitae urna. Pellentesque congue libero id lorem. Mauris leo lorem, blandit sit amet, convallis quis, consectetuer sed, eros. Mauris tincidunt, enim a gravida euismod, magna nulla fermentum libero, viverra egestas velit quam et tortor. Vivamus aliquet massa vitae justo. Nulla congue lacus ac elit. + +Phasellus commodo quam vel ligula. Proin non metus at eros pulvinar luctus. Mauris diam lorem, posuere quis, gravida et, tincidunt nec, ligula. Sed diam. Aliquam elit lectus, hendrerit ut, imperdiet sit amet, pretium sit amet, ipsum. Mauris vehicula nisl in dui. Curabitur eget quam ut magna elementum fermentum. Mauris scelerisque. Quisque laoreet. Etiam tempus turpis. Pellentesque augue quam, hendrerit sed, tincidunt at, pharetra at, nisl. Aliquam lacus. Suspendisse potenti. Aenean velit libero, ultrices in, lacinia eu, luctus vel, ante. Etiam dictum mi in felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce gravida dapibus nisl. Cras vitae nisl. + +Maecenas dignissim, ligula non porta cursus, enim nunc malesuada sem, eu porttitor nulla urna eu quam. Fusce eros. Aliquam eros. Nam auctor. Nulla molestie porta est. Suspendisse potenti. Vivamus molestie lorem sed erat. Sed eget ipsum. Integer aliquam pulvinar nulla. Cras aliquet sem ut nunc. Fusce faucibus tempus lectus. Cras sodales, nisi ac facilisis ultrices, eros arcu dapibus sapien, et ultrices mauris tellus non dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras cursus varius metus. Ut turpis. Vivamus eget tortor. + +Sed laoreet, velit non accumsan cursus, nunc urna posuere justo, in dictum lectus pede id ante. Cras vulputate. Cras congue dui sed elit. Proin lacus sem, ultrices at, consequat in, tempor quis, metus. Proin vel arcu. Nam euismod hendrerit elit. Ut erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed posuere. Morbi eros urna, semper at, semper non, convallis quis, velit. Maecenas orci. Vestibulum lobortis tristique metus. Vestibulum lorem nulla, sollicitudin vitae, condimentum quis, auctor ut, dui. Vivamus vestibulum magna ut nisi. Curabitur eleifend dui vel nunc. Curabitur mauris lacus, malesuada sit amet, suscipit sed, rutrum luctus, tellus. Integer facilisis urna vitae lectus. + +Aenean quam leo, lobortis quis, malesuada eu, vulputate vitae, nisl. Praesent eget eros. Ut fermentum turpis id quam. Nam tortor. Praesent nec orci. Nulla bibendum adipiscing augue. Ut commodo, magna id malesuada gravida, augue odio malesuada mi, porta malesuada elit est vitae diam. Mauris non nulla. Suspendisse tincidunt, nunc ultricies porta venenatis, mi pede tincidunt libero, eget varius ante libero ut ligula. Curabitur pretium porttitor tortor. + +Maecenas vitae elit eget nisi dapibus dictum. Nunc in libero. Nulla dictum orci eu erat auctor lobortis. Phasellus risus. Suspendisse potenti. Suspendisse potenti. Praesent adipiscing consequat elit. Integer id augue. Praesent in justo nec magna dapibus pulvinar. Duis nisl. Suspendisse ac odio. Vivamus imperdiet. Donec non velit sit amet risus dignissim congue. Nam aliquet posuere velit. Cras turpis. Morbi malesuada dignissim mi. + +Sed leo neque, varius quis, venenatis sed, pharetra sed, est. Morbi blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam semper pellentesque mi. Ut vel lorem. Nunc mi tortor, laoreet at, faucibus eu, tincidunt sit amet, erat. Duis tempor malesuada ipsum. Phasellus aliquet. Donec et elit. Pellentesque purus. Vestibulum rutrum semper nibh. Nulla facilisi. Phasellus et enim sit amet ante vestibulum vehicula. Phasellus id nisl. Donec mollis leo at eros. Mauris pellentesque neque at purus. Morbi quis dolor at ipsum scelerisque sodales. Etiam volutpat turpis a metus. In hac habitasse platea dictumst. Nunc lorem lorem, vestibulum ac, euismod eget, ullamcorper dignissim, velit. + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ultrices, nibh vel aliquam vestibulum, eros enim venenatis dui, id iaculis enim nunc vel massa. Morbi eleifend orci et massa. Aliquam erat volutpat. Nulla mollis egestas turpis. In sodales nunc eget tortor. Sed ipsum eros, tempor quis, aliquet vitae, imperdiet non, lorem. Pellentesque quis elit id mi luctus dapibus. Sed nunc arcu, rhoncus nec, convallis quis, cursus at, neque. Mauris convallis purus at erat. Pellentesque vestibulum. Vivamus fringilla elit at arcu. Nullam aliquet enim nec arcu. Nam id tortor. Nulla quis nunc. Ut arcu. Suspendisse potenti. Pellentesque ullamcorper ligula id arcu. + +Nam non libero vitae nisl scelerisque fringilla. Quisque varius ante id metus rhoncus fringilla. Nulla facilisi. Praesent eleifend porttitor ligula. Etiam quis dolor non augue commodo auctor. Donec a mi. Vestibulum tempor. Donec felis urna, auctor at, cursus dictum, gravida id, arcu. Aenean dictum malesuada dolor. Vivamus mattis. Phasellus eu pede. Fusce adipiscing justo fringilla metus. Etiam ante. Integer mollis massa quis nunc. Integer dictum neque luctus enim. + +Sed eu libero. Integer tempor ligula in velit. Ut tincidunt lacinia sem. Nullam vel risus. Sed sodales ante a dolor. Curabitur eros. Sed sodales. Sed non metus. Vestibulum elementum faucibus ante. Nulla vel nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In hac habitasse platea dictumst. Nunc nec lorem ut ipsum lacinia iaculis. Duis erat. Aliquam erat. Cras iaculis. In hac habitasse platea dictumst. + +Nullam ante. Cras vitae est. Pellentesque vel metus a ligula dapibus mattis. Duis feugiat aliquet felis. Etiam id nisl quis est dignissim condimentum. Suspendisse potenti. Morbi velit lorem, ornare quis, pellentesque vel, placerat eget, tortor. Vestibulum tincidunt molestie libero. Nulla nulla enim, malesuada id, ullamcorper vitae, dictum at, purus. Donec dignissim odio ut enim. Suspendisse at lectus. + +Praesent lobortis augue vel lectus. Ut in ligula ut felis congue suscipit. Quisque dignissim tortor ut mi. Fusce magna nisi, eleifend ac, ornare vel, porttitor vitae, quam. Vestibulum sodales justo quis turpis. Fusce urna nisi, rhoncus quis, condimentum vel, dictum eu, nunc. Fusce sed nibh vitae odio posuere adipiscing. Sed porta elit quis dolor. Nam libero nulla, auctor sed, tincidunt quis, faucibus sit amet, mi. Quisque orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam id sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vel eros. + +Vivamus luctus lobortis leo. Suspendisse vel elit a enim ullamcorper posuere. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec quis pede mattis lectus mollis adipiscing. Sed accumsan posuere erat. Praesent euismod tincidunt felis. Donec mi. Ut commodo arcu lacinia tellus. Aliquam a libero quis lectus semper viverra. Curabitur lacinia mauris at tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sit amet magna molestie orci suscipit fringilla. Fusce pretium metus non sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed hendrerit. Nulla felis. Suspendisse potenti. Aliquam blandit tristique neque. Curabitur quis erat vel nunc accumsan mollis. + +Duis sagittis, tellus ut aliquam fringilla, dolor mi ullamcorper nisl, ut tristique pede elit sed mauris. Curabitur id felis. Donec pulvinar lacus et lectus. Aliquam vulputate vulputate metus. Curabitur magna felis, adipiscing ac, accumsan vel, molestie quis, quam. Mauris elit arcu, pretium vitae, mollis sit amet, sollicitudin ut, mi. Donec imperdiet dignissim mi. Nullam sit amet tortor. Aliquam neque nulla, venenatis a, porta in, placerat tempus, lacus. Quisque vestibulum dui et lacus. Proin dignissim consectetuer purus. Etiam gravida tortor in nunc. Ut tempor tristique tortor. Sed laoreet tincidunt quam. Vestibulum porta turpis ut elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nibh dui, feugiat nec, laoreet id, malesuada eget, nisi. Ut neque massa, vehicula eu, commodo non, ultricies vitae, purus. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris euismod, felis vel tempor aliquet, tortor mauris malesuada nunc, vel fermentum sem diam id dui. Nam rutrum sapien eget odio. Aliquam sed libero non mi faucibus tempus. Fusce hendrerit, diam non volutpat rutrum, erat metus venenatis ligula, non scelerisque pede ligula vel quam. Morbi rhoncus eros ac dui feugiat elementum. Duis eu libero et tellus congue viverra. Morbi quam quam, elementum sed, ullamcorper imperdiet, commodo non, odio. Nam aliquet egestas urna. Mauris odio felis, varius eu, lacinia eu, condimentum a, lectus. Sed justo massa, pulvinar id, varius a, porttitor nec, libero. Etiam varius. Curabitur sodales, odio at posuere semper, eros nibh tincidunt lectus, vel rutrum sapien nisi in ligula. Suspendisse eget arcu. Phasellus imperdiet est ac sapien. Donec nulla tortor, placerat vel, tempus a, lobortis vel, nibh. Aliquam varius nisi. Nulla et enim. Fusce convallis laoreet lacus. + +Phasellus ipsum dolor, molestie quis, condimentum in, commodo eu, diam. Quisque bibendum lacinia dui. Nullam blandit vulputate orci. Ut lacinia massa vel augue. Aliquam gravida, quam quis imperdiet imperdiet, tellus diam pharetra erat, at pharetra lacus nibh egestas magna. Nulla sagittis lorem ut lorem. Duis condimentum, dui vitae aliquam posuere, diam quam convallis velit, ut gravida leo ipsum non risus. Ut fermentum sollicitudin erat. Donec sagittis scelerisque felis. Nunc arcu. Etiam tempus, magna sit amet suscipit euismod, eros sem rutrum dui, vitae sagittis nibh purus non lacus. Sed mollis arcu eget dolor. Donec ornare, arcu sit amet fermentum vulputate, risus enim fermentum libero, a lacinia dolor mi non velit. Etiam lobortis purus a elit. Nunc nulla dui, mattis quis, bibendum a, ultrices ac, augue. In aliquam vehicula turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Integer id nisl. Quisque dictum elementum odio. Aenean luctus. Sed eu sem a pede vulputate condimentum. Quisque magna. Donec aliquam mattis ipsum. Curabitur dictum sollicitudin sem. Aliquam pulvinar. Nunc sollicitudin risus a erat. Vivamus quis tellus sit amet nibh vestibulum consequat. Nulla pretium sollicitudin dolor. Aliquam iaculis tincidunt turpis. Phasellus ipsum leo, venenatis in, sagittis in, ornare at, nunc. + +Pellentesque ultrices, dui eu iaculis luctus, tellus augue volutpat sapien, in dignissim urna felis ut mi. Sed arcu dui, dignissim id, porttitor ut, imperdiet vitae, ante. Nulla dui sem, commodo nec, sagittis et, lacinia et, pede. Etiam eleifend dui ut nisl. Donec ante mauris, tempus sit amet, varius vitae, gravida quis, mi. In scelerisque, felis vitae viverra sagittis, velit metus ultricies neque, quis imperdiet velit elit et magna. Suspendisse potenti. Sed velit eros, euismod sed, condimentum nec, faucibus sed, sapien. Nam accumsan ligula sit amet neque. Aliquam erat volutpat. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam eu pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed eu felis sed tortor tempor fermentum. Phasellus commodo sem vel nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lectus elit, pharetra sit amet, accumsan sed, tincidunt et, mauris. Duis dapibus pharetra sem. Integer in justo. Praesent eros. Vestibulum ac ante. Aliquam scelerisque sem pellentesque nibh consectetuer sodales. Aliquam consectetuer odio. Duis lectus odio, luctus eu, commodo quis, mollis vitae, velit. Cras nec nunc non elit iaculis mattis. Aenean justo neque, sollicitudin eget, ullamcorper eget, egestas id, sem. In eu risus. Sed egestas. + +Integer at neque. Sed pretium scelerisque nulla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce ut pede. Etiam vitae quam a urna varius imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vehicula. Fusce ullamcorper nibh non erat. Quisque in neque. Praesent est. Pellentesque arcu. + +Proin posuere. Suspendisse potenti. Integer felis lacus, aliquam sed, vulputate in, mollis vel, tellus. Integer vehicula bibendum est. Nunc non dolor in tellus mattis facilisis. Integer vestibulum, augue at commodo aliquam, dui est mattis ligula, sit amet adipiscing orci sem vitae magna. Praesent enim velit, malesuada at, congue nec, luctus in, justo. Sed varius. Morbi pharetra. Donec eu massa nec tellus vulputate pulvinar. Ut commodo turpis non sem. Ut convallis ullamcorper risus. Etiam interdum pede id nisi. Cras magna sapien, suscipit a, laoreet non, rhoncus et, felis. Integer orci lorem, vestibulum dictum, ullamcorper a, porttitor et, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc et magna. Sed bibendum tellus in diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vitae tortor. Integer magna. Duis venenatis, leo ac tempor laoreet, elit nulla pharetra pede, non fermentum nunc odio a odio. Proin non velit. Sed imperdiet augue quis nisl. Integer condimentum nisl nec libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus placerat libero. Duis congue dictum magna. Aliquam dapibus bibendum enim. Nunc eleifend pede vel ipsum. + +Etiam vitae velit. Mauris erat nunc, malesuada ut, feugiat ac, placerat condimentum, augue. Nam volutpat. Aliquam vehicula ipsum id odio. Vivamus sollicitudin turpis id sapien. Fusce a felis vitae odio convallis blandit. Curabitur vitae eros id eros porta pretium. Nulla in magna eget urna lacinia convallis. Aliquam mattis venenatis purus. Sed sed mi eget erat tristique porta. Donec auctor dolor a erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In nec ligula. Nunc eleifend. Vestibulum quis nisi eget elit porttitor congue. Maecenas faucibus, magna eget adipiscing tincidunt, dolor ante malesuada elit, non elementum lacus turpis in pede. + +Ut malesuada mi nec metus. Praesent auctor augue ac nisl ultricies facilisis. Nam purus sapien, pellentesque dignissim, posuere eu, cursus id, diam. Quisque sollicitudin, elit a pellentesque scelerisque, lorem risus auctor quam, quis consequat tellus neque id urna. Suspendisse diam tortor, eleifend dignissim, egestas ut, luctus in, ante. Duis ante. Maecenas luctus. Curabitur cursus pharetra urna. Maecenas imperdiet, erat non elementum euismod, tortor odio euismod lectus, ac facilisis sem nibh vitae nulla. Nunc gravida. Morbi sollicitudin odio quis lacus. Aliquam a nibh non urna porta imperdiet. Aliquam erat volutpat. In iaculis lacinia velit. Sed libero lacus, tristique eu, lacinia ac, aliquet eget, urna. + +Etiam at nisl. Phasellus faucibus luctus lectus. Ut placerat vulputate dolor. Phasellus vel velit. Morbi viverra. Phasellus orci. Integer dignissim mattis mauris. Pellentesque posuere leo posuere quam. Quisque nec magna at diam viverra pellentesque. Suspendisse velit arcu, ultricies quis, congue a, venenatis eget, lacus. Integer sagittis hendrerit dolor. Fusce tincidunt ante a sem. + +Maecenas consectetuer, justo sed rhoncus venenatis, nibh arcu rutrum dolor, sed condimentum libero libero et ipsum. Vivamus mattis justo ut lorem tincidunt lobortis. Ut non velit id neque aliquet accumsan. Sed tempus viverra nulla. Curabitur ullamcorper, neque quis dapibus scelerisque, felis diam gravida orci, non cursus quam neque vitae elit. Etiam pharetra tincidunt lacus. Duis euismod fringilla est. Etiam ornare tincidunt lectus. Proin in turpis. Nunc blandit blandit turpis. Aenean ut augue. Duis orci justo, tincidunt eu, rutrum sed, rutrum et, turpis. Curabitur facilisis odio in ante. In hac habitasse platea dictumst. Sed eros est, pellentesque at, tincidunt eu, ultrices quis, metus. Morbi sit amet justo. Maecenas ac arcu. Mauris dignissim. + +Pellentesque ultricies rutrum orci. Aenean ornare. Vivamus eu risus vel mauris lobortis dictum. Sed et turpis auctor mi rhoncus pulvinar. Sed nec nunc a purus tempor viverra. Pellentesque suscipit. Donec tristique risus non nibh. Etiam nisl magna, sollicitudin ut, ultrices sit amet, egestas eu, nulla. Aliquam erat volutpat. Vestibulum pharetra. Sed egestas, metus sit amet lobortis consequat, erat elit imperdiet libero, eu interdum quam massa eget dolor. Suspendisse vitae odio. Proin blandit mauris iaculis metus. + +Vivamus vestibulum. Etiam et nisl. Aliquam in diam vel elit placerat suscipit. Duis sodales purus ac nibh. Nulla in odio eget enim luctus blandit. Curabitur ultrices ipsum non neque egestas eleifend. Sed turpis. Proin consectetuer. Vivamus mattis. In aliquet. + +Nunc id eros. Donec venenatis, nulla et mattis luctus, ante leo semper justo, non adipiscing odio risus sed lacus. Praesent vitae risus congue libero congue tempus. Phasellus ac eros. Nulla vehicula, lorem in aliquet suscipit, arcu erat egestas sem, quis lobortis quam ante eu massa. Curabitur non massa. Sed bibendum lacinia odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus volutpat blandit lacus. Proin porta, tellus ut auctor laoreet, lectus eros fermentum lectus, id sagittis arcu justo in turpis. Phasellus consequat. Nam pellentesque, mi id viverra convallis, nunc libero placerat leo, eleifend porta sem nisl vitae sapien. Pellentesque ligula libero, tristique non, porttitor rutrum, porttitor non, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer dictum tellus a tortor. Vivamus felis nunc, molestie non, rhoncus quis, pharetra id, dui. Donec risus metus, fringilla vel, aliquet eu, placerat id, neque. + +Suspendisse ipsum. Vivamus lectus. Sed viverra, massa eget convallis mattis, quam turpis consectetuer nunc, eget posuere magna sem id velit. In nec mauris. Aenean a purus sed quam lobortis fringilla. Proin ultricies lacinia ante. Sed adipiscing erat quis velit. Nullam vitae nisl id justo sollicitudin molestie. Nulla facilisi. Sed nec urna sed nisl fringilla dapibus. Nulla at diam. Aliquam eget nibh. Nunc ac nisi sit amet tellus egestas tempus. Nam scelerisque urna et neque. Donec est orci, sagittis non, vulputate a, commodo et, augue. Ut dapibus tortor. Ut nunc. Donec dictum dapibus odio. Nam ultricies ullamcorper ligula. Pellentesque accumsan varius leo. + +Morbi euismod laoreet erat. Vivamus quis ipsum. Morbi euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel purus. Nullam at magna. Curabitur lacus lorem, iaculis quis, dapibus non, volutpat vel, nulla. Donec ut arcu rhoncus dolor pretium dictum. Nullam vel metus. Ut arcu. Pellentesque nisi nunc, placerat eget, tincidunt vel, pharetra non, nunc. Integer tincidunt ultricies lectus. Integer semper, purus sed ultrices feugiat, nulla pede sollicitudin erat, vel auctor nulla ipsum vel lectus. Aenean mi. + +Nullam sed nisi et arcu imperdiet fermentum. Mauris nec metus. In ac dolor. In mi arcu, congue ac, pharetra nec, scelerisque sit amet, magna. Curabitur lacus. Curabitur et elit. Aliquam ullamcorper nunc eu elit. Sed convallis dolor at velit. Vestibulum dapibus, augue id consectetuer placerat, nunc massa blandit sapien, id aliquam elit nisi id mi. Phasellus sapien est, gravida eu, bibendum ut, adipiscing quis, est. Ut molestie quam vitae odio. Donec quis risus id erat faucibus sollicitudin. Nam id felis. Mauris sed enim vitae leo accumsan pretium. + +Nam justo. Donec turpis nisl, commodo et, interdum ac, consectetuer non, massa. Fusce sem metus, laoreet nec, posuere id, imperdiet in, velit. Donec vulputate justo eget turpis. Nulla pede. Morbi tincidunt. Fusce aliquet, quam et aliquam fringilla, ante ante iaculis dui, nec aliquam arcu purus sed erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus suscipit quam et est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; + +Integer sed tellus. Sed sed velit ultricies leo rutrum laoreet. Sed non eros ac purus sagittis feugiat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed hendrerit ligula sit amet nibh. Maecenas turpis. Morbi consectetuer, dolor et adipiscing imperdiet, ante neque feugiat dolor, at porta quam neque quis ligula. Mauris semper velit sit amet ipsum. Pellentesque tempus, purus in rutrum consequat, enim erat vehicula massa, id accumsan leo sapien nec purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In dolor. Integer facilisis libero sit amet pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut varius aliquet enim. Nulla facilisi. Curabitur consectetuer, odio eu pretium tincidunt, nunc nisi aliquet neque, vel imperdiet elit massa sit amet turpis. Pellentesque tempus, orci volutpat blandit fringilla, odio sem posuere ante, vitae bibendum urna lorem vitae eros. Praesent viverra rhoncus arcu. Sed auctor, est sit amet mollis mollis, quam quam gravida sapien, in commodo metus nulla auctor enim. Donec facilisis. + +Proin tincidunt, sapien eget ultricies adipiscing, est odio dictum arcu, ut mollis erat dui sit amet velit. Morbi est sem, interdum at, congue a, elementum vitae, metus. Suspendisse id augue. Mauris enim sem, pulvinar eget, tempus a, tempus sit amet, sapien. Fusce vestibulum consectetuer dui. Pellentesque erat. Sed dignissim placerat odio. Maecenas semper rhoncus lectus. Phasellus pretium. Duis libero elit, eleifend nec, egestas ut, cursus sed, felis. Nam nisl arcu, aliquet et, facilisis eu, luctus ut, risus. Etiam ultrices, dolor sed volutpat malesuada, turpis arcu imperdiet tortor, euismod commodo libero massa ut quam. Integer molestie purus non elit. Ut venenatis semper tortor. Etiam bibendum egestas ipsum. Mauris sollicitudin sem nec nibh. Nulla pretium metus eu metus. Pellentesque sit amet sem. + +Suspendisse ac nisi. Ut leo. Vestibulum hendrerit pretium dolor. Nunc feugiat malesuada purus. Cras et nibh. Curabitur nunc erat, malesuada vitae, laoreet ac, ultricies in, purus. Vivamus tellus arcu, sodales eu, facilisis a, lacinia nec, nunc. Pellentesque id velit. In eu nibh. Nunc nec erat. Sed dictum neque ut nisl. + +Morbi lectus tellus, tincidunt ac, porttitor ac, tristique in, eros. Donec luctus luctus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ut est et enim scelerisque accumsan. Donec ligula felis, lacinia quis, pellentesque in, semper vestibulum, elit. Mauris eget orci a felis congue vehicula. Ut sollicitudin. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam id dolor ut lorem dignissim venenatis. Suspendisse vitae sapien. Proin non magna ut eros viverra pulvinar. Donec quis odio. Nullam non arcu vel lorem suscipit aliquam. Aliquam rutrum turpis in leo. + +Ut luctus nibh tristique erat. Suspendisse bibendum odio vitae tortor. Donec lacinia. Cras sodales felis luctus nulla. Nam eleifend sagittis ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse vel neque. Morbi aliquet vehicula magna. Aenean at odio. Duis pellentesque magna. Nulla at tortor ut diam dictum faucibus. Mauris quis velit. Donec non tellus vitae lorem fringilla porttitor. Fusce ut sapien quis tortor feugiat sagittis. Donec viverra sem vitae sapien. Praesent sodales, lacus in fringilla viverra, odio augue adipiscing urna, vitae interdum ante sem non nisi. Nullam tortor lorem, eleifend ac, mollis non, laoreet ac, risus. Integer ornare leo sed justo. Quisque cursus, sem non facilisis bibendum, nisi mi varius felis, fermentum feugiat lorem eros laoreet risus. + +Quisque sit amet est et lorem vehicula lacinia. Donec nec tortor. Cras odio. Nam scelerisque vulputate urna. Praesent dui. Etiam nec nisl lobortis ipsum aliquet tempus. Maecenas pretium sollicitudin mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus augue massa, congue eget, convallis eget, tristique sit amet, eros. Sed consequat nisi eu felis. Pellentesque justo. Suspendisse non augue. In dignissim lobortis mauris. Mauris sagittis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + +Sed adipiscing. Donec a tellus vitae est cursus vehicula. Nam ante sem, sodales id, fringilla vel, condimentum vel, nulla. Quisque sodales. Etiam imperdiet elit id odio. Aliquam erat volutpat. Maecenas porta tempor arcu. Nulla sem augue, pellentesque ac, consequat ut, condimentum euismod, risus. Sed aliquam tincidunt mi. In interdum lobortis orci. + +Sed vehicula hendrerit purus. Etiam a diam. Curabitur convallis. Suspendisse a nisi. Donec id magna in quam sollicitudin ultricies. Donec viverra. Quisque volutpat est sed sem. Aliquam justo. Vestibulum tortor massa, porttitor sed, varius quis, iaculis quis, odio. Aliquam eget neque. + +Mauris nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum eu quam in neque ultrices pellentesque. Cras in dolor quis quam varius hendrerit. Aliquam nisi lacus, lobortis eu, convallis sit amet, facilisis ut, mi. Aliquam at neque. Cras sagittis elementum justo. Vestibulum ut lectus aliquet purus malesuada volutpat. Duis at lacus adipiscing libero tincidunt vestibulum. Morbi a libero. Cras purus. Morbi ut augue et purus interdum scelerisque. Integer a dui. In hac habitasse platea dictumst. Duis pharetra metus eget mauris. Aliquam interdum ullamcorper massa. + +Etiam ornare. Nullam euismod. Aenean consequat gravida ligula. Aliquam est. Proin vitae lacus. Praesent a eros sit amet dui luctus commodo. Phasellus vehicula arcu eget dolor. Praesent fermentum congue leo. Aliquam volutpat purus ut lorem. Fusce hendrerit enim at leo. Aliquam rhoncus nisl. Vivamus dictum egestas mi. Suspendisse pellentesque bibendum dolor. Pellentesque tincidunt, turpis semper pellentesque condimentum, ipsum metus sodales ligula, id volutpat diam turpis ut elit. + +Praesent sed lacus. Nam eleifend molestie mauris. Donec dapibus fermentum massa. Donec viverra faucibus purus. Curabitur congue, libero vitae viverra pellentesque, diam velit sodales enim, sed suscipit lectus nisi nec neque. Vestibulum malesuada, lacus at cursus congue, velit lectus tristique dolor, sit amet sodales neque ipsum a libero. Vestibulum et quam. Curabitur placerat. Curabitur nunc arcu, euismod nec, vulputate hendrerit, aliquet eget, quam. Curabitur vel enim. Suspendisse potenti. + +Nunc consequat orci ut lacus. Fusce velit dolor, dapibus sed, blandit sit amet, rhoncus id, risus. Duis urna nibh, scelerisque quis, dapibus a, scelerisque sed, nibh. Donec luctus. Ut eu mauris cursus diam lacinia rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam vehicula molestie justo. Maecenas imperdiet pede sed mi. Suspendisse nulla dolor, hendrerit eget, hendrerit id, dictum vel, leo. Duis accumsan. Curabitur in felis. Nunc lorem. Ut leo dolor, laoreet nec, vulputate at, eleifend in, nulla. Quisque nunc purus, varius eget, accumsan nec, aliquet et, nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras adipiscing viverra dolor. Mauris porttitor ultrices purus. Nulla facilisi. Praesent faucibus ante vitae mauris. + +Praesent lacinia lectus sed nisl. In tempus congue mauris. Integer facilisis ornare enim. Nulla id massa. Donec commodo diam at tellus. Nam dapibus viverra est. Nam tellus. Praesent a libero. In faucibus est eget nibh. Nulla eros orci, imperdiet non, blandit non, tempor eget, mi. Pellentesque convallis. + +Quisque eget mi ac leo euismod faucibus. Phasellus rhoncus purus id dui. Vestibulum malesuada eleifend ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque blandit mattis odio. Suspendisse consequat, lectus ac semper sollicitudin, mi velit dictum augue, ac tempus dolor erat sit amet dui. Proin hendrerit, felis quis volutpat posuere, diam odio malesuada odio, a interdum orci diam quis sapien. Pellentesque odio odio, viverra vel, gravida eu, molestie sed, nulla. Phasellus mauris pede, commodo ut, euismod eu, hendrerit eu, est. In hac habitasse platea dictumst. Nulla elementum lacus eu augue. Sed erat. Proin porta. Maecenas quis mi. Phasellus at enim ac justo gravida ultrices. Cras leo. + +Integer ut arcu. Donec sed magna. Proin felis. In iaculis, ligula id fringilla pretium, nibh diam accumsan tellus, eget accumsan metus dui varius turpis. Phasellus orci metus, eleifend sed, tempor ac, scelerisque ac, urna. Integer viverra neque a mauris. Mauris porttitor dolor eu velit. Integer odio elit, vestibulum ut, volutpat id, rhoncus commodo, urna. Etiam placerat pharetra erat. Ut tempor est. Integer dignissim blandit tellus. Morbi nibh dolor, scelerisque id, commodo malesuada, mattis at, mi. Cras tincidunt commodo purus. In tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ullamcorper. Ut hendrerit. Morbi ultrices. + +Praesent iaculis, eros ac egestas sodales, urna leo fermentum ligula, sit amet aliquam velit sem non purus. Donec rutrum arcu quis purus. Nam posuere, lacus at consequat placerat, nulla pede posuere orci, non euismod turpis dui quis nisl. Proin porta adipiscing nibh. Donec tristique dolor at tellus. Donec neque massa, auctor id, faucibus vitae, ullamcorper vel, nisi. Proin molestie neque sed massa. Nam tempor. Morbi aliquam sapien at tellus. Fusce quis risus et mi pretium pulvinar. Fusce sit amet ligula. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse eu enim et felis scelerisque lobortis. Praesent bibendum. Vivamus vehicula. Integer at nibh sed velit rhoncus molestie. Cras lacus. Sed ullamcorper eros vel erat. Fusce eu tortor sit amet diam euismod sagittis. Nunc quis lacus id nibh convallis varius. Suspendisse vitae mi. Vestibulum tristique. Donec malesuada ipsum id neque. Nullam sed lacus. Duis egestas, justo ut congue ornare, augue sapien luctus diam, at accumsan erat sapien ut libero. Phasellus vel nulla. Suspendisse arcu tellus, porttitor a, pharetra faucibus, aliquam sit amet, massa. Nulla porttitor tincidunt lorem. Nunc dolor odio, sagittis in, lobortis vel, volutpat sed, nibh. + +Quisque blandit leo ut sapien tempus facilisis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean ultricies porttitor justo. Fusce rutrum eros ut urna. Proin quis quam eget dui aliquam accumsan. Donec suscipit eleifend elit. Pellentesque mattis, felis sodales iaculis imperdiet, lacus sem convallis augue, sit amet aliquet arcu purus fringilla risus. In eu odio id magna pharetra ornare. Aliquam interdum pulvinar ipsum. Sed neque. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam sit amet nisi. Ut at augue. Mauris volutpat blandit ligula. Nulla eu metus. Vestibulum eget elit. Praesent posuere. Vestibulum id sem non lectus mollis tincidunt. Aliquam id felis at ante ornare tempor. Nulla lacus turpis, feugiat vitae, cursus quis, consectetuer non, mauris. Fusce lacus massa, porttitor ut, molestie ut, venenatis a, lorem. Praesent sit amet orci. Mauris rhoncus felis vitae felis adipiscing imperdiet. Maecenas mollis diam nec leo. + +Fusce enim ipsum, ultrices eu, molestie id, elementum id, sapien. Integer a urna. Nam velit libero, venenatis eget, tempor sit amet, feugiat vitae, ante. Fusce nunc. Sed semper nisl nec risus. In sed libero. Proin tortor neque, tincidunt ac, tempor ac, pharetra quis, velit. Duis lectus augue, ultricies vel, consequat id, iaculis id, ante. Vivamus auctor metus a ante. Curabitur arcu nisi, facilisis at, laoreet in, consectetuer sed, mauris. Quisque placerat diam sed dui. Vivamus pretium condimentum lorem. Curabitur laoreet. Aenean orci ligula, cursus eget, lacinia non, faucibus vel, lorem. + +Aliquam erat volutpat. Curabitur eros dolor, congue a, condimentum sed, luctus ut, nibh. Maecenas non tortor nec turpis commodo pellentesque. Praesent euismod placerat mi. Suspendisse potenti. Phasellus ut neque vitae orci mattis iaculis. Integer eget tellus. Donec at ante. Nam lacinia leo eget erat. Maecenas euismod magna congue tortor. Morbi nec massa eu enim malesuada sollicitudin. Sed accumsan. Nullam ipsum. Ut odio. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque id velit. Nam odio sem, aliquet ut, tempus sit amet, euismod et, nunc. + +Pellentesque libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent mauris nunc, varius ut, convallis molestie, luctus sit amet, leo. Sed dictum lorem et arcu. Nunc venenatis pellentesque massa. Nulla facilisi. Phasellus in tortor eget risus scelerisque vulputate. Sed nibh elit, sagittis ac, condimentum nec, convallis et, justo. Fusce volutpat metus. Nunc auctor. Vestibulum leo eros, pellentesque ac, mollis ultrices, rhoncus non, dolor. Mauris vehicula placerat nisl. Vestibulum bibendum, arcu quis congue elementum, velit nunc eleifend turpis, id luctus risus nisl sit amet tellus. Phasellus pede neque, blandit non, commodo vitae, ultricies eget, magna. Aliquam erat volutpat. + +Nulla facilisi. Aliquam ac ante. Cras risus. Morbi mauris lacus, posuere eu, blandit et, pharetra at, mi. Proin ac purus. Duis cursus nisl rutrum quam. Aliquam a odio non magna pellentesque ultricies. Maecenas ac massa quis sapien ullamcorper tempus. Cras cursus velit sed sapien. Proin nulla. Vivamus sodales aliquam nibh. Etiam et erat ut ante lacinia euismod. Fusce nisi. Proin quis nulla. + +Quisque venenatis, eros sed laoreet sollicitudin, orci ante pellentesque nisl, sit amet viverra quam erat non risus. Cras eget libero. Sed elit magna, semper eu, fringilla in, dignissim sodales, erat. Vivamus feugiat sem vel dui. Donec convallis sollicitudin diam. Cras sed purus. Donec felis eros, semper eget, tempor consectetuer, sagittis quis, nisl. Duis in ante. Cras non turpis. Nulla tempor velit aliquet turpis molestie placerat. Proin elementum fermentum mauris. Vivamus sed orci lacinia dui placerat venenatis. Vestibulum feugiat, tellus in volutpat rutrum, magna nisi ullamcorper eros, id pulvinar neque erat ut lacus. Vivamus sed augue. Nulla facilisi. Maecenas ante augue, elementum ut, sodales vitae, condimentum nec, lorem. Duis pede orci, fringilla at, eleifend nec, pretium in, erat. Nam sagittis, turpis vitae convallis pharetra, odio sem scelerisque lacus, nec lobortis dui diam vel eros. In semper gravida neque. + +Integer nunc. Ut pretium ipsum sit amet elit. In nec arcu. Sed vestibulum vulputate ipsum. Pellentesque tincidunt. Nulla gravida dolor in tellus. Cras vehicula, dolor ut pellentesque aliquam, erat enim auctor massa, vehicula lobortis odio eros quis quam. Proin dapibus neque in enim. Proin elit. Integer rhoncus tincidunt elit. Fusce lorem metus, semper ac, volutpat vitae, facilisis ut, tellus. Donec vel turpis vitae nisi pharetra porttitor. Maecenas tortor. Fusce mi. Nullam nec turpis. Sed sodales vestibulum nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Pellentesque dolor dolor, laoreet eu, aliquet quis, scelerisque sit amet, arcu. In hac habitasse platea dictumst. Nullam cursus urna eget elit. Quisque blandit sapien ac ante. Proin nulla eros, gravida volutpat, sodales vel, mollis eu, massa. Nulla tristique sollicitudin nisl. Curabitur vitae lorem vitae velit egestas ornare. Aenean eget eros. Aliquam erat volutpat. Fusce a urna id odio aliquet convallis. Curabitur sit amet nisl posuere leo posuere dapibus. Duis metus erat, luctus vel, rhoncus at, convallis sit amet, enim. Vivamus hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam eget elit. + +Nullam a nunc. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In metus urna, tincidunt et, lacinia sit amet, lobortis vitae, ligula. Proin et mauris vitae mi accumsan pellentesque. Etiam quam purus, hendrerit sed, feugiat vitae, euismod eget, tortor. Ut aliquam magna vitae justo. Suspendisse non justo vel velit condimentum tempus. Duis tempus ipsum vitae tellus. Proin in massa. Etiam ullamcorper dictum tellus. Proin aliquet felis at leo laoreet pulvinar. Vestibulum arcu purus, malesuada sit amet, cursus eu, placerat sit amet, nunc. Nam massa odio, sollicitudin in, adipiscing a, aliquam nec, risus. Aliquam blandit hendrerit libero. Mauris gravida. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur a nibh. Ut interdum fermentum neque. Pellentesque sed nunc. Mauris vehicula nisi et nunc. Praesent lorem. Donec semper. Integer eu lacus in est aliquam hendrerit. Vestibulum eget neque. Sed semper luctus velit. Curabitur nibh augue, congue eu, hendrerit id, congue et, enim. Integer placerat aliquam lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae eros. Donec vel nisl. + +In vestibulum facilisis urna. Ut risus. Mauris pharetra. Pellentesque mattis. Integer suscipit aliquam ipsum. Duis blandit, sapien et ultricies condimentum, felis mi elementum pede, nec sagittis metus mauris quis quam. Quisque accumsan arcu vel nulla. Cras sem sapien, porttitor id, ultricies sagittis, luctus eu, nulla. Integer quis eros. Morbi sed urna a tellus vehicula vulputate. Etiam nec augue eget felis semper tristique. Quisque ut dolor vel risus dictum consequat. Sed eget dolor sed nunc lacinia aliquet. Suspendisse ac tortor in ipsum posuere venenatis. Sed eget erat. Nulla faucibus. Duis laoreet, massa porttitor aliquet egestas, ipsum lectus rhoncus quam, in adipiscing eros sem ut tellus. Pellentesque feugiat tempus quam. Vivamus id dolor eget sapien consectetuer tempor. Aliquam erat volutpat. + +Nulla iaculis fermentum libero. Curabitur faucibus, massa malesuada cursus tincidunt, erat sem eleifend mauris, sed fringilla mi ante ac purus. Duis elementum lectus. Nunc ornare arcu eu tortor. Vestibulum vel dolor at purus lacinia fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas tincidunt, eros a egestas pellentesque, risus risus dictum libero, id aliquet metus justo in massa. Proin a tellus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed purus. Sed non pede. Aenean massa sapien, sodales sit amet, consequat dictum, eleifend vitae, tortor. Donec ultrices lacinia elit. + +Morbi adipiscing sodales dolor. Ut ullamcorper ultricies est. In venenatis tempus augue. Suspendisse tortor dolor, accumsan et, suscipit a, tincidunt ut, libero. Aliquam scelerisque magna sed felis. Quisque ut nunc a magna vulputate placerat. Aliquam rhoncus vehicula dui. Sed tortor. Nullam sit amet diam. Nunc sed eros. Sed et odio tincidunt elit gravida convallis. Curabitur quis tortor a lacus semper varius. Mauris at augue non mi sollicitudin aliquam. Integer ullamcorper. Pellentesque suscipit quam non purus. Aliquam ac eros at arcu ullamcorper consectetuer. Suspendisse pretium mattis leo. + +Duis at nunc. Sed dolor est, varius ac, porta et, tincidunt hendrerit, risus. Vivamus ut magna. Praesent ut mauris. In purus lacus, mattis sed, vestibulum nec, tempor at, nisl. Cras ullamcorper venenatis tellus. Ut dolor. Maecenas malesuada, pede a pulvinar mattis, arcu diam vehicula risus, quis porttitor augue massa in velit. Nunc congue. Morbi velit metus, rhoncus et, aliquam consectetuer, ultricies malesuada, ligula. Sed velit nisl, sagittis vitae, pharetra a, posuere sed, massa. Nulla facilisi. In varius, ligula id lobortis sodales, augue orci fermentum tellus, eu pulvinar risus ligula a sapien. Morbi laoreet ipsum non mi. Nam cursus lorem ut mi. Vivamus magna enim, posuere non, semper quis, sodales eu, arcu. Etiam mi purus, pretium feugiat, varius sed, pellentesque eget, ligula. In leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vitae orci eu orci sollicitudin feugiat. + +Praesent purus massa, euismod vitae, tempus nec, consequat hendrerit, metus. Aenean felis est, egestas vitae, accumsan eget, pellentesque in, sapien. Duis dapibus pede non sapien. Nunc urna. Integer vel libero. Duis augue arcu, dapibus non, facilisis vitae, posuere ut, eros. Donec vitae nunc sit amet arcu imperdiet dictum. Morbi eleifend, lorem eu consectetuer vestibulum, diam nunc ornare arcu, ac tempor felis dolor eget eros. Phasellus massa sem, sollicitudin ac, sodales gravida, luctus a, quam. Nam neque quam, viverra at, venenatis quis, sagittis non, enim. + +Nulla facilisi. Pellentesque egestas lacinia est. Sed tincidunt, pede sed tincidunt vestibulum, urna dolor adipiscing purus, vitae fringilla felis elit in nibh. Nulla sed nisi. Mauris suscipit scelerisque arcu. Etiam non enim vel eros accumsan malesuada. Nunc tincidunt commodo mauris. In tincidunt risus quis urna. Nulla diam tortor, aliquet et, tincidunt quis, sollicitudin ac, tortor. Cras nisl neque, vulputate suscipit, molestie quis, pulvinar at, nulla. Nullam ac metus nec odio posuere varius. Cras sed pede nec dui posuere bibendum. Duis euismod ullamcorper libero. Aliquam faucibus pulvinar turpis. + +In ut neque id nunc feugiat commodo. Curabitur dignissim, felis at sollicitudin lacinia, enim elit suscipit neque, sed luctus lorem ipsum in leo. Duis dapibus, odio quis auctor commodo, nisl odio mattis tellus, nec tincidunt turpis diam in arcu. Curabitur a sem. Nullam volutpat magna. Pellentesque sagittis, neque consequat pretium cursus, dolor lacus consectetuer arcu, sed laoreet est urna et metus. Suspendisse placerat, dui a porta tempor, lorem dui lobortis neque, sed venenatis diam enim id eros. Etiam et nisl non lectus faucibus consectetuer. Morbi scelerisque, sem nec tempus ullamcorper, ipsum diam feugiat lorem, a fringilla sapien elit quis nibh. Nullam diam urna, viverra sed, pharetra rhoncus, tincidunt vel, orci. Integer accumsan mattis erat. Nam dictum. Mauris nec leo. Nulla iaculis. Nulla nisl mi, dapibus quis, vehicula a, cursus eget, odio. + +Phasellus dapibus euismod nibh. Vivamus imperdiet ante in ligula. Pellentesque accumsan. In imperdiet, dui a auctor fringilla, metus nisi cursus dolor, vel luctus ligula lorem vitae mauris. Praesent mattis vestibulum elit. Aliquam enim lacus, pulvinar non, lacinia sit amet, eleifend non, velit. Vestibulum ac leo. Mauris imperdiet justo ac lectus. Sed molestie lectus sed dui. Sed fermentum tempus mauris. Nam ornare orci ac tellus. Ut malesuada, lacus id lacinia accumsan, diam elit adipiscing metus, et bibendum sapien nibh blandit orci. Suspendisse ipsum tellus, sagittis quis, vestibulum non, vulputate eu, eros. Praesent at nulla id pede scelerisque ultricies. Cras blandit pretium tellus. Maecenas dapibus condimentum augue. Phasellus tincidunt pharetra lorem. Morbi non eros. Sed tempor, nisl a tincidunt tincidunt, eros diam dictum sem, vel dignissim ante diam sed magna. Praesent non ligula id metus molestie consectetuer. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse vel mi. Curabitur ante nulla, rutrum a, convallis vel, vehicula ac, nunc. Nunc sagittis, enim sit amet auctor rutrum, mauris arcu vulputate neque, et euismod est felis quis ante. Vestibulum turpis tellus, hendrerit in, lacinia commodo, ullamcorper gravida, risus. Mauris rhoncus lacinia risus. Maecenas sollicitudin erat vitae nunc. Praesent pretium pellentesque augue. Donec interdum. Praesent ac eros vitae erat lobortis fringilla. Aenean consequat tellus. Nulla accumsan bibendum felis. Maecenas pretium ante id nisi. Aenean mi arcu, semper sed, mattis eu, venenatis sit amet, arcu. Donec aliquet euismod leo. Proin magna justo, tristique a, semper ac, sollicitudin a, ligula. Morbi velit. Aliquam vel nisi. + +In a lorem ut nunc feugiat congue. Donec fermentum bibendum dui. Proin varius est quis velit. Donec aliquet sem accumsan mi. Sed placerat. Nullam ac nisi a massa lobortis suscipit. Nunc id leo. Aliquam et massa. Nullam vestibulum elementum metus. In consectetuer nisi vel justo. Maecenas eget purus sed massa varius pellentesque. Phasellus faucibus felis quis felis. Aenean odio arcu, blandit quis, facilisis in, imperdiet eu, lorem. Nam posuere pulvinar mi. Fusce tristique, mauris et consectetuer ultricies, mauris lectus tempor justo, at fringilla est est sed nisi. Quisque faucibus. Sed in tortor tincidunt est lacinia iaculis. Maecenas a massa. Pellentesque a nibh at purus porta hendrerit. + +Nullam turpis. Fusce ac sem sed odio pellentesque imperdiet. Curabitur in arcu. Praesent lacus lacus, feugiat id, pulvinar in, tincidunt sed, neque. Maecenas viverra odio eget tortor. Integer aliquam, lorem rutrum venenatis dignissim, ligula magna malesuada arcu, vel feugiat lorem ipsum quis massa. Morbi ante. Vestibulum mauris libero, ullamcorper quis, ultrices quis, facilisis non, massa. Maecenas imperdiet. Aliquam erat volutpat. Pellentesque dignissim gravida lectus. In nibh odio, auctor eget, dapibus quis, dignissim venenatis, arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis pellentesque ligula quis massa. Curabitur condimentum, justo eget ornare luctus, lorem ligula sagittis pede, a porta nunc nunc in neque. Quisque felis mauris, condimentum vitae, auctor vitae, tincidunt quis, pede. Nunc lacinia ante in leo. Pellentesque libero. Aenean a ligula et nunc vestibulum consectetuer. + +Fusce ornare. Praesent id urna. Integer venenatis, quam non sagittis accumsan, ante nibh sagittis augue, sollicitudin adipiscing dolor velit eu erat. Proin quis enim eu purus vehicula aliquam. Nulla vel enim vel elit sollicitudin fringilla. Aliquam erat volutpat. Sed suscipit felis ut turpis. Etiam rutrum risus imperdiet est. Aliquam a tellus at tellus commodo dapibus. Mauris rutrum magna et odio. In at dolor. Curabitur vehicula lectus in tortor. Fusce justo purus, luctus vitae, mollis in, pharetra ac, purus. Nullam posuere interdum justo. Curabitur vitae lacus vel leo congue pulvinar. + +Aenean eleifend nibh varius tortor. Suspendisse vel eros. Proin nec diam a tortor ultrices ornare. Aliquam scelerisque feugiat justo. Vivamus ante urna, adipiscing vitae, porttitor eu, sodales et, felis. Suspendisse potenti. Curabitur ac massa in nisl sagittis mollis. Nam quam ligula, consectetuer eget, iaculis at, varius eu, leo. Duis dolor ligula, tincidunt at, ullamcorper sed, accumsan aliquam, ligula. Phasellus vulputate, lorem at tincidunt pharetra, risus lectus lacinia magna, quis rutrum enim magna at sem. In hac habitasse platea dictumst. Duis id sem a mauris sollicitudin tincidunt. Etiam eu purus eu arcu fringilla adipiscing. Vivamus ornare tempus diam. Proin turpis quam, lacinia non, egestas at, commodo eget, pede. Praesent vulputate risus in est. Nulla facilisi. + +Ut elementum lacinia purus. Proin vitae arcu ac nulla convallis aliquam. Nulla congue, libero id pellentesque mattis, quam lectus porttitor diam, a scelerisque dui libero in sapien. Nullam felis diam, vehicula vel, molestie ut, vestibulum aliquam, sapien. Donec convallis, est ut elementum volutpat, mauris ipsum gravida sem, commodo facilisis sapien lectus semper lectus. Quisque porttitor eros ut nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam mattis risus sed odio. Vestibulum et odio. In hac habitasse platea dictumst. Nam tristique massa ut ligula. Quisque nibh tellus, vehicula sit amet, adipiscing at, convallis nec, ligula. Vestibulum pretium, mi nec fringilla bibendum, dui nunc sodales pede, a semper magna nibh non diam. Donec massa nunc, viverra vel, consectetuer porta, dapibus non, ipsum. Duis nisl mauris, cursus vel, semper non, sollicitudin bibendum, felis. Vestibulum eu neque. + +Cras nec dolor. Donec laoreet tempus lectus. Cras sed tortor interdum lacus eleifend dignissim. Maecenas sit amet elit. Nullam quis dolor vel dui pharetra luctus. In sit amet quam sit amet pede ultrices ultrices. Maecenas diam. Integer urna. Curabitur dictum, velit sed placerat suscipit, erat turpis fermentum justo, sed interdum neque sem et nibh. Vivamus consequat convallis magna. Nam aliquam, est ac bibendum commodo, magna est dictum mi, vitae malesuada elit magna vitae odio. Maecenas tempor vulputate tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus dui. Etiam accumsan pede congue tortor. + +Morbi tempor libero ac lorem. In aliquet varius magna. In arcu. Phasellus odio. Fusce tincidunt aliquet felis. Quisque velit. Sed luctus. Aliquam feugiat fringilla mi. Aliquam molestie viverra risus. Proin arcu. Vestibulum lobortis tempus nisi. Praesent a arcu in velit viverra rutrum. + +In sed lectus. Donec risus dolor, blandit sit amet, elementum convallis, pharetra quis, pede. Integer ornare. Aenean egestas dapibus justo. Sed quam leo, posuere at, elementum vitae, commodo eget, est. Aliquam molestie rhoncus enim. Curabitur iaculis ultrices pede. Morbi aliquet rutrum lacus. Aliquam quam. Sed commodo, turpis in pharetra posuere, mi risus imperdiet erat, a vestibulum massa tellus vehicula sem. Mauris fringilla ultrices nunc. Nam nisi enim, eleifend sit amet, ultrices sed, fermentum non, augue. Proin congue lobortis nisi. Maecenas hendrerit. Nam sed nisl. Nunc elementum odio eu risus. In metus. Phasellus gravida pretium ligula. Nulla vitae neque. Nam nisi tortor, ornare non, blandit at, cursus eu, tortor. + +Duis bibendum ipsum in nunc cursus molestie. Nunc orci. Nullam nec ante non est dignissim viverra. Mauris blandit, velit id feugiat pretium, elit magna pellentesque dolor, at sagittis lacus velit egestas magna. Pellentesque cursus, diam consectetuer sagittis fringilla, tortor nisi adipiscing nunc, eu varius lacus risus ac elit. Mauris id nisi quis leo euismod venenatis. Pellentesque ac ante. Mauris arcu sapien, tempor at, porttitor id, condimentum ut, dui. Etiam fermentum ultricies augue. Cras ut eros at justo ultricies iaculis. Duis dignissim, nisl et facilisis fermentum, erat purus molestie tellus, quis tempus ipsum lectus at elit. Nulla vitae lorem. + +Aenean vel sem et diam semper congue. In bibendum diam quis tellus. Nunc facilisis ultricies nibh. Cras nunc enim, feugiat sed, ultrices vitae, sagittis vitae, ipsum. Fusce vitae nulla. Donec pellentesque, velit in porttitor eleifend, est neque lobortis velit, sit amet rutrum ante tortor nec dolor. Donec vehicula. Nulla facilisi. Sed egestas ultrices nibh. Donec elit lectus, convallis porttitor, aliquet dapibus, feugiat eget, ligula. Sed consectetuer justo. Maecenas a sapien sit amet nisi dapibus lobortis. Vivamus luctus lorem non nulla. Sed eget erat vitae libero interdum posuere. Cras pulvinar. Nullam imperdiet, dolor tempor dignissim blandit, dui sapien rhoncus neque, id malesuada augue magna sit amet urna. Duis sed mauris. + +Morbi accumsan. Sed mauris augue, fringilla non, auctor ut, auctor et, orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus ut pede. Donec viverra enim vel lorem. Pellentesque neque mauris, interdum eu, venenatis id, condimentum eu, sapien. Donec ipsum arcu, lacinia adipiscing, laoreet et, cursus vel, velit. Ut sagittis mauris quis risus. Integer eu odio vitae lacus viverra accumsan. Morbi leo ante, dignissim sed, varius quis, volutpat vitae, nisi. Nulla placerat interdum elit. Donec neque dui, sagittis vitae, sollicitudin quis, commodo vitae, neque. Nulla quis ligula ornare ligula dictum ornare. Mauris rutrum rutrum neque. Aenean vehicula tempus est. Donec varius scelerisque pede. Donec placerat vulputate leo. Nullam nunc nisl, posuere non, feugiat vitae, pellentesque quis, mauris. In dui neque, cursus eget, sagittis eget, dapibus vitae, mi. Proin eget est. + +Fusce porta est. Mauris magna. Aliquam ipsum lacus, ultricies id, vestibulum luctus, accumsan ut, ante. Sed mauris. Sed adipiscing leo sit amet magna. Suspendisse potenti. Nunc massa elit, fringilla eget, egestas vitae, luctus vitae, dolor. Phasellus quis nulla eu nisi interdum sollicitudin. Nullam id tellus. Integer iaculis dolor ac purus. Sed vel mi. Curabitur non magna sit amet justo condimentum vulputate. Quisque tincidunt pede eu nisl. Vivamus lobortis. Nunc metus metus, congue sed, tincidunt sed, pretium at, odio. Donec a arcu. In sem justo, vehicula sed, varius id, volutpat at, risus. Praesent iaculis massa. In arcu elit, hendrerit eget, ullamcorper in, porta id, tellus. Donec sagittis hendrerit diam. + +Suspendisse potenti. Sed et diam et augue sagittis lobortis. Phasellus dolor. Ut et arcu eget ante tempor posuere. Aliquam fermentum scelerisque dui. Mauris at purus. Donec erat sem, vestibulum nec, faucibus ac, mattis a, leo. Suspendisse adipiscing lacinia sem. Nullam orci arcu, dictum et, faucibus viverra, dapibus et, neque. Cras nunc diam, adipiscing non, sollicitudin in, interdum vel, massa. Mauris sagittis, justo at tristique tempus, mauris mauris aliquam ante, sit amet posuere diam dui eget ligula. In dignissim, nisl ut lacinia condimentum, erat justo porttitor nulla, non gravida ligula magna eget massa. Vestibulum vitae ligula at mi vestibulum suscipit. Duis laoreet. Nulla commodo libero sit amet lorem. Ut elementum sem. Integer vel dolor. Nam facilisis mi quis sem ultrices sagittis. Sed quis quam at metus molestie bibendum. + +Proin dui enim, lacinia a, feugiat ac, placerat vitae, pede. Quisque egestas, leo eget aliquam pretium, libero justo tincidunt eros, ut egestas augue pede elementum nibh. Curabitur mollis sodales enim. Donec augue. Phasellus id ipsum posuere dui pretium faucibus. Mauris luctus ante semper nisi interdum adipiscing. Duis dapibus, odio quis viverra rhoncus, justo quam bibendum dolor, id dapibus velit erat vel erat. Fusce sit amet nisl venenatis quam ultrices condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec rhoncus scelerisque ligula. Vestibulum mi odio, accumsan et, adipiscing eget, ornare ut, quam. Nullam blandit molestie mauris. Curabitur dignissim mauris et lorem. Suspendisse a justo. Nam mattis faucibus arcu. Duis blandit enim non massa. + +Nullam lorem. In hac habitasse platea dictumst. Mauris consectetuer posuere mauris. Maecenas tincidunt mauris in eros. Nulla eu metus eu orci sollicitudin faucibus. Suspendisse aliquam mauris id est. Cras blandit dui et urna. Nulla arcu. Sed a urna. Nulla dapibus vehicula tortor. Donec risus. Sed quam metus, egestas eu, cursus ut, viverra non, odio. Ut justo justo, malesuada sit amet, blandit suscipit, molestie in, justo. Vestibulum consequat, quam ac feugiat tincidunt, ipsum libero eleifend odio, non eleifend pede ipsum non ante. Nullam a metus. + +Nam ac nisi at felis cursus mattis. Pellentesque consequat sem quis orci. Quisque tempus. Aenean imperdiet molestie pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eu tellus. Nulla diam eros, sodales ut, sodales nec, tincidunt ac, nunc. Nunc lacinia faucibus ipsum. Vivamus vel neque in erat fermentum luctus. Nulla eget metus nec augue bibendum placerat. Vivamus tempus. Praesent congue ornare ipsum. Etiam mattis feugiat justo. + +Aliquam dui. Aenean commodo tortor vitae nulla. Morbi et ipsum. Mauris ac ipsum. Nam vel risus ut lectus mollis viverra. Curabitur elementum mollis est. Nullam elit. Vestibulum suscipit pretium enim. Vestibulum ut massa. Proin nec felis. Maecenas gravida, arcu nec consequat sagittis, eros tellus scelerisque mauris, vitae accumsan quam quam ut nunc. Integer eget ante eu velit laoreet malesuada. Nunc sagittis, mauris vitae pharetra volutpat, tellus tellus eleifend eros, sit amet rutrum ipsum nisi a velit. Praesent varius leo eu erat. Vivamus consequat placerat purus. Donec pretium elementum nibh. Proin at elit non sem aliquet mattis. Sed ullamcorper ipsum sit amet elit. + +Mauris in metus. Suspendisse magna lorem, faucibus vel, tincidunt quis, scelerisque non, tellus. Fusce quis lorem. Proin a lacus sit amet mauris iaculis pulvinar. Suspendisse rhoncus eros nec mi. Praesent euismod, turpis vitae rutrum pretium, odio metus volutpat neque, eget tempus sapien neque sed erat. Donec fermentum purus at lectus. Nullam sem. Fusce vel mi quis erat lobortis posuere. Aenean eget urna. Suspendisse ligula. Duis in nisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Curabitur vulputate lectus id pede. Phasellus eu velit. Etiam venenatis adipiscing nibh. Aliquam cursus pulvinar tellus. Vestibulum neque. Mauris nec justo et erat semper pellentesque. Fusce mattis dictum dolor. Etiam eget purus eu massa varius elementum. Pellentesque massa. Ut ultricies diam sed ipsum. Nullam diam. Pellentesque id magna id libero tristique aliquam. + +Ut eleifend, purus id placerat venenatis, urna augue aliquet ligula, in ultricies leo risus et tellus. Mauris et nulla id urna tristique tempus. Ut facilisis, urna eu vestibulum rhoncus, lacus eros consectetuer metus, et rutrum dui lectus in purus. Nunc vel nisl non ipsum tincidunt mollis. Nam quam lacus, ornare vitae, rhoncus non, congue sed, odio. Proin nibh dui, porta vel, venenatis non, pellentesque ut, nisi. Sed tristique felis a magna. Suspendisse eget tellus. Cras gravida imperdiet velit. Integer hendrerit risus. Proin orci. Aliquam ullamcorper mauris quis mauris. Nunc lacinia vestibulum metus. Duis tellus. Nullam faucibus, leo ac vulputate sollicitudin, leo dolor faucibus erat, quis bibendum orci odio non arcu. + +Nullam accumsan mattis dolor. Donec et dui. Praesent a felis mollis lacus semper lacinia. Curabitur pellentesque luctus est. Proin nulla dui, condimentum vel, faucibus non, interdum ac, erat. Maecenas scelerisque, lectus id volutpat accumsan, sapien tortor pellentesque dui, sed semper magna sem ut leo. Proin nulla. Nullam dapibus ullamcorper sem. Suspendisse vehicula metus in nunc. Pellentesque non quam vel arcu ultrices ullamcorper. Phasellus quis felis sit amet tellus ullamcorper fermentum. Sed vehicula sollicitudin urna. Curabitur pharetra scelerisque risus. Pellentesque id massa quis metus aliquam imperdiet. In nunc lacus, feugiat in, gravida eget, venenatis ut, tellus. Suspendisse potenti. Nam consequat adipiscing dui. In nulla nisi, feugiat ut, fermentum vel, gravida nec, tortor. In sed augue. + +Etiam ullamcorper augue at enim. Integer dignissim. Aliquam pulvinar congue nulla. Morbi enim massa, fringilla a, accumsan eget, condimentum nec, erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean pharetra. Etiam porttitor purus a metus. Aliquam interdum sem eget justo. Quisque volutpat luctus est. Aenean augue. Phasellus dui lectus, ultrices nec, commodo vel, auctor vel, nisi. Ut ultrices pellentesque nisi. Integer ac velit et sem imperdiet luctus. Fusce vitae turpis id augue mollis consectetuer. + +Maecenas nec lacus. Maecenas condimentum odio eu felis. Mauris ut nisl viverra erat faucibus adipiscing. Etiam egestas. Nunc et dolor vitae risus dignissim commodo. Morbi lectus velit, tincidunt nec, aliquet vel, mattis vitae, ligula. Maecenas ultricies semper dolor. Suspendisse malesuada. Integer mattis elit. Donec accumsan, lacus facilisis varius tempus, nulla elit porta erat, et rutrum elit sem sit amet dui. + +Maecenas mollis mi non nulla. Vivamus turpis. Suspendisse a metus. In quis mi in turpis congue auctor. Maecenas lacus. Suspendisse sollicitudin. Phasellus porta nunc non nisl pulvinar egestas. Sed nulla. Vestibulum ac mi. Mauris ultricies condimentum neque. Nulla tempus justo vel massa. Nulla suscipit congue arcu. Praesent id turpis. Mauris nibh pede, euismod semper, molestie ac, rhoncus vitae, ante. Maecenas erat felis, viverra sollicitudin, sagittis eget, pellentesque nec, orci. Fusce ultrices consequat lacus. Aliquam erat magna, feugiat at, viverra a, mollis non, turpis. + +Donec mi. Nam dictum pellentesque sem. Donec mollis rhoncus elit. Phasellus rhoncus pede sit amet risus. Donec eget augue. Maecenas non lectus. Phasellus sollicitudin nisi nec felis. Aliquam pretium, est eget semper convallis, nibh nunc sollicitudin purus, id tempor pede dui vel magna. Vivamus ac lorem. Etiam nisl tortor, adipiscing dictum, elementum in, facilisis sed, nibh. Proin mauris. Proin rutrum massa eget sem. Curabitur tempor adipiscing elit. Curabitur purus tellus, fermentum eget, aliquet vitae, convallis ac, mauris. + +Integer consequat velit eu eros tincidunt vehicula. Nullam lorem sapien, rhoncus non, mattis quis, ultricies sit amet, enim. Curabitur commodo, libero in euismod suscipit, sem purus fringilla enim, ac molestie tortor orci et velit. Donec pede. Etiam placerat condimentum turpis. Phasellus egestas enim nec magna. Vivamus condimentum, nulla vel luctus tristique, eros risus vestibulum nulla, in vehicula arcu ipsum at felis. Donec aliquam elit at augue. Quisque a eros eu ligula accumsan dictum. Etiam vehicula turpis quis libero. Aliquam non mi. Donec et leo. Proin leo libero, aliquam tincidunt, congue nec, adipiscing porta, enim. Nulla lobortis, tortor sit amet imperdiet ullamcorper, dolor orci malesuada pede, sed gravida nibh urna vel lorem. Sed pharetra malesuada eros. Quisque euismod aliquet erat. Suspendisse aliquet mattis purus. + +Nunc id nulla quis justo congue sollicitudin. Praesent erat turpis, rhoncus eu, pretium eu, pellentesque a, nibh. Vivamus tempus. Cras nec risus at turpis imperdiet lobortis. Ut mattis. Maecenas est felis, pellentesque non, imperdiet sed, eleifend tincidunt, lorem. In tincidunt. Sed vel leo. Donec et urna in turpis hendrerit blandit. Donec condimentum accumsan est. Ut pharetra, metus vitae mattis consectetuer, leo quam vulputate odio, nec laoreet nisi velit eu erat. Integer lectus augue, egestas in, interdum eu, venenatis vel, sapien. Quisque et est vitae eros laoreet lobortis. Nullam ut risus non nulla placerat adipiscing. Praesent dapibus. Etiam a felis. Ut sodales consequat mauris. Duis lorem felis, luctus a, tristique in, molestie at, risus. Sed vehicula bibendum tellus. Nam consequat euismod lacus. + +Aenean tortor elit, gravida nec, fermentum eu, lobortis id, ipsum. Maecenas eu purus. Cras ac turpis ut nisi iaculis rhoncus. Nulla purus metus, dignissim nec, tincidunt vitae, dapibus eu, nibh. Fusce lobortis, nunc at viverra eleifend, justo turpis scelerisque eros, ac pellentesque metus nisl at purus. Sed elementum tellus sed enim interdum blandit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer ultricies aliquet odio. Mauris eget nunc a ipsum ultrices sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean accumsan. Donec sapien lectus, congue at, porta id, hendrerit vitae, nisl. Curabitur vel quam vel neque accumsan laoreet. Morbi sapien est, pretium in, consectetuer ac, mollis ut, libero. Donec tincidunt adipiscing metus. Nunc vestibulum egestas augue. Donec scelerisque dui ut sem. Suspendisse vel metus id est molestie iaculis. + +Vivamus pharetra, elit eu malesuada blandit, diam tortor mollis dui, sed pulvinar massa nunc et magna. Sed placerat elit auctor tortor. Nulla ac erat. Pellentesque consectetuer, dui convallis tincidunt condimentum, sem odio volutpat libero, non elementum felis neque nec odio. Maecenas hendrerit eros id diam. Mauris vel purus ac orci convallis convallis. Sed sit amet lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque dictum varius lacus. Mauris eget nisl. Suspendisse placerat, nulla non ornare dignissim, nisl diam sagittis tellus, in semper nisi dolor at nibh. Duis ullamcorper viverra felis. Integer a tellus. Suspendisse eget nunc. Aenean diam est, accumsan id, suscipit interdum, fringilla vitae, justo. Proin pede. Maecenas at neque in neque vestibulum eleifend. + +Vestibulum nulla lorem, porttitor eget, euismod ac, aliquam at, nisl. Maecenas et est eget massa varius lobortis. In mi. Duis porttitor fermentum purus. Donec cursus imperdiet ligula. Morbi et ligula et ante molestie vehicula. Mauris sed dolor. Sed imperdiet felis ut sem. Sed vitae neque elementum leo auctor fermentum. Duis feugiat ullamcorper erat. Aenean purus. Morbi fermentum vestibulum est. Pellentesque venenatis mauris. Phasellus pulvinar. Integer ipsum lectus, iaculis a, lacinia id, accumsan id, arcu. Phasellus at est. Fusce neque quam, ultricies id, iaculis vel, dapibus vitae, lacus. In lobortis convallis ante. Nulla nunc purus, vulputate in, hendrerit et, blandit et, ligula. + +Pellentesque leo metus, sagittis in, molestie vitae, dictum in, pede. Morbi pretium felis nec quam. Pellentesque mattis ante sed quam sagittis dapibus. Suspendisse sapien. Praesent bibendum iaculis tortor. Duis a nisl. Aenean mi. Donec dictum arcu in est. Morbi interdum vulputate ipsum. Aenean sit amet magna non nisl tristique posuere. Phasellus velit metus, tempor ac, fermentum eget, condimentum non, velit. Vestibulum sit posuere. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras aliquet massa nec dui. Cras arcu nunc, hendrerit ac, eleifend eu, ullamcorper nec, tellus. Sed pharetra purus sit amet quam. Curabitur mollis. Nam vitae pede. Etiam risus massa, vehicula sit amet, pharetra nec, sollicitudin ut, dui. Donec egestas justo at quam. Proin nisl risus, vestibulum nec, pretium vitae, tristique ac, lorem. Aliquam erat volutpat. Cras sed nibh. Pellentesque sollicitudin euismod augue. + +Etiam fringilla sollicitudin orci. Mauris cursus elit quis lacus. Cras tortor. In adipiscing, lectus id auctor vestibulum, neque pede accumsan dolor, non imperdiet magna diam accumsan velit. Suspendisse at libero ut nisi blandit sagittis. Phasellus non mauris. Fusce elementum sagittis sem. Suspendisse aliquam eleifend tellus. Proin ligula lorem, imperdiet quis, venenatis id, iaculis mollis, nisl. Etiam convallis pede at massa. Morbi accumsan dui et mauris. + +Sed sed orci. Nunc purus. Suspendisse potenti. Ut luctus fringilla mauris. Donec nibh. Phasellus porta. Phasellus sit amet odio sed magna sodales pharetra. Cras lectus. Suspendisse libero ipsum, commodo nec, facilisis in, suscipit lobortis, ligula. Duis massa nulla, semper et, consequat nec, pharetra eu, elit. Vivamus ultricies aliquam odio. Vestibulum sit amet massa. Sed consequat lacus sed urna. Etiam faucibus felis vel orci. Phasellus ullamcorper. Aenean consectetuer lacus at libero. + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis facilisis, ligula vitae condimentum scelerisque, velit orci gravida felis, vel ultricies quam mi non diam. Vivamus auctor metus non libero. Praesent ligula nisi, commodo condimentum, molestie et, viverra et, justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus sollicitudin. Nunc blandit cursus ipsum. Aenean nec ligula ut tellus sodales mattis. Integer sem. Aliquam id ligula. Sed tortor mauris, blandit vitae, cursus vel, elementum et, nulla. Aliquam scelerisque metus et nisl. Duis adipiscing magna at neque. Quisque vulputate eleifend nunc. Aliquam eget elit. Phasellus dui odio, bibendum sagittis, vestibulum id, dignissim imperdiet, orci. Nullam eu felis non nunc lacinia sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Suspendisse pellentesque, libero mattis ultricies accumsan, tortor tortor malesuada sem, et sodales libero odio ac ipsum. Vivamus quis magna nec est suscipit lobortis. Cras tempus posuere nunc. Quisque ut enim a felis egestas semper. Sed pharetra mattis neque. Fusce turpis nunc, congue sed, consequat non, congue sed, nulla. Suspendisse varius lorem id risus porta vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce sed purus. In a felis. Integer egestas auctor orci. Mauris ultrices suscipit nisl. Nullam purus. + +Cras tempor adipiscing ipsum. Ut quis mi. Maecenas in justo ut nulla congue pharetra. Pellentesque ut libero eu dolor venenatis suscipit. Praesent feugiat consectetuer nibh. Morbi faucibus sem non felis. In hendrerit arcu ac massa. In accumsan ultrices mi. Proin malesuada auctor felis. Curabitur interdum. Sed diam ipsum, ultricies in, tempor sit amet, viverra imperdiet, elit. Morbi molestie nisi. Mauris ipsum. Fusce dictum mollis magna. Duis commodo dignissim nulla. Vestibulum augue enim, ultricies quis, iaculis nec, tincidunt vitae, diam. Mauris lacinia tempus ipsum. Sed at mauris. Ut lorem. Donec libero. + +Duis iaculis lacinia lectus. Aenean convallis eros ac ante. Sed quis orci nec risus auctor fringilla. Phasellus facilisis elementum nisi. In hac habitasse platea dictumst. Nunc porta lacus nec ante. Morbi mauris erat, adipiscing in, pulvinar nec, lobortis nec, odio. Ut eleifend lectus sed quam. Nullam mollis. In non turpis et nisl hendrerit blandit. Duis elementum. Nunc nec libero. Suspendisse vestibulum risus non pede. Morbi imperdiet odio sit amet libero. Sed sed massa vitae ipsum mattis tincidunt. Nulla nec tortor vitae libero volutpat tempus. Donec aliquam. + +Duis sed nunc. Curabitur turpis nulla, vehicula sed, luctus quis, elementum eget, felis. Maecenas et purus. Maecenas leo tellus, tincidunt a, facilisis vitae, lobortis sit amet, velit. Donec convallis sapien. Maecenas mollis odio eu nibh. Etiam gravida. Integer molestie, sapien eu molestie lacinia, nunc nibh aliquam ligula, eu sagittis tellus erat sollicitudin odio. Duis et risus. Phasellus nisi neque, placerat nec, condimentum non, ultrices eu, sem. Ut pede. Etiam nulla metus, volutpat id, convallis sed, suscipit vel, urna. Donec vel elit. Ut leo neque, venenatis faucibus, lacinia nec, tincidunt eu, enim. Cras id dui a libero pharetra dignissim. Donec eros leo, porta quis, laoreet ut, pellentesque volutpat, lectus. + +Nullam blandit. Aliquam erat volutpat. Fusce adipiscing enim. Suspendisse non dui quis ligula porta vestibulum. Donec eu tellus vel lorem pretium porttitor. Praesent luctus. Aliquam ac eros in massa dapibus tincidunt. Donec ut magna. Etiam auctor lacus sit amet lacus. Sed ultricies ipsum nec elit. Quisque a est in purus suscipit tristique. + +Aenean sed dui vel dolor pulvinar laoreet. Vivamus vehicula lorem in pede. Vivamus et diam. Integer ac odio vel diam hendrerit bibendum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a nisi. Phasellus tincidunt dui vitae augue. Duis faucibus, dui interdum fringilla tincidunt, odio elit vestibulum libero, ac molestie magna lectus id lacus. Aenean ligula. Nulla facilisi. + +Fusce vel sem eu velit fringilla ornare. Sed feugiat tincidunt felis. Nullam felis mi, euismod sit amet, mollis at, sodales eget, augue. Nam imperdiet nibh at velit. Sed ut erat. In dui. Nulla facilisi. Nullam augue libero, tincidunt nec, pretium eu, pulvinar in, dui. Morbi vitae felis. Pellentesque vel justo vel velit sagittis malesuada. Proin vehicula blandit massa. Etiam tincidunt pharetra urna. In metus est, auctor nec, blandit a, cursus nec, quam. Mauris ac metus a libero congue faucibus. Mauris mauris dolor, sodales in, cursus ut, sodales rutrum, eros. Quisque mauris eros, sagittis vitae, lobortis ut, eleifend id, nisi. + +Aenean neque. Vestibulum egestas pellentesque ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus sagittis justo vel risus. Sed pretium neque vitae urna. Pellentesque congue libero id lorem. Mauris leo lorem, blandit sit amet, convallis quis, consectetuer sed, eros. Mauris tincidunt, enim a gravida euismod, magna nulla fermentum libero, viverra egestas velit quam et tortor. Vivamus aliquet massa vitae justo. Nulla congue lacus ac elit. + +Phasellus commodo quam vel ligula. Proin non metus at eros pulvinar luctus. Mauris diam lorem, posuere quis, gravida et, tincidunt nec, ligula. Sed diam. Aliquam elit lectus, hendrerit ut, imperdiet sit amet, pretium sit amet, ipsum. Mauris vehicula nisl in dui. Curabitur eget quam ut magna elementum fermentum. Mauris scelerisque. Quisque laoreet. Etiam tempus turpis. Pellentesque augue quam, hendrerit sed, tincidunt at, pharetra at, nisl. Aliquam lacus. Suspendisse potenti. Aenean velit libero, ultrices in, lacinia eu, luctus vel, ante. Etiam dictum mi in felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce gravida dapibus nisl. Cras vitae nisl. + +Maecenas dignissim, ligula non porta cursus, enim nunc malesuada sem, eu porttitor nulla urna eu quam. Fusce eros. Aliquam eros. Nam auctor. Nulla molestie porta est. Suspendisse potenti. Vivamus molestie lorem sed erat. Sed eget ipsum. Integer aliquam pulvinar nulla. Cras aliquet sem ut nunc. Fusce faucibus tempus lectus. Cras sodales, nisi ac facilisis ultrices, eros arcu dapibus sapien, et ultrices mauris tellus non dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras cursus varius metus. Ut turpis. Vivamus eget tortor. + +Sed laoreet, velit non accumsan cursus, nunc urna posuere justo, in dictum lectus pede id ante. Cras vulputate. Cras congue dui sed elit. Proin lacus sem, ultrices at, consequat in, tempor quis, metus. Proin vel arcu. Nam euismod hendrerit elit. Ut erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed posuere. Morbi eros urna, semper at, semper non, convallis quis, velit. Maecenas orci. Vestibulum lobortis tristique metus. Vestibulum lorem nulla, sollicitudin vitae, condimentum quis, auctor ut, dui. Vivamus vestibulum magna ut nisi. Curabitur eleifend dui vel nunc. Curabitur mauris lacus, malesuada sit amet, suscipit sed, rutrum luctus, tellus. Integer facilisis urna vitae lectus. + +Aenean quam leo, lobortis quis, malesuada eu, vulputate vitae, nisl. Praesent eget eros. Ut fermentum turpis id quam. Nam tortor. Praesent nec orci. Nulla bibendum adipiscing augue. Ut commodo, magna id malesuada gravida, augue odio malesuada mi, porta malesuada elit est vitae diam. Mauris non nulla. Suspendisse tincidunt, nunc ultricies porta venenatis, mi pede tincidunt libero, eget varius ante libero ut ligula. Curabitur pretium porttitor tortor. + +Maecenas vitae elit eget nisi dapibus dictum. Nunc in libero. Nulla dictum orci eu erat auctor lobortis. Phasellus risus. Suspendisse potenti. Suspendisse potenti. Praesent adipiscing consequat elit. Integer id augue. Praesent in justo nec magna dapibus pulvinar. Duis nisl. Suspendisse ac odio. Vivamus imperdiet. Donec non velit sit amet risus dignissim congue. Nam aliquet posuere velit. Cras turpis. Morbi malesuada dignissim mi. + +Sed leo neque, varius quis, venenatis sed, pharetra sed, est. Morbi blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam semper pellentesque mi. Ut vel lorem. Nunc mi tortor, laoreet at, faucibus eu, tincidunt sit amet, erat. Duis tempor malesuada ipsum. Phasellus aliquet. Donec et elit. Pellentesque purus. Vestibulum rutrum semper nibh. Nulla facilisi. Phasellus et enim sit amet ante vestibulum vehicula. Phasellus id nisl. Donec mollis leo at eros. Mauris pellentesque neque at purus. Morbi quis dolor at ipsum scelerisque sodales. Etiam volutpat turpis a metus. In hac habitasse platea dictumst. Nunc lorem lorem, vestibulum ac, euismod eget, ullamcorper dignissim, velit. + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ultrices, nibh vel aliquam vestibulum, eros enim venenatis dui, id iaculis enim nunc vel massa. Morbi eleifend orci et massa. Aliquam erat volutpat. Nulla mollis egestas turpis. In sodales nunc eget tortor. Sed ipsum eros, tempor quis, aliquet vitae, imperdiet non, lorem. Pellentesque quis elit id mi luctus dapibus. Sed nunc arcu, rhoncus nec, convallis quis, cursus at, neque. Mauris convallis purus at erat. Pellentesque vestibulum. Vivamus fringilla elit at arcu. Nullam aliquet enim nec arcu. Nam id tortor. Nulla quis nunc. Ut arcu. Suspendisse potenti. Pellentesque ullamcorper ligula id arcu. + +Nam non libero vitae nisl scelerisque fringilla. Quisque varius ante id metus rhoncus fringilla. Nulla facilisi. Praesent eleifend porttitor ligula. Etiam quis dolor non augue commodo auctor. Donec a mi. Vestibulum tempor. Donec felis urna, auctor at, cursus dictum, gravida id, arcu. Aenean dictum malesuada dolor. Vivamus mattis. Phasellus eu pede. Fusce adipiscing justo fringilla metus. Etiam ante. Integer mollis massa quis nunc. Integer dictum neque luctus enim. + +Sed eu libero. Integer tempor ligula in velit. Ut tincidunt lacinia sem. Nullam vel risus. Sed sodales ante a dolor. Curabitur eros. Sed sodales. Sed non metus. Vestibulum elementum faucibus ante. Nulla vel nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In hac habitasse platea dictumst. Nunc nec lorem ut ipsum lacinia iaculis. Duis erat. Aliquam erat. Cras iaculis. In hac habitasse platea dictumst. + +Nullam ante. Cras vitae est. Pellentesque vel metus a ligula dapibus mattis. Duis feugiat aliquet felis. Etiam id nisl quis est dignissim condimentum. Suspendisse potenti. Morbi velit lorem, ornare quis, pellentesque vel, placerat eget, tortor. Vestibulum tincidunt molestie libero. Nulla nulla enim, malesuada id, ullamcorper vitae, dictum at, purus. Donec dignissim odio ut enim. Suspendisse at lectus. + +Praesent lobortis augue vel lectus. Ut in ligula ut felis congue suscipit. Quisque dignissim tortor ut mi. Fusce magna nisi, eleifend ac, ornare vel, porttitor vitae, quam. Vestibulum sodales justo quis turpis. Fusce urna nisi, rhoncus quis, condimentum vel, dictum eu, nunc. Fusce sed nibh vitae odio posuere adipiscing. Sed porta elit quis dolor. Nam libero nulla, auctor sed, tincidunt quis, faucibus sit amet, mi. Quisque orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam id sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vel eros. + +Vivamus luctus lobortis leo. Suspendisse vel elit a enim ullamcorper posuere. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec quis pede mattis lectus mollis adipiscing. Sed accumsan posuere erat. Praesent euismod tincidunt felis. Donec mi. Ut commodo arcu lacinia tellus. Aliquam a libero quis lectus semper viverra. Curabitur lacinia mauris at tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sit amet magna molestie orci suscipit fringilla. Fusce pretium metus non sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed hendrerit. Nulla felis. Suspendisse potenti. Aliquam blandit tristique neque. Curabitur quis erat vel nunc accumsan mollis. + +Duis sagittis, tellus ut aliquam fringilla, dolor mi ullamcorper nisl, ut tristique pede elit sed mauris. Curabitur id felis. Donec pulvinar lacus et lectus. Aliquam vulputate vulputate metus. Curabitur magna felis, adipiscing ac, accumsan vel, molestie quis, quam. Mauris elit arcu, pretium vitae, mollis sit amet, sollicitudin ut, mi. Donec imperdiet dignissim mi. Nullam sit amet tortor. Aliquam neque nulla, venenatis a, porta in, placerat tempus, lacus. Quisque vestibulum dui et lacus. Proin dignissim consectetuer purus. Etiam gravida tortor in nunc. Ut tempor tristique tortor. Sed laoreet tincidunt quam. Vestibulum porta turpis ut elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nibh dui, feugiat nec, laoreet id, malesuada eget, nisi. Ut neque massa, vehicula eu, commodo non, ultricies vitae, purus. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris euismod, felis vel tempor aliquet, tortor mauris malesuada nunc, vel fermentum sem diam id dui. Nam rutrum sapien eget odio. Aliquam sed libero non mi faucibus tempus. Fusce hendrerit, diam non volutpat rutrum, erat metus venenatis ligula, non scelerisque pede ligula vel quam. Morbi rhoncus eros ac dui feugiat elementum. Duis eu libero et tellus congue viverra. Morbi quam quam, elementum sed, ullamcorper imperdiet, commodo non, odio. Nam aliquet egestas urna. Mauris odio felis, varius eu, lacinia eu, condimentum a, lectus. Sed justo massa, pulvinar id, varius a, porttitor nec, libero. Etiam varius. Curabitur sodales, odio at posuere semper, eros nibh tincidunt lectus, vel rutrum sapien nisi in ligula. Suspendisse eget arcu. Phasellus imperdiet est ac sapien. Donec nulla tortor, placerat vel, tempus a, lobortis vel, nibh. Aliquam varius nisi. Nulla et enim. Fusce convallis laoreet lacus. + +Phasellus ipsum dolor, molestie quis, condimentum in, commodo eu, diam. Quisque bibendum lacinia dui. Nullam blandit vulputate orci. Ut lacinia massa vel augue. Aliquam gravida, quam quis imperdiet imperdiet, tellus diam pharetra erat, at pharetra lacus nibh egestas magna. Nulla sagittis lorem ut lorem. Duis condimentum, dui vitae aliquam posuere, diam quam convallis velit, ut gravida leo ipsum non risus. Ut fermentum sollicitudin erat. Donec sagittis scelerisque felis. Nunc arcu. Etiam tempus, magna sit amet suscipit euismod, eros sem rutrum dui, vitae sagittis nibh purus non lacus. Sed mollis arcu eget dolor. Donec ornare, arcu sit amet fermentum vulputate, risus enim fermentum libero, a lacinia dolor mi non velit. Etiam lobortis purus a elit. Nunc nulla dui, mattis quis, bibendum a, ultrices ac, augue. In aliquam vehicula turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Integer id nisl. Quisque dictum elementum odio. Aenean luctus. Sed eu sem a pede vulputate condimentum. Quisque magna. Donec aliquam mattis ipsum. Curabitur dictum sollicitudin sem. Aliquam pulvinar. Nunc sollicitudin risus a erat. Vivamus quis tellus sit amet nibh vestibulum consequat. Nulla pretium sollicitudin dolor. Aliquam iaculis tincidunt turpis. Phasellus ipsum leo, venenatis in, sagittis in, ornare at, nunc. + +Pellentesque ultrices, dui eu iaculis luctus, tellus augue volutpat sapien, in dignissim urna felis ut mi. Sed arcu dui, dignissim id, porttitor ut, imperdiet vitae, ante. Nulla dui sem, commodo nec, sagittis et, lacinia et, pede. Etiam eleifend dui ut nisl. Donec ante mauris, tempus sit amet, varius vitae, gravida quis, mi. In scelerisque, felis vitae viverra sagittis, velit metus ultricies neque, quis imperdiet velit elit et magna. Suspendisse potenti. Sed velit eros, euismod sed, condimentum nec, faucibus sed, sapien. Nam accumsan ligula sit amet neque. Aliquam erat volutpat. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam eu pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed eu felis sed tortor tempor fermentum. Phasellus commodo sem vel nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lectus elit, pharetra sit amet, accumsan sed, tincidunt et, mauris. Duis dapibus pharetra sem. Integer in justo. Praesent eros. Vestibulum ac ante. Aliquam scelerisque sem pellentesque nibh consectetuer sodales. Aliquam consectetuer odio. Duis lectus odio, luctus eu, commodo quis, mollis vitae, velit. Cras nec nunc non elit iaculis mattis. Aenean justo neque, sollicitudin eget, ullamcorper eget, egestas id, sem. In eu risus. Sed egestas. + +Integer at neque. Sed pretium scelerisque nulla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce ut pede. Etiam vitae quam a urna varius imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vehicula. Fusce ullamcorper nibh non erat. Quisque in neque. Praesent est. Pellentesque arcu. + +Proin posuere. Suspendisse potenti. Integer felis lacus, aliquam sed, vulputate in, mollis vel, tellus. Integer vehicula bibendum est. Nunc non dolor in tellus mattis facilisis. Integer vestibulum, augue at commodo aliquam, dui est mattis ligula, sit amet adipiscing orci sem vitae magna. Praesent enim velit, malesuada at, congue nec, luctus in, justo. Sed varius. Morbi pharetra. Donec eu massa nec tellus vulputate pulvinar. Ut commodo turpis non sem. Ut convallis ullamcorper risus. Etiam interdum pede id nisi. Cras magna sapien, suscipit a, laoreet non, rhoncus et, felis. Integer orci lorem, vestibulum dictum, ullamcorper a, porttitor et, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc et magna. Sed bibendum tellus in diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vitae tortor. Integer magna. Duis venenatis, leo ac tempor laoreet, elit nulla pharetra pede, non fermentum nunc odio a odio. Proin non velit. Sed imperdiet augue quis nisl. Integer condimentum nisl nec libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus placerat libero. Duis congue dictum magna. Aliquam dapibus bibendum enim. Nunc eleifend pede vel ipsum. + +Etiam vitae velit. Mauris erat nunc, malesuada ut, feugiat ac, placerat condimentum, augue. Nam volutpat. Aliquam vehicula ipsum id odio. Vivamus sollicitudin turpis id sapien. Fusce a felis vitae odio convallis blandit. Curabitur vitae eros id eros porta pretium. Nulla in magna eget urna lacinia convallis. Aliquam mattis venenatis purus. Sed sed mi eget erat tristique porta. Donec auctor dolor a erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In nec ligula. Nunc eleifend. Vestibulum quis nisi eget elit porttitor congue. Maecenas faucibus, magna eget adipiscing tincidunt, dolor ante malesuada elit, non elementum lacus turpis in pede. + +Ut malesuada mi nec metus. Praesent auctor augue ac nisl ultricies facilisis. Nam purus sapien, pellentesque dignissim, posuere eu, cursus id, diam. Quisque sollicitudin, elit a pellentesque scelerisque, lorem risus auctor quam, quis consequat tellus neque id urna. Suspendisse diam tortor, eleifend dignissim, egestas ut, luctus in, ante. Duis ante. Maecenas luctus. Curabitur cursus pharetra urna. Maecenas imperdiet, erat non elementum euismod, tortor odio euismod lectus, ac facilisis sem nibh vitae nulla. Nunc gravida. Morbi sollicitudin odio quis lacus. Aliquam a nibh non urna porta imperdiet. Aliquam erat volutpat. In iaculis lacinia velit. Sed libero lacus, tristique eu, lacinia ac, aliquet eget, urna. + +Etiam at nisl. Phasellus faucibus luctus lectus. Ut placerat vulputate dolor. Phasellus vel velit. Morbi viverra. Phasellus orci. Integer dignissim mattis mauris. Pellentesque posuere leo posuere quam. Quisque nec magna at diam viverra pellentesque. Suspendisse velit arcu, ultricies quis, congue a, venenatis eget, lacus. Integer sagittis hendrerit dolor. Fusce tincidunt ante a sem. + +Maecenas consectetuer, justo sed rhoncus venenatis, nibh arcu rutrum dolor, sed condimentum libero libero et ipsum. Vivamus mattis justo ut lorem tincidunt lobortis. Ut non velit id neque aliquet accumsan. Sed tempus viverra nulla. Curabitur ullamcorper, neque quis dapibus scelerisque, felis diam gravida orci, non cursus quam neque vitae elit. Etiam pharetra tincidunt lacus. Duis euismod fringilla est. Etiam ornare tincidunt lectus. Proin in turpis. Nunc blandit blandit turpis. Aenean ut augue. Duis orci justo, tincidunt eu, rutrum sed, rutrum et, turpis. Curabitur facilisis odio in ante. In hac habitasse platea dictumst. Sed eros est, pellentesque at, tincidunt eu, ultrices quis, metus. Morbi sit amet justo. Maecenas ac arcu. Mauris dignissim. + +Pellentesque ultricies rutrum orci. Aenean ornare. Vivamus eu risus vel mauris lobortis dictum. Sed et turpis auctor mi rhoncus pulvinar. Sed nec nunc a purus tempor viverra. Pellentesque suscipit. Donec tristique risus non nibh. Etiam nisl magna, sollicitudin ut, ultrices sit amet, egestas eu, nulla. Aliquam erat volutpat. Vestibulum pharetra. Sed egestas, metus sit amet lobortis consequat, erat elit imperdiet libero, eu interdum quam massa eget dolor. Suspendisse vitae odio. Proin blandit mauris iaculis metus. + +Vivamus vestibulum. Etiam et nisl. Aliquam in diam vel elit placerat suscipit. Duis sodales purus ac nibh. Nulla in odio eget enim luctus blandit. Curabitur ultrices ipsum non neque egestas eleifend. Sed turpis. Proin consectetuer. Vivamus mattis. In aliquet. + +Nunc id eros. Donec venenatis, nulla et mattis luctus, ante leo semper justo, non adipiscing odio risus sed lacus. Praesent vitae risus congue libero congue tempus. Phasellus ac eros. Nulla vehicula, lorem in aliquet suscipit, arcu erat egestas sem, quis lobortis quam ante eu massa. Curabitur non massa. Sed bibendum lacinia odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus volutpat blandit lacus. Proin porta, tellus ut auctor laoreet, lectus eros fermentum lectus, id sagittis arcu justo in turpis. Phasellus consequat. Nam pellentesque, mi id viverra convallis, nunc libero placerat leo, eleifend porta sem nisl vitae sapien. Pellentesque ligula libero, tristique non, porttitor rutrum, porttitor non, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer dictum tellus a tortor. Vivamus felis nunc, molestie non, rhoncus quis, pharetra id, dui. Donec risus metus, fringilla vel, aliquet eu, placerat id, neque. + +Suspendisse ipsum. Vivamus lectus. Sed viverra, massa eget convallis mattis, quam turpis consectetuer nunc, eget posuere magna sem id velit. In nec mauris. Aenean a purus sed quam lobortis fringilla. Proin ultricies lacinia ante. Sed adipiscing erat quis velit. Nullam vitae nisl id justo sollicitudin molestie. Nulla facilisi. Sed nec urna sed nisl fringilla dapibus. Nulla at diam. Aliquam eget nibh. Nunc ac nisi sit amet tellus egestas tempus. Nam scelerisque urna et neque. Donec est orci, sagittis non, vulputate a, commodo et, augue. Ut dapibus tortor. Ut nunc. Donec dictum dapibus odio. Nam ultricies ullamcorper ligula. Pellentesque accumsan varius leo. + +Morbi euismod laoreet erat. Vivamus quis ipsum. Morbi euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel purus. Nullam at magna. Curabitur lacus lorem, iaculis quis, dapibus non, volutpat vel, nulla. Donec ut arcu rhoncus dolor pretium dictum. Nullam vel metus. Ut arcu. Pellentesque nisi nunc, placerat eget, tincidunt vel, pharetra non, nunc. Integer tincidunt ultricies lectus. Integer semper, purus sed ultrices feugiat, nulla pede sollicitudin erat, vel auctor nulla ipsum vel lectus. Aenean mi. + +Nullam sed nisi et arcu imperdiet fermentum. Mauris nec metus. In ac dolor. In mi arcu, congue ac, pharetra nec, scelerisque sit amet, magna. Curabitur lacus. Curabitur et elit. Aliquam ullamcorper nunc eu elit. Sed convallis dolor at velit. Vestibulum dapibus, augue id consectetuer placerat, nunc massa blandit sapien, id aliquam elit nisi id mi. Phasellus sapien est, gravida eu, bibendum ut, adipiscing quis, est. Ut molestie quam vitae odio. Donec quis risus id erat faucibus sollicitudin. Nam id felis. Mauris sed enim vitae leo accumsan pretium. + +Nam justo. Donec turpis nisl, commodo et, interdum ac, consectetuer non, massa. Fusce sem metus, laoreet nec, posuere id, imperdiet in, velit. Donec vulputate justo eget turpis. Nulla pede. Morbi tincidunt. Fusce aliquet, quam et aliquam fringilla, ante ante iaculis dui, nec aliquam arcu purus sed erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus suscipit quam et est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; + +Integer sed tellus. Sed sed velit ultricies leo rutrum laoreet. Sed non eros ac purus sagittis feugiat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed hendrerit ligula sit amet nibh. Maecenas turpis. Morbi consectetuer, dolor et adipiscing imperdiet, ante neque feugiat dolor, at porta quam neque quis ligula. Mauris semper velit sit amet ipsum. Pellentesque tempus, purus in rutrum consequat, enim erat vehicula massa, id accumsan leo sapien nec purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In dolor. Integer facilisis libero sit amet pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut varius aliquet enim. Nulla facilisi. Curabitur consectetuer, odio eu pretium tincidunt, nunc nisi aliquet neque, vel imperdiet elit massa sit amet turpis. Pellentesque tempus, orci volutpat blandit fringilla, odio sem posuere ante, vitae bibendum urna lorem vitae eros. Praesent viverra rhoncus arcu. Sed auctor, est sit amet mollis mollis, quam quam gravida sapien, in commodo metus nulla auctor enim. Donec facilisis. + +Proin tincidunt, sapien eget ultricies adipiscing, est odio dictum arcu, ut mollis erat dui sit amet velit. Morbi est sem, interdum at, congue a, elementum vitae, metus. Suspendisse id augue. Mauris enim sem, pulvinar eget, tempus a, tempus sit amet, sapien. Fusce vestibulum consectetuer dui. Pellentesque erat. Sed dignissim placerat odio. Maecenas semper rhoncus lectus. Phasellus pretium. Duis libero elit, eleifend nec, egestas ut, cursus sed, felis. Nam nisl arcu, aliquet et, facilisis eu, luctus ut, risus. Etiam ultrices, dolor sed volutpat malesuada, turpis arcu imperdiet tortor, euismod commodo libero massa ut quam. Integer molestie purus non elit. Ut venenatis semper tortor. Etiam bibendum egestas ipsum. Mauris sollicitudin sem nec nibh. Nulla pretium metus eu metus. Pellentesque sit amet sem. + +Suspendisse ac nisi. Ut leo. Vestibulum hendrerit pretium dolor. Nunc feugiat malesuada purus. Cras et nibh. Curabitur nunc erat, malesuada vitae, laoreet ac, ultricies in, purus. Vivamus tellus arcu, sodales eu, facilisis a, lacinia nec, nunc. Pellentesque id velit. In eu nibh. Nunc nec erat. Sed dictum neque ut nisl. + +Morbi lectus tellus, tincidunt ac, porttitor ac, tristique in, eros. Donec luctus luctus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ut est et enim scelerisque accumsan. Donec ligula felis, lacinia quis, pellentesque in, semper vestibulum, elit. Mauris eget orci a felis congue vehicula. Ut sollicitudin. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam id dolor ut lorem dignissim venenatis. Suspendisse vitae sapien. Proin non magna ut eros viverra pulvinar. Donec quis odio. Nullam non arcu vel lorem suscipit aliquam. Aliquam rutrum turpis in leo. + +Ut luctus nibh tristique erat. Suspendisse bibendum odio vitae tortor. Donec lacinia. Cras sodales felis luctus nulla. Nam eleifend sagittis ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse vel neque. Morbi aliquet vehicula magna. Aenean at odio. Duis pellentesque magna. Nulla at tortor ut diam dictum faucibus. Mauris quis velit. Donec non tellus vitae lorem fringilla porttitor. Fusce ut sapien quis tortor feugiat sagittis. Donec viverra sem vitae sapien. Praesent sodales, lacus in fringilla viverra, odio augue adipiscing urna, vitae interdum ante sem non nisi. Nullam tortor lorem, eleifend ac, mollis non, laoreet ac, risus. Integer ornare leo sed justo. Quisque cursus, sem non facilisis bibendum, nisi mi varius felis, fermentum feugiat lorem eros laoreet risus. + +Quisque sit amet est et lorem vehicula lacinia. Donec nec tortor. Cras odio. Nam scelerisque vulputate urna. Praesent dui. Etiam nec nisl lobortis ipsum aliquet tempus. Maecenas pretium sollicitudin mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus augue massa, congue eget, convallis eget, tristique sit amet, eros. Sed consequat nisi eu felis. Pellentesque justo. Suspendisse non augue. In dignissim lobortis mauris. Mauris sagittis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + +Sed adipiscing. Donec a tellus vitae est cursus vehicula. Nam ante sem, sodales id, fringilla vel, condimentum vel, nulla. Quisque sodales. Etiam imperdiet elit id odio. Aliquam erat volutpat. Maecenas porta tempor arcu. Nulla sem augue, pellentesque ac, consequat ut, condimentum euismod, risus. Sed aliquam tincidunt mi. In interdum lobortis orci. + +Sed vehicula hendrerit purus. Etiam a diam. Curabitur convallis. Suspendisse a nisi. Donec id magna in quam sollicitudin ultricies. Donec viverra. Quisque volutpat est sed sem. Aliquam justo. Vestibulum tortor massa, porttitor sed, varius quis, iaculis quis, odio. Aliquam eget neque. + +Mauris nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum eu quam in neque ultrices pellentesque. Cras in dolor quis quam varius hendrerit. Aliquam nisi lacus, lobortis eu, convallis sit amet, facilisis ut, mi. Aliquam at neque. Cras sagittis elementum justo. Vestibulum ut lectus aliquet purus malesuada volutpat. Duis at lacus adipiscing libero tincidunt vestibulum. Morbi a libero. Cras purus. Morbi ut augue et purus interdum scelerisque. Integer a dui. In hac habitasse platea dictumst. Duis pharetra metus eget mauris. Aliquam interdum ullamcorper massa. + +Etiam ornare. Nullam euismod. Aenean consequat gravida ligula. Aliquam est. Proin vitae lacus. Praesent a eros sit amet dui luctus commodo. Phasellus vehicula arcu eget dolor. Praesent fermentum congue leo. Aliquam volutpat purus ut lorem. Fusce hendrerit enim at leo. Aliquam rhoncus nisl. Vivamus dictum egestas mi. Suspendisse pellentesque bibendum dolor. Pellentesque tincidunt, turpis semper pellentesque condimentum, ipsum metus sodales ligula, id volutpat diam turpis ut elit. + +Praesent sed lacus. Nam eleifend molestie mauris. Donec dapibus fermentum massa. Donec viverra faucibus purus. Curabitur congue, libero vitae viverra pellentesque, diam velit sodales enim, sed suscipit lectus nisi nec neque. Vestibulum malesuada, lacus at cursus congue, velit lectus tristique dolor, sit amet sodales neque ipsum a libero. Vestibulum et quam. Curabitur placerat. Curabitur nunc arcu, euismod nec, vulputate hendrerit, aliquet eget, quam. Curabitur vel enim. Suspendisse potenti. + +Nunc consequat orci ut lacus. Fusce velit dolor, dapibus sed, blandit sit amet, rhoncus id, risus. Duis urna nibh, scelerisque quis, dapibus a, scelerisque sed, nibh. Donec luctus. Ut eu mauris cursus diam lacinia rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam vehicula molestie justo. Maecenas imperdiet pede sed mi. Suspendisse nulla dolor, hendrerit eget, hendrerit id, dictum vel, leo. Duis accumsan. Curabitur in felis. Nunc lorem. Ut leo dolor, laoreet nec, vulputate at, eleifend in, nulla. Quisque nunc purus, varius eget, accumsan nec, aliquet et, nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras adipiscing viverra dolor. Mauris porttitor ultrices purus. Nulla facilisi. Praesent faucibus ante vitae mauris. + +Praesent lacinia lectus sed nisl. In tempus congue mauris. Integer facilisis ornare enim. Nulla id massa. Donec commodo diam at tellus. Nam dapibus viverra est. Nam tellus. Praesent a libero. In faucibus est eget nibh. Nulla eros orci, imperdiet non, blandit non, tempor eget, mi. Pellentesque convallis. + +Quisque eget mi ac leo euismod faucibus. Phasellus rhoncus purus id dui. Vestibulum malesuada eleifend ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque blandit mattis odio. Suspendisse consequat, lectus ac semper sollicitudin, mi velit dictum augue, ac tempus dolor erat sit amet dui. Proin hendrerit, felis quis volutpat posuere, diam odio malesuada odio, a interdum orci diam quis sapien. Pellentesque odio odio, viverra vel, gravida eu, molestie sed, nulla. Phasellus mauris pede, commodo ut, euismod eu, hendrerit eu, est. In hac habitasse platea dictumst. Nulla elementum lacus eu augue. Sed erat. Proin porta. Maecenas quis mi. Phasellus at enim ac justo gravida ultrices. Cras leo. + +Integer ut arcu. Donec sed magna. Proin felis. In iaculis, ligula id fringilla pretium, nibh diam accumsan tellus, eget accumsan metus dui varius turpis. Phasellus orci metus, eleifend sed, tempor ac, scelerisque ac, urna. Integer viverra neque a mauris. Mauris porttitor dolor eu velit. Integer odio elit, vestibulum ut, volutpat id, rhoncus commodo, urna. Etiam placerat pharetra erat. Ut tempor est. Integer dignissim blandit tellus. Morbi nibh dolor, scelerisque id, commodo malesuada, mattis at, mi. Cras tincidunt commodo purus. In tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ullamcorper. Ut hendrerit. Morbi ultrices. + +Praesent iaculis, eros ac egestas sodales, urna leo fermentum ligula, sit amet aliquam velit sem non purus. Donec rutrum arcu quis purus. Nam posuere, lacus at consequat placerat, nulla pede posuere orci, non euismod turpis dui quis nisl. Proin porta adipiscing nibh. Donec tristique dolor at tellus. Donec neque massa, auctor id, faucibus vitae, ullamcorper vel, nisi. Proin molestie neque sed massa. Nam tempor. Morbi aliquam sapien at tellus. Fusce quis risus et mi pretium pulvinar. Fusce sit amet ligula. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse eu enim et felis scelerisque lobortis. Praesent bibendum. Vivamus vehicula. Integer at nibh sed velit rhoncus molestie. Cras lacus. Sed ullamcorper eros vel erat. Fusce eu tortor sit amet diam euismod sagittis. Nunc quis lacus id nibh convallis varius. Suspendisse vitae mi. Vestibulum tristique. Donec malesuada ipsum id neque. Nullam sed lacus. Duis egestas, justo ut congue ornare, augue sapien luctus diam, at accumsan erat sapien ut libero. Phasellus vel nulla. Suspendisse arcu tellus, porttitor a, pharetra faucibus, aliquam sit amet, massa. Nulla porttitor tincidunt lorem. Nunc dolor odio, sagittis in, lobortis vel, volutpat sed, nibh. + +Quisque blandit leo ut sapien tempus facilisis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean ultricies porttitor justo. Fusce rutrum eros ut urna. Proin quis quam eget dui aliquam accumsan. Donec suscipit eleifend elit. Pellentesque mattis, felis sodales iaculis imperdiet, lacus sem convallis augue, sit amet aliquet arcu purus fringilla risus. In eu odio id magna pharetra ornare. Aliquam interdum pulvinar ipsum. Sed neque. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam sit amet nisi. Ut at augue. Mauris volutpat blandit ligula. Nulla eu metus. Vestibulum eget elit. Praesent posuere. Vestibulum id sem non lectus mollis tincidunt. Aliquam id felis at ante ornare tempor. Nulla lacus turpis, feugiat vitae, cursus quis, consectetuer non, mauris. Fusce lacus massa, porttitor ut, molestie ut, venenatis a, lorem. Praesent sit amet orci. Mauris rhoncus felis vitae felis adipiscing imperdiet. Maecenas mollis diam nec leo. + +Fusce enim ipsum, ultrices eu, molestie id, elementum id, sapien. Integer a urna. Nam velit libero, venenatis eget, tempor sit amet, feugiat vitae, ante. Fusce nunc. Sed semper nisl nec risus. In sed libero. Proin tortor neque, tincidunt ac, tempor ac, pharetra quis, velit. Duis lectus augue, ultricies vel, consequat id, iaculis id, ante. Vivamus auctor metus a ante. Curabitur arcu nisi, facilisis at, laoreet in, consectetuer sed, mauris. Quisque placerat diam sed dui. Vivamus pretium condimentum lorem. Curabitur laoreet. Aenean orci ligula, cursus eget, lacinia non, faucibus vel, lorem. + +Aliquam erat volutpat. Curabitur eros dolor, congue a, condimentum sed, luctus ut, nibh. Maecenas non tortor nec turpis commodo pellentesque. Praesent euismod placerat mi. Suspendisse potenti. Phasellus ut neque vitae orci mattis iaculis. Integer eget tellus. Donec at ante. Nam lacinia leo eget erat. Maecenas euismod magna congue tortor. Morbi nec massa eu enim malesuada sollicitudin. Sed accumsan. Nullam ipsum. Ut odio. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque id velit. Nam odio sem, aliquet ut, tempus sit amet, euismod et, nunc. + +Pellentesque libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent mauris nunc, varius ut, convallis molestie, luctus sit amet, leo. Sed dictum lorem et arcu. Nunc venenatis pellentesque massa. Nulla facilisi. Phasellus in tortor eget risus scelerisque vulputate. Sed nibh elit, sagittis ac, condimentum nec, convallis et, justo. Fusce volutpat metus. Nunc auctor. Vestibulum leo eros, pellentesque ac, mollis ultrices, rhoncus non, dolor. Mauris vehicula placerat nisl. Vestibulum bibendum, arcu quis congue elementum, velit nunc eleifend turpis, id luctus risus nisl sit amet tellus. Phasellus pede neque, blandit non, commodo vitae, ultricies eget, magna. Aliquam erat volutpat. + +Nulla facilisi. Aliquam ac ante. Cras risus. Morbi mauris lacus, posuere eu, blandit et, pharetra at, mi. Proin ac purus. Duis cursus nisl rutrum quam. Aliquam a odio non magna pellentesque ultricies. Maecenas ac massa quis sapien ullamcorper tempus. Cras cursus velit sed sapien. Proin nulla. Vivamus sodales aliquam nibh. Etiam et erat ut ante lacinia euismod. Fusce nisi. Proin quis nulla. + +Quisque venenatis, eros sed laoreet sollicitudin, orci ante pellentesque nisl, sit amet viverra quam erat non risus. Cras eget libero. Sed elit magna, semper eu, fringilla in, dignissim sodales, erat. Vivamus feugiat sem vel dui. Donec convallis sollicitudin diam. Cras sed purus. Donec felis eros, semper eget, tempor consectetuer, sagittis quis, nisl. Duis in ante. Cras non turpis. Nulla tempor velit aliquet turpis molestie placerat. Proin elementum fermentum mauris. Vivamus sed orci lacinia dui placerat venenatis. Vestibulum feugiat, tellus in volutpat rutrum, magna nisi ullamcorper eros, id pulvinar neque erat ut lacus. Vivamus sed augue. Nulla facilisi. Maecenas ante augue, elementum ut, sodales vitae, condimentum nec, lorem. Duis pede orci, fringilla at, eleifend nec, pretium in, erat. Nam sagittis, turpis vitae convallis pharetra, odio sem scelerisque lacus, nec lobortis dui diam vel eros. In semper gravida neque. + +Integer nunc. Ut pretium ipsum sit amet elit. In nec arcu. Sed vestibulum vulputate ipsum. Pellentesque tincidunt. Nulla gravida dolor in tellus. Cras vehicula, dolor ut pellentesque aliquam, erat enim auctor massa, vehicula lobortis odio eros quis quam. Proin dapibus neque in enim. Proin elit. Integer rhoncus tincidunt elit. Fusce lorem metus, semper ac, volutpat vitae, facilisis ut, tellus. Donec vel turpis vitae nisi pharetra porttitor. Maecenas tortor. Fusce mi. Nullam nec turpis. Sed sodales vestibulum nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Pellentesque dolor dolor, laoreet eu, aliquet quis, scelerisque sit amet, arcu. In hac habitasse platea dictumst. Nullam cursus urna eget elit. Quisque blandit sapien ac ante. Proin nulla eros, gravida volutpat, sodales vel, mollis eu, massa. Nulla tristique sollicitudin nisl. Curabitur vitae lorem vitae velit egestas ornare. Aenean eget eros. Aliquam erat volutpat. Fusce a urna id odio aliquet convallis. Curabitur sit amet nisl posuere leo posuere dapibus. Duis metus erat, luctus vel, rhoncus at, convallis sit amet, enim. Vivamus hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam eget elit. + +Nullam a nunc. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In metus urna, tincidunt et, lacinia sit amet, lobortis vitae, ligula. Proin et mauris vitae mi accumsan pellentesque. Etiam quam purus, hendrerit sed, feugiat vitae, euismod eget, tortor. Ut aliquam magna vitae justo. Suspendisse non justo vel velit condimentum tempus. Duis tempus ipsum vitae tellus. Proin in massa. Etiam ullamcorper dictum tellus. Proin aliquet felis at leo laoreet pulvinar. Vestibulum arcu purus, malesuada sit amet, cursus eu, placerat sit amet, nunc. Nam massa odio, sollicitudin in, adipiscing a, aliquam nec, risus. Aliquam blandit hendrerit libero. Mauris gravida. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur a nibh. Ut interdum fermentum neque. Pellentesque sed nunc. Mauris vehicula nisi et nunc. Praesent lorem. Donec semper. Integer eu lacus in est aliquam hendrerit. Vestibulum eget neque. Sed semper luctus velit. Curabitur nibh augue, congue eu, hendrerit id, congue et, enim. Integer placerat aliquam lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae eros. Donec vel nisl. + +In vestibulum facilisis urna. Ut risus. Mauris pharetra. Pellentesque mattis. Integer suscipit aliquam ipsum. Duis blandit, sapien et ultricies condimentum, felis mi elementum pede, nec sagittis metus mauris quis quam. Quisque accumsan arcu vel nulla. Cras sem sapien, porttitor id, ultricies sagittis, luctus eu, nulla. Integer quis eros. Morbi sed urna a tellus vehicula vulputate. Etiam nec augue eget felis semper tristique. Quisque ut dolor vel risus dictum consequat. Sed eget dolor sed nunc lacinia aliquet. Suspendisse ac tortor in ipsum posuere venenatis. Sed eget erat. Nulla faucibus. Duis laoreet, massa porttitor aliquet egestas, ipsum lectus rhoncus quam, in adipiscing eros sem ut tellus. Pellentesque feugiat tempus quam. Vivamus id dolor eget sapien consectetuer tempor. Aliquam erat volutpat. + +Nulla iaculis fermentum libero. Curabitur faucibus, massa malesuada cursus tincidunt, erat sem eleifend mauris, sed fringilla mi ante ac purus. Duis elementum lectus. Nunc ornare arcu eu tortor. Vestibulum vel dolor at purus lacinia fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas tincidunt, eros a egestas pellentesque, risus risus dictum libero, id aliquet metus justo in massa. Proin a tellus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed purus. Sed non pede. Aenean massa sapien, sodales sit amet, consequat dictum, eleifend vitae, tortor. Donec ultrices lacinia elit. + +Morbi adipiscing sodales dolor. Ut ullamcorper ultricies est. In venenatis tempus augue. Suspendisse tortor dolor, accumsan et, suscipit a, tincidunt ut, libero. Aliquam scelerisque magna sed felis. Quisque ut nunc a magna vulputate placerat. Aliquam rhoncus vehicula dui. Sed tortor. Nullam sit amet diam. Nunc sed eros. Sed et odio tincidunt elit gravida convallis. Curabitur quis tortor a lacus semper varius. Mauris at augue non mi sollicitudin aliquam. Integer ullamcorper. Pellentesque suscipit quam non purus. Aliquam ac eros at arcu ullamcorper consectetuer. Suspendisse pretium mattis leo. + +Duis at nunc. Sed dolor est, varius ac, porta et, tincidunt hendrerit, risus. Vivamus ut magna. Praesent ut mauris. In purus lacus, mattis sed, vestibulum nec, tempor at, nisl. Cras ullamcorper venenatis tellus. Ut dolor. Maecenas malesuada, pede a pulvinar mattis, arcu diam vehicula risus, quis porttitor augue massa in velit. Nunc congue. Morbi velit metus, rhoncus et, aliquam consectetuer, ultricies malesuada, ligula. Sed velit nisl, sagittis vitae, pharetra a, posuere sed, massa. Nulla facilisi. In varius, ligula id lobortis sodales, augue orci fermentum tellus, eu pulvinar risus ligula a sapien. Morbi laoreet ipsum non mi. Nam cursus lorem ut mi. Vivamus magna enim, posuere non, semper quis, sodales eu, arcu. Etiam mi purus, pretium feugiat, varius sed, pellentesque eget, ligula. In leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vitae orci eu orci sollicitudin feugiat. + +Praesent purus massa, euismod vitae, tempus nec, consequat hendrerit, metus. Aenean felis est, egestas vitae, accumsan eget, pellentesque in, sapien. Duis dapibus pede non sapien. Nunc urna. Integer vel libero. Duis augue arcu, dapibus non, facilisis vitae, posuere ut, eros. Donec vitae nunc sit amet arcu imperdiet dictum. Morbi eleifend, lorem eu consectetuer vestibulum, diam nunc ornare arcu, ac tempor felis dolor eget eros. Phasellus massa sem, sollicitudin ac, sodales gravida, luctus a, quam. Nam neque quam, viverra at, venenatis quis, sagittis non, enim. + +Nulla facilisi. Pellentesque egestas lacinia est. Sed tincidunt, pede sed tincidunt vestibulum, urna dolor adipiscing purus, vitae fringilla felis elit in nibh. Nulla sed nisi. Mauris suscipit scelerisque arcu. Etiam non enim vel eros accumsan malesuada. Nunc tincidunt commodo mauris. In tincidunt risus quis urna. Nulla diam tortor, aliquet et, tincidunt quis, sollicitudin ac, tortor. Cras nisl neque, vulputate suscipit, molestie quis, pulvinar at, nulla. Nullam ac metus nec odio posuere varius. Cras sed pede nec dui posuere bibendum. Duis euismod ullamcorper libero. Aliquam faucibus pulvinar turpis. + +In ut neque id nunc feugiat commodo. Curabitur dignissim, felis at sollicitudin lacinia, enim elit suscipit neque, sed luctus lorem ipsum in leo. Duis dapibus, odio quis auctor commodo, nisl odio mattis tellus, nec tincidunt turpis diam in arcu. Curabitur a sem. Nullam volutpat magna. Pellentesque sagittis, neque consequat pretium cursus, dolor lacus consectetuer arcu, sed laoreet est urna et metus. Suspendisse placerat, dui a porta tempor, lorem dui lobortis neque, sed venenatis diam enim id eros. Etiam et nisl non lectus faucibus consectetuer. Morbi scelerisque, sem nec tempus ullamcorper, ipsum diam feugiat lorem, a fringilla sapien elit quis nibh. Nullam diam urna, viverra sed, pharetra rhoncus, tincidunt vel, orci. Integer accumsan mattis erat. Nam dictum. Mauris nec leo. Nulla iaculis. Nulla nisl mi, dapibus quis, vehicula a, cursus eget, odio. + +Phasellus dapibus euismod nibh. Vivamus imperdiet ante in ligula. Pellentesque accumsan. In imperdiet, dui a auctor fringilla, metus nisi cursus dolor, vel luctus ligula lorem vitae mauris. Praesent mattis vestibulum elit. Aliquam enim lacus, pulvinar non, lacinia sit amet, eleifend non, velit. Vestibulum ac leo. Mauris imperdiet justo ac lectus. Sed molestie lectus sed dui. Sed fermentum tempus mauris. Nam ornare orci ac tellus. Ut malesuada, lacus id lacinia accumsan, diam elit adipiscing metus, et bibendum sapien nibh blandit orci. Suspendisse ipsum tellus, sagittis quis, vestibulum non, vulputate eu, eros. Praesent at nulla id pede scelerisque ultricies. Cras blandit pretium tellus. Maecenas dapibus condimentum augue. Phasellus tincidunt pharetra lorem. Morbi non eros. Sed tempor, nisl a tincidunt tincidunt, eros diam dictum sem, vel dignissim ante diam sed magna. Praesent non ligula id metus molestie consectetuer. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse vel mi. Curabitur ante nulla, rutrum a, convallis vel, vehicula ac, nunc. Nunc sagittis, enim sit amet auctor rutrum, mauris arcu vulputate neque, et euismod est felis quis ante. Vestibulum turpis tellus, hendrerit in, lacinia commodo, ullamcorper gravida, risus. Mauris rhoncus lacinia risus. Maecenas sollicitudin erat vitae nunc. Praesent pretium pellentesque augue. Donec interdum. Praesent ac eros vitae erat lobortis fringilla. Aenean consequat tellus. Nulla accumsan bibendum felis. Maecenas pretium ante id nisi. Aenean mi arcu, semper sed, mattis eu, venenatis sit amet, arcu. Donec aliquet euismod leo. Proin magna justo, tristique a, semper ac, sollicitudin a, ligula. Morbi velit. Aliquam vel nisi. + +In a lorem ut nunc feugiat congue. Donec fermentum bibendum dui. Proin varius est quis velit. Donec aliquet sem accumsan mi. Sed placerat. Nullam ac nisi a massa lobortis suscipit. Nunc id leo. Aliquam et massa. Nullam vestibulum elementum metus. In consectetuer nisi vel justo. Maecenas eget purus sed massa varius pellentesque. Phasellus faucibus felis quis felis. Aenean odio arcu, blandit quis, facilisis in, imperdiet eu, lorem. Nam posuere pulvinar mi. Fusce tristique, mauris et consectetuer ultricies, mauris lectus tempor justo, at fringilla est est sed nisi. Quisque faucibus. Sed in tortor tincidunt est lacinia iaculis. Maecenas a massa. Pellentesque a nibh at purus porta hendrerit. + +Nullam turpis. Fusce ac sem sed odio pellentesque imperdiet. Curabitur in arcu. Praesent lacus lacus, feugiat id, pulvinar in, tincidunt sed, neque. Maecenas viverra odio eget tortor. Integer aliquam, lorem rutrum venenatis dignissim, ligula magna malesuada arcu, vel feugiat lorem ipsum quis massa. Morbi ante. Vestibulum mauris libero, ullamcorper quis, ultrices quis, facilisis non, massa. Maecenas imperdiet. Aliquam erat volutpat. Pellentesque dignissim gravida lectus. In nibh odio, auctor eget, dapibus quis, dignissim venenatis, arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis pellentesque ligula quis massa. Curabitur condimentum, justo eget ornare luctus, lorem ligula sagittis pede, a porta nunc nunc in neque. Quisque felis mauris, condimentum vitae, auctor vitae, tincidunt quis, pede. Nunc lacinia ante in leo. Pellentesque libero. Aenean a ligula et nunc vestibulum consectetuer. + +Fusce ornare. Praesent id urna. Integer venenatis, quam non sagittis accumsan, ante nibh sagittis augue, sollicitudin adipiscing dolor velit eu erat. Proin quis enim eu purus vehicula aliquam. Nulla vel enim vel elit sollicitudin fringilla. Aliquam erat volutpat. Sed suscipit felis ut turpis. Etiam rutrum risus imperdiet est. Aliquam a tellus at tellus commodo dapibus. Mauris rutrum magna et odio. In at dolor. Curabitur vehicula lectus in tortor. Fusce justo purus, luctus vitae, mollis in, pharetra ac, purus. Nullam posuere interdum justo. Curabitur vitae lacus vel leo congue pulvinar. + +Aenean eleifend nibh varius tortor. Suspendisse vel eros. Proin nec diam a tortor ultrices ornare. Aliquam scelerisque feugiat justo. Vivamus ante urna, adipiscing vitae, porttitor eu, sodales et, felis. Suspendisse potenti. Curabitur ac massa in nisl sagittis mollis. Nam quam ligula, consectetuer eget, iaculis at, varius eu, leo. Duis dolor ligula, tincidunt at, ullamcorper sed, accumsan aliquam, ligula. Phasellus vulputate, lorem at tincidunt pharetra, risus lectus lacinia magna, quis rutrum enim magna at sem. In hac habitasse platea dictumst. Duis id sem a mauris sollicitudin tincidunt. Etiam eu purus eu arcu fringilla adipiscing. Vivamus ornare tempus diam. Proin turpis quam, lacinia non, egestas at, commodo eget, pede. Praesent vulputate risus in est. Nulla facilisi. + +Ut elementum lacinia purus. Proin vitae arcu ac nulla convallis aliquam. Nulla congue, libero id pellentesque mattis, quam lectus porttitor diam, a scelerisque dui libero in sapien. Nullam felis diam, vehicula vel, molestie ut, vestibulum aliquam, sapien. Donec convallis, est ut elementum volutpat, mauris ipsum gravida sem, commodo facilisis sapien lectus semper lectus. Quisque porttitor eros ut nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam mattis risus sed odio. Vestibulum et odio. In hac habitasse platea dictumst. Nam tristique massa ut ligula. Quisque nibh tellus, vehicula sit amet, adipiscing at, convallis nec, ligula. Vestibulum pretium, mi nec fringilla bibendum, dui nunc sodales pede, a semper magna nibh non diam. Donec massa nunc, viverra vel, consectetuer porta, dapibus non, ipsum. Duis nisl mauris, cursus vel, semper non, sollicitudin bibendum, felis. Vestibulum eu neque. + +Cras nec dolor. Donec laoreet tempus lectus. Cras sed tortor interdum lacus eleifend dignissim. Maecenas sit amet elit. Nullam quis dolor vel dui pharetra luctus. In sit amet quam sit amet pede ultrices ultrices. Maecenas diam. Integer urna. Curabitur dictum, velit sed placerat suscipit, erat turpis fermentum justo, sed interdum neque sem et nibh. Vivamus consequat convallis magna. Nam aliquam, est ac bibendum commodo, magna est dictum mi, vitae malesuada elit magna vitae odio. Maecenas tempor vulputate tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus dui. Etiam accumsan pede congue tortor. + +Morbi tempor libero ac lorem. In aliquet varius magna. In arcu. Phasellus odio. Fusce tincidunt aliquet felis. Quisque velit. Sed luctus. Aliquam feugiat fringilla mi. Aliquam molestie viverra risus. Proin arcu. Vestibulum lobortis tempus nisi. Praesent a arcu in velit viverra rutrum. + +In sed lectus. Donec risus dolor, blandit sit amet, elementum convallis, pharetra quis, pede. Integer ornare. Aenean egestas dapibus justo. Sed quam leo, posuere at, elementum vitae, commodo eget, est. Aliquam molestie rhoncus enim. Curabitur iaculis ultrices pede. Morbi aliquet rutrum lacus. Aliquam quam. Sed commodo, turpis in pharetra posuere, mi risus imperdiet erat, a vestibulum massa tellus vehicula sem. Mauris fringilla ultrices nunc. Nam nisi enim, eleifend sit amet, ultrices sed, fermentum non, augue. Proin congue lobortis nisi. Maecenas hendrerit. Nam sed nisl. Nunc elementum odio eu risus. In metus. Phasellus gravida pretium ligula. Nulla vitae neque. Nam nisi tortor, ornare non, blandit at, cursus eu, tortor. + +Duis bibendum ipsum in nunc cursus molestie. Nunc orci. Nullam nec ante non est dignissim viverra. Mauris blandit, velit id feugiat pretium, elit magna pellentesque dolor, at sagittis lacus velit egestas magna. Pellentesque cursus, diam consectetuer sagittis fringilla, tortor nisi adipiscing nunc, eu varius lacus risus ac elit. Mauris id nisi quis leo euismod venenatis. Pellentesque ac ante. Mauris arcu sapien, tempor at, porttitor id, condimentum ut, dui. Etiam fermentum ultricies augue. Cras ut eros at justo ultricies iaculis. Duis dignissim, nisl et facilisis fermentum, erat purus molestie tellus, quis tempus ipsum lectus at elit. Nulla vitae lorem. + +Aenean vel sem et diam semper congue. In bibendum diam quis tellus. Nunc facilisis ultricies nibh. Cras nunc enim, feugiat sed, ultrices vitae, sagittis vitae, ipsum. Fusce vitae nulla. Donec pellentesque, velit in porttitor eleifend, est neque lobortis velit, sit amet rutrum ante tortor nec dolor. Donec vehicula. Nulla facilisi. Sed egestas ultrices nibh. Donec elit lectus, convallis porttitor, aliquet dapibus, feugiat eget, ligula. Sed consectetuer justo. Maecenas a sapien sit amet nisi dapibus lobortis. Vivamus luctus lorem non nulla. Sed eget erat vitae libero interdum posuere. Cras pulvinar. Nullam imperdiet, dolor tempor dignissim blandit, dui sapien rhoncus neque, id malesuada augue magna sit amet urna. Duis sed mauris. + +Morbi accumsan. Sed mauris augue, fringilla non, auctor ut, auctor et, orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus ut pede. Donec viverra enim vel lorem. Pellentesque neque mauris, interdum eu, venenatis id, condimentum eu, sapien. Donec ipsum arcu, lacinia adipiscing, laoreet et, cursus vel, velit. Ut sagittis mauris quis risus. Integer eu odio vitae lacus viverra accumsan. Morbi leo ante, dignissim sed, varius quis, volutpat vitae, nisi. Nulla placerat interdum elit. Donec neque dui, sagittis vitae, sollicitudin quis, commodo vitae, neque. Nulla quis ligula ornare ligula dictum ornare. Mauris rutrum rutrum neque. Aenean vehicula tempus est. Donec varius scelerisque pede. Donec placerat vulputate leo. Nullam nunc nisl, posuere non, feugiat vitae, pellentesque quis, mauris. In dui neque, cursus eget, sagittis eget, dapibus vitae, mi. Proin eget est. + +Fusce porta est. Mauris magna. Aliquam ipsum lacus, ultricies id, vestibulum luctus, accumsan ut, ante. Sed mauris. Sed adipiscing leo sit amet magna. Suspendisse potenti. Nunc massa elit, fringilla eget, egestas vitae, luctus vitae, dolor. Phasellus quis nulla eu nisi interdum sollicitudin. Nullam id tellus. Integer iaculis dolor ac purus. Sed vel mi. Curabitur non magna sit amet justo condimentum vulputate. Quisque tincidunt pede eu nisl. Vivamus lobortis. Nunc metus metus, congue sed, tincidunt sed, pretium at, odio. Donec a arcu. In sem justo, vehicula sed, varius id, volutpat at, risus. Praesent iaculis massa. In arcu elit, hendrerit eget, ullamcorper in, porta id, tellus. Donec sagittis hendrerit diam. + +Suspendisse potenti. Sed et diam et augue sagittis lobortis. Phasellus dolor. Ut et arcu eget ante tempor posuere. Aliquam fermentum scelerisque dui. Mauris at purus. Donec erat sem, vestibulum nec, faucibus ac, mattis a, leo. Suspendisse adipiscing lacinia sem. Nullam orci arcu, dictum et, faucibus viverra, dapibus et, neque. Cras nunc diam, adipiscing non, sollicitudin in, interdum vel, massa. Mauris sagittis, justo at tristique tempus, mauris mauris aliquam ante, sit amet posuere diam dui eget ligula. In dignissim, nisl ut lacinia condimentum, erat justo porttitor nulla, non gravida ligula magna eget massa. Vestibulum vitae ligula at mi vestibulum suscipit. Duis laoreet. Nulla commodo libero sit amet lorem. Ut elementum sem. Integer vel dolor. Nam facilisis mi quis sem ultrices sagittis. Sed quis quam at metus molestie bibendum. + +Proin dui enim, lacinia a, feugiat ac, placerat vitae, pede. Quisque egestas, leo eget aliquam pretium, libero justo tincidunt eros, ut egestas augue pede elementum nibh. Curabitur mollis sodales enim. Donec augue. Phasellus id ipsum posuere dui pretium faucibus. Mauris luctus ante semper nisi interdum adipiscing. Duis dapibus, odio quis viverra rhoncus, justo quam bibendum dolor, id dapibus velit erat vel erat. Fusce sit amet nisl venenatis quam ultrices condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec rhoncus scelerisque ligula. Vestibulum mi odio, accumsan et, adipiscing eget, ornare ut, quam. Nullam blandit molestie mauris. Curabitur dignissim mauris et lorem. Suspendisse a justo. Nam mattis faucibus arcu. Duis blandit enim non massa. + +Nullam lorem. In hac habitasse platea dictumst. Mauris consectetuer posuere mauris. Maecenas tincidunt mauris in eros. Nulla eu metus eu orci sollicitudin faucibus. Suspendisse aliquam mauris id est. Cras blandit dui et urna. Nulla arcu. Sed a urna. Nulla dapibus vehicula tortor. Donec risus. Sed quam metus, egestas eu, cursus ut, viverra non, odio. Ut justo justo, malesuada sit amet, blandit suscipit, molestie in, justo. Vestibulum consequat, quam ac feugiat tincidunt, ipsum libero eleifend odio, non eleifend pede ipsum non ante. Nullam a metus. + +Nam ac nisi at felis cursus mattis. Pellentesque consequat sem quis orci. Quisque tempus. Aenean imperdiet molestie pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eu tellus. Nulla diam eros, sodales ut, sodales nec, tincidunt ac, nunc. Nunc lacinia faucibus ipsum. Vivamus vel neque in erat fermentum luctus. Nulla eget metus nec augue bibendum placerat. Vivamus tempus. Praesent congue ornare ipsum. Etiam mattis feugiat justo. + +Aliquam dui. Aenean commodo tortor vitae nulla. Morbi et ipsum. Mauris ac ipsum. Nam vel risus ut lectus mollis viverra. Curabitur elementum mollis est. Nullam elit. Vestibulum suscipit pretium enim. Vestibulum ut massa. Proin nec felis. Maecenas gravida, arcu nec consequat sagittis, eros tellus scelerisque mauris, vitae accumsan quam quam ut nunc. Integer eget ante eu velit laoreet malesuada. Nunc sagittis, mauris vitae pharetra volutpat, tellus tellus eleifend eros, sit amet rutrum ipsum nisi a velit. Praesent varius leo eu erat. Vivamus consequat placerat purus. Donec pretium elementum nibh. Proin at elit non sem aliquet mattis. Sed ullamcorper ipsum sit amet elit. + +Mauris in metus. Suspendisse magna lorem, faucibus vel, tincidunt quis, scelerisque non, tellus. Fusce quis lorem. Proin a lacus sit amet mauris iaculis pulvinar. Suspendisse rhoncus eros nec mi. Praesent euismod, turpis vitae rutrum pretium, odio metus volutpat neque, eget tempus sapien neque sed erat. Donec fermentum purus at lectus. Nullam sem. Fusce vel mi quis erat lobortis posuere. Aenean eget urna. Suspendisse ligula. Duis in nisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Curabitur vulputate lectus id pede. Phasellus eu velit. Etiam venenatis adipiscing nibh. Aliquam cursus pulvinar tellus. Vestibulum neque. Mauris nec justo et erat semper pellentesque. Fusce mattis dictum dolor. Etiam eget purus eu massa varius elementum. Pellentesque massa. Ut ultricies diam sed ipsum. Nullam diam. Pellentesque id magna id libero tristique aliquam. + +Ut eleifend, purus id placerat venenatis, urna augue aliquet ligula, in ultricies leo risus et tellus. Mauris et nulla id urna tristique tempus. Ut facilisis, urna eu vestibulum rhoncus, lacus eros consectetuer metus, et rutrum dui lectus in purus. Nunc vel nisl non ipsum tincidunt mollis. Nam quam lacus, ornare vitae, rhoncus non, congue sed, odio. Proin nibh dui, porta vel, venenatis non, pellentesque ut, nisi. Sed tristique felis a magna. Suspendisse eget tellus. Cras gravida imperdiet velit. Integer hendrerit risus. Proin orci. Aliquam ullamcorper mauris quis mauris. Nunc lacinia vestibulum metus. Duis tellus. Nullam faucibus, leo ac vulputate sollicitudin, leo dolor faucibus erat, quis bibendum orci odio non arcu. + +Nullam accumsan mattis dolor. Donec et dui. Praesent a felis mollis lacus semper lacinia. Curabitur pellentesque luctus est. Proin nulla dui, condimentum vel, faucibus non, interdum ac, erat. Maecenas scelerisque, lectus id volutpat accumsan, sapien tortor pellentesque dui, sed semper magna sem ut leo. Proin nulla. Nullam dapibus ullamcorper sem. Suspendisse vehicula metus in nunc. Pellentesque non quam vel arcu ultrices ullamcorper. Phasellus quis felis sit amet tellus ullamcorper fermentum. Sed vehicula sollicitudin urna. Curabitur pharetra scelerisque risus. Pellentesque id massa quis metus aliquam imperdiet. In nunc lacus, feugiat in, gravida eget, venenatis ut, tellus. Suspendisse potenti. Nam consequat adipiscing dui. In nulla nisi, feugiat ut, fermentum vel, gravida nec, tortor. In sed augue. + +Etiam ullamcorper augue at enim. Integer dignissim. Aliquam pulvinar congue nulla. Morbi enim massa, fringilla a, accumsan eget, condimentum nec, erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean pharetra. Etiam porttitor purus a metus. Aliquam interdum sem eget justo. Quisque volutpat luctus est. Aenean augue. Phasellus dui lectus, ultrices nec, commodo vel, auctor vel, nisi. Ut ultrices pellentesque nisi. Integer ac velit et sem imperdiet luctus. Fusce vitae turpis id augue mollis consectetuer. + +Maecenas nec lacus. Maecenas condimentum odio eu felis. Mauris ut nisl viverra erat faucibus adipiscing. Etiam egestas. Nunc et dolor vitae risus dignissim commodo. Morbi lectus velit, tincidunt nec, aliquet vel, mattis vitae, ligula. Maecenas ultricies semper dolor. Suspendisse malesuada. Integer mattis elit. Donec accumsan, lacus facilisis varius tempus, nulla elit porta erat, et rutrum elit sem sit amet dui. + +Maecenas mollis mi non nulla. Vivamus turpis. Suspendisse a metus. In quis mi in turpis congue auctor. Maecenas lacus. Suspendisse sollicitudin. Phasellus porta nunc non nisl pulvinar egestas. Sed nulla. Vestibulum ac mi. Mauris ultricies condimentum neque. Nulla tempus justo vel massa. Nulla suscipit congue arcu. Praesent id turpis. Mauris nibh pede, euismod semper, molestie ac, rhoncus vitae, ante. Maecenas erat felis, viverra sollicitudin, sagittis eget, pellentesque nec, orci. Fusce ultrices consequat lacus. Aliquam erat magna, feugiat at, viverra a, mollis non, turpis. + +Donec mi. Nam dictum pellentesque sem. Donec mollis rhoncus elit. Phasellus rhoncus pede sit amet risus. Donec eget augue. Maecenas non lectus. Phasellus sollicitudin nisi nec felis. Aliquam pretium, est eget semper convallis, nibh nunc sollicitudin purus, id tempor pede dui vel magna. Vivamus ac lorem. Etiam nisl tortor, adipiscing dictum, elementum in, facilisis sed, nibh. Proin mauris. Proin rutrum massa eget sem. Curabitur tempor adipiscing elit. Curabitur purus tellus, fermentum eget, aliquet vitae, convallis ac, mauris. + +Integer consequat velit eu eros tincidunt vehicula. Nullam lorem sapien, rhoncus non, mattis quis, ultricies sit amet, enim. Curabitur commodo, libero in euismod suscipit, sem purus fringilla enim, ac molestie tortor orci et velit. Donec pede. Etiam placerat condimentum turpis. Phasellus egestas enim nec magna. Vivamus condimentum, nulla vel luctus tristique, eros risus vestibulum nulla, in vehicula arcu ipsum at felis. Donec aliquam elit at augue. Quisque a eros eu ligula accumsan dictum. Etiam vehicula turpis quis libero. Aliquam non mi. Donec et leo. Proin leo libero, aliquam tincidunt, congue nec, adipiscing porta, enim. Nulla lobortis, tortor sit amet imperdiet ullamcorper, dolor orci malesuada pede, sed gravida nibh urna vel lorem. Sed pharetra malesuada eros. Quisque euismod aliquet erat. Suspendisse aliquet mattis purus. + +Nunc id nulla quis justo congue sollicitudin. Praesent erat turpis, rhoncus eu, pretium eu, pellentesque a, nibh. Vivamus tempus. Cras nec risus at turpis imperdiet lobortis. Ut mattis. Maecenas est felis, pellentesque non, imperdiet sed, eleifend tincidunt, lorem. In tincidunt. Sed vel leo. Donec et urna in turpis hendrerit blandit. Donec condimentum accumsan est. Ut pharetra, metus vitae mattis consectetuer, leo quam vulputate odio, nec laoreet nisi velit eu erat. Integer lectus augue, egestas in, interdum eu, venenatis vel, sapien. Quisque et est vitae eros laoreet lobortis. Nullam ut risus non nulla placerat adipiscing. Praesent dapibus. Etiam a felis. Ut sodales consequat mauris. Duis lorem felis, luctus a, tristique in, molestie at, risus. Sed vehicula bibendum tellus. Nam consequat euismod lacus. + +Aenean tortor elit, gravida nec, fermentum eu, lobortis id, ipsum. Maecenas eu purus. Cras ac turpis ut nisi iaculis rhoncus. Nulla purus metus, dignissim nec, tincidunt vitae, dapibus eu, nibh. Fusce lobortis, nunc at viverra eleifend, justo turpis scelerisque eros, ac pellentesque metus nisl at purus. Sed elementum tellus sed enim interdum blandit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer ultricies aliquet odio. Mauris eget nunc a ipsum ultrices sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean accumsan. Donec sapien lectus, congue at, porta id, hendrerit vitae, nisl. Curabitur vel quam vel neque accumsan laoreet. Morbi sapien est, pretium in, consectetuer ac, mollis ut, libero. Donec tincidunt adipiscing metus. Nunc vestibulum egestas augue. Donec scelerisque dui ut sem. Suspendisse vel metus id est molestie iaculis. + +Vivamus pharetra, elit eu malesuada blandit, diam tortor mollis dui, sed pulvinar massa nunc et magna. Sed placerat elit auctor tortor. Nulla ac erat. Pellentesque consectetuer, dui convallis tincidunt condimentum, sem odio volutpat libero, non elementum felis neque nec odio. Maecenas hendrerit eros id diam. Mauris vel purus ac orci convallis convallis. Sed sit amet lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque dictum varius lacus. Mauris eget nisl. Suspendisse placerat, nulla non ornare dignissim, nisl diam sagittis tellus, in semper nisi dolor at nibh. Duis ullamcorper viverra felis. Integer a tellus. Suspendisse eget nunc. Aenean diam est, accumsan id, suscipit interdum, fringilla vitae, justo. Proin pede. Maecenas at neque in neque vestibulum eleifend. + +Vestibulum nulla lorem, porttitor eget, euismod ac, aliquam at, nisl. Maecenas et est eget massa varius lobortis. In mi. Duis porttitor fermentum purus. Donec cursus imperdiet ligula. Morbi et ligula et ante molestie vehicula. Mauris sed dolor. Sed imperdiet felis ut sem. Sed vitae neque elementum leo auctor fermentum. Duis feugiat ullamcorper erat. Aenean purus. Morbi fermentum vestibulum est. Pellentesque venenatis mauris. Phasellus pulvinar. Integer ipsum lectus, iaculis a, lacinia id, accumsan id, arcu. Phasellus at est. Fusce neque quam, ultricies id, iaculis vel, dapibus vitae, lacus. In lobortis convallis ante. Nulla nunc purus, vulputate in, hendrerit et, blandit et, ligula. + +Pellentesque leo metus, sagittis in, molestie vitae, dictum in, pede. Morbi pretium felis nec quam. Pellentesque mattis ante sed quam sagittis dapibus. Suspendisse sapien. Praesent bibendum iaculis tortor. Duis a nisl. Aenean mi. Donec dictum arcu in est. Morbi interdum vulputate ipsum. Aenean sit amet magna non nisl tristique posuere. Phasellus velit metus, tempor ac, fermentum eget, condimentum non, velit. Vestibulum sit posuere. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras aliquet massa nec dui. Cras arcu nunc, hendrerit ac, eleifend eu, ullamcorper nec, tellus. Sed pharetra purus sit amet quam. Curabitur mollis. Nam vitae pede. Etiam risus massa, vehicula sit amet, pharetra nec, sollicitudin ut, dui. Donec egestas justo at quam. Proin nisl risus, vestibulum nec, pretium vitae, tristique ac, lorem. Aliquam erat volutpat. Cras sed nibh. Pellentesque sollicitudin euismod augue. + +Etiam fringilla sollicitudin orci. Mauris cursus elit quis lacus. Cras tortor. In adipiscing, lectus id auctor vestibulum, neque pede accumsan dolor, non imperdiet magna diam accumsan velit. Suspendisse at libero ut nisi blandit sagittis. Phasellus non mauris. Fusce elementum sagittis sem. Suspendisse aliquam eleifend tellus. Proin ligula lorem, imperdiet quis, venenatis id, iaculis mollis, nisl. Etiam convallis pede at massa. Morbi accumsan dui et mauris. + +Sed sed orci. Nunc purus. Suspendisse potenti. Ut luctus fringilla mauris. Donec nibh. Phasellus porta. Phasellus sit amet odio sed magna sodales pharetra. Cras lectus. Suspendisse libero ipsum, commodo nec, facilisis in, suscipit lobortis, ligula. Duis massa nulla, semper et, consequat nec, pharetra eu, elit. Vivamus ultricies aliquam odio. Vestibulum sit amet massa. Sed consequat lacus sed urna. Etiam faucibus felis vel orci. Phasellus ullamcorper. Aenean consectetuer lacus at libero. + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis facilisis, ligula vitae condimentum scelerisque, velit orci gravida felis, vel ultricies quam mi non diam. Vivamus auctor metus non libero. Praesent ligula nisi, commodo condimentum, molestie et, viverra et, justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus sollicitudin. Nunc blandit cursus ipsum. Aenean nec ligula ut tellus sodales mattis. Integer sem. Aliquam id ligula. Sed tortor mauris, blandit vitae, cursus vel, elementum et, nulla. Aliquam scelerisque metus et nisl. Duis adipiscing magna at neque. Quisque vulputate eleifend nunc. Aliquam eget elit. Phasellus dui odio, bibendum sagittis, vestibulum id, dignissim imperdiet, orci. Nullam eu felis non nunc lacinia sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Suspendisse pellentesque, libero mattis ultricies accumsan, tortor tortor malesuada sem, et sodales libero odio ac ipsum. Vivamus quis magna nec est suscipit lobortis. Cras tempus posuere nunc. Quisque ut enim a felis egestas semper. Sed pharetra mattis neque. Fusce turpis nunc, congue sed, consequat non, congue sed, nulla. Suspendisse varius lorem id risus porta vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce sed purus. In a felis. Integer egestas auctor orci. Mauris ultrices suscipit nisl. Nullam purus. + +Cras tempor adipiscing ipsum. Ut quis mi. Maecenas in justo ut nulla congue pharetra. Pellentesque ut libero eu dolor venenatis suscipit. Praesent feugiat consectetuer nibh. Morbi faucibus sem non felis. In hendrerit arcu ac massa. In accumsan ultrices mi. Proin malesuada auctor felis. Curabitur interdum. Sed diam ipsum, ultricies in, tempor sit amet, viverra imperdiet, elit. Morbi molestie nisi. Mauris ipsum. Fusce dictum mollis magna. Duis commodo dignissim nulla. Vestibulum augue enim, ultricies quis, iaculis nec, tincidunt vitae, diam. Mauris lacinia tempus ipsum. Sed at mauris. Ut lorem. Donec libero. + +Duis iaculis lacinia lectus. Aenean convallis eros ac ante. Sed quis orci nec risus auctor fringilla. Phasellus facilisis elementum nisi. In hac habitasse platea dictumst. Nunc porta lacus nec ante. Morbi mauris erat, adipiscing in, pulvinar nec, lobortis nec, odio. Ut eleifend lectus sed quam. Nullam mollis. In non turpis et nisl hendrerit blandit. Duis elementum. Nunc nec libero. Suspendisse vestibulum risus non pede. Morbi imperdiet odio sit amet libero. Sed sed massa vitae ipsum mattis tincidunt. Nulla nec tortor vitae libero volutpat tempus. Donec aliquam. + +Duis sed nunc. Curabitur turpis nulla, vehicula sed, luctus quis, elementum eget, felis. Maecenas et purus. Maecenas leo tellus, tincidunt a, facilisis vitae, lobortis sit amet, velit. Donec convallis sapien. Maecenas mollis odio eu nibh. Etiam gravida. Integer molestie, sapien eu molestie lacinia, nunc nibh aliquam ligula, eu sagittis tellus erat sollicitudin odio. Duis et risus. Phasellus nisi neque, placerat nec, condimentum non, ultrices eu, sem. Ut pede. Etiam nulla metus, volutpat id, convallis sed, suscipit vel, urna. Donec vel elit. Ut leo neque, venenatis faucibus, lacinia nec, tincidunt eu, enim. Cras id dui a libero pharetra dignissim. Donec eros leo, porta quis, laoreet ut, pellentesque volutpat, lectus. + +Nullam blandit. Aliquam erat volutpat. Fusce adipiscing enim. Suspendisse non dui quis ligula porta vestibulum. Donec eu tellus vel lorem pretium porttitor. Praesent luctus. Aliquam ac eros in massa dapibus tincidunt. Donec ut magna. Etiam auctor lacus sit amet lacus. Sed ultricies ipsum nec elit. Quisque a est in purus suscipit tristique. + +Aenean sed dui vel dolor pulvinar laoreet. Vivamus vehicula lorem in pede. Vivamus et diam. Integer ac odio vel diam hendrerit bibendum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a nisi. Phasellus tincidunt dui vitae augue. Duis faucibus, dui interdum fringilla tincidunt, odio elit vestibulum libero, ac molestie magna lectus id lacus. Aenean ligula. Nulla facilisi. + +Fusce vel sem eu velit fringilla ornare. Sed feugiat tincidunt felis. Nullam felis mi, euismod sit amet, mollis at, sodales eget, augue. Nam imperdiet nibh at velit. Sed ut erat. In dui. Nulla facilisi. Nullam augue libero, tincidunt nec, pretium eu, pulvinar in, dui. Morbi vitae felis. Pellentesque vel justo vel velit sagittis malesuada. Proin vehicula blandit massa. Etiam tincidunt pharetra urna. In metus est, auctor nec, blandit a, cursus nec, quam. Mauris ac metus a libero congue faucibus. Mauris mauris dolor, sodales in, cursus ut, sodales rutrum, eros. Quisque mauris eros, sagittis vitae, lobortis ut, eleifend id, nisi. + +Aenean neque. Vestibulum egestas pellentesque ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus sagittis justo vel risus. Sed pretium neque vitae urna. Pellentesque congue libero id lorem. Mauris leo lorem, blandit sit amet, convallis quis, consectetuer sed, eros. Mauris tincidunt, enim a gravida euismod, magna nulla fermentum libero, viverra egestas velit quam et tortor. Vivamus aliquet massa vitae justo. Nulla congue lacus ac elit. + +Phasellus commodo quam vel ligula. Proin non metus at eros pulvinar luctus. Mauris diam lorem, posuere quis, gravida et, tincidunt nec, ligula. Sed diam. Aliquam elit lectus, hendrerit ut, imperdiet sit amet, pretium sit amet, ipsum. Mauris vehicula nisl in dui. Curabitur eget quam ut magna elementum fermentum. Mauris scelerisque. Quisque laoreet. Etiam tempus turpis. Pellentesque augue quam, hendrerit sed, tincidunt at, pharetra at, nisl. Aliquam lacus. Suspendisse potenti. Aenean velit libero, ultrices in, lacinia eu, luctus vel, ante. Etiam dictum mi in felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce gravida dapibus nisl. Cras vitae nisl. + +Maecenas dignissim, ligula non porta cursus, enim nunc malesuada sem, eu porttitor nulla urna eu quam. Fusce eros. Aliquam eros. Nam auctor. Nulla molestie porta est. Suspendisse potenti. Vivamus molestie lorem sed erat. Sed eget ipsum. Integer aliquam pulvinar nulla. Cras aliquet sem ut nunc. Fusce faucibus tempus lectus. Cras sodales, nisi ac facilisis ultrices, eros arcu dapibus sapien, et ultrices mauris tellus non dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras cursus varius metus. Ut turpis. Vivamus eget tortor. + +Sed laoreet, velit non accumsan cursus, nunc urna posuere justo, in dictum lectus pede id ante. Cras vulputate. Cras congue dui sed elit. Proin lacus sem, ultrices at, consequat in, tempor quis, metus. Proin vel arcu. Nam euismod hendrerit elit. Ut erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed posuere. Morbi eros urna, semper at, semper non, convallis quis, velit. Maecenas orci. Vestibulum lobortis tristique metus. Vestibulum lorem nulla, sollicitudin vitae, condimentum quis, auctor ut, dui. Vivamus vestibulum magna ut nisi. Curabitur eleifend dui vel nunc. Curabitur mauris lacus, malesuada sit amet, suscipit sed, rutrum luctus, tellus. Integer facilisis urna vitae lectus. + +Aenean quam leo, lobortis quis, malesuada eu, vulputate vitae, nisl. Praesent eget eros. Ut fermentum turpis id quam. Nam tortor. Praesent nec orci. Nulla bibendum adipiscing augue. Ut commodo, magna id malesuada gravida, augue odio malesuada mi, porta malesuada elit est vitae diam. Mauris non nulla. Suspendisse tincidunt, nunc ultricies porta venenatis, mi pede tincidunt libero, eget varius ante libero ut ligula. Curabitur pretium porttitor tortor. + +Maecenas vitae elit eget nisi dapibus dictum. Nunc in libero. Nulla dictum orci eu erat auctor lobortis. Phasellus risus. Suspendisse potenti. Suspendisse potenti. Praesent adipiscing consequat elit. Integer id augue. Praesent in justo nec magna dapibus pulvinar. Duis nisl. Suspendisse ac odio. Vivamus imperdiet. Donec non velit sit amet risus dignissim congue. Nam aliquet posuere velit. Cras turpis. Morbi malesuada dignissim mi. + +Sed leo neque, varius quis, venenatis sed, pharetra sed, est. Morbi blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam semper pellentesque mi. Ut vel lorem. Nunc mi tortor, laoreet at, faucibus eu, tincidunt sit amet, erat. Duis tempor malesuada ipsum. Phasellus aliquet. Donec et elit. Pellentesque purus. Vestibulum rutrum semper nibh. Nulla facilisi. Phasellus et enim sit amet ante vestibulum vehicula. Phasellus id nisl. Donec mollis leo at eros. Mauris pellentesque neque at purus. Morbi quis dolor at ipsum scelerisque sodales. Etiam volutpat turpis a metus. In hac habitasse platea dictumst. Nunc lorem lorem, vestibulum ac, euismod eget, ullamcorper dignissim, velit. + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ultrices, nibh vel aliquam vestibulum, eros enim venenatis dui, id iaculis enim nunc vel massa. Morbi eleifend orci et massa. Aliquam erat volutpat. Nulla mollis egestas turpis. In sodales nunc eget tortor. Sed ipsum eros, tempor quis, aliquet vitae, imperdiet non, lorem. Pellentesque quis elit id mi luctus dapibus. Sed nunc arcu, rhoncus nec, convallis quis, cursus at, neque. Mauris convallis purus at erat. Pellentesque vestibulum. Vivamus fringilla elit at arcu. Nullam aliquet enim nec arcu. Nam id tortor. Nulla quis nunc. Ut arcu. Suspendisse potenti. Pellentesque ullamcorper ligula id arcu. + +Nam non libero vitae nisl scelerisque fringilla. Quisque varius ante id metus rhoncus fringilla. Nulla facilisi. Praesent eleifend porttitor ligula. Etiam quis dolor non augue commodo auctor. Donec a mi. Vestibulum tempor. Donec felis urna, auctor at, cursus dictum, gravida id, arcu. Aenean dictum malesuada dolor. Vivamus mattis. Phasellus eu pede. Fusce adipiscing justo fringilla metus. Etiam ante. Integer mollis massa quis nunc. Integer dictum neque luctus enim. + +Sed eu libero. Integer tempor ligula in velit. Ut tincidunt lacinia sem. Nullam vel risus. Sed sodales ante a dolor. Curabitur eros. Sed sodales. Sed non metus. Vestibulum elementum faucibus ante. Nulla vel nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In hac habitasse platea dictumst. Nunc nec lorem ut ipsum lacinia iaculis. Duis erat. Aliquam erat. Cras iaculis. In hac habitasse platea dictumst. + +Nullam ante. Cras vitae est. Pellentesque vel metus a ligula dapibus mattis. Duis feugiat aliquet felis. Etiam id nisl quis est dignissim condimentum. Suspendisse potenti. Morbi velit lorem, ornare quis, pellentesque vel, placerat eget, tortor. Vestibulum tincidunt molestie libero. Nulla nulla enim, malesuada id, ullamcorper vitae, dictum at, purus. Donec dignissim odio ut enim. Suspendisse at lectus. + +Praesent lobortis augue vel lectus. Ut in ligula ut felis congue suscipit. Quisque dignissim tortor ut mi. Fusce magna nisi, eleifend ac, ornare vel, porttitor vitae, quam. Vestibulum sodales justo quis turpis. Fusce urna nisi, rhoncus quis, condimentum vel, dictum eu, nunc. Fusce sed nibh vitae odio posuere adipiscing. Sed porta elit quis dolor. Nam libero nulla, auctor sed, tincidunt quis, faucibus sit amet, mi. Quisque orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam id sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vel eros. + +Vivamus luctus lobortis leo. Suspendisse vel elit a enim ullamcorper posuere. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec quis pede mattis lectus mollis adipiscing. Sed accumsan posuere erat. Praesent euismod tincidunt felis. Donec mi. Ut commodo arcu lacinia tellus. Aliquam a libero quis lectus semper viverra. Curabitur lacinia mauris at tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sit amet magna molestie orci suscipit fringilla. Fusce pretium metus non sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed hendrerit. Nulla felis. Suspendisse potenti. Aliquam blandit tristique neque. Curabitur quis erat vel nunc accumsan mollis. + +Duis sagittis, tellus ut aliquam fringilla, dolor mi ullamcorper nisl, ut tristique pede elit sed mauris. Curabitur id felis. Donec pulvinar lacus et lectus. Aliquam vulputate vulputate metus. Curabitur magna felis, adipiscing ac, accumsan vel, molestie quis, quam. Mauris elit arcu, pretium vitae, mollis sit amet, sollicitudin ut, mi. Donec imperdiet dignissim mi. Nullam sit amet tortor. Aliquam neque nulla, venenatis a, porta in, placerat tempus, lacus. Quisque vestibulum dui et lacus. Proin dignissim consectetuer purus. Etiam gravida tortor in nunc. Ut tempor tristique tortor. Sed laoreet tincidunt quam. Vestibulum porta turpis ut elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nibh dui, feugiat nec, laoreet id, malesuada eget, nisi. Ut neque massa, vehicula eu, commodo non, ultricies vitae, purus. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris euismod, felis vel tempor aliquet, tortor mauris malesuada nunc, vel fermentum sem diam id dui. Nam rutrum sapien eget odio. Aliquam sed libero non mi faucibus tempus. Fusce hendrerit, diam non volutpat rutrum, erat metus venenatis ligula, non scelerisque pede ligula vel quam. Morbi rhoncus eros ac dui feugiat elementum. Duis eu libero et tellus congue viverra. Morbi quam quam, elementum sed, ullamcorper imperdiet, commodo non, odio. Nam aliquet egestas urna. Mauris odio felis, varius eu, lacinia eu, condimentum a, lectus. Sed justo massa, pulvinar id, varius a, porttitor nec, libero. Etiam varius. Curabitur sodales, odio at posuere semper, eros nibh tincidunt lectus, vel rutrum sapien nisi in ligula. Suspendisse eget arcu. Phasellus imperdiet est ac sapien. Donec nulla tortor, placerat vel, tempus a, lobortis vel, nibh. Aliquam varius nisi. Nulla et enim. Fusce convallis laoreet lacus. + +Phasellus ipsum dolor, molestie quis, condimentum in, commodo eu, diam. Quisque bibendum lacinia dui. Nullam blandit vulputate orci. Ut lacinia massa vel augue. Aliquam gravida, quam quis imperdiet imperdiet, tellus diam pharetra erat, at pharetra lacus nibh egestas magna. Nulla sagittis lorem ut lorem. Duis condimentum, dui vitae aliquam posuere, diam quam convallis velit, ut gravida leo ipsum non risus. Ut fermentum sollicitudin erat. Donec sagittis scelerisque felis. Nunc arcu. Etiam tempus, magna sit amet suscipit euismod, eros sem rutrum dui, vitae sagittis nibh purus non lacus. Sed mollis arcu eget dolor. Donec ornare, arcu sit amet fermentum vulputate, risus enim fermentum libero, a lacinia dolor mi non velit. Etiam lobortis purus a elit. Nunc nulla dui, mattis quis, bibendum a, ultrices ac, augue. In aliquam vehicula turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Integer id nisl. Quisque dictum elementum odio. Aenean luctus. Sed eu sem a pede vulputate condimentum. Quisque magna. Donec aliquam mattis ipsum. Curabitur dictum sollicitudin sem. Aliquam pulvinar. Nunc sollicitudin risus a erat. Vivamus quis tellus sit amet nibh vestibulum consequat. Nulla pretium sollicitudin dolor. Aliquam iaculis tincidunt turpis. Phasellus ipsum leo, venenatis in, sagittis in, ornare at, nunc. + +Pellentesque ultrices, dui eu iaculis luctus, tellus augue volutpat sapien, in dignissim urna felis ut mi. Sed arcu dui, dignissim id, porttitor ut, imperdiet vitae, ante. Nulla dui sem, commodo nec, sagittis et, lacinia et, pede. Etiam eleifend dui ut nisl. Donec ante mauris, tempus sit amet, varius vitae, gravida quis, mi. In scelerisque, felis vitae viverra sagittis, velit metus ultricies neque, quis imperdiet velit elit et magna. Suspendisse potenti. Sed velit eros, euismod sed, condimentum nec, faucibus sed, sapien. Nam accumsan ligula sit amet neque. Aliquam erat volutpat. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam eu pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed eu felis sed tortor tempor fermentum. Phasellus commodo sem vel nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lectus elit, pharetra sit amet, accumsan sed, tincidunt et, mauris. Duis dapibus pharetra sem. Integer in justo. Praesent eros. Vestibulum ac ante. Aliquam scelerisque sem pellentesque nibh consectetuer sodales. Aliquam consectetuer odio. Duis lectus odio, luctus eu, commodo quis, mollis vitae, velit. Cras nec nunc non elit iaculis mattis. Aenean justo neque, sollicitudin eget, ullamcorper eget, egestas id, sem. In eu risus. Sed egestas. + +Integer at neque. Sed pretium scelerisque nulla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce ut pede. Etiam vitae quam a urna varius imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vehicula. Fusce ullamcorper nibh non erat. Quisque in neque. Praesent est. Pellentesque arcu. + +Proin posuere. Suspendisse potenti. Integer felis lacus, aliquam sed, vulputate in, mollis vel, tellus. Integer vehicula bibendum est. Nunc non dolor in tellus mattis facilisis. Integer vestibulum, augue at commodo aliquam, dui est mattis ligula, sit amet adipiscing orci sem vitae magna. Praesent enim velit, malesuada at, congue nec, luctus in, justo. Sed varius. Morbi pharetra. Donec eu massa nec tellus vulputate pulvinar. Ut commodo turpis non sem. Ut convallis ullamcorper risus. Etiam interdum pede id nisi. Cras magna sapien, suscipit a, laoreet non, rhoncus et, felis. Integer orci lorem, vestibulum dictum, ullamcorper a, porttitor et, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc et magna. Sed bibendum tellus in diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vitae tortor. Integer magna. Duis venenatis, leo ac tempor laoreet, elit nulla pharetra pede, non fermentum nunc odio a odio. Proin non velit. Sed imperdiet augue quis nisl. Integer condimentum nisl nec libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus placerat libero. Duis congue dictum magna. Aliquam dapibus bibendum enim. Nunc eleifend pede vel ipsum. + +Etiam vitae velit. Mauris erat nunc, malesuada ut, feugiat ac, placerat condimentum, augue. Nam volutpat. Aliquam vehicula ipsum id odio. Vivamus sollicitudin turpis id sapien. Fusce a felis vitae odio convallis blandit. Curabitur vitae eros id eros porta pretium. Nulla in magna eget urna lacinia convallis. Aliquam mattis venenatis purus. Sed sed mi eget erat tristique porta. Donec auctor dolor a erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In nec ligula. Nunc eleifend. Vestibulum quis nisi eget elit porttitor congue. Maecenas faucibus, magna eget adipiscing tincidunt, dolor ante malesuada elit, non elementum lacus turpis in pede. + +Ut malesuada mi nec metus. Praesent auctor augue ac nisl ultricies facilisis. Nam purus sapien, pellentesque dignissim, posuere eu, cursus id, diam. Quisque sollicitudin, elit a pellentesque scelerisque, lorem risus auctor quam, quis consequat tellus neque id urna. Suspendisse diam tortor, eleifend dignissim, egestas ut, luctus in, ante. Duis ante. Maecenas luctus. Curabitur cursus pharetra urna. Maecenas imperdiet, erat non elementum euismod, tortor odio euismod lectus, ac facilisis sem nibh vitae nulla. Nunc gravida. Morbi sollicitudin odio quis lacus. Aliquam a nibh non urna porta imperdiet. Aliquam erat volutpat. In iaculis lacinia velit. Sed libero lacus, tristique eu, lacinia ac, aliquet eget, urna. + +Etiam at nisl. Phasellus faucibus luctus lectus. Ut placerat vulputate dolor. Phasellus vel velit. Morbi viverra. Phasellus orci. Integer dignissim mattis mauris. Pellentesque posuere leo posuere quam. Quisque nec magna at diam viverra pellentesque. Suspendisse velit arcu, ultricies quis, congue a, venenatis eget, lacus. Integer sagittis hendrerit dolor. Fusce tincidunt ante a sem. + +Maecenas consectetuer, justo sed rhoncus venenatis, nibh arcu rutrum dolor, sed condimentum libero libero et ipsum. Vivamus mattis justo ut lorem tincidunt lobortis. Ut non velit id neque aliquet accumsan. Sed tempus viverra nulla. Curabitur ullamcorper, neque quis dapibus scelerisque, felis diam gravida orci, non cursus quam neque vitae elit. Etiam pharetra tincidunt lacus. Duis euismod fringilla est. Etiam ornare tincidunt lectus. Proin in turpis. Nunc blandit blandit turpis. Aenean ut augue. Duis orci justo, tincidunt eu, rutrum sed, rutrum et, turpis. Curabitur facilisis odio in ante. In hac habitasse platea dictumst. Sed eros est, pellentesque at, tincidunt eu, ultrices quis, metus. Morbi sit amet justo. Maecenas ac arcu. Mauris dignissim. + +Pellentesque ultricies rutrum orci. Aenean ornare. Vivamus eu risus vel mauris lobortis dictum. Sed et turpis auctor mi rhoncus pulvinar. Sed nec nunc a purus tempor viverra. Pellentesque suscipit. Donec tristique risus non nibh. Etiam nisl magna, sollicitudin ut, ultrices sit amet, egestas eu, nulla. Aliquam erat volutpat. Vestibulum pharetra. Sed egestas, metus sit amet lobortis consequat, erat elit imperdiet libero, eu interdum quam massa eget dolor. Suspendisse vitae odio. Proin blandit mauris iaculis metus. + +Vivamus vestibulum. Etiam et nisl. Aliquam in diam vel elit placerat suscipit. Duis sodales purus ac nibh. Nulla in odio eget enim luctus blandit. Curabitur ultrices ipsum non neque egestas eleifend. Sed turpis. Proin consectetuer. Vivamus mattis. In aliquet. + +Nunc id eros. Donec venenatis, nulla et mattis luctus, ante leo semper justo, non adipiscing odio risus sed lacus. Praesent vitae risus congue libero congue tempus. Phasellus ac eros. Nulla vehicula, lorem in aliquet suscipit, arcu erat egestas sem, quis lobortis quam ante eu massa. Curabitur non massa. Sed bibendum lacinia odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus volutpat blandit lacus. Proin porta, tellus ut auctor laoreet, lectus eros fermentum lectus, id sagittis arcu justo in turpis. Phasellus consequat. Nam pellentesque, mi id viverra convallis, nunc libero placerat leo, eleifend porta sem nisl vitae sapien. Pellentesque ligula libero, tristique non, porttitor rutrum, porttitor non, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer dictum tellus a tortor. Vivamus felis nunc, molestie non, rhoncus quis, pharetra id, dui. Donec risus metus, fringilla vel, aliquet eu, placerat id, neque. + +Suspendisse ipsum. Vivamus lectus. Sed viverra, massa eget convallis mattis, quam turpis consectetuer nunc, eget posuere magna sem id velit. In nec mauris. Aenean a purus sed quam lobortis fringilla. Proin ultricies lacinia ante. Sed adipiscing erat quis velit. Nullam vitae nisl id justo sollicitudin molestie. Nulla facilisi. Sed nec urna sed nisl fringilla dapibus. Nulla at diam. Aliquam eget nibh. Nunc ac nisi sit amet tellus egestas tempus. Nam scelerisque urna et neque. Donec est orci, sagittis non, vulputate a, commodo et, augue. Ut dapibus tortor. Ut nunc. Donec dictum dapibus odio. Nam ultricies ullamcorper ligula. Pellentesque accumsan varius leo. + +Morbi euismod laoreet erat. Vivamus quis ipsum. Morbi euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel purus. Nullam at magna. Curabitur lacus lorem, iaculis quis, dapibus non, volutpat vel, nulla. Donec ut arcu rhoncus dolor pretium dictum. Nullam vel metus. Ut arcu. Pellentesque nisi nunc, placerat eget, tincidunt vel, pharetra non, nunc. Integer tincidunt ultricies lectus. Integer semper, purus sed ultrices feugiat, nulla pede sollicitudin erat, vel auctor nulla ipsum vel lectus. Aenean mi. + +Nullam sed nisi et arcu imperdiet fermentum. Mauris nec metus. In ac dolor. In mi arcu, congue ac, pharetra nec, scelerisque sit amet, magna. Curabitur lacus. Curabitur et elit. Aliquam ullamcorper nunc eu elit. Sed convallis dolor at velit. Vestibulum dapibus, augue id consectetuer placerat, nunc massa blandit sapien, id aliquam elit nisi id mi. Phasellus sapien est, gravida eu, bibendum ut, adipiscing quis, est. Ut molestie quam vitae odio. Donec quis risus id erat faucibus sollicitudin. Nam id felis. Mauris sed enim vitae leo accumsan pretium. + +Nam justo. Donec turpis nisl, commodo et, interdum ac, consectetuer non, massa. Fusce sem metus, laoreet nec, posuere id, imperdiet in, velit. Donec vulputate justo eget turpis. Nulla pede. Morbi tincidunt. Fusce aliquet, quam et aliquam fringilla, ante ante iaculis dui, nec aliquam arcu purus sed erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus suscipit quam et est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; + +Integer sed tellus. Sed sed velit ultricies leo rutrum laoreet. Sed non eros ac purus sagittis feugiat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed hendrerit ligula sit amet nibh. Maecenas turpis. Morbi consectetuer, dolor et adipiscing imperdiet, ante neque feugiat dolor, at porta quam neque quis ligula. Mauris semper velit sit amet ipsum. Pellentesque tempus, purus in rutrum consequat, enim erat vehicula massa, id accumsan leo sapien nec purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In dolor. Integer facilisis libero sit amet pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut varius aliquet enim. Nulla facilisi. Curabitur consectetuer, odio eu pretium tincidunt, nunc nisi aliquet neque, vel imperdiet elit massa sit amet turpis. Pellentesque tempus, orci volutpat blandit fringilla, odio sem posuere ante, vitae bibendum urna lorem vitae eros. Praesent viverra rhoncus arcu. Sed auctor, est sit amet mollis mollis, quam quam gravida sapien, in commodo metus nulla auctor enim. Donec facilisis. + +Proin tincidunt, sapien eget ultricies adipiscing, est odio dictum arcu, ut mollis erat dui sit amet velit. Morbi est sem, interdum at, congue a, elementum vitae, metus. Suspendisse id augue. Mauris enim sem, pulvinar eget, tempus a, tempus sit amet, sapien. Fusce vestibulum consectetuer dui. Pellentesque erat. Sed dignissim placerat odio. Maecenas semper rhoncus lectus. Phasellus pretium. Duis libero elit, eleifend nec, egestas ut, cursus sed, felis. Nam nisl arcu, aliquet et, facilisis eu, luctus ut, risus. Etiam ultrices, dolor sed volutpat malesuada, turpis arcu imperdiet tortor, euismod commodo libero massa ut quam. Integer molestie purus non elit. Ut venenatis semper tortor. Etiam bibendum egestas ipsum. Mauris sollicitudin sem nec nibh. Nulla pretium metus eu metus. Pellentesque sit amet sem. + +Suspendisse ac nisi. Ut leo. Vestibulum hendrerit pretium dolor. Nunc feugiat malesuada purus. Cras et nibh. Curabitur nunc erat, malesuada vitae, laoreet ac, ultricies in, purus. Vivamus tellus arcu, sodales eu, facilisis a, lacinia nec, nunc. Pellentesque id velit. In eu nibh. Nunc nec erat. Sed dictum neque ut nisl. + +Morbi lectus tellus, tincidunt ac, porttitor ac, tristique in, eros. Donec luctus luctus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ut est et enim scelerisque accumsan. Donec ligula felis, lacinia quis, pellentesque in, semper vestibulum, elit. Mauris eget orci a felis congue vehicula. Ut sollicitudin. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam id dolor ut lorem dignissim venenatis. Suspendisse vitae sapien. Proin non magna ut eros viverra pulvinar. Donec quis odio. Nullam non arcu vel lorem suscipit aliquam. Aliquam rutrum turpis in leo. + +Ut luctus nibh tristique erat. Suspendisse bibendum odio vitae tortor. Donec lacinia. Cras sodales felis luctus nulla. Nam eleifend sagittis ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse vel neque. Morbi aliquet vehicula magna. Aenean at odio. Duis pellentesque magna. Nulla at tortor ut diam dictum faucibus. Mauris quis velit. Donec non tellus vitae lorem fringilla porttitor. Fusce ut sapien quis tortor feugiat sagittis. Donec viverra sem vitae sapien. Praesent sodales, lacus in fringilla viverra, odio augue adipiscing urna, vitae interdum ante sem non nisi. Nullam tortor lorem, eleifend ac, mollis non, laoreet ac, risus. Integer ornare leo sed justo. Quisque cursus, sem non facilisis bibendum, nisi mi varius felis, fermentum feugiat lorem eros laoreet risus. + +Quisque sit amet est et lorem vehicula lacinia. Donec nec tortor. Cras odio. Nam scelerisque vulputate urna. Praesent dui. Etiam nec nisl lobortis ipsum aliquet tempus. Maecenas pretium sollicitudin mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus augue massa, congue eget, convallis eget, tristique sit amet, eros. Sed consequat nisi eu felis. Pellentesque justo. Suspendisse non augue. In dignissim lobortis mauris. Mauris sagittis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + +Sed adipiscing. Donec a tellus vitae est cursus vehicula. Nam ante sem, sodales id, fringilla vel, condimentum vel, nulla. Quisque sodales. Etiam imperdiet elit id odio. Aliquam erat volutpat. Maecenas porta tempor arcu. Nulla sem augue, pellentesque ac, consequat ut, condimentum euismod, risus. Sed aliquam tincidunt mi. In interdum lobortis orci. + +Sed vehicula hendrerit purus. Etiam a diam. Curabitur convallis. Suspendisse a nisi. Donec id magna in quam sollicitudin ultricies. Donec viverra. Quisque volutpat est sed sem. Aliquam justo. Vestibulum tortor massa, porttitor sed, varius quis, iaculis quis, odio. Aliquam eget neque. + +Mauris nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum eu quam in neque ultrices pellentesque. Cras in dolor quis quam varius hendrerit. Aliquam nisi lacus, lobortis eu, convallis sit amet, facilisis ut, mi. Aliquam at neque. Cras sagittis elementum justo. Vestibulum ut lectus aliquet purus malesuada volutpat. Duis at lacus adipiscing libero tincidunt vestibulum. Morbi a libero. Cras purus. Morbi ut augue et purus interdum scelerisque. Integer a dui. In hac habitasse platea dictumst. Duis pharetra metus eget mauris. Aliquam interdum ullamcorper massa. + +Etiam ornare. Nullam euismod. Aenean consequat gravida ligula. Aliquam est. Proin vitae lacus. Praesent a eros sit amet dui luctus commodo. Phasellus vehicula arcu eget dolor. Praesent fermentum congue leo. Aliquam volutpat purus ut lorem. Fusce hendrerit enim at leo. Aliquam rhoncus nisl. Vivamus dictum egestas mi. Suspendisse pellentesque bibendum dolor. Pellentesque tincidunt, turpis semper pellentesque condimentum, ipsum metus sodales ligula, id volutpat diam turpis ut elit. + +Praesent sed lacus. Nam eleifend molestie mauris. Donec dapibus fermentum massa. Donec viverra faucibus purus. Curabitur congue, libero vitae viverra pellentesque, diam velit sodales enim, sed suscipit lectus nisi nec neque. Vestibulum malesuada, lacus at cursus congue, velit lectus tristique dolor, sit amet sodales neque ipsum a libero. Vestibulum et quam. Curabitur placerat. Curabitur nunc arcu, euismod nec, vulputate hendrerit, aliquet eget, quam. Curabitur vel enim. Suspendisse potenti. + +Nunc consequat orci ut lacus. Fusce velit dolor, dapibus sed, blandit sit amet, rhoncus id, risus. Duis urna nibh, scelerisque quis, dapibus a, scelerisque sed, nibh. Donec luctus. Ut eu mauris cursus diam lacinia rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam vehicula molestie justo. Maecenas imperdiet pede sed mi. Suspendisse nulla dolor, hendrerit eget, hendrerit id, dictum vel, leo. Duis accumsan. Curabitur in felis. Nunc lorem. Ut leo dolor, laoreet nec, vulputate at, eleifend in, nulla. Quisque nunc purus, varius eget, accumsan nec, aliquet et, nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras adipiscing viverra dolor. Mauris porttitor ultrices purus. Nulla facilisi. Praesent faucibus ante vitae mauris. + +Praesent lacinia lectus sed nisl. In tempus congue mauris. Integer facilisis ornare enim. Nulla id massa. Donec commodo diam at tellus. Nam dapibus viverra est. Nam tellus. Praesent a libero. In faucibus est eget nibh. Nulla eros orci, imperdiet non, blandit non, tempor eget, mi. Pellentesque convallis. + +Quisque eget mi ac leo euismod faucibus. Phasellus rhoncus purus id dui. Vestibulum malesuada eleifend ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque blandit mattis odio. Suspendisse consequat, lectus ac semper sollicitudin, mi velit dictum augue, ac tempus dolor erat sit amet dui. Proin hendrerit, felis quis volutpat posuere, diam odio malesuada odio, a interdum orci diam quis sapien. Pellentesque odio odio, viverra vel, gravida eu, molestie sed, nulla. Phasellus mauris pede, commodo ut, euismod eu, hendrerit eu, est. In hac habitasse platea dictumst. Nulla elementum lacus eu augue. Sed erat. Proin porta. Maecenas quis mi. Phasellus at enim ac justo gravida ultrices. Cras leo. + +Integer ut arcu. Donec sed magna. Proin felis. In iaculis, ligula id fringilla pretium, nibh diam accumsan tellus, eget accumsan metus dui varius turpis. Phasellus orci metus, eleifend sed, tempor ac, scelerisque ac, urna. Integer viverra neque a mauris. Mauris porttitor dolor eu velit. Integer odio elit, vestibulum ut, volutpat id, rhoncus commodo, urna. Etiam placerat pharetra erat. Ut tempor est. Integer dignissim blandit tellus. Morbi nibh dolor, scelerisque id, commodo malesuada, mattis at, mi. Cras tincidunt commodo purus. In tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ullamcorper. Ut hendrerit. Morbi ultrices. + +Praesent iaculis, eros ac egestas sodales, urna leo fermentum ligula, sit amet aliquam velit sem non purus. Donec rutrum arcu quis purus. Nam posuere, lacus at consequat placerat, nulla pede posuere orci, non euismod turpis dui quis nisl. Proin porta adipiscing nibh. Donec tristique dolor at tellus. Donec neque massa, auctor id, faucibus vitae, ullamcorper vel, nisi. Proin molestie neque sed massa. Nam tempor. Morbi aliquam sapien at tellus. Fusce quis risus et mi pretium pulvinar. Fusce sit amet ligula. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse eu enim et felis scelerisque lobortis. Praesent bibendum. Vivamus vehicula. Integer at nibh sed velit rhoncus molestie. Cras lacus. Sed ullamcorper eros vel erat. Fusce eu tortor sit amet diam euismod sagittis. Nunc quis lacus id nibh convallis varius. Suspendisse vitae mi. Vestibulum tristique. Donec malesuada ipsum id neque. Nullam sed lacus. Duis egestas, justo ut congue ornare, augue sapien luctus diam, at accumsan erat sapien ut libero. Phasellus vel nulla. Suspendisse arcu tellus, porttitor a, pharetra faucibus, aliquam sit amet, massa. Nulla porttitor tincidunt lorem. Nunc dolor odio, sagittis in, lobortis vel, volutpat sed, nibh. + +Quisque blandit leo ut sapien tempus facilisis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean ultricies porttitor justo. Fusce rutrum eros ut urna. Proin quis quam eget dui aliquam accumsan. Donec suscipit eleifend elit. Pellentesque mattis, felis sodales iaculis imperdiet, lacus sem convallis augue, sit amet aliquet arcu purus fringilla risus. In eu odio id magna pharetra ornare. Aliquam interdum pulvinar ipsum. Sed neque. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam sit amet nisi. Ut at augue. Mauris volutpat blandit ligula. Nulla eu metus. Vestibulum eget elit. Praesent posuere. Vestibulum id sem non lectus mollis tincidunt. Aliquam id felis at ante ornare tempor. Nulla lacus turpis, feugiat vitae, cursus quis, consectetuer non, mauris. Fusce lacus massa, porttitor ut, molestie ut, venenatis a, lorem. Praesent sit amet orci. Mauris rhoncus felis vitae felis adipiscing imperdiet. Maecenas mollis diam nec leo. + +Fusce enim ipsum, ultrices eu, molestie id, elementum id, sapien. Integer a urna. Nam velit libero, venenatis eget, tempor sit amet, feugiat vitae, ante. Fusce nunc. Sed semper nisl nec risus. In sed libero. Proin tortor neque, tincidunt ac, tempor ac, pharetra quis, velit. Duis lectus augue, ultricies vel, consequat id, iaculis id, ante. Vivamus auctor metus a ante. Curabitur arcu nisi, facilisis at, laoreet in, consectetuer sed, mauris. Quisque placerat diam sed dui. Vivamus pretium condimentum lorem. Curabitur laoreet. Aenean orci ligula, cursus eget, lacinia non, faucibus vel, lorem. + +Aliquam erat volutpat. Curabitur eros dolor, congue a, condimentum sed, luctus ut, nibh. Maecenas non tortor nec turpis commodo pellentesque. Praesent euismod placerat mi. Suspendisse potenti. Phasellus ut neque vitae orci mattis iaculis. Integer eget tellus. Donec at ante. Nam lacinia leo eget erat. Maecenas euismod magna congue tortor. Morbi nec massa eu enim malesuada sollicitudin. Sed accumsan. Nullam ipsum. Ut odio. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque id velit. Nam odio sem, aliquet ut, tempus sit amet, euismod et, nunc. + +Pellentesque libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent mauris nunc, varius ut, convallis molestie, luctus sit amet, leo. Sed dictum lorem et arcu. Nunc venenatis pellentesque massa. Nulla facilisi. Phasellus in tortor eget risus scelerisque vulputate. Sed nibh elit, sagittis ac, condimentum nec, convallis et, justo. Fusce volutpat metus. Nunc auctor. Vestibulum leo eros, pellentesque ac, mollis ultrices, rhoncus non, dolor. Mauris vehicula placerat nisl. Vestibulum bibendum, arcu quis congue elementum, velit nunc eleifend turpis, id luctus risus nisl sit amet tellus. Phasellus pede neque, blandit non, commodo vitae, ultricies eget, magna. Aliquam erat volutpat. + +Nulla facilisi. Aliquam ac ante. Cras risus. Morbi mauris lacus, posuere eu, blandit et, pharetra at, mi. Proin ac purus. Duis cursus nisl rutrum quam. Aliquam a odio non magna pellentesque ultricies. Maecenas ac massa quis sapien ullamcorper tempus. Cras cursus velit sed sapien. Proin nulla. Vivamus sodales aliquam nibh. Etiam et erat ut ante lacinia euismod. Fusce nisi. Proin quis nulla. + +Quisque venenatis, eros sed laoreet sollicitudin, orci ante pellentesque nisl, sit amet viverra quam erat non risus. Cras eget libero. Sed elit magna, semper eu, fringilla in, dignissim sodales, erat. Vivamus feugiat sem vel dui. Donec convallis sollicitudin diam. Cras sed purus. Donec felis eros, semper eget, tempor consectetuer, sagittis quis, nisl. Duis in ante. Cras non turpis. Nulla tempor velit aliquet turpis molestie placerat. Proin elementum fermentum mauris. Vivamus sed orci lacinia dui placerat venenatis. Vestibulum feugiat, tellus in volutpat rutrum, magna nisi ullamcorper eros, id pulvinar neque erat ut lacus. Vivamus sed augue. Nulla facilisi. Maecenas ante augue, elementum ut, sodales vitae, condimentum nec, lorem. Duis pede orci, fringilla at, eleifend nec, pretium in, erat. Nam sagittis, turpis vitae convallis pharetra, odio sem scelerisque lacus, nec lobortis dui diam vel eros. In semper gravida neque. + +Integer nunc. Ut pretium ipsum sit amet elit. In nec arcu. Sed vestibulum vulputate ipsum. Pellentesque tincidunt. Nulla gravida dolor in tellus. Cras vehicula, dolor ut pellentesque aliquam, erat enim auctor massa, vehicula lobortis odio eros quis quam. Proin dapibus neque in enim. Proin elit. Integer rhoncus tincidunt elit. Fusce lorem metus, semper ac, volutpat vitae, facilisis ut, tellus. Donec vel turpis vitae nisi pharetra porttitor. Maecenas tortor. Fusce mi. Nullam nec turpis. Sed sodales vestibulum nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Pellentesque dolor dolor, laoreet eu, aliquet quis, scelerisque sit amet, arcu. In hac habitasse platea dictumst. Nullam cursus urna eget elit. Quisque blandit sapien ac ante. Proin nulla eros, gravida volutpat, sodales vel, mollis eu, massa. Nulla tristique sollicitudin nisl. Curabitur vitae lorem vitae velit egestas ornare. Aenean eget eros. Aliquam erat volutpat. Fusce a urna id odio aliquet convallis. Curabitur sit amet nisl posuere leo posuere dapibus. Duis metus erat, luctus vel, rhoncus at, convallis sit amet, enim. Vivamus hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam eget elit. + +Nullam a nunc. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In metus urna, tincidunt et, lacinia sit amet, lobortis vitae, ligula. Proin et mauris vitae mi accumsan pellentesque. Etiam quam purus, hendrerit sed, feugiat vitae, euismod eget, tortor. Ut aliquam magna vitae justo. Suspendisse non justo vel velit condimentum tempus. Duis tempus ipsum vitae tellus. Proin in massa. Etiam ullamcorper dictum tellus. Proin aliquet felis at leo laoreet pulvinar. Vestibulum arcu purus, malesuada sit amet, cursus eu, placerat sit amet, nunc. Nam massa odio, sollicitudin in, adipiscing a, aliquam nec, risus. Aliquam blandit hendrerit libero. Mauris gravida. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur a nibh. Ut interdum fermentum neque. Pellentesque sed nunc. Mauris vehicula nisi et nunc. Praesent lorem. Donec semper. Integer eu lacus in est aliquam hendrerit. Vestibulum eget neque. Sed semper luctus velit. Curabitur nibh augue, congue eu, hendrerit id, congue et, enim. Integer placerat aliquam lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae eros. Donec vel nisl. + +In vestibulum facilisis urna. Ut risus. Mauris pharetra. Pellentesque mattis. Integer suscipit aliquam ipsum. Duis blandit, sapien et ultricies condimentum, felis mi elementum pede, nec sagittis metus mauris quis quam. Quisque accumsan arcu vel nulla. Cras sem sapien, porttitor id, ultricies sagittis, luctus eu, nulla. Integer quis eros. Morbi sed urna a tellus vehicula vulputate. Etiam nec augue eget felis semper tristique. Quisque ut dolor vel risus dictum consequat. Sed eget dolor sed nunc lacinia aliquet. Suspendisse ac tortor in ipsum posuere venenatis. Sed eget erat. Nulla faucibus. Duis laoreet, massa porttitor aliquet egestas, ipsum lectus rhoncus quam, in adipiscing eros sem ut tellus. Pellentesque feugiat tempus quam. Vivamus id dolor eget sapien consectetuer tempor. Aliquam erat volutpat. + +Nulla iaculis fermentum libero. Curabitur faucibus, massa malesuada cursus tincidunt, erat sem eleifend mauris, sed fringilla mi ante ac purus. Duis elementum lectus. Nunc ornare arcu eu tortor. Vestibulum vel dolor at purus lacinia fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas tincidunt, eros a egestas pellentesque, risus risus dictum libero, id aliquet metus justo in massa. Proin a tellus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed purus. Sed non pede. Aenean massa sapien, sodales sit amet, consequat dictum, eleifend vitae, tortor. Donec ultrices lacinia elit. + +Morbi adipiscing sodales dolor. Ut ullamcorper ultricies est. In venenatis tempus augue. Suspendisse tortor dolor, accumsan et, suscipit a, tincidunt ut, libero. Aliquam scelerisque magna sed felis. Quisque ut nunc a magna vulputate placerat. Aliquam rhoncus vehicula dui. Sed tortor. Nullam sit amet diam. Nunc sed eros. Sed et odio tincidunt elit gravida convallis. Curabitur quis tortor a lacus semper varius. Mauris at augue non mi sollicitudin aliquam. Integer ullamcorper. Pellentesque suscipit quam non purus. Aliquam ac eros at arcu ullamcorper consectetuer. Suspendisse pretium mattis leo. + +Duis at nunc. Sed dolor est, varius ac, porta et, tincidunt hendrerit, risus. Vivamus ut magna. Praesent ut mauris. In purus lacus, mattis sed, vestibulum nec, tempor at, nisl. Cras ullamcorper venenatis tellus. Ut dolor. Maecenas malesuada, pede a pulvinar mattis, arcu diam vehicula risus, quis porttitor augue massa in velit. Nunc congue. Morbi velit metus, rhoncus et, aliquam consectetuer, ultricies malesuada, ligula. Sed velit nisl, sagittis vitae, pharetra a, posuere sed, massa. Nulla facilisi. In varius, ligula id lobortis sodales, augue orci fermentum tellus, eu pulvinar risus ligula a sapien. Morbi laoreet ipsum non mi. Nam cursus lorem ut mi. Vivamus magna enim, posuere non, semper quis, sodales eu, arcu. Etiam mi purus, pretium feugiat, varius sed, pellentesque eget, ligula. In leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vitae orci eu orci sollicitudin feugiat. + +Praesent purus massa, euismod vitae, tempus nec, consequat hendrerit, metus. Aenean felis est, egestas vitae, accumsan eget, pellentesque in, sapien. Duis dapibus pede non sapien. Nunc urna. Integer vel libero. Duis augue arcu, dapibus non, facilisis vitae, posuere ut, eros. Donec vitae nunc sit amet arcu imperdiet dictum. Morbi eleifend, lorem eu consectetuer vestibulum, diam nunc ornare arcu, ac tempor felis dolor eget eros. Phasellus massa sem, sollicitudin ac, sodales gravida, luctus a, quam. Nam neque quam, viverra at, venenatis quis, sagittis non, enim. + +Nulla facilisi. Pellentesque egestas lacinia est. Sed tincidunt, pede sed tincidunt vestibulum, urna dolor adipiscing purus, vitae fringilla felis elit in nibh. Nulla sed nisi. Mauris suscipit scelerisque arcu. Etiam non enim vel eros accumsan malesuada. Nunc tincidunt commodo mauris. In tincidunt risus quis urna. Nulla diam tortor, aliquet et, tincidunt quis, sollicitudin ac, tortor. Cras nisl neque, vulputate suscipit, molestie quis, pulvinar at, nulla. Nullam ac metus nec odio posuere varius. Cras sed pede nec dui posuere bibendum. Duis euismod ullamcorper libero. Aliquam faucibus pulvinar turpis. + +In ut neque id nunc feugiat commodo. Curabitur dignissim, felis at sollicitudin lacinia, enim elit suscipit neque, sed luctus lorem ipsum in leo. Duis dapibus, odio quis auctor commodo, nisl odio mattis tellus, nec tincidunt turpis diam in arcu. Curabitur a sem. Nullam volutpat magna. Pellentesque sagittis, neque consequat pretium cursus, dolor lacus consectetuer arcu, sed laoreet est urna et metus. Suspendisse placerat, dui a porta tempor, lorem dui lobortis neque, sed venenatis diam enim id eros. Etiam et nisl non lectus faucibus consectetuer. Morbi scelerisque, sem nec tempus ullamcorper, ipsum diam feugiat lorem, a fringilla sapien elit quis nibh. Nullam diam urna, viverra sed, pharetra rhoncus, tincidunt vel, orci. Integer accumsan mattis erat. Nam dictum. Mauris nec leo. Nulla iaculis. Nulla nisl mi, dapibus quis, vehicula a, cursus eget, odio. + +Phasellus dapibus euismod nibh. Vivamus imperdiet ante in ligula. Pellentesque accumsan. In imperdiet, dui a auctor fringilla, metus nisi cursus dolor, vel luctus ligula lorem vitae mauris. Praesent mattis vestibulum elit. Aliquam enim lacus, pulvinar non, lacinia sit amet, eleifend non, velit. Vestibulum ac leo. Mauris imperdiet justo ac lectus. Sed molestie lectus sed dui. Sed fermentum tempus mauris. Nam ornare orci ac tellus. Ut malesuada, lacus id lacinia accumsan, diam elit adipiscing metus, et bibendum sapien nibh blandit orci. Suspendisse ipsum tellus, sagittis quis, vestibulum non, vulputate eu, eros. Praesent at nulla id pede scelerisque ultricies. Cras blandit pretium tellus. Maecenas dapibus condimentum augue. Phasellus tincidunt pharetra lorem. Morbi non eros. Sed tempor, nisl a tincidunt tincidunt, eros diam dictum sem, vel dignissim ante diam sed magna. Praesent non ligula id metus molestie consectetuer. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse vel mi. Curabitur ante nulla, rutrum a, convallis vel, vehicula ac, nunc. Nunc sagittis, enim sit amet auctor rutrum, mauris arcu vulputate neque, et euismod est felis quis ante. Vestibulum turpis tellus, hendrerit in, lacinia commodo, ullamcorper gravida, risus. Mauris rhoncus lacinia risus. Maecenas sollicitudin erat vitae nunc. Praesent pretium pellentesque augue. Donec interdum. Praesent ac eros vitae erat lobortis fringilla. Aenean consequat tellus. Nulla accumsan bibendum felis. Maecenas pretium ante id nisi. Aenean mi arcu, semper sed, mattis eu, venenatis sit amet, arcu. Donec aliquet euismod leo. Proin magna justo, tristique a, semper ac, sollicitudin a, ligula. Morbi velit. Aliquam vel nisi. + +In a lorem ut nunc feugiat congue. Donec fermentum bibendum dui. Proin varius est quis velit. Donec aliquet sem accumsan mi. Sed placerat. Nullam ac nisi a massa lobortis suscipit. Nunc id leo. Aliquam et massa. Nullam vestibulum elementum metus. In consectetuer nisi vel justo. Maecenas eget purus sed massa varius pellentesque. Phasellus faucibus felis quis felis. Aenean odio arcu, blandit quis, facilisis in, imperdiet eu, lorem. Nam posuere pulvinar mi. Fusce tristique, mauris et consectetuer ultricies, mauris lectus tempor justo, at fringilla est est sed nisi. Quisque faucibus. Sed in tortor tincidunt est lacinia iaculis. Maecenas a massa. Pellentesque a nibh at purus porta hendrerit. + +Nullam turpis. Fusce ac sem sed odio pellentesque imperdiet. Curabitur in arcu. Praesent lacus lacus, feugiat id, pulvinar in, tincidunt sed, neque. Maecenas viverra odio eget tortor. Integer aliquam, lorem rutrum venenatis dignissim, ligula magna malesuada arcu, vel feugiat lorem ipsum quis massa. Morbi ante. Vestibulum mauris libero, ullamcorper quis, ultrices quis, facilisis non, massa. Maecenas imperdiet. Aliquam erat volutpat. Pellentesque dignissim gravida lectus. In nibh odio, auctor eget, dapibus quis, dignissim venenatis, arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis pellentesque ligula quis massa. Curabitur condimentum, justo eget ornare luctus, lorem ligula sagittis pede, a porta nunc nunc in neque. Quisque felis mauris, condimentum vitae, auctor vitae, tincidunt quis, pede. Nunc lacinia ante in leo. Pellentesque libero. Aenean a ligula et nunc vestibulum consectetuer. + +Fusce ornare. Praesent id urna. Integer venenatis, quam non sagittis accumsan, ante nibh sagittis augue, sollicitudin adipiscing dolor velit eu erat. Proin quis enim eu purus vehicula aliquam. Nulla vel enim vel elit sollicitudin fringilla. Aliquam erat volutpat. Sed suscipit felis ut turpis. Etiam rutrum risus imperdiet est. Aliquam a tellus at tellus commodo dapibus. Mauris rutrum magna et odio. In at dolor. Curabitur vehicula lectus in tortor. Fusce justo purus, luctus vitae, mollis in, pharetra ac, purus. Nullam posuere interdum justo. Curabitur vitae lacus vel leo congue pulvinar. + +Aenean eleifend nibh varius tortor. Suspendisse vel eros. Proin nec diam a tortor ultrices ornare. Aliquam scelerisque feugiat justo. Vivamus ante urna, adipiscing vitae, porttitor eu, sodales et, felis. Suspendisse potenti. Curabitur ac massa in nisl sagittis mollis. Nam quam ligula, consectetuer eget, iaculis at, varius eu, leo. Duis dolor ligula, tincidunt at, ullamcorper sed, accumsan aliquam, ligula. Phasellus vulputate, lorem at tincidunt pharetra, risus lectus lacinia magna, quis rutrum enim magna at sem. In hac habitasse platea dictumst. Duis id sem a mauris sollicitudin tincidunt. Etiam eu purus eu arcu fringilla adipiscing. Vivamus ornare tempus diam. Proin turpis quam, lacinia non, egestas at, commodo eget, pede. Praesent vulputate risus in est. Nulla facilisi. + +Ut elementum lacinia purus. Proin vitae arcu ac nulla convallis aliquam. Nulla congue, libero id pellentesque mattis, quam lectus porttitor diam, a scelerisque dui libero in sapien. Nullam felis diam, vehicula vel, molestie ut, vestibulum aliquam, sapien. Donec convallis, est ut elementum volutpat, mauris ipsum gravida sem, commodo facilisis sapien lectus semper lectus. Quisque porttitor eros ut nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam mattis risus sed odio. Vestibulum et odio. In hac habitasse platea dictumst. Nam tristique massa ut ligula. Quisque nibh tellus, vehicula sit amet, adipiscing at, convallis nec, ligula. Vestibulum pretium, mi nec fringilla bibendum, dui nunc sodales pede, a semper magna nibh non diam. Donec massa nunc, viverra vel, consectetuer porta, dapibus non, ipsum. Duis nisl mauris, cursus vel, semper non, sollicitudin bibendum, felis. Vestibulum eu neque. + +Cras nec dolor. Donec laoreet tempus lectus. Cras sed tortor interdum lacus eleifend dignissim. Maecenas sit amet elit. Nullam quis dolor vel dui pharetra luctus. In sit amet quam sit amet pede ultrices ultrices. Maecenas diam. Integer urna. Curabitur dictum, velit sed placerat suscipit, erat turpis fermentum justo, sed interdum neque sem et nibh. Vivamus consequat convallis magna. Nam aliquam, est ac bibendum commodo, magna est dictum mi, vitae malesuada elit magna vitae odio. Maecenas tempor vulputate tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus dui. Etiam accumsan pede congue tortor. + +Morbi tempor libero ac lorem. In aliquet varius magna. In arcu. Phasellus odio. Fusce tincidunt aliquet felis. Quisque velit. Sed luctus. Aliquam feugiat fringilla mi. Aliquam molestie viverra risus. Proin arcu. Vestibulum lobortis tempus nisi. Praesent a arcu in velit viverra rutrum. + +In sed lectus. Donec risus dolor, blandit sit amet, elementum convallis, pharetra quis, pede. Integer ornare. Aenean egestas dapibus justo. Sed quam leo, posuere at, elementum vitae, commodo eget, est. Aliquam molestie rhoncus enim. Curabitur iaculis ultrices pede. Morbi aliquet rutrum lacus. Aliquam quam. Sed commodo, turpis in pharetra posuere, mi risus imperdiet erat, a vestibulum massa tellus vehicula sem. Mauris fringilla ultrices nunc. Nam nisi enim, eleifend sit amet, ultrices sed, fermentum non, augue. Proin congue lobortis nisi. Maecenas hendrerit. Nam sed nisl. Nunc elementum odio eu risus. In metus. Phasellus gravida pretium ligula. Nulla vitae neque. Nam nisi tortor, ornare non, blandit at, cursus eu, tortor. + +Duis bibendum ipsum in nunc cursus molestie. Nunc orci. Nullam nec ante non est dignissim viverra. Mauris blandit, velit id feugiat pretium, elit magna pellentesque dolor, at sagittis lacus velit egestas magna. Pellentesque cursus, diam consectetuer sagittis fringilla, tortor nisi adipiscing nunc, eu varius lacus risus ac elit. Mauris id nisi quis leo euismod venenatis. Pellentesque ac ante. Mauris arcu sapien, tempor at, porttitor id, condimentum ut, dui. Etiam fermentum ultricies augue. Cras ut eros at justo ultricies iaculis. Duis dignissim, nisl et facilisis fermentum, erat purus molestie tellus, quis tempus ipsum lectus at elit. Nulla vitae lorem. + +Aenean vel sem et diam semper congue. In bibendum diam quis tellus. Nunc facilisis ultricies nibh. Cras nunc enim, feugiat sed, ultrices vitae, sagittis vitae, ipsum. Fusce vitae nulla. Donec pellentesque, velit in porttitor eleifend, est neque lobortis velit, sit amet rutrum ante tortor nec dolor. Donec vehicula. Nulla facilisi. Sed egestas ultrices nibh. Donec elit lectus, convallis porttitor, aliquet dapibus, feugiat eget, ligula. Sed consectetuer justo. Maecenas a sapien sit amet nisi dapibus lobortis. Vivamus luctus lorem non nulla. Sed eget erat vitae libero interdum posuere. Cras pulvinar. Nullam imperdiet, dolor tempor dignissim blandit, dui sapien rhoncus neque, id malesuada augue magna sit amet urna. Duis sed mauris. + +Morbi accumsan. Sed mauris augue, fringilla non, auctor ut, auctor et, orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus ut pede. Donec viverra enim vel lorem. Pellentesque neque mauris, interdum eu, venenatis id, condimentum eu, sapien. Donec ipsum arcu, lacinia adipiscing, laoreet et, cursus vel, velit. Ut sagittis mauris quis risus. Integer eu odio vitae lacus viverra accumsan. Morbi leo ante, dignissim sed, varius quis, volutpat vitae, nisi. Nulla placerat interdum elit. Donec neque dui, sagittis vitae, sollicitudin quis, commodo vitae, neque. Nulla quis ligula ornare ligula dictum ornare. Mauris rutrum rutrum neque. Aenean vehicula tempus est. Donec varius scelerisque pede. Donec placerat vulputate leo. Nullam nunc nisl, posuere non, feugiat vitae, pellentesque quis, mauris. In dui neque, cursus eget, sagittis eget, dapibus vitae, mi. Proin eget est. + +Fusce porta est. Mauris magna. Aliquam ipsum lacus, ultricies id, vestibulum luctus, accumsan ut, ante. Sed mauris. Sed adipiscing leo sit amet magna. Suspendisse potenti. Nunc massa elit, fringilla eget, egestas vitae, luctus vitae, dolor. Phasellus quis nulla eu nisi interdum sollicitudin. Nullam id tellus. Integer iaculis dolor ac purus. Sed vel mi. Curabitur non magna sit amet justo condimentum vulputate. Quisque tincidunt pede eu nisl. Vivamus lobortis. Nunc metus metus, congue sed, tincidunt sed, pretium at, odio. Donec a arcu. In sem justo, vehicula sed, varius id, volutpat at, risus. Praesent iaculis massa. In arcu elit, hendrerit eget, ullamcorper in, porta id, tellus. Donec sagittis hendrerit diam. + +Suspendisse potenti. Sed et diam et augue sagittis lobortis. Phasellus dolor. Ut et arcu eget ante tempor posuere. Aliquam fermentum scelerisque dui. Mauris at purus. Donec erat sem, vestibulum nec, faucibus ac, mattis a, leo. Suspendisse adipiscing lacinia sem. Nullam orci arcu, dictum et, faucibus viverra, dapibus et, neque. Cras nunc diam, adipiscing non, sollicitudin in, interdum vel, massa. Mauris sagittis, justo at tristique tempus, mauris mauris aliquam ante, sit amet posuere diam dui eget ligula. In dignissim, nisl ut lacinia condimentum, erat justo porttitor nulla, non gravida ligula magna eget massa. Vestibulum vitae ligula at mi vestibulum suscipit. Duis laoreet. Nulla commodo libero sit amet lorem. Ut elementum sem. Integer vel dolor. Nam facilisis mi quis sem ultrices sagittis. Sed quis quam at metus molestie bibendum. + +Proin dui enim, lacinia a, feugiat ac, placerat vitae, pede. Quisque egestas, leo eget aliquam pretium, libero justo tincidunt eros, ut egestas augue pede elementum nibh. Curabitur mollis sodales enim. Donec augue. Phasellus id ipsum posuere dui pretium faucibus. Mauris luctus ante semper nisi interdum adipiscing. Duis dapibus, odio quis viverra rhoncus, justo quam bibendum dolor, id dapibus velit erat vel erat. Fusce sit amet nisl venenatis quam ultrices condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec rhoncus scelerisque ligula. Vestibulum mi odio, accumsan et, adipiscing eget, ornare ut, quam. Nullam blandit molestie mauris. Curabitur dignissim mauris et lorem. Suspendisse a justo. Nam mattis faucibus arcu. Duis blandit enim non massa. + +Nullam lorem. In hac habitasse platea dictumst. Mauris consectetuer posuere mauris. Maecenas tincidunt mauris in eros. Nulla eu metus eu orci sollicitudin faucibus. Suspendisse aliquam mauris id est. Cras blandit dui et urna. Nulla arcu. Sed a urna. Nulla dapibus vehicula tortor. Donec risus. Sed quam metus, egestas eu, cursus ut, viverra non, odio. Ut justo justo, malesuada sit amet, blandit suscipit, molestie in, justo. Vestibulum consequat, quam ac feugiat tincidunt, ipsum libero eleifend odio, non eleifend pede ipsum non ante. Nullam a metus. + +Nam ac nisi at felis cursus mattis. Pellentesque consequat sem quis orci. Quisque tempus. Aenean imperdiet molestie pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eu tellus. Nulla diam eros, sodales ut, sodales nec, tincidunt ac, nunc. Nunc lacinia faucibus ipsum. Vivamus vel neque in erat fermentum luctus. Nulla eget metus nec augue bibendum placerat. Vivamus tempus. Praesent congue ornare ipsum. Etiam mattis feugiat justo. + +Aliquam dui. Aenean commodo tortor vitae nulla. Morbi et ipsum. Mauris ac ipsum. Nam vel risus ut lectus mollis viverra. Curabitur elementum mollis est. Nullam elit. Vestibulum suscipit pretium enim. Vestibulum ut massa. Proin nec felis. Maecenas gravida, arcu nec consequat sagittis, eros tellus scelerisque mauris, vitae accumsan quam quam ut nunc. Integer eget ante eu velit laoreet malesuada. Nunc sagittis, mauris vitae pharetra volutpat, tellus tellus eleifend eros, sit amet rutrum ipsum nisi a velit. Praesent varius leo eu erat. Vivamus consequat placerat purus. Donec pretium elementum nibh. Proin at elit non sem aliquet mattis. Sed ullamcorper ipsum sit amet elit. + +Mauris in metus. Suspendisse magna lorem, faucibus vel, tincidunt quis, scelerisque non, tellus. Fusce quis lorem. Proin a lacus sit amet mauris iaculis pulvinar. Suspendisse rhoncus eros nec mi. Praesent euismod, turpis vitae rutrum pretium, odio metus volutpat neque, eget tempus sapien neque sed erat. Donec fermentum purus at lectus. Nullam sem. Fusce vel mi quis erat lobortis posuere. Aenean eget urna. Suspendisse ligula. Duis in nisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Curabitur vulputate lectus id pede. Phasellus eu velit. Etiam venenatis adipiscing nibh. Aliquam cursus pulvinar tellus. Vestibulum neque. Mauris nec justo et erat semper pellentesque. Fusce mattis dictum dolor. Etiam eget purus eu massa varius elementum. Pellentesque massa. Ut ultricies diam sed ipsum. Nullam diam. Pellentesque id magna id libero tristique aliquam. + +Ut eleifend, purus id placerat venenatis, urna augue aliquet ligula, in ultricies leo risus et tellus. Mauris et nulla id urna tristique tempus. Ut facilisis, urna eu vestibulum rhoncus, lacus eros consectetuer metus, et rutrum dui lectus in purus. Nunc vel nisl non ipsum tincidunt mollis. Nam quam lacus, ornare vitae, rhoncus non, congue sed, odio. Proin nibh dui, porta vel, venenatis non, pellentesque ut, nisi. Sed tristique felis a magna. Suspendisse eget tellus. Cras gravida imperdiet velit. Integer hendrerit risus. Proin orci. Aliquam ullamcorper mauris quis mauris. Nunc lacinia vestibulum metus. Duis tellus. Nullam faucibus, leo ac vulputate sollicitudin, leo dolor faucibus erat, quis bibendum orci odio non arcu. + +Nullam accumsan mattis dolor. Donec et dui. Praesent a felis mollis lacus semper lacinia. Curabitur pellentesque luctus est. Proin nulla dui, condimentum vel, faucibus non, interdum ac, erat. Maecenas scelerisque, lectus id volutpat accumsan, sapien tortor pellentesque dui, sed semper magna sem ut leo. Proin nulla. Nullam dapibus ullamcorper sem. Suspendisse vehicula metus in nunc. Pellentesque non quam vel arcu ultrices ullamcorper. Phasellus quis felis sit amet tellus ullamcorper fermentum. Sed vehicula sollicitudin urna. Curabitur pharetra scelerisque risus. Pellentesque id massa quis metus aliquam imperdiet. In nunc lacus, feugiat in, gravida eget, venenatis ut, tellus. Suspendisse potenti. Nam consequat adipiscing dui. In nulla nisi, feugiat ut, fermentum vel, gravida nec, tortor. In sed augue. + +Etiam ullamcorper augue at enim. Integer dignissim. Aliquam pulvinar congue nulla. Morbi enim massa, fringilla a, accumsan eget, condimentum nec, erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean pharetra. Etiam porttitor purus a metus. Aliquam interdum sem eget justo. Quisque volutpat luctus est. Aenean augue. Phasellus dui lectus, ultrices nec, commodo vel, auctor vel, nisi. Ut ultrices pellentesque nisi. Integer ac velit et sem imperdiet luctus. Fusce vitae turpis id augue mollis consectetuer. + +Maecenas nec lacus. Maecenas condimentum odio eu felis. Mauris ut nisl viverra erat faucibus adipiscing. Etiam egestas. Nunc et dolor vitae risus dignissim commodo. Morbi lectus velit, tincidunt nec, aliquet vel, mattis vitae, ligula. Maecenas ultricies semper dolor. Suspendisse malesuada. Integer mattis elit. Donec accumsan, lacus facilisis varius tempus, nulla elit porta erat, et rutrum elit sem sit amet dui. + +Maecenas mollis mi non nulla. Vivamus turpis. Suspendisse a metus. In quis mi in turpis congue auctor. Maecenas lacus. Suspendisse sollicitudin. Phasellus porta nunc non nisl pulvinar egestas. Sed nulla. Vestibulum ac mi. Mauris ultricies condimentum neque. Nulla tempus justo vel massa. Nulla suscipit congue arcu. Praesent id turpis. Mauris nibh pede, euismod semper, molestie ac, rhoncus vitae, ante. Maecenas erat felis, viverra sollicitudin, sagittis eget, pellentesque nec, orci. Fusce ultrices consequat lacus. Aliquam erat magna, feugiat at, viverra a, mollis non, turpis. + +Donec mi. Nam dictum pellentesque sem. Donec mollis rhoncus elit. Phasellus rhoncus pede sit amet risus. Donec eget augue. Maecenas non lectus. Phasellus sollicitudin nisi nec felis. Aliquam pretium, est eget semper convallis, nibh nunc sollicitudin purus, id tempor pede dui vel magna. Vivamus ac lorem. Etiam nisl tortor, adipiscing dictum, elementum in, facilisis sed, nibh. Proin mauris. Proin rutrum massa eget sem. Curabitur tempor adipiscing elit. Curabitur purus tellus, fermentum eget, aliquet vitae, convallis ac, mauris. + +Integer consequat velit eu eros tincidunt vehicula. Nullam lorem sapien, rhoncus non, mattis quis, ultricies sit amet, enim. Curabitur commodo, libero in euismod suscipit, sem purus fringilla enim, ac molestie tortor orci et velit. Donec pede. Etiam placerat condimentum turpis. Phasellus egestas enim nec magna. Vivamus condimentum, nulla vel luctus tristique, eros risus vestibulum nulla, in vehicula arcu ipsum at felis. Donec aliquam elit at augue. Quisque a eros eu ligula accumsan dictum. Etiam vehicula turpis quis libero. Aliquam non mi. Donec et leo. Proin leo libero, aliquam tincidunt, congue nec, adipiscing porta, enim. Nulla lobortis, tortor sit amet imperdiet ullamcorper, dolor orci malesuada pede, sed gravida nibh urna vel lorem. Sed pharetra malesuada eros. Quisque euismod aliquet erat. Suspendisse aliquet mattis purus. + +Nunc id nulla quis justo congue sollicitudin. Praesent erat turpis, rhoncus eu, pretium eu, pellentesque a, nibh. Vivamus tempus. Cras nec risus at turpis imperdiet lobortis. Ut mattis. Maecenas est felis, pellentesque non, imperdiet sed, eleifend tincidunt, lorem. In tincidunt. Sed vel leo. Donec et urna in turpis hendrerit blandit. Donec condimentum accumsan est. Ut pharetra, metus vitae mattis consectetuer, leo quam vulputate odio, nec laoreet nisi velit eu erat. Integer lectus augue, egestas in, interdum eu, venenatis vel, sapien. Quisque et est vitae eros laoreet lobortis. Nullam ut risus non nulla placerat adipiscing. Praesent dapibus. Etiam a felis. Ut sodales consequat mauris. Duis lorem felis, luctus a, tristique in, molestie at, risus. Sed vehicula bibendum tellus. Nam consequat euismod lacus. + +Aenean tortor elit, gravida nec, fermentum eu, lobortis id, ipsum. Maecenas eu purus. Cras ac turpis ut nisi iaculis rhoncus. Nulla purus metus, dignissim nec, tincidunt vitae, dapibus eu, nibh. Fusce lobortis, nunc at viverra eleifend, justo turpis scelerisque eros, ac pellentesque metus nisl at purus. Sed elementum tellus sed enim interdum blandit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer ultricies aliquet odio. Mauris eget nunc a ipsum ultrices sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean accumsan. Donec sapien lectus, congue at, porta id, hendrerit vitae, nisl. Curabitur vel quam vel neque accumsan laoreet. Morbi sapien est, pretium in, consectetuer ac, mollis ut, libero. Donec tincidunt adipiscing metus. Nunc vestibulum egestas augue. Donec scelerisque dui ut sem. Suspendisse vel metus id est molestie iaculis. + +Vivamus pharetra, elit eu malesuada blandit, diam tortor mollis dui, sed pulvinar massa nunc et magna. Sed placerat elit auctor tortor. Nulla ac erat. Pellentesque consectetuer, dui convallis tincidunt condimentum, sem odio volutpat libero, non elementum felis neque nec odio. Maecenas hendrerit eros id diam. Mauris vel purus ac orci convallis convallis. Sed sit amet lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque dictum varius lacus. Mauris eget nisl. Suspendisse placerat, nulla non ornare dignissim, nisl diam sagittis tellus, in semper nisi dolor at nibh. Duis ullamcorper viverra felis. Integer a tellus. Suspendisse eget nunc. Aenean diam est, accumsan id, suscipit interdum, fringilla vitae, justo. Proin pede. Maecenas at neque in neque vestibulum eleifend. + +Vestibulum nulla lorem, porttitor eget, euismod ac, aliquam at, nisl. Maecenas et est eget massa varius lobortis. In mi. Duis porttitor fermentum purus. Donec cursus imperdiet ligula. Morbi et ligula et ante molestie vehicula. Mauris sed dolor. Sed imperdiet felis ut sem. Sed vitae neque elementum leo auctor fermentum. Duis feugiat ullamcorper erat. Aenean purus. Morbi fermentum vestibulum est. Pellentesque venenatis mauris. Phasellus pulvinar. Integer ipsum lectus, iaculis a, lacinia id, accumsan id, arcu. Phasellus at est. Fusce neque quam, ultricies id, iaculis vel, dapibus vitae, lacus. In lobortis convallis ante. Nulla nunc purus, vulputate in, hendrerit et, blandit et, ligula. + +Pellentesque leo metus, sagittis in, molestie vitae, dictum in, pede. Morbi pretium felis nec quam. Pellentesque mattis ante sed quam sagittis dapibus. Suspendisse sapien. Praesent bibendum iaculis tortor. Duis a nisl. Aenean mi. Donec dictum arcu in est. Morbi interdum vulputate ipsum. Aenean sit amet magna non nisl tristique posuere. Phasellus velit metus, tempor ac, fermentum eget, condimentum non, velit. Vestibulum sit posuere. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras aliquet massa nec dui. Cras arcu nunc, hendrerit ac, eleifend eu, ullamcorper nec, tellus. Sed pharetra purus sit amet quam. Curabitur mollis. Nam vitae pede. Etiam risus massa, vehicula sit amet, pharetra nec, sollicitudin ut, dui. Donec egestas justo at quam. Proin nisl risus, vestibulum nec, pretium vitae, tristique ac, lorem. Aliquam erat volutpat. Cras sed nibh. Pellentesque sollicitudin euismod augue. + +Etiam fringilla sollicitudin orci. Mauris cursus elit quis lacus. Cras tortor. In adipiscing, lectus id auctor vestibulum, neque pede accumsan dolor, non imperdiet magna diam accumsan velit. Suspendisse at libero ut nisi blandit sagittis. Phasellus non mauris. Fusce elementum sagittis sem. Suspendisse aliquam eleifend tellus. Proin ligula lorem, imperdiet quis, venenatis id, iaculis mollis, nisl. Etiam convallis pede at massa. Morbi accumsan dui et mauris. + +Sed sed orci. Nunc purus. Suspendisse potenti. Ut luctus fringilla mauris. Donec nibh. Phasellus porta. Phasellus sit amet odio sed magna sodales pharetra. Cras lectus. Suspendisse libero ipsum, commodo nec, facilisis in, suscipit lobortis, ligula. Duis massa nulla, semper et, consequat nec, pharetra eu, elit. Vivamus ultricies aliquam odio. Vestibulum sit amet massa. Sed consequat lacus sed urna. Etiam faucibus felis vel orci. Phasellus ullamcorper. Aenean consectetuer lacus at libero. + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis facilisis, ligula vitae condimentum scelerisque, velit orci gravida felis, vel ultricies quam mi non diam. Vivamus auctor metus non libero. Praesent ligula nisi, commodo condimentum, molestie et, viverra et, justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus sollicitudin. Nunc blandit cursus ipsum. Aenean nec ligula ut tellus sodales mattis. Integer sem. Aliquam id ligula. Sed tortor mauris, blandit vitae, cursus vel, elementum et, nulla. Aliquam scelerisque metus et nisl. Duis adipiscing magna at neque. Quisque vulputate eleifend nunc. Aliquam eget elit. Phasellus dui odio, bibendum sagittis, vestibulum id, dignissim imperdiet, orci. Nullam eu felis non nunc lacinia sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Suspendisse pellentesque, libero mattis ultricies accumsan, tortor tortor malesuada sem, et sodales libero odio ac ipsum. Vivamus quis magna nec est suscipit lobortis. Cras tempus posuere nunc. Quisque ut enim a felis egestas semper. Sed pharetra mattis neque. Fusce turpis nunc, congue sed, consequat non, congue sed, nulla. Suspendisse varius lorem id risus porta vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce sed purus. In a felis. Integer egestas auctor orci. Mauris ultrices suscipit nisl. Nullam purus. + +Cras tempor adipiscing ipsum. Ut quis mi. Maecenas in justo ut nulla congue pharetra. Pellentesque ut libero eu dolor venenatis suscipit. Praesent feugiat consectetuer nibh. Morbi faucibus sem non felis. In hendrerit arcu ac massa. In accumsan ultrices mi. Proin malesuada auctor felis. Curabitur interdum. Sed diam ipsum, ultricies in, tempor sit amet, viverra imperdiet, elit. Morbi molestie nisi. Mauris ipsum. Fusce dictum mollis magna. Duis commodo dignissim nulla. Vestibulum augue enim, ultricies quis, iaculis nec, tincidunt vitae, diam. Mauris lacinia tempus ipsum. Sed at mauris. Ut lorem. Donec libero. + +Duis iaculis lacinia lectus. Aenean convallis eros ac ante. Sed quis orci nec risus auctor fringilla. Phasellus facilisis elementum nisi. In hac habitasse platea dictumst. Nunc porta lacus nec ante. Morbi mauris erat, adipiscing in, pulvinar nec, lobortis nec, odio. Ut eleifend lectus sed quam. Nullam mollis. In non turpis et nisl hendrerit blandit. Duis elementum. Nunc nec libero. Suspendisse vestibulum risus non pede. Morbi imperdiet odio sit amet libero. Sed sed massa vitae ipsum mattis tincidunt. Nulla nec tortor vitae libero volutpat tempus. Donec aliquam. + +Duis sed nunc. Curabitur turpis nulla, vehicula sed, luctus quis, elementum eget, felis. Maecenas et purus. Maecenas leo tellus, tincidunt a, facilisis vitae, lobortis sit amet, velit. Donec convallis sapien. Maecenas mollis odio eu nibh. Etiam gravida. Integer molestie, sapien eu molestie lacinia, nunc nibh aliquam ligula, eu sagittis tellus erat sollicitudin odio. Duis et risus. Phasellus nisi neque, placerat nec, condimentum non, ultrices eu, sem. Ut pede. Etiam nulla metus, volutpat id, convallis sed, suscipit vel, urna. Donec vel elit. Ut leo neque, venenatis faucibus, lacinia nec, tincidunt eu, enim. Cras id dui a libero pharetra dignissim. Donec eros leo, porta quis, laoreet ut, pellentesque volutpat, lectus. + +Nullam blandit. Aliquam erat volutpat. Fusce adipiscing enim. Suspendisse non dui quis ligula porta vestibulum. Donec eu tellus vel lorem pretium porttitor. Praesent luctus. Aliquam ac eros in massa dapibus tincidunt. Donec ut magna. Etiam auctor lacus sit amet lacus. Sed ultricies ipsum nec elit. Quisque a est in purus suscipit tristique. + +Aenean sed dui vel dolor pulvinar laoreet. Vivamus vehicula lorem in pede. Vivamus et diam. Integer ac odio vel diam hendrerit bibendum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a nisi. Phasellus tincidunt dui vitae augue. Duis faucibus, dui interdum fringilla tincidunt, odio elit vestibulum libero, ac molestie magna lectus id lacus. Aenean ligula. Nulla facilisi. + +Fusce vel sem eu velit fringilla ornare. Sed feugiat tincidunt felis. Nullam felis mi, euismod sit amet, mollis at, sodales eget, augue. Nam imperdiet nibh at velit. Sed ut erat. In dui. Nulla facilisi. Nullam augue libero, tincidunt nec, pretium eu, pulvinar in, dui. Morbi vitae felis. Pellentesque vel justo vel velit sagittis malesuada. Proin vehicula blandit massa. Etiam tincidunt pharetra urna. In metus est, auctor nec, blandit a, cursus nec, quam. Mauris ac metus a libero congue faucibus. Mauris mauris dolor, sodales in, cursus ut, sodales rutrum, eros. Quisque mauris eros, sagittis vitae, lobortis ut, eleifend id, nisi. + +Aenean neque. Vestibulum egestas pellentesque ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus sagittis justo vel risus. Sed pretium neque vitae urna. Pellentesque congue libero id lorem. Mauris leo lorem, blandit sit amet, convallis quis, consectetuer sed, eros. Mauris tincidunt, enim a gravida euismod, magna nulla fermentum libero, viverra egestas velit quam et tortor. Vivamus aliquet massa vitae justo. Nulla congue lacus ac elit. + +Phasellus commodo quam vel ligula. Proin non metus at eros pulvinar luctus. Mauris diam lorem, posuere quis, gravida et, tincidunt nec, ligula. Sed diam. Aliquam elit lectus, hendrerit ut, imperdiet sit amet, pretium sit amet, ipsum. Mauris vehicula nisl in dui. Curabitur eget quam ut magna elementum fermentum. Mauris scelerisque. Quisque laoreet. Etiam tempus turpis. Pellentesque augue quam, hendrerit sed, tincidunt at, pharetra at, nisl. Aliquam lacus. Suspendisse potenti. Aenean velit libero, ultrices in, lacinia eu, luctus vel, ante. Etiam dictum mi in felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce gravida dapibus nisl. Cras vitae nisl. + +Maecenas dignissim, ligula non porta cursus, enim nunc malesuada sem, eu porttitor nulla urna eu quam. Fusce eros. Aliquam eros. Nam auctor. Nulla molestie porta est. Suspendisse potenti. Vivamus molestie lorem sed erat. Sed eget ipsum. Integer aliquam pulvinar nulla. Cras aliquet sem ut nunc. Fusce faucibus tempus lectus. Cras sodales, nisi ac facilisis ultrices, eros arcu dapibus sapien, et ultrices mauris tellus non dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras cursus varius metus. Ut turpis. Vivamus eget tortor. + +Sed laoreet, velit non accumsan cursus, nunc urna posuere justo, in dictum lectus pede id ante. Cras vulputate. Cras congue dui sed elit. Proin lacus sem, ultrices at, consequat in, tempor quis, metus. Proin vel arcu. Nam euismod hendrerit elit. Ut erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed posuere. Morbi eros urna, semper at, semper non, convallis quis, velit. Maecenas orci. Vestibulum lobortis tristique metus. Vestibulum lorem nulla, sollicitudin vitae, condimentum quis, auctor ut, dui. Vivamus vestibulum magna ut nisi. Curabitur eleifend dui vel nunc. Curabitur mauris lacus, malesuada sit amet, suscipit sed, rutrum luctus, tellus. Integer facilisis urna vitae lectus. + +Aenean quam leo, lobortis quis, malesuada eu, vulputate vitae, nisl. Praesent eget eros. Ut fermentum turpis id quam. Nam tortor. Praesent nec orci. Nulla bibendum adipiscing augue. Ut commodo, magna id malesuada gravida, augue odio malesuada mi, porta malesuada elit est vitae diam. Mauris non nulla. Suspendisse tincidunt, nunc ultricies porta venenatis, mi pede tincidunt libero, eget varius ante libero ut ligula. Curabitur pretium porttitor tortor. + +Maecenas vitae elit eget nisi dapibus dictum. Nunc in libero. Nulla dictum orci eu erat auctor lobortis. Phasellus risus. Suspendisse potenti. Suspendisse potenti. Praesent adipiscing consequat elit. Integer id augue. Praesent in justo nec magna dapibus pulvinar. Duis nisl. Suspendisse ac odio. Vivamus imperdiet. Donec non velit sit amet risus dignissim congue. Nam aliquet posuere velit. Cras turpis. Morbi malesuada dignissim mi. + +Sed leo neque, varius quis, venenatis sed, pharetra sed, est. Morbi blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam semper pellentesque mi. Ut vel lorem. Nunc mi tortor, laoreet at, faucibus eu, tincidunt sit amet, erat. Duis tempor malesuada ipsum. Phasellus aliquet. Donec et elit. Pellentesque purus. Vestibulum rutrum semper nibh. Nulla facilisi. Phasellus et enim sit amet ante vestibulum vehicula. Phasellus id nisl. Donec mollis leo at eros. Mauris pellentesque neque at purus. Morbi quis dolor at ipsum scelerisque sodales. Etiam volutpat turpis a metus. In hac habitasse platea dictumst. Nunc lorem lorem, vestibulum ac, euismod eget, ullamcorper dignissim, velit. + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ultrices, nibh vel aliquam vestibulum, eros enim venenatis dui, id iaculis enim nunc vel massa. Morbi eleifend orci et massa. Aliquam erat volutpat. Nulla mollis egestas turpis. In sodales nunc eget tortor. Sed ipsum eros, tempor quis, aliquet vitae, imperdiet non, lorem. Pellentesque quis elit id mi luctus dapibus. Sed nunc arcu, rhoncus nec, convallis quis, cursus at, neque. Mauris convallis purus at erat. Pellentesque vestibulum. Vivamus fringilla elit at arcu. Nullam aliquet enim nec arcu. Nam id tortor. Nulla quis nunc. Ut arcu. Suspendisse potenti. Pellentesque ullamcorper ligula id arcu. + +Nam non libero vitae nisl scelerisque fringilla. Quisque varius ante id metus rhoncus fringilla. Nulla facilisi. Praesent eleifend porttitor ligula. Etiam quis dolor non augue commodo auctor. Donec a mi. Vestibulum tempor. Donec felis urna, auctor at, cursus dictum, gravida id, arcu. Aenean dictum malesuada dolor. Vivamus mattis. Phasellus eu pede. Fusce adipiscing justo fringilla metus. Etiam ante. Integer mollis massa quis nunc. Integer dictum neque luctus enim. + +Sed eu libero. Integer tempor ligula in velit. Ut tincidunt lacinia sem. Nullam vel risus. Sed sodales ante a dolor. Curabitur eros. Sed sodales. Sed non metus. Vestibulum elementum faucibus ante. Nulla vel nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In hac habitasse platea dictumst. Nunc nec lorem ut ipsum lacinia iaculis. Duis erat. Aliquam erat. Cras iaculis. In hac habitasse platea dictumst. + +Nullam ante. Cras vitae est. Pellentesque vel metus a ligula dapibus mattis. Duis feugiat aliquet felis. Etiam id nisl quis est dignissim condimentum. Suspendisse potenti. Morbi velit lorem, ornare quis, pellentesque vel, placerat eget, tortor. Vestibulum tincidunt molestie libero. Nulla nulla enim, malesuada id, ullamcorper vitae, dictum at, purus. Donec dignissim odio ut enim. Suspendisse at lectus. + +Praesent lobortis augue vel lectus. Ut in ligula ut felis congue suscipit. Quisque dignissim tortor ut mi. Fusce magna nisi, eleifend ac, ornare vel, porttitor vitae, quam. Vestibulum sodales justo quis turpis. Fusce urna nisi, rhoncus quis, condimentum vel, dictum eu, nunc. Fusce sed nibh vitae odio posuere adipiscing. Sed porta elit quis dolor. Nam libero nulla, auctor sed, tincidunt quis, faucibus sit amet, mi. Quisque orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam id sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vel eros. + +Vivamus luctus lobortis leo. Suspendisse vel elit a enim ullamcorper posuere. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec quis pede mattis lectus mollis adipiscing. Sed accumsan posuere erat. Praesent euismod tincidunt felis. Donec mi. Ut commodo arcu lacinia tellus. Aliquam a libero quis lectus semper viverra. Curabitur lacinia mauris at tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sit amet magna molestie orci suscipit fringilla. Fusce pretium metus non sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed hendrerit. Nulla felis. Suspendisse potenti. Aliquam blandit tristique neque. Curabitur quis erat vel nunc accumsan mollis. + +Duis sagittis, tellus ut aliquam fringilla, dolor mi ullamcorper nisl, ut tristique pede elit sed mauris. Curabitur id felis. Donec pulvinar lacus et lectus. Aliquam vulputate vulputate metus. Curabitur magna felis, adipiscing ac, accumsan vel, molestie quis, quam. Mauris elit arcu, pretium vitae, mollis sit amet, sollicitudin ut, mi. Donec imperdiet dignissim mi. Nullam sit amet tortor. Aliquam neque nulla, venenatis a, porta in, placerat tempus, lacus. Quisque vestibulum dui et lacus. Proin dignissim consectetuer purus. Etiam gravida tortor in nunc. Ut tempor tristique tortor. Sed laoreet tincidunt quam. Vestibulum porta turpis ut elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nibh dui, feugiat nec, laoreet id, malesuada eget, nisi. Ut neque massa, vehicula eu, commodo non, ultricies vitae, purus. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris euismod, felis vel tempor aliquet, tortor mauris malesuada nunc, vel fermentum sem diam id dui. Nam rutrum sapien eget odio. Aliquam sed libero non mi faucibus tempus. Fusce hendrerit, diam non volutpat rutrum, erat metus venenatis ligula, non scelerisque pede ligula vel quam. Morbi rhoncus eros ac dui feugiat elementum. Duis eu libero et tellus congue viverra. Morbi quam quam, elementum sed, ullamcorper imperdiet, commodo non, odio. Nam aliquet egestas urna. Mauris odio felis, varius eu, lacinia eu, condimentum a, lectus. Sed justo massa, pulvinar id, varius a, porttitor nec, libero. Etiam varius. Curabitur sodales, odio at posuere semper, eros nibh tincidunt lectus, vel rutrum sapien nisi in ligula. Suspendisse eget arcu. Phasellus imperdiet est ac sapien. Donec nulla tortor, placerat vel, tempus a, lobortis vel, nibh. Aliquam varius nisi. Nulla et enim. Fusce convallis laoreet lacus. + +Phasellus ipsum dolor, molestie quis, condimentum in, commodo eu, diam. Quisque bibendum lacinia dui. Nullam blandit vulputate orci. Ut lacinia massa vel augue. Aliquam gravida, quam quis imperdiet imperdiet, tellus diam pharetra erat, at pharetra lacus nibh egestas magna. Nulla sagittis lorem ut lorem. Duis condimentum, dui vitae aliquam posuere, diam quam convallis velit, ut gravida leo ipsum non risus. Ut fermentum sollicitudin erat. Donec sagittis scelerisque felis. Nunc arcu. Etiam tempus, magna sit amet suscipit euismod, eros sem rutrum dui, vitae sagittis nibh purus non lacus. Sed mollis arcu eget dolor. Donec ornare, arcu sit amet fermentum vulputate, risus enim fermentum libero, a lacinia dolor mi non velit. Etiam lobortis purus a elit. Nunc nulla dui, mattis quis, bibendum a, ultrices ac, augue. In aliquam vehicula turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Integer id nisl. Quisque dictum elementum odio. Aenean luctus. Sed eu sem a pede vulputate condimentum. Quisque magna. Donec aliquam mattis ipsum. Curabitur dictum sollicitudin sem. Aliquam pulvinar. Nunc sollicitudin risus a erat. Vivamus quis tellus sit amet nibh vestibulum consequat. Nulla pretium sollicitudin dolor. Aliquam iaculis tincidunt turpis. Phasellus ipsum leo, venenatis in, sagittis in, ornare at, nunc. + +Pellentesque ultrices, dui eu iaculis luctus, tellus augue volutpat sapien, in dignissim urna felis ut mi. Sed arcu dui, dignissim id, porttitor ut, imperdiet vitae, ante. Nulla dui sem, commodo nec, sagittis et, lacinia et, pede. Etiam eleifend dui ut nisl. Donec ante mauris, tempus sit amet, varius vitae, gravida quis, mi. In scelerisque, felis vitae viverra sagittis, velit metus ultricies neque, quis imperdiet velit elit et magna. Suspendisse potenti. Sed velit eros, euismod sed, condimentum nec, faucibus sed, sapien. Nam accumsan ligula sit amet neque. Aliquam erat volutpat. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam eu pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed eu felis sed tortor tempor fermentum. Phasellus commodo sem vel nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lectus elit, pharetra sit amet, accumsan sed, tincidunt et, mauris. Duis dapibus pharetra sem. Integer in justo. Praesent eros. Vestibulum ac ante. Aliquam scelerisque sem pellentesque nibh consectetuer sodales. Aliquam consectetuer odio. Duis lectus odio, luctus eu, commodo quis, mollis vitae, velit. Cras nec nunc non elit iaculis mattis. Aenean justo neque, sollicitudin eget, ullamcorper eget, egestas id, sem. In eu risus. Sed egestas. + +Integer at neque. Sed pretium scelerisque nulla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce ut pede. Etiam vitae quam a urna varius imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vehicula. Fusce ullamcorper nibh non erat. Quisque in neque. Praesent est. Pellentesque arcu. + +Proin posuere. Suspendisse potenti. Integer felis lacus, aliquam sed, vulputate in, mollis vel, tellus. Integer vehicula bibendum est. Nunc non dolor in tellus mattis facilisis. Integer vestibulum, augue at commodo aliquam, dui est mattis ligula, sit amet adipiscing orci sem vitae magna. Praesent enim velit, malesuada at, congue nec, luctus in, justo. Sed varius. Morbi pharetra. Donec eu massa nec tellus vulputate pulvinar. Ut commodo turpis non sem. Ut convallis ullamcorper risus. Etiam interdum pede id nisi. Cras magna sapien, suscipit a, laoreet non, rhoncus et, felis. Integer orci lorem, vestibulum dictum, ullamcorper a, porttitor et, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc et magna. Sed bibendum tellus in diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vitae tortor. Integer magna. Duis venenatis, leo ac tempor laoreet, elit nulla pharetra pede, non fermentum nunc odio a odio. Proin non velit. Sed imperdiet augue quis nisl. Integer condimentum nisl nec libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus placerat libero. Duis congue dictum magna. Aliquam dapibus bibendum enim. Nunc eleifend pede vel ipsum. + +Etiam vitae velit. Mauris erat nunc, malesuada ut, feugiat ac, placerat condimentum, augue. Nam volutpat. Aliquam vehicula ipsum id odio. Vivamus sollicitudin turpis id sapien. Fusce a felis vitae odio convallis blandit. Curabitur vitae eros id eros porta pretium. Nulla in magna eget urna lacinia convallis. Aliquam mattis venenatis purus. Sed sed mi eget erat tristique porta. Donec auctor dolor a erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In nec ligula. Nunc eleifend. Vestibulum quis nisi eget elit porttitor congue. Maecenas faucibus, magna eget adipiscing tincidunt, dolor ante malesuada elit, non elementum lacus turpis in pede. + +Ut malesuada mi nec metus. Praesent auctor augue ac nisl ultricies facilisis. Nam purus sapien, pellentesque dignissim, posuere eu, cursus id, diam. Quisque sollicitudin, elit a pellentesque scelerisque, lorem risus auctor quam, quis consequat tellus neque id urna. Suspendisse diam tortor, eleifend dignissim, egestas ut, luctus in, ante. Duis ante. Maecenas luctus. Curabitur cursus pharetra urna. Maecenas imperdiet, erat non elementum euismod, tortor odio euismod lectus, ac facilisis sem nibh vitae nulla. Nunc gravida. Morbi sollicitudin odio quis lacus. Aliquam a nibh non urna porta imperdiet. Aliquam erat volutpat. In iaculis lacinia velit. Sed libero lacus, tristique eu, lacinia ac, aliquet eget, urna. + +Etiam at nisl. Phasellus faucibus luctus lectus. Ut placerat vulputate dolor. Phasellus vel velit. Morbi viverra. Phasellus orci. Integer dignissim mattis mauris. Pellentesque posuere leo posuere quam. Quisque nec magna at diam viverra pellentesque. Suspendisse velit arcu, ultricies quis, congue a, venenatis eget, lacus. Integer sagittis hendrerit dolor. Fusce tincidunt ante a sem. + +Maecenas consectetuer, justo sed rhoncus venenatis, nibh arcu rutrum dolor, sed condimentum libero libero et ipsum. Vivamus mattis justo ut lorem tincidunt lobortis. Ut non velit id neque aliquet accumsan. Sed tempus viverra nulla. Curabitur ullamcorper, neque quis dapibus scelerisque, felis diam gravida orci, non cursus quam neque vitae elit. Etiam pharetra tincidunt lacus. Duis euismod fringilla est. Etiam ornare tincidunt lectus. Proin in turpis. Nunc blandit blandit turpis. Aenean ut augue. Duis orci justo, tincidunt eu, rutrum sed, rutrum et, turpis. Curabitur facilisis odio in ante. In hac habitasse platea dictumst. Sed eros est, pellentesque at, tincidunt eu, ultrices quis, metus. Morbi sit amet justo. Maecenas ac arcu. Mauris dignissim. + +Pellentesque ultricies rutrum orci. Aenean ornare. Vivamus eu risus vel mauris lobortis dictum. Sed et turpis auctor mi rhoncus pulvinar. Sed nec nunc a purus tempor viverra. Pellentesque suscipit. Donec tristique risus non nibh. Etiam nisl magna, sollicitudin ut, ultrices sit amet, egestas eu, nulla. Aliquam erat volutpat. Vestibulum pharetra. Sed egestas, metus sit amet lobortis consequat, erat elit imperdiet libero, eu interdum quam massa eget dolor. Suspendisse vitae odio. Proin blandit mauris iaculis metus. + +Vivamus vestibulum. Etiam et nisl. Aliquam in diam vel elit placerat suscipit. Duis sodales purus ac nibh. Nulla in odio eget enim luctus blandit. Curabitur ultrices ipsum non neque egestas eleifend. Sed turpis. Proin consectetuer. Vivamus mattis. In aliquet. + +Nunc id eros. Donec venenatis, nulla et mattis luctus, ante leo semper justo, non adipiscing odio risus sed lacus. Praesent vitae risus congue libero congue tempus. Phasellus ac eros. Nulla vehicula, lorem in aliquet suscipit, arcu erat egestas sem, quis lobortis quam ante eu massa. Curabitur non massa. Sed bibendum lacinia odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus volutpat blandit lacus. Proin porta, tellus ut auctor laoreet, lectus eros fermentum lectus, id sagittis arcu justo in turpis. Phasellus consequat. Nam pellentesque, mi id viverra convallis, nunc libero placerat leo, eleifend porta sem nisl vitae sapien. Pellentesque ligula libero, tristique non, porttitor rutrum, porttitor non, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer dictum tellus a tortor. Vivamus felis nunc, molestie non, rhoncus quis, pharetra id, dui. Donec risus metus, fringilla vel, aliquet eu, placerat id, neque. + +Suspendisse ipsum. Vivamus lectus. Sed viverra, massa eget convallis mattis, quam turpis consectetuer nunc, eget posuere magna sem id velit. In nec mauris. Aenean a purus sed quam lobortis fringilla. Proin ultricies lacinia ante. Sed adipiscing erat quis velit. Nullam vitae nisl id justo sollicitudin molestie. Nulla facilisi. Sed nec urna sed nisl fringilla dapibus. Nulla at diam. Aliquam eget nibh. Nunc ac nisi sit amet tellus egestas tempus. Nam scelerisque urna et neque. Donec est orci, sagittis non, vulputate a, commodo et, augue. Ut dapibus tortor. Ut nunc. Donec dictum dapibus odio. Nam ultricies ullamcorper ligula. Pellentesque accumsan varius leo. + +Morbi euismod laoreet erat. Vivamus quis ipsum. Morbi euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel purus. Nullam at magna. Curabitur lacus lorem, iaculis quis, dapibus non, volutpat vel, nulla. Donec ut arcu rhoncus dolor pretium dictum. Nullam vel metus. Ut arcu. Pellentesque nisi nunc, placerat eget, tincidunt vel, pharetra non, nunc. Integer tincidunt ultricies lectus. Integer semper, purus sed ultrices feugiat, nulla pede sollicitudin erat, vel auctor nulla ipsum vel lectus. Aenean mi. + +Nullam sed nisi et arcu imperdiet fermentum. Mauris nec metus. In ac dolor. In mi arcu, congue ac, pharetra nec, scelerisque sit amet, magna. Curabitur lacus. Curabitur et elit. Aliquam ullamcorper nunc eu elit. Sed convallis dolor at velit. Vestibulum dapibus, augue id consectetuer placerat, nunc massa blandit sapien, id aliquam elit nisi id mi. Phasellus sapien est, gravida eu, bibendum ut, adipiscing quis, est. Ut molestie quam vitae odio. Donec quis risus id erat faucibus sollicitudin. Nam id felis. Mauris sed enim vitae leo accumsan pretium. + +Nam justo. Donec turpis nisl, commodo et, interdum ac, consectetuer non, massa. Fusce sem metus, laoreet nec, posuere id, imperdiet in, velit. Donec vulputate justo eget turpis. Nulla pede. Morbi tincidunt. Fusce aliquet, quam et aliquam fringilla, ante ante iaculis dui, nec aliquam arcu purus sed erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus suscipit quam et est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; + +Integer sed tellus. Sed sed velit ultricies leo rutrum laoreet. Sed non eros ac purus sagittis feugiat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed hendrerit ligula sit amet nibh. Maecenas turpis. Morbi consectetuer, dolor et adipiscing imperdiet, ante neque feugiat dolor, at porta quam neque quis ligula. Mauris semper velit sit amet ipsum. Pellentesque tempus, purus in rutrum consequat, enim erat vehicula massa, id accumsan leo sapien nec purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In dolor. Integer facilisis libero sit amet pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut varius aliquet enim. Nulla facilisi. Curabitur consectetuer, odio eu pretium tincidunt, nunc nisi aliquet neque, vel imperdiet elit massa sit amet turpis. Pellentesque tempus, orci volutpat blandit fringilla, odio sem posuere ante, vitae bibendum urna lorem vitae eros. Praesent viverra rhoncus arcu. Sed auctor, est sit amet mollis mollis, quam quam gravida sapien, in commodo metus nulla auctor enim. Donec facilisis. + +Proin tincidunt, sapien eget ultricies adipiscing, est odio dictum arcu, ut mollis erat dui sit amet velit. Morbi est sem, interdum at, congue a, elementum vitae, metus. Suspendisse id augue. Mauris enim sem, pulvinar eget, tempus a, tempus sit amet, sapien. Fusce vestibulum consectetuer dui. Pellentesque erat. Sed dignissim placerat odio. Maecenas semper rhoncus lectus. Phasellus pretium. Duis libero elit, eleifend nec, egestas ut, cursus sed, felis. Nam nisl arcu, aliquet et, facilisis eu, luctus ut, risus. Etiam ultrices, dolor sed volutpat malesuada, turpis arcu imperdiet tortor, euismod commodo libero massa ut quam. Integer molestie purus non elit. Ut venenatis semper tortor. Etiam bibendum egestas ipsum. Mauris sollicitudin sem nec nibh. Nulla pretium metus eu metus. Pellentesque sit amet sem. + +Suspendisse ac nisi. Ut leo. Vestibulum hendrerit pretium dolor. Nunc feugiat malesuada purus. Cras et nibh. Curabitur nunc erat, malesuada vitae, laoreet ac, ultricies in, purus. Vivamus tellus arcu, sodales eu, facilisis a, lacinia nec, nunc. Pellentesque id velit. In eu nibh. Nunc nec erat. Sed dictum neque ut nisl. + +Morbi lectus tellus, tincidunt ac, porttitor ac, tristique in, eros. Donec luctus luctus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ut est et enim scelerisque accumsan. Donec ligula felis, lacinia quis, pellentesque in, semper vestibulum, elit. Mauris eget orci a felis congue vehicula. Ut sollicitudin. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam id dolor ut lorem dignissim venenatis. Suspendisse vitae sapien. Proin non magna ut eros viverra pulvinar. Donec quis odio. Nullam non arcu vel lorem suscipit aliquam. Aliquam rutrum turpis in leo. + +Ut luctus nibh tristique erat. Suspendisse bibendum odio vitae tortor. Donec lacinia. Cras sodales felis luctus nulla. Nam eleifend sagittis ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse vel neque. Morbi aliquet vehicula magna. Aenean at odio. Duis pellentesque magna. Nulla at tortor ut diam dictum faucibus. Mauris quis velit. Donec non tellus vitae lorem fringilla porttitor. Fusce ut sapien quis tortor feugiat sagittis. Donec viverra sem vitae sapien. Praesent sodales, lacus in fringilla viverra, odio augue adipiscing urna, vitae interdum ante sem non nisi. Nullam tortor lorem, eleifend ac, mollis non, laoreet ac, risus. Integer ornare leo sed justo. Quisque cursus, sem non facilisis bibendum, nisi mi varius felis, fermentum feugiat lorem eros laoreet risus. + +Quisque sit amet est et lorem vehicula lacinia. Donec nec tortor. Cras odio. Nam scelerisque vulputate urna. Praesent dui. Etiam nec nisl lobortis ipsum aliquet tempus. Maecenas pretium sollicitudin mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus augue massa, congue eget, convallis eget, tristique sit amet, eros. Sed consequat nisi eu felis. Pellentesque justo. Suspendisse non augue. In dignissim lobortis mauris. Mauris sagittis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + +Sed adipiscing. Donec a tellus vitae est cursus vehicula. Nam ante sem, sodales id, fringilla vel, condimentum vel, nulla. Quisque sodales. Etiam imperdiet elit id odio. Aliquam erat volutpat. Maecenas porta tempor arcu. Nulla sem augue, pellentesque ac, consequat ut, condimentum euismod, risus. Sed aliquam tincidunt mi. In interdum lobortis orci. + +Sed vehicula hendrerit purus. Etiam a diam. Curabitur convallis. Suspendisse a nisi. Donec id magna in quam sollicitudin ultricies. Donec viverra. Quisque volutpat est sed sem. Aliquam justo. Vestibulum tortor massa, porttitor sed, varius quis, iaculis quis, odio. Aliquam eget neque. + +Mauris nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum eu quam in neque ultrices pellentesque. Cras in dolor quis quam varius hendrerit. Aliquam nisi lacus, lobortis eu, convallis sit amet, facilisis ut, mi. Aliquam at neque. Cras sagittis elementum justo. Vestibulum ut lectus aliquet purus malesuada volutpat. Duis at lacus adipiscing libero tincidunt vestibulum. Morbi a libero. Cras purus. Morbi ut augue et purus interdum scelerisque. Integer a dui. In hac habitasse platea dictumst. Duis pharetra metus eget mauris. Aliquam interdum ullamcorper massa. + +Etiam ornare. Nullam euismod. Aenean consequat gravida ligula. Aliquam est. Proin vitae lacus. Praesent a eros sit amet dui luctus commodo. Phasellus vehicula arcu eget dolor. Praesent fermentum congue leo. Aliquam volutpat purus ut lorem. Fusce hendrerit enim at leo. Aliquam rhoncus nisl. Vivamus dictum egestas mi. Suspendisse pellentesque bibendum dolor. Pellentesque tincidunt, turpis semper pellentesque condimentum, ipsum metus sodales ligula, id volutpat diam turpis ut elit. + +Praesent sed lacus. Nam eleifend molestie mauris. Donec dapibus fermentum massa. Donec viverra faucibus purus. Curabitur congue, libero vitae viverra pellentesque, diam velit sodales enim, sed suscipit lectus nisi nec neque. Vestibulum malesuada, lacus at cursus congue, velit lectus tristique dolor, sit amet sodales neque ipsum a libero. Vestibulum et quam. Curabitur placerat. Curabitur nunc arcu, euismod nec, vulputate hendrerit, aliquet eget, quam. Curabitur vel enim. Suspendisse potenti. + +Nunc consequat orci ut lacus. Fusce velit dolor, dapibus sed, blandit sit amet, rhoncus id, risus. Duis urna nibh, scelerisque quis, dapibus a, scelerisque sed, nibh. Donec luctus. Ut eu mauris cursus diam lacinia rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam vehicula molestie justo. Maecenas imperdiet pede sed mi. Suspendisse nulla dolor, hendrerit eget, hendrerit id, dictum vel, leo. Duis accumsan. Curabitur in felis. Nunc lorem. Ut leo dolor, laoreet nec, vulputate at, eleifend in, nulla. Quisque nunc purus, varius eget, accumsan nec, aliquet et, nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras adipiscing viverra dolor. Mauris porttitor ultrices purus. Nulla facilisi. Praesent faucibus ante vitae mauris. + +Praesent lacinia lectus sed nisl. In tempus congue mauris. Integer facilisis ornare enim. Nulla id massa. Donec commodo diam at tellus. Nam dapibus viverra est. Nam tellus. Praesent a libero. In faucibus est eget nibh. Nulla eros orci, imperdiet non, blandit non, tempor eget, mi. Pellentesque convallis. + +Quisque eget mi ac leo euismod faucibus. Phasellus rhoncus purus id dui. Vestibulum malesuada eleifend ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque blandit mattis odio. Suspendisse consequat, lectus ac semper sollicitudin, mi velit dictum augue, ac tempus dolor erat sit amet dui. Proin hendrerit, felis quis volutpat posuere, diam odio malesuada odio, a interdum orci diam quis sapien. Pellentesque odio odio, viverra vel, gravida eu, molestie sed, nulla. Phasellus mauris pede, commodo ut, euismod eu, hendrerit eu, est. In hac habitasse platea dictumst. Nulla elementum lacus eu augue. Sed erat. Proin porta. Maecenas quis mi. Phasellus at enim ac justo gravida ultrices. Cras leo. + +Integer ut arcu. Donec sed magna. Proin felis. In iaculis, ligula id fringilla pretium, nibh diam accumsan tellus, eget accumsan metus dui varius turpis. Phasellus orci metus, eleifend sed, tempor ac, scelerisque ac, urna. Integer viverra neque a mauris. Mauris porttitor dolor eu velit. Integer odio elit, vestibulum ut, volutpat id, rhoncus commodo, urna. Etiam placerat pharetra erat. Ut tempor est. Integer dignissim blandit tellus. Morbi nibh dolor, scelerisque id, commodo malesuada, mattis at, mi. Cras tincidunt commodo purus. In tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ullamcorper. Ut hendrerit. Morbi ultrices. + +Praesent iaculis, eros ac egestas sodales, urna leo fermentum ligula, sit amet aliquam velit sem non purus. Donec rutrum arcu quis purus. Nam posuere, lacus at consequat placerat, nulla pede posuere orci, non euismod turpis dui quis nisl. Proin porta adipiscing nibh. Donec tristique dolor at tellus. Donec neque massa, auctor id, faucibus vitae, ullamcorper vel, nisi. Proin molestie neque sed massa. Nam tempor. Morbi aliquam sapien at tellus. Fusce quis risus et mi pretium pulvinar. Fusce sit amet ligula. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse eu enim et felis scelerisque lobortis. Praesent bibendum. Vivamus vehicula. Integer at nibh sed velit rhoncus molestie. Cras lacus. Sed ullamcorper eros vel erat. Fusce eu tortor sit amet diam euismod sagittis. Nunc quis lacus id nibh convallis varius. Suspendisse vitae mi. Vestibulum tristique. Donec malesuada ipsum id neque. Nullam sed lacus. Duis egestas, justo ut congue ornare, augue sapien luctus diam, at accumsan erat sapien ut libero. Phasellus vel nulla. Suspendisse arcu tellus, porttitor a, pharetra faucibus, aliquam sit amet, massa. Nulla porttitor tincidunt lorem. Nunc dolor odio, sagittis in, lobortis vel, volutpat sed, nibh. + +Quisque blandit leo ut sapien tempus facilisis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean ultricies porttitor justo. Fusce rutrum eros ut urna. Proin quis quam eget dui aliquam accumsan. Donec suscipit eleifend elit. Pellentesque mattis, felis sodales iaculis imperdiet, lacus sem convallis augue, sit amet aliquet arcu purus fringilla risus. In eu odio id magna pharetra ornare. Aliquam interdum pulvinar ipsum. Sed neque. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam sit amet nisi. Ut at augue. Mauris volutpat blandit ligula. Nulla eu metus. Vestibulum eget elit. Praesent posuere. Vestibulum id sem non lectus mollis tincidunt. Aliquam id felis at ante ornare tempor. Nulla lacus turpis, feugiat vitae, cursus quis, consectetuer non, mauris. Fusce lacus massa, porttitor ut, molestie ut, venenatis a, lorem. Praesent sit amet orci. Mauris rhoncus felis vitae felis adipiscing imperdiet. Maecenas mollis diam nec leo. + +Fusce enim ipsum, ultrices eu, molestie id, elementum id, sapien. Integer a urna. Nam velit libero, venenatis eget, tempor sit amet, feugiat vitae, ante. Fusce nunc. Sed semper nisl nec risus. In sed libero. Proin tortor neque, tincidunt ac, tempor ac, pharetra quis, velit. Duis lectus augue, ultricies vel, consequat id, iaculis id, ante. Vivamus auctor metus a ante. Curabitur arcu nisi, facilisis at, laoreet in, consectetuer sed, mauris. Quisque placerat diam sed dui. Vivamus pretium condimentum lorem. Curabitur laoreet. Aenean orci ligula, cursus eget, lacinia non, faucibus vel, lorem. + +Aliquam erat volutpat. Curabitur eros dolor, congue a, condimentum sed, luctus ut, nibh. Maecenas non tortor nec turpis commodo pellentesque. Praesent euismod placerat mi. Suspendisse potenti. Phasellus ut neque vitae orci mattis iaculis. Integer eget tellus. Donec at ante. Nam lacinia leo eget erat. Maecenas euismod magna congue tortor. Morbi nec massa eu enim malesuada sollicitudin. Sed accumsan. Nullam ipsum. Ut odio. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque id velit. Nam odio sem, aliquet ut, tempus sit amet, euismod et, nunc. + +Pellentesque libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent mauris nunc, varius ut, convallis molestie, luctus sit amet, leo. Sed dictum lorem et arcu. Nunc venenatis pellentesque massa. Nulla facilisi. Phasellus in tortor eget risus scelerisque vulputate. Sed nibh elit, sagittis ac, condimentum nec, convallis et, justo. Fusce volutpat metus. Nunc auctor. Vestibulum leo eros, pellentesque ac, mollis ultrices, rhoncus non, dolor. Mauris vehicula placerat nisl. Vestibulum bibendum, arcu quis congue elementum, velit nunc eleifend turpis, id luctus risus nisl sit amet tellus. Phasellus pede neque, blandit non, commodo vitae, ultricies eget, magna. Aliquam erat volutpat. + +Nulla facilisi. Aliquam ac ante. Cras risus. Morbi mauris lacus, posuere eu, blandit et, pharetra at, mi. Proin ac purus. Duis cursus nisl rutrum quam. Aliquam a odio non magna pellentesque ultricies. Maecenas ac massa quis sapien ullamcorper tempus. Cras cursus velit sed sapien. Proin nulla. Vivamus sodales aliquam nibh. Etiam et erat ut ante lacinia euismod. Fusce nisi. Proin quis nulla. + +Quisque venenatis, eros sed laoreet sollicitudin, orci ante pellentesque nisl, sit amet viverra quam erat non risus. Cras eget libero. Sed elit magna, semper eu, fringilla in, dignissim sodales, erat. Vivamus feugiat sem vel dui. Donec convallis sollicitudin diam. Cras sed purus. Donec felis eros, semper eget, tempor consectetuer, sagittis quis, nisl. Duis in ante. Cras non turpis. Nulla tempor velit aliquet turpis molestie placerat. Proin elementum fermentum mauris. Vivamus sed orci lacinia dui placerat venenatis. Vestibulum feugiat, tellus in volutpat rutrum, magna nisi ullamcorper eros, id pulvinar neque erat ut lacus. Vivamus sed augue. Nulla facilisi. Maecenas ante augue, elementum ut, sodales vitae, condimentum nec, lorem. Duis pede orci, fringilla at, eleifend nec, pretium in, erat. Nam sagittis, turpis vitae convallis pharetra, odio sem scelerisque lacus, nec lobortis dui diam vel eros. In semper gravida neque. + +Integer nunc. Ut pretium ipsum sit amet elit. In nec arcu. Sed vestibulum vulputate ipsum. Pellentesque tincidunt. Nulla gravida dolor in tellus. Cras vehicula, dolor ut pellentesque aliquam, erat enim auctor massa, vehicula lobortis odio eros quis quam. Proin dapibus neque in enim. Proin elit. Integer rhoncus tincidunt elit. Fusce lorem metus, semper ac, volutpat vitae, facilisis ut, tellus. Donec vel turpis vitae nisi pharetra porttitor. Maecenas tortor. Fusce mi. Nullam nec turpis. Sed sodales vestibulum nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Pellentesque dolor dolor, laoreet eu, aliquet quis, scelerisque sit amet, arcu. In hac habitasse platea dictumst. Nullam cursus urna eget elit. Quisque blandit sapien ac ante. Proin nulla eros, gravida volutpat, sodales vel, mollis eu, massa. Nulla tristique sollicitudin nisl. Curabitur vitae lorem vitae velit egestas ornare. Aenean eget eros. Aliquam erat volutpat. Fusce a urna id odio aliquet convallis. Curabitur sit amet nisl posuere leo posuere dapibus. Duis metus erat, luctus vel, rhoncus at, convallis sit amet, enim. Vivamus hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam eget elit. + +Nullam a nunc. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In metus urna, tincidunt et, lacinia sit amet, lobortis vitae, ligula. Proin et mauris vitae mi accumsan pellentesque. Etiam quam purus, hendrerit sed, feugiat vitae, euismod eget, tortor. Ut aliquam magna vitae justo. Suspendisse non justo vel velit condimentum tempus. Duis tempus ipsum vitae tellus. Proin in massa. Etiam ullamcorper dictum tellus. Proin aliquet felis at leo laoreet pulvinar. Vestibulum arcu purus, malesuada sit amet, cursus eu, placerat sit amet, nunc. Nam massa odio, sollicitudin in, adipiscing a, aliquam nec, risus. Aliquam blandit hendrerit libero. Mauris gravida. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur a nibh. Ut interdum fermentum neque. Pellentesque sed nunc. Mauris vehicula nisi et nunc. Praesent lorem. Donec semper. Integer eu lacus in est aliquam hendrerit. Vestibulum eget neque. Sed semper luctus velit. Curabitur nibh augue, congue eu, hendrerit id, congue et, enim. Integer placerat aliquam lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae eros. Donec vel nisl. + +In vestibulum facilisis urna. Ut risus. Mauris pharetra. Pellentesque mattis. Integer suscipit aliquam ipsum. Duis blandit, sapien et ultricies condimentum, felis mi elementum pede, nec sagittis metus mauris quis quam. Quisque accumsan arcu vel nulla. Cras sem sapien, porttitor id, ultricies sagittis, luctus eu, nulla. Integer quis eros. Morbi sed urna a tellus vehicula vulputate. Etiam nec augue eget felis semper tristique. Quisque ut dolor vel risus dictum consequat. Sed eget dolor sed nunc lacinia aliquet. Suspendisse ac tortor in ipsum posuere venenatis. Sed eget erat. Nulla faucibus. Duis laoreet, massa porttitor aliquet egestas, ipsum lectus rhoncus quam, in adipiscing eros sem ut tellus. Pellentesque feugiat tempus quam. Vivamus id dolor eget sapien consectetuer tempor. Aliquam erat volutpat. + +Nulla iaculis fermentum libero. Curabitur faucibus, massa malesuada cursus tincidunt, erat sem eleifend mauris, sed fringilla mi ante ac purus. Duis elementum lectus. Nunc ornare arcu eu tortor. Vestibulum vel dolor at purus lacinia fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas tincidunt, eros a egestas pellentesque, risus risus dictum libero, id aliquet metus justo in massa. Proin a tellus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed purus. Sed non pede. Aenean massa sapien, sodales sit amet, consequat dictum, eleifend vitae, tortor. Donec ultrices lacinia elit. + +Morbi adipiscing sodales dolor. Ut ullamcorper ultricies est. In venenatis tempus augue. Suspendisse tortor dolor, accumsan et, suscipit a, tincidunt ut, libero. Aliquam scelerisque magna sed felis. Quisque ut nunc a magna vulputate placerat. Aliquam rhoncus vehicula dui. Sed tortor. Nullam sit amet diam. Nunc sed eros. Sed et odio tincidunt elit gravida convallis. Curabitur quis tortor a lacus semper varius. Mauris at augue non mi sollicitudin aliquam. Integer ullamcorper. Pellentesque suscipit quam non purus. Aliquam ac eros at arcu ullamcorper consectetuer. Suspendisse pretium mattis leo. + +Duis at nunc. Sed dolor est, varius ac, porta et, tincidunt hendrerit, risus. Vivamus ut magna. Praesent ut mauris. In purus lacus, mattis sed, vestibulum nec, tempor at, nisl. Cras ullamcorper venenatis tellus. Ut dolor. Maecenas malesuada, pede a pulvinar mattis, arcu diam vehicula risus, quis porttitor augue massa in velit. Nunc congue. Morbi velit metus, rhoncus et, aliquam consectetuer, ultricies malesuada, ligula. Sed velit nisl, sagittis vitae, pharetra a, posuere sed, massa. Nulla facilisi. In varius, ligula id lobortis sodales, augue orci fermentum tellus, eu pulvinar risus ligula a sapien. Morbi laoreet ipsum non mi. Nam cursus lorem ut mi. Vivamus magna enim, posuere non, semper quis, sodales eu, arcu. Etiam mi purus, pretium feugiat, varius sed, pellentesque eget, ligula. In leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vitae orci eu orci sollicitudin feugiat. + +Praesent purus massa, euismod vitae, tempus nec, consequat hendrerit, metus. Aenean felis est, egestas vitae, accumsan eget, pellentesque in, sapien. Duis dapibus pede non sapien. Nunc urna. Integer vel libero. Duis augue arcu, dapibus non, facilisis vitae, posuere ut, eros. Donec vitae nunc sit amet arcu imperdiet dictum. Morbi eleifend, lorem eu consectetuer vestibulum, diam nunc ornare arcu, ac tempor felis dolor eget eros. Phasellus massa sem, sollicitudin ac, sodales gravida, luctus a, quam. Nam neque quam, viverra at, venenatis quis, sagittis non, enim. + +Nulla facilisi. Pellentesque egestas lacinia est. Sed tincidunt, pede sed tincidunt vestibulum, urna dolor adipiscing purus, vitae fringilla felis elit in nibh. Nulla sed nisi. Mauris suscipit scelerisque arcu. Etiam non enim vel eros accumsan malesuada. Nunc tincidunt commodo mauris. In tincidunt risus quis urna. Nulla diam tortor, aliquet et, tincidunt quis, sollicitudin ac, tortor. Cras nisl neque, vulputate suscipit, molestie quis, pulvinar at, nulla. Nullam ac metus nec odio posuere varius. Cras sed pede nec dui posuere bibendum. Duis euismod ullamcorper libero. Aliquam faucibus pulvinar turpis. + +In ut neque id nunc feugiat commodo. Curabitur dignissim, felis at sollicitudin lacinia, enim elit suscipit neque, sed luctus lorem ipsum in leo. Duis dapibus, odio quis auctor commodo, nisl odio mattis tellus, nec tincidunt turpis diam in arcu. Curabitur a sem. Nullam volutpat magna. Pellentesque sagittis, neque consequat pretium cursus, dolor lacus consectetuer arcu, sed laoreet est urna et metus. Suspendisse placerat, dui a porta tempor, lorem dui lobortis neque, sed venenatis diam enim id eros. Etiam et nisl non lectus faucibus consectetuer. Morbi scelerisque, sem nec tempus ullamcorper, ipsum diam feugiat lorem, a fringilla sapien elit quis nibh. Nullam diam urna, viverra sed, pharetra rhoncus, tincidunt vel, orci. Integer accumsan mattis erat. Nam dictum. Mauris nec leo. Nulla iaculis. Nulla nisl mi, dapibus quis, vehicula a, cursus eget, odio. + +Phasellus dapibus euismod nibh. Vivamus imperdiet ante in ligula. Pellentesque accumsan. In imperdiet, dui a auctor fringilla, metus nisi cursus dolor, vel luctus ligula lorem vitae mauris. Praesent mattis vestibulum elit. Aliquam enim lacus, pulvinar non, lacinia sit amet, eleifend non, velit. Vestibulum ac leo. Mauris imperdiet justo ac lectus. Sed molestie lectus sed dui. Sed fermentum tempus mauris. Nam ornare orci ac tellus. Ut malesuada, lacus id lacinia accumsan, diam elit adipiscing metus, et bibendum sapien nibh blandit orci. Suspendisse ipsum tellus, sagittis quis, vestibulum non, vulputate eu, eros. Praesent at nulla id pede scelerisque ultricies. Cras blandit pretium tellus. Maecenas dapibus condimentum augue. Phasellus tincidunt pharetra lorem. Morbi non eros. Sed tempor, nisl a tincidunt tincidunt, eros diam dictum sem, vel dignissim ante diam sed magna. Praesent non ligula id metus molestie consectetuer. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse vel mi. Curabitur ante nulla, rutrum a, convallis vel, vehicula ac, nunc. Nunc sagittis, enim sit amet auctor rutrum, mauris arcu vulputate neque, et euismod est felis quis ante. Vestibulum turpis tellus, hendrerit in, lacinia commodo, ullamcorper gravida, risus. Mauris rhoncus lacinia risus. Maecenas sollicitudin erat vitae nunc. Praesent pretium pellentesque augue. Donec interdum. Praesent ac eros vitae erat lobortis fringilla. Aenean consequat tellus. Nulla accumsan bibendum felis. Maecenas pretium ante id nisi. Aenean mi arcu, semper sed, mattis eu, venenatis sit amet, arcu. Donec aliquet euismod leo. Proin magna justo, tristique a, semper ac, sollicitudin a, ligula. Morbi velit. Aliquam vel nisi. + +In a lorem ut nunc feugiat congue. Donec fermentum bibendum dui. Proin varius est quis velit. Donec aliquet sem accumsan mi. Sed placerat. Nullam ac nisi a massa lobortis suscipit. Nunc id leo. Aliquam et massa. Nullam vestibulum elementum metus. In consectetuer nisi vel justo. Maecenas eget purus sed massa varius pellentesque. Phasellus faucibus felis quis felis. Aenean odio arcu, blandit quis, facilisis in, imperdiet eu, lorem. Nam posuere pulvinar mi. Fusce tristique, mauris et consectetuer ultricies, mauris lectus tempor justo, at fringilla est est sed nisi. Quisque faucibus. Sed in tortor tincidunt est lacinia iaculis. Maecenas a massa. Pellentesque a nibh at purus porta hendrerit. + +Nullam turpis. Fusce ac sem sed odio pellentesque imperdiet. Curabitur in arcu. Praesent lacus lacus, feugiat id, pulvinar in, tincidunt sed, neque. Maecenas viverra odio eget tortor. Integer aliquam, lorem rutrum venenatis dignissim, ligula magna malesuada arcu, vel feugiat lorem ipsum quis massa. Morbi ante. Vestibulum mauris libero, ullamcorper quis, ultrices quis, facilisis non, massa. Maecenas imperdiet. Aliquam erat volutpat. Pellentesque dignissim gravida lectus. In nibh odio, auctor eget, dapibus quis, dignissim venenatis, arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis pellentesque ligula quis massa. Curabitur condimentum, justo eget ornare luctus, lorem ligula sagittis pede, a porta nunc nunc in neque. Quisque felis mauris, condimentum vitae, auctor vitae, tincidunt quis, pede. Nunc lacinia ante in leo. Pellentesque libero. Aenean a ligula et nunc vestibulum consectetuer. + +Fusce ornare. Praesent id urna. Integer venenatis, quam non sagittis accumsan, ante nibh sagittis augue, sollicitudin adipiscing dolor velit eu erat. Proin quis enim eu purus vehicula aliquam. Nulla vel enim vel elit sollicitudin fringilla. Aliquam erat volutpat. Sed suscipit felis ut turpis. Etiam rutrum risus imperdiet est. Aliquam a tellus at tellus commodo dapibus. Mauris rutrum magna et odio. In at dolor. Curabitur vehicula lectus in tortor. Fusce justo purus, luctus vitae, mollis in, pharetra ac, purus. Nullam posuere interdum justo. Curabitur vitae lacus vel leo congue pulvinar. + +Aenean eleifend nibh varius tortor. Suspendisse vel eros. Proin nec diam a tortor ultrices ornare. Aliquam scelerisque feugiat justo. Vivamus ante urna, adipiscing vitae, porttitor eu, sodales et, felis. Suspendisse potenti. Curabitur ac massa in nisl sagittis mollis. Nam quam ligula, consectetuer eget, iaculis at, varius eu, leo. Duis dolor ligula, tincidunt at, ullamcorper sed, accumsan aliquam, ligula. Phasellus vulputate, lorem at tincidunt pharetra, risus lectus lacinia magna, quis rutrum enim magna at sem. In hac habitasse platea dictumst. Duis id sem a mauris sollicitudin tincidunt. Etiam eu purus eu arcu fringilla adipiscing. Vivamus ornare tempus diam. Proin turpis quam, lacinia non, egestas at, commodo eget, pede. Praesent vulputate risus in est. Nulla facilisi. + +Ut elementum lacinia purus. Proin vitae arcu ac nulla convallis aliquam. Nulla congue, libero id pellentesque mattis, quam lectus porttitor diam, a scelerisque dui libero in sapien. Nullam felis diam, vehicula vel, molestie ut, vestibulum aliquam, sapien. Donec convallis, est ut elementum volutpat, mauris ipsum gravida sem, commodo facilisis sapien lectus semper lectus. Quisque porttitor eros ut nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam mattis risus sed odio. Vestibulum et odio. In hac habitasse platea dictumst. Nam tristique massa ut ligula. Quisque nibh tellus, vehicula sit amet, adipiscing at, convallis nec, ligula. Vestibulum pretium, mi nec fringilla bibendum, dui nunc sodales pede, a semper magna nibh non diam. Donec massa nunc, viverra vel, consectetuer porta, dapibus non, ipsum. Duis nisl mauris, cursus vel, semper non, sollicitudin bibendum, felis. Vestibulum eu neque. + +Cras nec dolor. Donec laoreet tempus lectus. Cras sed tortor interdum lacus eleifend dignissim. Maecenas sit amet elit. Nullam quis dolor vel dui pharetra luctus. In sit amet quam sit amet pede ultrices ultrices. Maecenas diam. Integer urna. Curabitur dictum, velit sed placerat suscipit, erat turpis fermentum justo, sed interdum neque sem et nibh. Vivamus consequat convallis magna. Nam aliquam, est ac bibendum commodo, magna est dictum mi, vitae malesuada elit magna vitae odio. Maecenas tempor vulputate tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus dui. Etiam accumsan pede congue tortor. + +Morbi tempor libero ac lorem. In aliquet varius magna. In arcu. Phasellus odio. Fusce tincidunt aliquet felis. Quisque velit. Sed luctus. Aliquam feugiat fringilla mi. Aliquam molestie viverra risus. Proin arcu. Vestibulum lobortis tempus nisi. Praesent a arcu in velit viverra rutrum. + +In sed lectus. Donec risus dolor, blandit sit amet, elementum convallis, pharetra quis, pede. Integer ornare. Aenean egestas dapibus justo. Sed quam leo, posuere at, elementum vitae, commodo eget, est. Aliquam molestie rhoncus enim. Curabitur iaculis ultrices pede. Morbi aliquet rutrum lacus. Aliquam quam. Sed commodo, turpis in pharetra posuere, mi risus imperdiet erat, a vestibulum massa tellus vehicula sem. Mauris fringilla ultrices nunc. Nam nisi enim, eleifend sit amet, ultrices sed, fermentum non, augue. Proin congue lobortis nisi. Maecenas hendrerit. Nam sed nisl. Nunc elementum odio eu risus. In metus. Phasellus gravida pretium ligula. Nulla vitae neque. Nam nisi tortor, ornare non, blandit at, cursus eu, tortor. + +Duis bibendum ipsum in nunc cursus molestie. Nunc orci. Nullam nec ante non est dignissim viverra. Mauris blandit, velit id feugiat pretium, elit magna pellentesque dolor, at sagittis lacus velit egestas magna. Pellentesque cursus, diam consectetuer sagittis fringilla, tortor nisi adipiscing nunc, eu varius lacus risus ac elit. Mauris id nisi quis leo euismod venenatis. Pellentesque ac ante. Mauris arcu sapien, tempor at, porttitor id, condimentum ut, dui. Etiam fermentum ultricies augue. Cras ut eros at justo ultricies iaculis. Duis dignissim, nisl et facilisis fermentum, erat purus molestie tellus, quis tempus ipsum lectus at elit. Nulla vitae lorem. + +Aenean vel sem et diam semper congue. In bibendum diam quis tellus. Nunc facilisis ultricies nibh. Cras nunc enim, feugiat sed, ultrices vitae, sagittis vitae, ipsum. Fusce vitae nulla. Donec pellentesque, velit in porttitor eleifend, est neque lobortis velit, sit amet rutrum ante tortor nec dolor. Donec vehicula. Nulla facilisi. Sed egestas ultrices nibh. Donec elit lectus, convallis porttitor, aliquet dapibus, feugiat eget, ligula. Sed consectetuer justo. Maecenas a sapien sit amet nisi dapibus lobortis. Vivamus luctus lorem non nulla. Sed eget erat vitae libero interdum posuere. Cras pulvinar. Nullam imperdiet, dolor tempor dignissim blandit, dui sapien rhoncus neque, id malesuada augue magna sit amet urna. Duis sed mauris. + +Morbi accumsan. Sed mauris augue, fringilla non, auctor ut, auctor et, orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus ut pede. Donec viverra enim vel lorem. Pellentesque neque mauris, interdum eu, venenatis id, condimentum eu, sapien. Donec ipsum arcu, lacinia adipiscing, laoreet et, cursus vel, velit. Ut sagittis mauris quis risus. Integer eu odio vitae lacus viverra accumsan. Morbi leo ante, dignissim sed, varius quis, volutpat vitae, nisi. Nulla placerat interdum elit. Donec neque dui, sagittis vitae, sollicitudin quis, commodo vitae, neque. Nulla quis ligula ornare ligula dictum ornare. Mauris rutrum rutrum neque. Aenean vehicula tempus est. Donec varius scelerisque pede. Donec placerat vulputate leo. Nullam nunc nisl, posuere non, feugiat vitae, pellentesque quis, mauris. In dui neque, cursus eget, sagittis eget, dapibus vitae, mi. Proin eget est. + +Fusce porta est. Mauris magna. Aliquam ipsum lacus, ultricies id, vestibulum luctus, accumsan ut, ante. Sed mauris. Sed adipiscing leo sit amet magna. Suspendisse potenti. Nunc massa elit, fringilla eget, egestas vitae, luctus vitae, dolor. Phasellus quis nulla eu nisi interdum sollicitudin. Nullam id tellus. Integer iaculis dolor ac purus. Sed vel mi. Curabitur non magna sit amet justo condimentum vulputate. Quisque tincidunt pede eu nisl. Vivamus lobortis. Nunc metus metus, congue sed, tincidunt sed, pretium at, odio. Donec a arcu. In sem justo, vehicula sed, varius id, volutpat at, risus. Praesent iaculis massa. In arcu elit, hendrerit eget, ullamcorper in, porta id, tellus. Donec sagittis hendrerit diam. + +Suspendisse potenti. Sed et diam et augue sagittis lobortis. Phasellus dolor. Ut et arcu eget ante tempor posuere. Aliquam fermentum scelerisque dui. Mauris at purus. Donec erat sem, vestibulum nec, faucibus ac, mattis a, leo. Suspendisse adipiscing lacinia sem. Nullam orci arcu, dictum et, faucibus viverra, dapibus et, neque. Cras nunc diam, adipiscing non, sollicitudin in, interdum vel, massa. Mauris sagittis, justo at tristique tempus, mauris mauris aliquam ante, sit amet posuere diam dui eget ligula. In dignissim, nisl ut lacinia condimentum, erat justo porttitor nulla, non gravida ligula magna eget massa. Vestibulum vitae ligula at mi vestibulum suscipit. Duis laoreet. Nulla commodo libero sit amet lorem. Ut elementum sem. Integer vel dolor. Nam facilisis mi quis sem ultrices sagittis. Sed quis quam at metus molestie bibendum. + +Proin dui enim, lacinia a, feugiat ac, placerat vitae, pede. Quisque egestas, leo eget aliquam pretium, libero justo tincidunt eros, ut egestas augue pede elementum nibh. Curabitur mollis sodales enim. Donec augue. Phasellus id ipsum posuere dui pretium faucibus. Mauris luctus ante semper nisi interdum adipiscing. Duis dapibus, odio quis viverra rhoncus, justo quam bibendum dolor, id dapibus velit erat vel erat. Fusce sit amet nisl venenatis quam ultrices condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec rhoncus scelerisque ligula. Vestibulum mi odio, accumsan et, adipiscing eget, ornare ut, quam. Nullam blandit molestie mauris. Curabitur dignissim mauris et lorem. Suspendisse a justo. Nam mattis faucibus arcu. Duis blandit enim non massa. + +Nullam lorem. In hac habitasse platea dictumst. Mauris consectetuer posuere mauris. Maecenas tincidunt mauris in eros. Nulla eu metus eu orci sollicitudin faucibus. Suspendisse aliquam mauris id est. Cras blandit dui et urna. Nulla arcu. Sed a urna. Nulla dapibus vehicula tortor. Donec risus. Sed quam metus, egestas eu, cursus ut, viverra non, odio. Ut justo justo, malesuada sit amet, blandit suscipit, molestie in, justo. Vestibulum consequat, quam ac feugiat tincidunt, ipsum libero eleifend odio, non eleifend pede ipsum non ante. Nullam a metus. + +Nam ac nisi at felis cursus mattis. Pellentesque consequat sem quis orci. Quisque tempus. Aenean imperdiet molestie pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eu tellus. Nulla diam eros, sodales ut, sodales nec, tincidunt ac, nunc. Nunc lacinia faucibus ipsum. Vivamus vel neque in erat fermentum luctus. Nulla eget metus nec augue bibendum placerat. Vivamus tempus. Praesent congue ornare ipsum. Etiam mattis feugiat justo. + +Aliquam dui. Aenean commodo tortor vitae nulla. Morbi et ipsum. Mauris ac ipsum. Nam vel risus ut lectus mollis viverra. Curabitur elementum mollis est. Nullam elit. Vestibulum suscipit pretium enim. Vestibulum ut massa. Proin nec felis. Maecenas gravida, arcu nec consequat sagittis, eros tellus scelerisque mauris, vitae accumsan quam quam ut nunc. Integer eget ante eu velit laoreet malesuada. Nunc sagittis, mauris vitae pharetra volutpat, tellus tellus eleifend eros, sit amet rutrum ipsum nisi a velit. Praesent varius leo eu erat. Vivamus consequat placerat purus. Donec pretium elementum nibh. Proin at elit non sem aliquet mattis. Sed ullamcorper ipsum sit amet elit. + +Mauris in metus. Suspendisse magna lorem, faucibus vel, tincidunt quis, scelerisque non, tellus. Fusce quis lorem. Proin a lacus sit amet mauris iaculis pulvinar. Suspendisse rhoncus eros nec mi. Praesent euismod, turpis vitae rutrum pretium, odio metus volutpat neque, eget tempus sapien neque sed erat. Donec fermentum purus at lectus. Nullam sem. Fusce vel mi quis erat lobortis posuere. Aenean eget urna. Suspendisse ligula. Duis in nisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Curabitur vulputate lectus id pede. Phasellus eu velit. Etiam venenatis adipiscing nibh. Aliquam cursus pulvinar tellus. Vestibulum neque. Mauris nec justo et erat semper pellentesque. Fusce mattis dictum dolor. Etiam eget purus eu massa varius elementum. Pellentesque massa. Ut ultricies diam sed ipsum. Nullam diam. Pellentesque id magna id libero tristique aliquam. + +Ut eleifend, purus id placerat venenatis, urna augue aliquet ligula, in ultricies leo risus et tellus. Mauris et nulla id urna tristique tempus. Ut facilisis, urna eu vestibulum rhoncus, lacus eros consectetuer metus, et rutrum dui lectus in purus. Nunc vel nisl non ipsum tincidunt mollis. Nam quam lacus, ornare vitae, rhoncus non, congue sed, odio. Proin nibh dui, porta vel, venenatis non, pellentesque ut, nisi. Sed tristique felis a magna. Suspendisse eget tellus. Cras gravida imperdiet velit. Integer hendrerit risus. Proin orci. Aliquam ullamcorper mauris quis mauris. Nunc lacinia vestibulum metus. Duis tellus. Nullam faucibus, leo ac vulputate sollicitudin, leo dolor faucibus erat, quis bibendum orci odio non arcu. + +Nullam accumsan mattis dolor. Donec et dui. Praesent a felis mollis lacus semper lacinia. Curabitur pellentesque luctus est. Proin nulla dui, condimentum vel, faucibus non, interdum ac, erat. Maecenas scelerisque, lectus id volutpat accumsan, sapien tortor pellentesque dui, sed semper magna sem ut leo. Proin nulla. Nullam dapibus ullamcorper sem. Suspendisse vehicula metus in nunc. Pellentesque non quam vel arcu ultrices ullamcorper. Phasellus quis felis sit amet tellus ullamcorper fermentum. Sed vehicula sollicitudin urna. Curabitur pharetra scelerisque risus. Pellentesque id massa quis metus aliquam imperdiet. In nunc lacus, feugiat in, gravida eget, venenatis ut, tellus. Suspendisse potenti. Nam consequat adipiscing dui. In nulla nisi, feugiat ut, fermentum vel, gravida nec, tortor. In sed augue. + +Etiam ullamcorper augue at enim. Integer dignissim. Aliquam pulvinar congue nulla. Morbi enim massa, fringilla a, accumsan eget, condimentum nec, erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean pharetra. Etiam porttitor purus a metus. Aliquam interdum sem eget justo. Quisque volutpat luctus est. Aenean augue. Phasellus dui lectus, ultrices nec, commodo vel, auctor vel, nisi. Ut ultrices pellentesque nisi. Integer ac velit et sem imperdiet luctus. Fusce vitae turpis id augue mollis consectetuer. + +Maecenas nec lacus. Maecenas condimentum odio eu felis. Mauris ut nisl viverra erat faucibus adipiscing. Etiam egestas. Nunc et dolor vitae risus dignissim commodo. Morbi lectus velit, tincidunt nec, aliquet vel, mattis vitae, ligula. Maecenas ultricies semper dolor. Suspendisse malesuada. Integer mattis elit. Donec accumsan, lacus facilisis varius tempus, nulla elit porta erat, et rutrum elit sem sit amet dui. + +Maecenas mollis mi non nulla. Vivamus turpis. Suspendisse a metus. In quis mi in turpis congue auctor. Maecenas lacus. Suspendisse sollicitudin. Phasellus porta nunc non nisl pulvinar egestas. Sed nulla. Vestibulum ac mi. Mauris ultricies condimentum neque. Nulla tempus justo vel massa. Nulla suscipit congue arcu. Praesent id turpis. Mauris nibh pede, euismod semper, molestie ac, rhoncus vitae, ante. Maecenas erat felis, viverra sollicitudin, sagittis eget, pellentesque nec, orci. Fusce ultrices consequat lacus. Aliquam erat magna, feugiat at, viverra a, mollis non, turpis. + +Donec mi. Nam dictum pellentesque sem. Donec mollis rhoncus elit. Phasellus rhoncus pede sit amet risus. Donec eget augue. Maecenas non lectus. Phasellus sollicitudin nisi nec felis. Aliquam pretium, est eget semper convallis, nibh nunc sollicitudin purus, id tempor pede dui vel magna. Vivamus ac lorem. Etiam nisl tortor, adipiscing dictum, elementum in, facilisis sed, nibh. Proin mauris. Proin rutrum massa eget sem. Curabitur tempor adipiscing elit. Curabitur purus tellus, fermentum eget, aliquet vitae, convallis ac, mauris. + +Integer consequat velit eu eros tincidunt vehicula. Nullam lorem sapien, rhoncus non, mattis quis, ultricies sit amet, enim. Curabitur commodo, libero in euismod suscipit, sem purus fringilla enim, ac molestie tortor orci et velit. Donec pede. Etiam placerat condimentum turpis. Phasellus egestas enim nec magna. Vivamus condimentum, nulla vel luctus tristique, eros risus vestibulum nulla, in vehicula arcu ipsum at felis. Donec aliquam elit at augue. Quisque a eros eu ligula accumsan dictum. Etiam vehicula turpis quis libero. Aliquam non mi. Donec et leo. Proin leo libero, aliquam tincidunt, congue nec, adipiscing porta, enim. Nulla lobortis, tortor sit amet imperdiet ullamcorper, dolor orci malesuada pede, sed gravida nibh urna vel lorem. Sed pharetra malesuada eros. Quisque euismod aliquet erat. Suspendisse aliquet mattis purus. + +Nunc id nulla quis justo congue sollicitudin. Praesent erat turpis, rhoncus eu, pretium eu, pellentesque a, nibh. Vivamus tempus. Cras nec risus at turpis imperdiet lobortis. Ut mattis. Maecenas est felis, pellentesque non, imperdiet sed, eleifend tincidunt, lorem. In tincidunt. Sed vel leo. Donec et urna in turpis hendrerit blandit. Donec condimentum accumsan est. Ut pharetra, metus vitae mattis consectetuer, leo quam vulputate odio, nec laoreet nisi velit eu erat. Integer lectus augue, egestas in, interdum eu, venenatis vel, sapien. Quisque et est vitae eros laoreet lobortis. Nullam ut risus non nulla placerat adipiscing. Praesent dapibus. Etiam a felis. Ut sodales consequat mauris. Duis lorem felis, luctus a, tristique in, molestie at, risus. Sed vehicula bibendum tellus. Nam consequat euismod lacus. + +Aenean tortor elit, gravida nec, fermentum eu, lobortis id, ipsum. Maecenas eu purus. Cras ac turpis ut nisi iaculis rhoncus. Nulla purus metus, dignissim nec, tincidunt vitae, dapibus eu, nibh. Fusce lobortis, nunc at viverra eleifend, justo turpis scelerisque eros, ac pellentesque metus nisl at purus. Sed elementum tellus sed enim interdum blandit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer ultricies aliquet odio. Mauris eget nunc a ipsum ultrices sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean accumsan. Donec sapien lectus, congue at, porta id, hendrerit vitae, nisl. Curabitur vel quam vel neque accumsan laoreet. Morbi sapien est, pretium in, consectetuer ac, mollis ut, libero. Donec tincidunt adipiscing metus. Nunc vestibulum egestas augue. Donec scelerisque dui ut sem. Suspendisse vel metus id est molestie iaculis. + +Vivamus pharetra, elit eu malesuada blandit, diam tortor mollis dui, sed pulvinar massa nunc et magna. Sed placerat elit auctor tortor. Nulla ac erat. Pellentesque consectetuer, dui convallis tincidunt condimentum, sem odio volutpat libero, non elementum felis neque nec odio. Maecenas hendrerit eros id diam. Mauris vel purus ac orci convallis convallis. Sed sit amet lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque dictum varius lacus. Mauris eget nisl. Suspendisse placerat, nulla non ornare dignissim, nisl diam sagittis tellus, in semper nisi dolor at nibh. Duis ullamcorper viverra felis. Integer a tellus. Suspendisse eget nunc. Aenean diam est, accumsan id, suscipit interdum, fringilla vitae, justo. Proin pede. Maecenas at neque in neque vestibulum eleifend. + +Vestibulum nulla lorem, porttitor eget, euismod ac, aliquam at, nisl. Maecenas et est eget massa varius lobortis. In mi. Duis porttitor fermentum purus. Donec cursus imperdiet ligula. Morbi et ligula et ante molestie vehicula. Mauris sed dolor. Sed imperdiet felis ut sem. Sed vitae neque elementum leo auctor fermentum. Duis feugiat ullamcorper erat. Aenean purus. Morbi fermentum vestibulum est. Pellentesque venenatis mauris. Phasellus pulvinar. Integer ipsum lectus, iaculis a, lacinia id, accumsan id, arcu. Phasellus at est. Fusce neque quam, ultricies id, iaculis vel, dapibus vitae, lacus. In lobortis convallis ante. Nulla nunc purus, vulputate in, hendrerit et, blandit et, ligula. + +Pellentesque leo metus, sagittis in, molestie vitae, dictum in, pede. Morbi pretium felis nec quam. Pellentesque mattis ante sed quam sagittis dapibus. Suspendisse sapien. Praesent bibendum iaculis tortor. Duis a nisl. Aenean mi. Donec dictum arcu in est. Morbi interdum vulputate ipsum. Aenean sit amet magna non nisl tristique posuere. Phasellus velit metus, tempor ac, fermentum eget, condimentum non, velit. Vestibulum sit posuere. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras aliquet massa nec dui. Cras arcu nunc, hendrerit ac, eleifend eu, ullamcorper nec, tellus. Sed pharetra purus sit amet quam. Curabitur mollis. Nam vitae pede. Etiam risus massa, vehicula sit amet, pharetra nec, sollicitudin ut, dui. Donec egestas justo at quam. Proin nisl risus, vestibulum nec, pretium vitae, tristique ac, lorem. Aliquam erat volutpat. Cras sed nibh. Pellentesque sollicitudin euismod augue. + +Etiam fringilla sollicitudin orci. Mauris cursus elit quis lacus. Cras tortor. In adipiscing, lectus id auctor vestibulum, neque pede accumsan dolor, non imperdiet magna diam accumsan velit. Suspendisse at libero ut nisi blandit sagittis. Phasellus non mauris. Fusce elementum sagittis sem. Suspendisse aliquam eleifend tellus. Proin ligula lorem, imperdiet quis, venenatis id, iaculis mollis, nisl. Etiam convallis pede at massa. Morbi accumsan dui et mauris. + +Sed sed orci. Nunc purus. Suspendisse potenti. Ut luctus fringilla mauris. Donec nibh. Phasellus porta. Phasellus sit amet odio sed magna sodales pharetra. Cras lectus. Suspendisse libero ipsum, commodo nec, facilisis in, suscipit lobortis, ligula. Duis massa nulla, semper et, consequat nec, pharetra eu, elit. Vivamus ultricies aliquam odio. Vestibulum sit amet massa. Sed consequat lacus sed urna. Etiam faucibus felis vel orci. Phasellus ullamcorper. Aenean consectetuer lacus at libero. + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis facilisis, ligula vitae condimentum scelerisque, velit orci gravida felis, vel ultricies quam mi non diam. Vivamus auctor metus non libero. Praesent ligula nisi, commodo condimentum, molestie et, viverra et, justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus sollicitudin. Nunc blandit cursus ipsum. Aenean nec ligula ut tellus sodales mattis. Integer sem. Aliquam id ligula. Sed tortor mauris, blandit vitae, cursus vel, elementum et, nulla. Aliquam scelerisque metus et nisl. Duis adipiscing magna at neque. Quisque vulputate eleifend nunc. Aliquam eget elit. Phasellus dui odio, bibendum sagittis, vestibulum id, dignissim imperdiet, orci. Nullam eu felis non nunc lacinia sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Suspendisse pellentesque, libero mattis ultricies accumsan, tortor tortor malesuada sem, et sodales libero odio ac ipsum. Vivamus quis magna nec est suscipit lobortis. Cras tempus posuere nunc. Quisque ut enim a felis egestas semper. Sed pharetra mattis neque. Fusce turpis nunc, congue sed, consequat non, congue sed, nulla. Suspendisse varius lorem id risus porta vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce sed purus. In a felis. Integer egestas auctor orci. Mauris ultrices suscipit nisl. Nullam purus. + +Cras tempor adipiscing ipsum. Ut quis mi. Maecenas in justo ut nulla congue pharetra. Pellentesque ut libero eu dolor venenatis suscipit. Praesent feugiat consectetuer nibh. Morbi faucibus sem non felis. In hendrerit arcu ac massa. In accumsan ultrices mi. Proin malesuada auctor felis. Curabitur interdum. Sed diam ipsum, ultricies in, tempor sit amet, viverra imperdiet, elit. Morbi molestie nisi. Mauris ipsum. Fusce dictum mollis magna. Duis commodo dignissim nulla. Vestibulum augue enim, ultricies quis, iaculis nec, tincidunt vitae, diam. Mauris lacinia tempus ipsum. Sed at mauris. Ut lorem. Donec libero. + +Duis iaculis lacinia lectus. Aenean convallis eros ac ante. Sed quis orci nec risus auctor fringilla. Phasellus facilisis elementum nisi. In hac habitasse platea dictumst. Nunc porta lacus nec ante. Morbi mauris erat, adipiscing in, pulvinar nec, lobortis nec, odio. Ut eleifend lectus sed quam. Nullam mollis. In non turpis et nisl hendrerit blandit. Duis elementum. Nunc nec libero. Suspendisse vestibulum risus non pede. Morbi imperdiet odio sit amet libero. Sed sed massa vitae ipsum mattis tincidunt. Nulla nec tortor vitae libero volutpat tempus. Donec aliquam. + +Duis sed nunc. Curabitur turpis nulla, vehicula sed, luctus quis, elementum eget, felis. Maecenas et purus. Maecenas leo tellus, tincidunt a, facilisis vitae, lobortis sit amet, velit. Donec convallis sapien. Maecenas mollis odio eu nibh. Etiam gravida. Integer molestie, sapien eu molestie lacinia, nunc nibh aliquam ligula, eu sagittis tellus erat sollicitudin odio. Duis et risus. Phasellus nisi neque, placerat nec, condimentum non, ultrices eu, sem. Ut pede. Etiam nulla metus, volutpat id, convallis sed, suscipit vel, urna. Donec vel elit. Ut leo neque, venenatis faucibus, lacinia nec, tincidunt eu, enim. Cras id dui a libero pharetra dignissim. Donec eros leo, porta quis, laoreet ut, pellentesque volutpat, lectus. + +Nullam blandit. Aliquam erat volutpat. Fusce adipiscing enim. Suspendisse non dui quis ligula porta vestibulum. Donec eu tellus vel lorem pretium porttitor. Praesent luctus. Aliquam ac eros in massa dapibus tincidunt. Donec ut magna. Etiam auctor lacus sit amet lacus. Sed ultricies ipsum nec elit. Quisque a est in purus suscipit tristique. + +Aenean sed dui vel dolor pulvinar laoreet. Vivamus vehicula lorem in pede. Vivamus et diam. Integer ac odio vel diam hendrerit bibendum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a nisi. Phasellus tincidunt dui vitae augue. Duis faucibus, dui interdum fringilla tincidunt, odio elit vestibulum libero, ac molestie magna lectus id lacus. Aenean ligula. Nulla facilisi. + +Fusce vel sem eu velit fringilla ornare. Sed feugiat tincidunt felis. Nullam felis mi, euismod sit amet, mollis at, sodales eget, augue. Nam imperdiet nibh at velit. Sed ut erat. In dui. Nulla facilisi. Nullam augue libero, tincidunt nec, pretium eu, pulvinar in, dui. Morbi vitae felis. Pellentesque vel justo vel velit sagittis malesuada. Proin vehicula blandit massa. Etiam tincidunt pharetra urna. In metus est, auctor nec, blandit a, cursus nec, quam. Mauris ac metus a libero congue faucibus. Mauris mauris dolor, sodales in, cursus ut, sodales rutrum, eros. Quisque mauris eros, sagittis vitae, lobortis ut, eleifend id, nisi. + +Aenean neque. Vestibulum egestas pellentesque ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus sagittis justo vel risus. Sed pretium neque vitae urna. Pellentesque congue libero id lorem. Mauris leo lorem, blandit sit amet, convallis quis, consectetuer sed, eros. Mauris tincidunt, enim a gravida euismod, magna nulla fermentum libero, viverra egestas velit quam et tortor. Vivamus aliquet massa vitae justo. Nulla congue lacus ac elit. + +Phasellus commodo quam vel ligula. Proin non metus at eros pulvinar luctus. Mauris diam lorem, posuere quis, gravida et, tincidunt nec, ligula. Sed diam. Aliquam elit lectus, hendrerit ut, imperdiet sit amet, pretium sit amet, ipsum. Mauris vehicula nisl in dui. Curabitur eget quam ut magna elementum fermentum. Mauris scelerisque. Quisque laoreet. Etiam tempus turpis. Pellentesque augue quam, hendrerit sed, tincidunt at, pharetra at, nisl. Aliquam lacus. Suspendisse potenti. Aenean velit libero, ultrices in, lacinia eu, luctus vel, ante. Etiam dictum mi in felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce gravida dapibus nisl. Cras vitae nisl. + +Maecenas dignissim, ligula non porta cursus, enim nunc malesuada sem, eu porttitor nulla urna eu quam. Fusce eros. Aliquam eros. Nam auctor. Nulla molestie porta est. Suspendisse potenti. Vivamus molestie lorem sed erat. Sed eget ipsum. Integer aliquam pulvinar nulla. Cras aliquet sem ut nunc. Fusce faucibus tempus lectus. Cras sodales, nisi ac facilisis ultrices, eros arcu dapibus sapien, et ultrices mauris tellus non dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras cursus varius metus. Ut turpis. Vivamus eget tortor. + +Sed laoreet, velit non accumsan cursus, nunc urna posuere justo, in dictum lectus pede id ante. Cras vulputate. Cras congue dui sed elit. Proin lacus sem, ultrices at, consequat in, tempor quis, metus. Proin vel arcu. Nam euismod hendrerit elit. Ut erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed posuere. Morbi eros urna, semper at, semper non, convallis quis, velit. Maecenas orci. Vestibulum lobortis tristique metus. Vestibulum lorem nulla, sollicitudin vitae, condimentum quis, auctor ut, dui. Vivamus vestibulum magna ut nisi. Curabitur eleifend dui vel nunc. Curabitur mauris lacus, malesuada sit amet, suscipit sed, rutrum luctus, tellus. Integer facilisis urna vitae lectus. + +Aenean quam leo, lobortis quis, malesuada eu, vulputate vitae, nisl. Praesent eget eros. Ut fermentum turpis id quam. Nam tortor. Praesent nec orci. Nulla bibendum adipiscing augue. Ut commodo, magna id malesuada gravida, augue odio malesuada mi, porta malesuada elit est vitae diam. Mauris non nulla. Suspendisse tincidunt, nunc ultricies porta venenatis, mi pede tincidunt libero, eget varius ante libero ut ligula. Curabitur pretium porttitor tortor. + +Maecenas vitae elit eget nisi dapibus dictum. Nunc in libero. Nulla dictum orci eu erat auctor lobortis. Phasellus risus. Suspendisse potenti. Suspendisse potenti. Praesent adipiscing consequat elit. Integer id augue. Praesent in justo nec magna dapibus pulvinar. Duis nisl. Suspendisse ac odio. Vivamus imperdiet. Donec non velit sit amet risus dignissim congue. Nam aliquet posuere velit. Cras turpis. Morbi malesuada dignissim mi. + +Sed leo neque, varius quis, venenatis sed, pharetra sed, est. Morbi blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam semper pellentesque mi. Ut vel lorem. Nunc mi tortor, laoreet at, faucibus eu, tincidunt sit amet, erat. Duis tempor malesuada ipsum. Phasellus aliquet. Donec et elit. Pellentesque purus. Vestibulum rutrum semper nibh. Nulla facilisi. Phasellus et enim sit amet ante vestibulum vehicula. Phasellus id nisl. Donec mollis leo at eros. Mauris pellentesque neque at purus. Morbi quis dolor at ipsum scelerisque sodales. Etiam volutpat turpis a metus. In hac habitasse platea dictumst. Nunc lorem lorem, vestibulum ac, euismod eget, ullamcorper dignissim, velit. + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ultrices, nibh vel aliquam vestibulum, eros enim venenatis dui, id iaculis enim nunc vel massa. Morbi eleifend orci et massa. Aliquam erat volutpat. Nulla mollis egestas turpis. In sodales nunc eget tortor. Sed ipsum eros, tempor quis, aliquet vitae, imperdiet non, lorem. Pellentesque quis elit id mi luctus dapibus. Sed nunc arcu, rhoncus nec, convallis quis, cursus at, neque. Mauris convallis purus at erat. Pellentesque vestibulum. Vivamus fringilla elit at arcu. Nullam aliquet enim nec arcu. Nam id tortor. Nulla quis nunc. Ut arcu. Suspendisse potenti. Pellentesque ullamcorper ligula id arcu. + +Nam non libero vitae nisl scelerisque fringilla. Quisque varius ante id metus rhoncus fringilla. Nulla facilisi. Praesent eleifend porttitor ligula. Etiam quis dolor non augue commodo auctor. Donec a mi. Vestibulum tempor. Donec felis urna, auctor at, cursus dictum, gravida id, arcu. Aenean dictum malesuada dolor. Vivamus mattis. Phasellus eu pede. Fusce adipiscing justo fringilla metus. Etiam ante. Integer mollis massa quis nunc. Integer dictum neque luctus enim. + +Sed eu libero. Integer tempor ligula in velit. Ut tincidunt lacinia sem. Nullam vel risus. Sed sodales ante a dolor. Curabitur eros. Sed sodales. Sed non metus. Vestibulum elementum faucibus ante. Nulla vel nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In hac habitasse platea dictumst. Nunc nec lorem ut ipsum lacinia iaculis. Duis erat. Aliquam erat. Cras iaculis. In hac habitasse platea dictumst. + +Nullam ante. Cras vitae est. Pellentesque vel metus a ligula dapibus mattis. Duis feugiat aliquet felis. Etiam id nisl quis est dignissim condimentum. Suspendisse potenti. Morbi velit lorem, ornare quis, pellentesque vel, placerat eget, tortor. Vestibulum tincidunt molestie libero. Nulla nulla enim, malesuada id, ullamcorper vitae, dictum at, purus. Donec dignissim odio ut enim. Suspendisse at lectus. + +Praesent lobortis augue vel lectus. Ut in ligula ut felis congue suscipit. Quisque dignissim tortor ut mi. Fusce magna nisi, eleifend ac, ornare vel, porttitor vitae, quam. Vestibulum sodales justo quis turpis. Fusce urna nisi, rhoncus quis, condimentum vel, dictum eu, nunc. Fusce sed nibh vitae odio posuere adipiscing. Sed porta elit quis dolor. Nam libero nulla, auctor sed, tincidunt quis, faucibus sit amet, mi. Quisque orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam id sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vel eros. + +Vivamus luctus lobortis leo. Suspendisse vel elit a enim ullamcorper posuere. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec quis pede mattis lectus mollis adipiscing. Sed accumsan posuere erat. Praesent euismod tincidunt felis. Donec mi. Ut commodo arcu lacinia tellus. Aliquam a libero quis lectus semper viverra. Curabitur lacinia mauris at tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sit amet magna molestie orci suscipit fringilla. Fusce pretium metus non sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed hendrerit. Nulla felis. Suspendisse potenti. Aliquam blandit tristique neque. Curabitur quis erat vel nunc accumsan mollis. + +Duis sagittis, tellus ut aliquam fringilla, dolor mi ullamcorper nisl, ut tristique pede elit sed mauris. Curabitur id felis. Donec pulvinar lacus et lectus. Aliquam vulputate vulputate metus. Curabitur magna felis, adipiscing ac, accumsan vel, molestie quis, quam. Mauris elit arcu, pretium vitae, mollis sit amet, sollicitudin ut, mi. Donec imperdiet dignissim mi. Nullam sit amet tortor. Aliquam neque nulla, venenatis a, porta in, placerat tempus, lacus. Quisque vestibulum dui et lacus. Proin dignissim consectetuer purus. Etiam gravida tortor in nunc. Ut tempor tristique tortor. Sed laoreet tincidunt quam. Vestibulum porta turpis ut elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nibh dui, feugiat nec, laoreet id, malesuada eget, nisi. Ut neque massa, vehicula eu, commodo non, ultricies vitae, purus. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris euismod, felis vel tempor aliquet, tortor mauris malesuada nunc, vel fermentum sem diam id dui. Nam rutrum sapien eget odio. Aliquam sed libero non mi faucibus tempus. Fusce hendrerit, diam non volutpat rutrum, erat metus venenatis ligula, non scelerisque pede ligula vel quam. Morbi rhoncus eros ac dui feugiat elementum. Duis eu libero et tellus congue viverra. Morbi quam quam, elementum sed, ullamcorper imperdiet, commodo non, odio. Nam aliquet egestas urna. Mauris odio felis, varius eu, lacinia eu, condimentum a, lectus. Sed justo massa, pulvinar id, varius a, porttitor nec, libero. Etiam varius. Curabitur sodales, odio at posuere semper, eros nibh tincidunt lectus, vel rutrum sapien nisi in ligula. Suspendisse eget arcu. Phasellus imperdiet est ac sapien. Donec nulla tortor, placerat vel, tempus a, lobortis vel, nibh. Aliquam varius nisi. Nulla et enim. Fusce convallis laoreet lacus. + +Phasellus ipsum dolor, molestie quis, condimentum in, commodo eu, diam. Quisque bibendum lacinia dui. Nullam blandit vulputate orci. Ut lacinia massa vel augue. Aliquam gravida, quam quis imperdiet imperdiet, tellus diam pharetra erat, at pharetra lacus nibh egestas magna. Nulla sagittis lorem ut lorem. Duis condimentum, dui vitae aliquam posuere, diam quam convallis velit, ut gravida leo ipsum non risus. Ut fermentum sollicitudin erat. Donec sagittis scelerisque felis. Nunc arcu. Etiam tempus, magna sit amet suscipit euismod, eros sem rutrum dui, vitae sagittis nibh purus non lacus. Sed mollis arcu eget dolor. Donec ornare, arcu sit amet fermentum vulputate, risus enim fermentum libero, a lacinia dolor mi non velit. Etiam lobortis purus a elit. Nunc nulla dui, mattis quis, bibendum a, ultrices ac, augue. In aliquam vehicula turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Integer id nisl. Quisque dictum elementum odio. Aenean luctus. Sed eu sem a pede vulputate condimentum. Quisque magna. Donec aliquam mattis ipsum. Curabitur dictum sollicitudin sem. Aliquam pulvinar. Nunc sollicitudin risus a erat. Vivamus quis tellus sit amet nibh vestibulum consequat. Nulla pretium sollicitudin dolor. Aliquam iaculis tincidunt turpis. Phasellus ipsum leo, venenatis in, sagittis in, ornare at, nunc. + +Pellentesque ultrices, dui eu iaculis luctus, tellus augue volutpat sapien, in dignissim urna felis ut mi. Sed arcu dui, dignissim id, porttitor ut, imperdiet vitae, ante. Nulla dui sem, commodo nec, sagittis et, lacinia et, pede. Etiam eleifend dui ut nisl. Donec ante mauris, tempus sit amet, varius vitae, gravida quis, mi. In scelerisque, felis vitae viverra sagittis, velit metus ultricies neque, quis imperdiet velit elit et magna. Suspendisse potenti. Sed velit eros, euismod sed, condimentum nec, faucibus sed, sapien. Nam accumsan ligula sit amet neque. Aliquam erat volutpat. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam eu pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed eu felis sed tortor tempor fermentum. Phasellus commodo sem vel nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lectus elit, pharetra sit amet, accumsan sed, tincidunt et, mauris. Duis dapibus pharetra sem. Integer in justo. Praesent eros. Vestibulum ac ante. Aliquam scelerisque sem pellentesque nibh consectetuer sodales. Aliquam consectetuer odio. Duis lectus odio, luctus eu, commodo quis, mollis vitae, velit. Cras nec nunc non elit iaculis mattis. Aenean justo neque, sollicitudin eget, ullamcorper eget, egestas id, sem. In eu risus. Sed egestas. + +Integer at neque. Sed pretium scelerisque nulla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce ut pede. Etiam vitae quam a urna varius imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vehicula. Fusce ullamcorper nibh non erat. Quisque in neque. Praesent est. Pellentesque arcu. + +Proin posuere. Suspendisse potenti. Integer felis lacus, aliquam sed, vulputate in, mollis vel, tellus. Integer vehicula bibendum est. Nunc non dolor in tellus mattis facilisis. Integer vestibulum, augue at commodo aliquam, dui est mattis ligula, sit amet adipiscing orci sem vitae magna. Praesent enim velit, malesuada at, congue nec, luctus in, justo. Sed varius. Morbi pharetra. Donec eu massa nec tellus vulputate pulvinar. Ut commodo turpis non sem. Ut convallis ullamcorper risus. Etiam interdum pede id nisi. Cras magna sapien, suscipit a, laoreet non, rhoncus et, felis. Integer orci lorem, vestibulum dictum, ullamcorper a, porttitor et, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc et magna. Sed bibendum tellus in diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vitae tortor. Integer magna. Duis venenatis, leo ac tempor laoreet, elit nulla pharetra pede, non fermentum nunc odio a odio. Proin non velit. Sed imperdiet augue quis nisl. Integer condimentum nisl nec libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus placerat libero. Duis congue dictum magna. Aliquam dapibus bibendum enim. Nunc eleifend pede vel ipsum. + +Etiam vitae velit. Mauris erat nunc, malesuada ut, feugiat ac, placerat condimentum, augue. Nam volutpat. Aliquam vehicula ipsum id odio. Vivamus sollicitudin turpis id sapien. Fusce a felis vitae odio convallis blandit. Curabitur vitae eros id eros porta pretium. Nulla in magna eget urna lacinia convallis. Aliquam mattis venenatis purus. Sed sed mi eget erat tristique porta. Donec auctor dolor a erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In nec ligula. Nunc eleifend. Vestibulum quis nisi eget elit porttitor congue. Maecenas faucibus, magna eget adipiscing tincidunt, dolor ante malesuada elit, non elementum lacus turpis in pede. + +Ut malesuada mi nec metus. Praesent auctor augue ac nisl ultricies facilisis. Nam purus sapien, pellentesque dignissim, posuere eu, cursus id, diam. Quisque sollicitudin, elit a pellentesque scelerisque, lorem risus auctor quam, quis consequat tellus neque id urna. Suspendisse diam tortor, eleifend dignissim, egestas ut, luctus in, ante. Duis ante. Maecenas luctus. Curabitur cursus pharetra urna. Maecenas imperdiet, erat non elementum euismod, tortor odio euismod lectus, ac facilisis sem nibh vitae nulla. Nunc gravida. Morbi sollicitudin odio quis lacus. Aliquam a nibh non urna porta imperdiet. Aliquam erat volutpat. In iaculis lacinia velit. Sed libero lacus, tristique eu, lacinia ac, aliquet eget, urna. + +Etiam at nisl. Phasellus faucibus luctus lectus. Ut placerat vulputate dolor. Phasellus vel velit. Morbi viverra. Phasellus orci. Integer dignissim mattis mauris. Pellentesque posuere leo posuere quam. Quisque nec magna at diam viverra pellentesque. Suspendisse velit arcu, ultricies quis, congue a, venenatis eget, lacus. Integer sagittis hendrerit dolor. Fusce tincidunt ante a sem. + +Maecenas consectetuer, justo sed rhoncus venenatis, nibh arcu rutrum dolor, sed condimentum libero libero et ipsum. Vivamus mattis justo ut lorem tincidunt lobortis. Ut non velit id neque aliquet accumsan. Sed tempus viverra nulla. Curabitur ullamcorper, neque quis dapibus scelerisque, felis diam gravida orci, non cursus quam neque vitae elit. Etiam pharetra tincidunt lacus. Duis euismod fringilla est. Etiam ornare tincidunt lectus. Proin in turpis. Nunc blandit blandit turpis. Aenean ut augue. Duis orci justo, tincidunt eu, rutrum sed, rutrum et, turpis. Curabitur facilisis odio in ante. In hac habitasse platea dictumst. Sed eros est, pellentesque at, tincidunt eu, ultrices quis, metus. Morbi sit amet justo. Maecenas ac arcu. Mauris dignissim. + +Pellentesque ultricies rutrum orci. Aenean ornare. Vivamus eu risus vel mauris lobortis dictum. Sed et turpis auctor mi rhoncus pulvinar. Sed nec nunc a purus tempor viverra. Pellentesque suscipit. Donec tristique risus non nibh. Etiam nisl magna, sollicitudin ut, ultrices sit amet, egestas eu, nulla. Aliquam erat volutpat. Vestibulum pharetra. Sed egestas, metus sit amet lobortis consequat, erat elit imperdiet libero, eu interdum quam massa eget dolor. Suspendisse vitae odio. Proin blandit mauris iaculis metus. + +Vivamus vestibulum. Etiam et nisl. Aliquam in diam vel elit placerat suscipit. Duis sodales purus ac nibh. Nulla in odio eget enim luctus blandit. Curabitur ultrices ipsum non neque egestas eleifend. Sed turpis. Proin consectetuer. Vivamus mattis. In aliquet. + +Nunc id eros. Donec venenatis, nulla et mattis luctus, ante leo semper justo, non adipiscing odio risus sed lacus. Praesent vitae risus congue libero congue tempus. Phasellus ac eros. Nulla vehicula, lorem in aliquet suscipit, arcu erat egestas sem, quis lobortis quam ante eu massa. Curabitur non massa. Sed bibendum lacinia odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus volutpat blandit lacus. Proin porta, tellus ut auctor laoreet, lectus eros fermentum lectus, id sagittis arcu justo in turpis. Phasellus consequat. Nam pellentesque, mi id viverra convallis, nunc libero placerat leo, eleifend porta sem nisl vitae sapien. Pellentesque ligula libero, tristique non, porttitor rutrum, porttitor non, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer dictum tellus a tortor. Vivamus felis nunc, molestie non, rhoncus quis, pharetra id, dui. Donec risus metus, fringilla vel, aliquet eu, placerat id, neque. + +Suspendisse ipsum. Vivamus lectus. Sed viverra, massa eget convallis mattis, quam turpis consectetuer nunc, eget posuere magna sem id velit. In nec mauris. Aenean a purus sed quam lobortis fringilla. Proin ultricies lacinia ante. Sed adipiscing erat quis velit. Nullam vitae nisl id justo sollicitudin molestie. Nulla facilisi. Sed nec urna sed nisl fringilla dapibus. Nulla at diam. Aliquam eget nibh. Nunc ac nisi sit amet tellus egestas tempus. Nam scelerisque urna et neque. Donec est orci, sagittis non, vulputate a, commodo et, augue. Ut dapibus tortor. Ut nunc. Donec dictum dapibus odio. Nam ultricies ullamcorper ligula. Pellentesque accumsan varius leo. + +Morbi euismod laoreet erat. Vivamus quis ipsum. Morbi euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel purus. Nullam at magna. Curabitur lacus lorem, iaculis quis, dapibus non, volutpat vel, nulla. Donec ut arcu rhoncus dolor pretium dictum. Nullam vel metus. Ut arcu. Pellentesque nisi nunc, placerat eget, tincidunt vel, pharetra non, nunc. Integer tincidunt ultricies lectus. Integer semper, purus sed ultrices feugiat, nulla pede sollicitudin erat, vel auctor nulla ipsum vel lectus. Aenean mi. + +Nullam sed nisi et arcu imperdiet fermentum. Mauris nec metus. In ac dolor. In mi arcu, congue ac, pharetra nec, scelerisque sit amet, magna. Curabitur lacus. Curabitur et elit. Aliquam ullamcorper nunc eu elit. Sed convallis dolor at velit. Vestibulum dapibus, augue id consectetuer placerat, nunc massa blandit sapien, id aliquam elit nisi id mi. Phasellus sapien est, gravida eu, bibendum ut, adipiscing quis, est. Ut molestie quam vitae odio. Donec quis risus id erat faucibus sollicitudin. Nam id felis. Mauris sed enim vitae leo accumsan pretium. + +Nam justo. Donec turpis nisl, commodo et, interdum ac, consectetuer non, massa. Fusce sem metus, laoreet nec, posuere id, imperdiet in, velit. Donec vulputate justo eget turpis. Nulla pede. Morbi tincidunt. Fusce aliquet, quam et aliquam fringilla, ante ante iaculis dui, nec aliquam arcu purus sed erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus suscipit quam et est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; + +Integer sed tellus. Sed sed velit ultricies leo rutrum laoreet. Sed non eros ac purus sagittis feugiat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed hendrerit ligula sit amet nibh. Maecenas turpis. Morbi consectetuer, dolor et adipiscing imperdiet, ante neque feugiat dolor, at porta quam neque quis ligula. Mauris semper velit sit amet ipsum. Pellentesque tempus, purus in rutrum consequat, enim erat vehicula massa, id accumsan leo sapien nec purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In dolor. Integer facilisis libero sit amet pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut varius aliquet enim. Nulla facilisi. Curabitur consectetuer, odio eu pretium tincidunt, nunc nisi aliquet neque, vel imperdiet elit massa sit amet turpis. Pellentesque tempus, orci volutpat blandit fringilla, odio sem posuere ante, vitae bibendum urna lorem vitae eros. Praesent viverra rhoncus arcu. Sed auctor, est sit amet mollis mollis, quam quam gravida sapien, in commodo metus nulla auctor enim. Donec facilisis. + +Proin tincidunt, sapien eget ultricies adipiscing, est odio dictum arcu, ut mollis erat dui sit amet velit. Morbi est sem, interdum at, congue a, elementum vitae, metus. Suspendisse id augue. Mauris enim sem, pulvinar eget, tempus a, tempus sit amet, sapien. Fusce vestibulum consectetuer dui. Pellentesque erat. Sed dignissim placerat odio. Maecenas semper rhoncus lectus. Phasellus pretium. Duis libero elit, eleifend nec, egestas ut, cursus sed, felis. Nam nisl arcu, aliquet et, facilisis eu, luctus ut, risus. Etiam ultrices, dolor sed volutpat malesuada, turpis arcu imperdiet tortor, euismod commodo libero massa ut quam. Integer molestie purus non elit. Ut venenatis semper tortor. Etiam bibendum egestas ipsum. Mauris sollicitudin sem nec nibh. Nulla pretium metus eu metus. Pellentesque sit amet sem. + +Suspendisse ac nisi. Ut leo. Vestibulum hendrerit pretium dolor. Nunc feugiat malesuada purus. Cras et nibh. Curabitur nunc erat, malesuada vitae, laoreet ac, ultricies in, purus. Vivamus tellus arcu, sodales eu, facilisis a, lacinia nec, nunc. Pellentesque id velit. In eu nibh. Nunc nec erat. Sed dictum neque ut nisl. + +Morbi lectus tellus, tincidunt ac, porttitor ac, tristique in, eros. Donec luctus luctus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ut est et enim scelerisque accumsan. Donec ligula felis, lacinia quis, pellentesque in, semper vestibulum, elit. Mauris eget orci a felis congue vehicula. Ut sollicitudin. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam id dolor ut lorem dignissim venenatis. Suspendisse vitae sapien. Proin non magna ut eros viverra pulvinar. Donec quis odio. Nullam non arcu vel lorem suscipit aliquam. Aliquam rutrum turpis in leo. + +Ut luctus nibh tristique erat. Suspendisse bibendum odio vitae tortor. Donec lacinia. Cras sodales felis luctus nulla. Nam eleifend sagittis ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse vel neque. Morbi aliquet vehicula magna. Aenean at odio. Duis pellentesque magna. Nulla at tortor ut diam dictum faucibus. Mauris quis velit. Donec non tellus vitae lorem fringilla porttitor. Fusce ut sapien quis tortor feugiat sagittis. Donec viverra sem vitae sapien. Praesent sodales, lacus in fringilla viverra, odio augue adipiscing urna, vitae interdum ante sem non nisi. Nullam tortor lorem, eleifend ac, mollis non, laoreet ac, risus. Integer ornare leo sed justo. Quisque cursus, sem non facilisis bibendum, nisi mi varius felis, fermentum feugiat lorem eros laoreet risus. + +Quisque sit amet est et lorem vehicula lacinia. Donec nec tortor. Cras odio. Nam scelerisque vulputate urna. Praesent dui. Etiam nec nisl lobortis ipsum aliquet tempus. Maecenas pretium sollicitudin mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus augue massa, congue eget, convallis eget, tristique sit amet, eros. Sed consequat nisi eu felis. Pellentesque justo. Suspendisse non augue. In dignissim lobortis mauris. Mauris sagittis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + +Sed adipiscing. Donec a tellus vitae est cursus vehicula. Nam ante sem, sodales id, fringilla vel, condimentum vel, nulla. Quisque sodales. Etiam imperdiet elit id odio. Aliquam erat volutpat. Maecenas porta tempor arcu. Nulla sem augue, pellentesque ac, consequat ut, condimentum euismod, risus. Sed aliquam tincidunt mi. In interdum lobortis orci. + +Sed vehicula hendrerit purus. Etiam a diam. Curabitur convallis. Suspendisse a nisi. Donec id magna in quam sollicitudin ultricies. Donec viverra. Quisque volutpat est sed sem. Aliquam justo. Vestibulum tortor massa, porttitor sed, varius quis, iaculis quis, odio. Aliquam eget neque. + +Mauris nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum eu quam in neque ultrices pellentesque. Cras in dolor quis quam varius hendrerit. Aliquam nisi lacus, lobortis eu, convallis sit amet, facilisis ut, mi. Aliquam at neque. Cras sagittis elementum justo. Vestibulum ut lectus aliquet purus malesuada volutpat. Duis at lacus adipiscing libero tincidunt vestibulum. Morbi a libero. Cras purus. Morbi ut augue et purus interdum scelerisque. Integer a dui. In hac habitasse platea dictumst. Duis pharetra metus eget mauris. Aliquam interdum ullamcorper massa. + +Etiam ornare. Nullam euismod. Aenean consequat gravida ligula. Aliquam est. Proin vitae lacus. Praesent a eros sit amet dui luctus commodo. Phasellus vehicula arcu eget dolor. Praesent fermentum congue leo. Aliquam volutpat purus ut lorem. Fusce hendrerit enim at leo. Aliquam rhoncus nisl. Vivamus dictum egestas mi. Suspendisse pellentesque bibendum dolor. Pellentesque tincidunt, turpis semper pellentesque condimentum, ipsum metus sodales ligula, id volutpat diam turpis ut elit. + +Praesent sed lacus. Nam eleifend molestie mauris. Donec dapibus fermentum massa. Donec viverra faucibus purus. Curabitur congue, libero vitae viverra pellentesque, diam velit sodales enim, sed suscipit lectus nisi nec neque. Vestibulum malesuada, lacus at cursus congue, velit lectus tristique dolor, sit amet sodales neque ipsum a libero. Vestibulum et quam. Curabitur placerat. Curabitur nunc arcu, euismod nec, vulputate hendrerit, aliquet eget, quam. Curabitur vel enim. Suspendisse potenti. + +Nunc consequat orci ut lacus. Fusce velit dolor, dapibus sed, blandit sit amet, rhoncus id, risus. Duis urna nibh, scelerisque quis, dapibus a, scelerisque sed, nibh. Donec luctus. Ut eu mauris cursus diam lacinia rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam vehicula molestie justo. Maecenas imperdiet pede sed mi. Suspendisse nulla dolor, hendrerit eget, hendrerit id, dictum vel, leo. Duis accumsan. Curabitur in felis. Nunc lorem. Ut leo dolor, laoreet nec, vulputate at, eleifend in, nulla. Quisque nunc purus, varius eget, accumsan nec, aliquet et, nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras adipiscing viverra dolor. Mauris porttitor ultrices purus. Nulla facilisi. Praesent faucibus ante vitae mauris. + +Praesent lacinia lectus sed nisl. In tempus congue mauris. Integer facilisis ornare enim. Nulla id massa. Donec commodo diam at tellus. Nam dapibus viverra est. Nam tellus. Praesent a libero. In faucibus est eget nibh. Nulla eros orci, imperdiet non, blandit non, tempor eget, mi. Pellentesque convallis. + +Quisque eget mi ac leo euismod faucibus. Phasellus rhoncus purus id dui. Vestibulum malesuada eleifend ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque blandit mattis odio. Suspendisse consequat, lectus ac semper sollicitudin, mi velit dictum augue, ac tempus dolor erat sit amet dui. Proin hendrerit, felis quis volutpat posuere, diam odio malesuada odio, a interdum orci diam quis sapien. Pellentesque odio odio, viverra vel, gravida eu, molestie sed, nulla. Phasellus mauris pede, commodo ut, euismod eu, hendrerit eu, est. In hac habitasse platea dictumst. Nulla elementum lacus eu augue. Sed erat. Proin porta. Maecenas quis mi. Phasellus at enim ac justo gravida ultrices. Cras leo. + +Integer ut arcu. Donec sed magna. Proin felis. In iaculis, ligula id fringilla pretium, nibh diam accumsan tellus, eget accumsan metus dui varius turpis. Phasellus orci metus, eleifend sed, tempor ac, scelerisque ac, urna. Integer viverra neque a mauris. Mauris porttitor dolor eu velit. Integer odio elit, vestibulum ut, volutpat id, rhoncus commodo, urna. Etiam placerat pharetra erat. Ut tempor est. Integer dignissim blandit tellus. Morbi nibh dolor, scelerisque id, commodo malesuada, mattis at, mi. Cras tincidunt commodo purus. In tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ullamcorper. Ut hendrerit. Morbi ultrices. + +Praesent iaculis, eros ac egestas sodales, urna leo fermentum ligula, sit amet aliquam velit sem non purus. Donec rutrum arcu quis purus. Nam posuere, lacus at consequat placerat, nulla pede posuere orci, non euismod turpis dui quis nisl. Proin porta adipiscing nibh. Donec tristique dolor at tellus. Donec neque massa, auctor id, faucibus vitae, ullamcorper vel, nisi. Proin molestie neque sed massa. Nam tempor. Morbi aliquam sapien at tellus. Fusce quis risus et mi pretium pulvinar. Fusce sit amet ligula. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse eu enim et felis scelerisque lobortis. Praesent bibendum. Vivamus vehicula. Integer at nibh sed velit rhoncus molestie. Cras lacus. Sed ullamcorper eros vel erat. Fusce eu tortor sit amet diam euismod sagittis. Nunc quis lacus id nibh convallis varius. Suspendisse vitae mi. Vestibulum tristique. Donec malesuada ipsum id neque. Nullam sed lacus. Duis egestas, justo ut congue ornare, augue sapien luctus diam, at accumsan erat sapien ut libero. Phasellus vel nulla. Suspendisse arcu tellus, porttitor a, pharetra faucibus, aliquam sit amet, massa. Nulla porttitor tincidunt lorem. Nunc dolor odio, sagittis in, lobortis vel, volutpat sed, nibh. + +Quisque blandit leo ut sapien tempus facilisis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean ultricies porttitor justo. Fusce rutrum eros ut urna. Proin quis quam eget dui aliquam accumsan. Donec suscipit eleifend elit. Pellentesque mattis, felis sodales iaculis imperdiet, lacus sem convallis augue, sit amet aliquet arcu purus fringilla risus. In eu odio id magna pharetra ornare. Aliquam interdum pulvinar ipsum. Sed neque. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam sit amet nisi. Ut at augue. Mauris volutpat blandit ligula. Nulla eu metus. Vestibulum eget elit. Praesent posuere. Vestibulum id sem non lectus mollis tincidunt. Aliquam id felis at ante ornare tempor. Nulla lacus turpis, feugiat vitae, cursus quis, consectetuer non, mauris. Fusce lacus massa, porttitor ut, molestie ut, venenatis a, lorem. Praesent sit amet orci. Mauris rhoncus felis vitae felis adipiscing imperdiet. Maecenas mollis diam nec leo. + +Fusce enim ipsum, ultrices eu, molestie id, elementum id, sapien. Integer a urna. Nam velit libero, venenatis eget, tempor sit amet, feugiat vitae, ante. Fusce nunc. Sed semper nisl nec risus. In sed libero. Proin tortor neque, tincidunt ac, tempor ac, pharetra quis, velit. Duis lectus augue, ultricies vel, consequat id, iaculis id, ante. Vivamus auctor metus a ante. Curabitur arcu nisi, facilisis at, laoreet in, consectetuer sed, mauris. Quisque placerat diam sed dui. Vivamus pretium condimentum lorem. Curabitur laoreet. Aenean orci ligula, cursus eget, lacinia non, faucibus vel, lorem. + +Aliquam erat volutpat. Curabitur eros dolor, congue a, condimentum sed, luctus ut, nibh. Maecenas non tortor nec turpis commodo pellentesque. Praesent euismod placerat mi. Suspendisse potenti. Phasellus ut neque vitae orci mattis iaculis. Integer eget tellus. Donec at ante. Nam lacinia leo eget erat. Maecenas euismod magna congue tortor. Morbi nec massa eu enim malesuada sollicitudin. Sed accumsan. Nullam ipsum. Ut odio. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque id velit. Nam odio sem, aliquet ut, tempus sit amet, euismod et, nunc. + +Pellentesque libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent mauris nunc, varius ut, convallis molestie, luctus sit amet, leo. Sed dictum lorem et arcu. Nunc venenatis pellentesque massa. Nulla facilisi. Phasellus in tortor eget risus scelerisque vulputate. Sed nibh elit, sagittis ac, condimentum nec, convallis et, justo. Fusce volutpat metus. Nunc auctor. Vestibulum leo eros, pellentesque ac, mollis ultrices, rhoncus non, dolor. Mauris vehicula placerat nisl. Vestibulum bibendum, arcu quis congue elementum, velit nunc eleifend turpis, id luctus risus nisl sit amet tellus. Phasellus pede neque, blandit non, commodo vitae, ultricies eget, magna. Aliquam erat volutpat. + +Nulla facilisi. Aliquam ac ante. Cras risus. Morbi mauris lacus, posuere eu, blandit et, pharetra at, mi. Proin ac purus. Duis cursus nisl rutrum quam. Aliquam a odio non magna pellentesque ultricies. Maecenas ac massa quis sapien ullamcorper tempus. Cras cursus velit sed sapien. Proin nulla. Vivamus sodales aliquam nibh. Etiam et erat ut ante lacinia euismod. Fusce nisi. Proin quis nulla. + +Quisque venenatis, eros sed laoreet sollicitudin, orci ante pellentesque nisl, sit amet viverra quam erat non risus. Cras eget libero. Sed elit magna, semper eu, fringilla in, dignissim sodales, erat. Vivamus feugiat sem vel dui. Donec convallis sollicitudin diam. Cras sed purus. Donec felis eros, semper eget, tempor consectetuer, sagittis quis, nisl. Duis in ante. Cras non turpis. Nulla tempor velit aliquet turpis molestie placerat. Proin elementum fermentum mauris. Vivamus sed orci lacinia dui placerat venenatis. Vestibulum feugiat, tellus in volutpat rutrum, magna nisi ullamcorper eros, id pulvinar neque erat ut lacus. Vivamus sed augue. Nulla facilisi. Maecenas ante augue, elementum ut, sodales vitae, condimentum nec, lorem. Duis pede orci, fringilla at, eleifend nec, pretium in, erat. Nam sagittis, turpis vitae convallis pharetra, odio sem scelerisque lacus, nec lobortis dui diam vel eros. In semper gravida neque. + +Integer nunc. Ut pretium ipsum sit amet elit. In nec arcu. Sed vestibulum vulputate ipsum. Pellentesque tincidunt. Nulla gravida dolor in tellus. Cras vehicula, dolor ut pellentesque aliquam, erat enim auctor massa, vehicula lobortis odio eros quis quam. Proin dapibus neque in enim. Proin elit. Integer rhoncus tincidunt elit. Fusce lorem metus, semper ac, volutpat vitae, facilisis ut, tellus. Donec vel turpis vitae nisi pharetra porttitor. Maecenas tortor. Fusce mi. Nullam nec turpis. Sed sodales vestibulum nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Pellentesque dolor dolor, laoreet eu, aliquet quis, scelerisque sit amet, arcu. In hac habitasse platea dictumst. Nullam cursus urna eget elit. Quisque blandit sapien ac ante. Proin nulla eros, gravida volutpat, sodales vel, mollis eu, massa. Nulla tristique sollicitudin nisl. Curabitur vitae lorem vitae velit egestas ornare. Aenean eget eros. Aliquam erat volutpat. Fusce a urna id odio aliquet convallis. Curabitur sit amet nisl posuere leo posuere dapibus. Duis metus erat, luctus vel, rhoncus at, convallis sit amet, enim. Vivamus hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam eget elit. + +Nullam a nunc. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In metus urna, tincidunt et, lacinia sit amet, lobortis vitae, ligula. Proin et mauris vitae mi accumsan pellentesque. Etiam quam purus, hendrerit sed, feugiat vitae, euismod eget, tortor. Ut aliquam magna vitae justo. Suspendisse non justo vel velit condimentum tempus. Duis tempus ipsum vitae tellus. Proin in massa. Etiam ullamcorper dictum tellus. Proin aliquet felis at leo laoreet pulvinar. Vestibulum arcu purus, malesuada sit amet, cursus eu, placerat sit amet, nunc. Nam massa odio, sollicitudin in, adipiscing a, aliquam nec, risus. Aliquam blandit hendrerit libero. Mauris gravida. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur a nibh. Ut interdum fermentum neque. Pellentesque sed nunc. Mauris vehicula nisi et nunc. Praesent lorem. Donec semper. Integer eu lacus in est aliquam hendrerit. Vestibulum eget neque. Sed semper luctus velit. Curabitur nibh augue, congue eu, hendrerit id, congue et, enim. Integer placerat aliquam lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae eros. Donec vel nisl. + +In vestibulum facilisis urna. Ut risus. Mauris pharetra. Pellentesque mattis. Integer suscipit aliquam ipsum. Duis blandit, sapien et ultricies condimentum, felis mi elementum pede, nec sagittis metus mauris quis quam. Quisque accumsan arcu vel nulla. Cras sem sapien, porttitor id, ultricies sagittis, luctus eu, nulla. Integer quis eros. Morbi sed urna a tellus vehicula vulputate. Etiam nec augue eget felis semper tristique. Quisque ut dolor vel risus dictum consequat. Sed eget dolor sed nunc lacinia aliquet. Suspendisse ac tortor in ipsum posuere venenatis. Sed eget erat. Nulla faucibus. Duis laoreet, massa porttitor aliquet egestas, ipsum lectus rhoncus quam, in adipiscing eros sem ut tellus. Pellentesque feugiat tempus quam. Vivamus id dolor eget sapien consectetuer tempor. Aliquam erat volutpat. + +Nulla iaculis fermentum libero. Curabitur faucibus, massa malesuada cursus tincidunt, erat sem eleifend mauris, sed fringilla mi ante ac purus. Duis elementum lectus. Nunc ornare arcu eu tortor. Vestibulum vel dolor at purus lacinia fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas tincidunt, eros a egestas pellentesque, risus risus dictum libero, id aliquet metus justo in massa. Proin a tellus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed purus. Sed non pede. Aenean massa sapien, sodales sit amet, consequat dictum, eleifend vitae, tortor. Donec ultrices lacinia elit. + +Morbi adipiscing sodales dolor. Ut ullamcorper ultricies est. In venenatis tempus augue. Suspendisse tortor dolor, accumsan et, suscipit a, tincidunt ut, libero. Aliquam scelerisque magna sed felis. Quisque ut nunc a magna vulputate placerat. Aliquam rhoncus vehicula dui. Sed tortor. Nullam sit amet diam. Nunc sed eros. Sed et odio tincidunt elit gravida convallis. Curabitur quis tortor a lacus semper varius. Mauris at augue non mi sollicitudin aliquam. Integer ullamcorper. Pellentesque suscipit quam non purus. Aliquam ac eros at arcu ullamcorper consectetuer. Suspendisse pretium mattis leo. + +Duis at nunc. Sed dolor est, varius ac, porta et, tincidunt hendrerit, risus. Vivamus ut magna. Praesent ut mauris. In purus lacus, mattis sed, vestibulum nec, tempor at, nisl. Cras ullamcorper venenatis tellus. Ut dolor. Maecenas malesuada, pede a pulvinar mattis, arcu diam vehicula risus, quis porttitor augue massa in velit. Nunc congue. Morbi velit metus, rhoncus et, aliquam consectetuer, ultricies malesuada, ligula. Sed velit nisl, sagittis vitae, pharetra a, posuere sed, massa. Nulla facilisi. In varius, ligula id lobortis sodales, augue orci fermentum tellus, eu pulvinar risus ligula a sapien. Morbi laoreet ipsum non mi. Nam cursus lorem ut mi. Vivamus magna enim, posuere non, semper quis, sodales eu, arcu. Etiam mi purus, pretium feugiat, varius sed, pellentesque eget, ligula. In leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vitae orci eu orci sollicitudin feugiat. + +Praesent purus massa, euismod vitae, tempus nec, consequat hendrerit, metus. Aenean felis est, egestas vitae, accumsan eget, pellentesque in, sapien. Duis dapibus pede non sapien. Nunc urna. Integer vel libero. Duis augue arcu, dapibus non, facilisis vitae, posuere ut, eros. Donec vitae nunc sit amet arcu imperdiet dictum. Morbi eleifend, lorem eu consectetuer vestibulum, diam nunc ornare arcu, ac tempor felis dolor eget eros. Phasellus massa sem, sollicitudin ac, sodales gravida, luctus a, quam. Nam neque quam, viverra at, venenatis quis, sagittis non, enim. + +Nulla facilisi. Pellentesque egestas lacinia est. Sed tincidunt, pede sed tincidunt vestibulum, urna dolor adipiscing purus, vitae fringilla felis elit in nibh. Nulla sed nisi. Mauris suscipit scelerisque arcu. Etiam non enim vel eros accumsan malesuada. Nunc tincidunt commodo mauris. In tincidunt risus quis urna. Nulla diam tortor, aliquet et, tincidunt quis, sollicitudin ac, tortor. Cras nisl neque, vulputate suscipit, molestie quis, pulvinar at, nulla. Nullam ac metus nec odio posuere varius. Cras sed pede nec dui posuere bibendum. Duis euismod ullamcorper libero. Aliquam faucibus pulvinar turpis. + +In ut neque id nunc feugiat commodo. Curabitur dignissim, felis at sollicitudin lacinia, enim elit suscipit neque, sed luctus lorem ipsum in leo. Duis dapibus, odio quis auctor commodo, nisl odio mattis tellus, nec tincidunt turpis diam in arcu. Curabitur a sem. Nullam volutpat magna. Pellentesque sagittis, neque consequat pretium cursus, dolor lacus consectetuer arcu, sed laoreet est urna et metus. Suspendisse placerat, dui a porta tempor, lorem dui lobortis neque, sed venenatis diam enim id eros. Etiam et nisl non lectus faucibus consectetuer. Morbi scelerisque, sem nec tempus ullamcorper, ipsum diam feugiat lorem, a fringilla sapien elit quis nibh. Nullam diam urna, viverra sed, pharetra rhoncus, tincidunt vel, orci. Integer accumsan mattis erat. Nam dictum. Mauris nec leo. Nulla iaculis. Nulla nisl mi, dapibus quis, vehicula a, cursus eget, odio. + +Phasellus dapibus euismod nibh. Vivamus imperdiet ante in ligula. Pellentesque accumsan. In imperdiet, dui a auctor fringilla, metus nisi cursus dolor, vel luctus ligula lorem vitae mauris. Praesent mattis vestibulum elit. Aliquam enim lacus, pulvinar non, lacinia sit amet, eleifend non, velit. Vestibulum ac leo. Mauris imperdiet justo ac lectus. Sed molestie lectus sed dui. Sed fermentum tempus mauris. Nam ornare orci ac tellus. Ut malesuada, lacus id lacinia accumsan, diam elit adipiscing metus, et bibendum sapien nibh blandit orci. Suspendisse ipsum tellus, sagittis quis, vestibulum non, vulputate eu, eros. Praesent at nulla id pede scelerisque ultricies. Cras blandit pretium tellus. Maecenas dapibus condimentum augue. Phasellus tincidunt pharetra lorem. Morbi non eros. Sed tempor, nisl a tincidunt tincidunt, eros diam dictum sem, vel dignissim ante diam sed magna. Praesent non ligula id metus molestie consectetuer. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse vel mi. Curabitur ante nulla, rutrum a, convallis vel, vehicula ac, nunc. Nunc sagittis, enim sit amet auctor rutrum, mauris arcu vulputate neque, et euismod est felis quis ante. Vestibulum turpis tellus, hendrerit in, lacinia commodo, ullamcorper gravida, risus. Mauris rhoncus lacinia risus. Maecenas sollicitudin erat vitae nunc. Praesent pretium pellentesque augue. Donec interdum. Praesent ac eros vitae erat lobortis fringilla. Aenean consequat tellus. Nulla accumsan bibendum felis. Maecenas pretium ante id nisi. Aenean mi arcu, semper sed, mattis eu, venenatis sit amet, arcu. Donec aliquet euismod leo. Proin magna justo, tristique a, semper ac, sollicitudin a, ligula. Morbi velit. Aliquam vel nisi. + +In a lorem ut nunc feugiat congue. Donec fermentum bibendum dui. Proin varius est quis velit. Donec aliquet sem accumsan mi. Sed placerat. Nullam ac nisi a massa lobortis suscipit. Nunc id leo. Aliquam et massa. Nullam vestibulum elementum metus. In consectetuer nisi vel justo. Maecenas eget purus sed massa varius pellentesque. Phasellus faucibus felis quis felis. Aenean odio arcu, blandit quis, facilisis in, imperdiet eu, lorem. Nam posuere pulvinar mi. Fusce tristique, mauris et consectetuer ultricies, mauris lectus tempor justo, at fringilla est est sed nisi. Quisque faucibus. Sed in tortor tincidunt est lacinia iaculis. Maecenas a massa. Pellentesque a nibh at purus porta hendrerit. + +Nullam turpis. Fusce ac sem sed odio pellentesque imperdiet. Curabitur in arcu. Praesent lacus lacus, feugiat id, pulvinar in, tincidunt sed, neque. Maecenas viverra odio eget tortor. Integer aliquam, lorem rutrum venenatis dignissim, ligula magna malesuada arcu, vel feugiat lorem ipsum quis massa. Morbi ante. Vestibulum mauris libero, ullamcorper quis, ultrices quis, facilisis non, massa. Maecenas imperdiet. Aliquam erat volutpat. Pellentesque dignissim gravida lectus. In nibh odio, auctor eget, dapibus quis, dignissim venenatis, arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis pellentesque ligula quis massa. Curabitur condimentum, justo eget ornare luctus, lorem ligula sagittis pede, a porta nunc nunc in neque. Quisque felis mauris, condimentum vitae, auctor vitae, tincidunt quis, pede. Nunc lacinia ante in leo. Pellentesque libero. Aenean a ligula et nunc vestibulum consectetuer. + +Fusce ornare. Praesent id urna. Integer venenatis, quam non sagittis accumsan, ante nibh sagittis augue, sollicitudin adipiscing dolor velit eu erat. Proin quis enim eu purus vehicula aliquam. Nulla vel enim vel elit sollicitudin fringilla. Aliquam erat volutpat. Sed suscipit felis ut turpis. Etiam rutrum risus imperdiet est. Aliquam a tellus at tellus commodo dapibus. Mauris rutrum magna et odio. In at dolor. Curabitur vehicula lectus in tortor. Fusce justo purus, luctus vitae, mollis in, pharetra ac, purus. Nullam posuere interdum justo. Curabitur vitae lacus vel leo congue pulvinar. + +Aenean eleifend nibh varius tortor. Suspendisse vel eros. Proin nec diam a tortor ultrices ornare. Aliquam scelerisque feugiat justo. Vivamus ante urna, adipiscing vitae, porttitor eu, sodales et, felis. Suspendisse potenti. Curabitur ac massa in nisl sagittis mollis. Nam quam ligula, consectetuer eget, iaculis at, varius eu, leo. Duis dolor ligula, tincidunt at, ullamcorper sed, accumsan aliquam, ligula. Phasellus vulputate, lorem at tincidunt pharetra, risus lectus lacinia magna, quis rutrum enim magna at sem. In hac habitasse platea dictumst. Duis id sem a mauris sollicitudin tincidunt. Etiam eu purus eu arcu fringilla adipiscing. Vivamus ornare tempus diam. Proin turpis quam, lacinia non, egestas at, commodo eget, pede. Praesent vulputate risus in est. Nulla facilisi. + +Ut elementum lacinia purus. Proin vitae arcu ac nulla convallis aliquam. Nulla congue, libero id pellentesque mattis, quam lectus porttitor diam, a scelerisque dui libero in sapien. Nullam felis diam, vehicula vel, molestie ut, vestibulum aliquam, sapien. Donec convallis, est ut elementum volutpat, mauris ipsum gravida sem, commodo facilisis sapien lectus semper lectus. Quisque porttitor eros ut nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam mattis risus sed odio. Vestibulum et odio. In hac habitasse platea dictumst. Nam tristique massa ut ligula. Quisque nibh tellus, vehicula sit amet, adipiscing at, convallis nec, ligula. Vestibulum pretium, mi nec fringilla bibendum, dui nunc sodales pede, a semper magna nibh non diam. Donec massa nunc, viverra vel, consectetuer porta, dapibus non, ipsum. Duis nisl mauris, cursus vel, semper non, sollicitudin bibendum, felis. Vestibulum eu neque. + +Cras nec dolor. Donec laoreet tempus lectus. Cras sed tortor interdum lacus eleifend dignissim. Maecenas sit amet elit. Nullam quis dolor vel dui pharetra luctus. In sit amet quam sit amet pede ultrices ultrices. Maecenas diam. Integer urna. Curabitur dictum, velit sed placerat suscipit, erat turpis fermentum justo, sed interdum neque sem et nibh. Vivamus consequat convallis magna. Nam aliquam, est ac bibendum commodo, magna est dictum mi, vitae malesuada elit magna vitae odio. Maecenas tempor vulputate tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus dui. Etiam accumsan pede congue tortor. + +Morbi tempor libero ac lorem. In aliquet varius magna. In arcu. Phasellus odio. Fusce tincidunt aliquet felis. Quisque velit. Sed luctus. Aliquam feugiat fringilla mi. Aliquam molestie viverra risus. Proin arcu. Vestibulum lobortis tempus nisi. Praesent a arcu in velit viverra rutrum. + +In sed lectus. Donec risus dolor, blandit sit amet, elementum convallis, pharetra quis, pede. Integer ornare. Aenean egestas dapibus justo. Sed quam leo, posuere at, elementum vitae, commodo eget, est. Aliquam molestie rhoncus enim. Curabitur iaculis ultrices pede. Morbi aliquet rutrum lacus. Aliquam quam. Sed commodo, turpis in pharetra posuere, mi risus imperdiet erat, a vestibulum massa tellus vehicula sem. Mauris fringilla ultrices nunc. Nam nisi enim, eleifend sit amet, ultrices sed, fermentum non, augue. Proin congue lobortis nisi. Maecenas hendrerit. Nam sed nisl. Nunc elementum odio eu risus. In metus. Phasellus gravida pretium ligula. Nulla vitae neque. Nam nisi tortor, ornare non, blandit at, cursus eu, tortor. + +Duis bibendum ipsum in nunc cursus molestie. Nunc orci. Nullam nec ante non est dignissim viverra. Mauris blandit, velit id feugiat pretium, elit magna pellentesque dolor, at sagittis lacus velit egestas magna. Pellentesque cursus, diam consectetuer sagittis fringilla, tortor nisi adipiscing nunc, eu varius lacus risus ac elit. Mauris id nisi quis leo euismod venenatis. Pellentesque ac ante. Mauris arcu sapien, tempor at, porttitor id, condimentum ut, dui. Etiam fermentum ultricies augue. Cras ut eros at justo ultricies iaculis. Duis dignissim, nisl et facilisis fermentum, erat purus molestie tellus, quis tempus ipsum lectus at elit. Nulla vitae lorem. + +Aenean vel sem et diam semper congue. In bibendum diam quis tellus. Nunc facilisis ultricies nibh. Cras nunc enim, feugiat sed, ultrices vitae, sagittis vitae, ipsum. Fusce vitae nulla. Donec pellentesque, velit in porttitor eleifend, est neque lobortis velit, sit amet rutrum ante tortor nec dolor. Donec vehicula. Nulla facilisi. Sed egestas ultrices nibh. Donec elit lectus, convallis porttitor, aliquet dapibus, feugiat eget, ligula. Sed consectetuer justo. Maecenas a sapien sit amet nisi dapibus lobortis. Vivamus luctus lorem non nulla. Sed eget erat vitae libero interdum posuere. Cras pulvinar. Nullam imperdiet, dolor tempor dignissim blandit, dui sapien rhoncus neque, id malesuada augue magna sit amet urna. Duis sed mauris. + +Morbi accumsan. Sed mauris augue, fringilla non, auctor ut, auctor et, orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus ut pede. Donec viverra enim vel lorem. Pellentesque neque mauris, interdum eu, venenatis id, condimentum eu, sapien. Donec ipsum arcu, lacinia adipiscing, laoreet et, cursus vel, velit. Ut sagittis mauris quis risus. Integer eu odio vitae lacus viverra accumsan. Morbi leo ante, dignissim sed, varius quis, volutpat vitae, nisi. Nulla placerat interdum elit. Donec neque dui, sagittis vitae, sollicitudin quis, commodo vitae, neque. Nulla quis ligula ornare ligula dictum ornare. Mauris rutrum rutrum neque. Aenean vehicula tempus est. Donec varius scelerisque pede. Donec placerat vulputate leo. Nullam nunc nisl, posuere non, feugiat vitae, pellentesque quis, mauris. In dui neque, cursus eget, sagittis eget, dapibus vitae, mi. Proin eget est. + +Fusce porta est. Mauris magna. Aliquam ipsum lacus, ultricies id, vestibulum luctus, accumsan ut, ante. Sed mauris. Sed adipiscing leo sit amet magna. Suspendisse potenti. Nunc massa elit, fringilla eget, egestas vitae, luctus vitae, dolor. Phasellus quis nulla eu nisi interdum sollicitudin. Nullam id tellus. Integer iaculis dolor ac purus. Sed vel mi. Curabitur non magna sit amet justo condimentum vulputate. Quisque tincidunt pede eu nisl. Vivamus lobortis. Nunc metus metus, congue sed, tincidunt sed, pretium at, odio. Donec a arcu. In sem justo, vehicula sed, varius id, volutpat at, risus. Praesent iaculis massa. In arcu elit, hendrerit eget, ullamcorper in, porta id, tellus. Donec sagittis hendrerit diam. + +Suspendisse potenti. Sed et diam et augue sagittis lobortis. Phasellus dolor. Ut et arcu eget ante tempor posuere. Aliquam fermentum scelerisque dui. Mauris at purus. Donec erat sem, vestibulum nec, faucibus ac, mattis a, leo. Suspendisse adipiscing lacinia sem. Nullam orci arcu, dictum et, faucibus viverra, dapibus et, neque. Cras nunc diam, adipiscing non, sollicitudin in, interdum vel, massa. Mauris sagittis, justo at tristique tempus, mauris mauris aliquam ante, sit amet posuere diam dui eget ligula. In dignissim, nisl ut lacinia condimentum, erat justo porttitor nulla, non gravida ligula magna eget massa. Vestibulum vitae ligula at mi vestibulum suscipit. Duis laoreet. Nulla commodo libero sit amet lorem. Ut elementum sem. Integer vel dolor. Nam facilisis mi quis sem ultrices sagittis. Sed quis quam at metus molestie bibendum. + +Proin dui enim, lacinia a, feugiat ac, placerat vitae, pede. Quisque egestas, leo eget aliquam pretium, libero justo tincidunt eros, ut egestas augue pede elementum nibh. Curabitur mollis sodales enim. Donec augue. Phasellus id ipsum posuere dui pretium faucibus. Mauris luctus ante semper nisi interdum adipiscing. Duis dapibus, odio quis viverra rhoncus, justo quam bibendum dolor, id dapibus velit erat vel erat. Fusce sit amet nisl venenatis quam ultrices condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec rhoncus scelerisque ligula. Vestibulum mi odio, accumsan et, adipiscing eget, ornare ut, quam. Nullam blandit molestie mauris. Curabitur dignissim mauris et lorem. Suspendisse a justo. Nam mattis faucibus arcu. Duis blandit enim non massa. + +Nullam lorem. In hac habitasse platea dictumst. Mauris consectetuer posuere mauris. Maecenas tincidunt mauris in eros. Nulla eu metus eu orci sollicitudin faucibus. Suspendisse aliquam mauris id est. Cras blandit dui et urna. Nulla arcu. Sed a urna. Nulla dapibus vehicula tortor. Donec risus. Sed quam metus, egestas eu, cursus ut, viverra non, odio. Ut justo justo, malesuada sit amet, blandit suscipit, molestie in, justo. Vestibulum consequat, quam ac feugiat tincidunt, ipsum libero eleifend odio, non eleifend pede ipsum non ante. Nullam a metus. + +Nam ac nisi at felis cursus mattis. Pellentesque consequat sem quis orci. Quisque tempus. Aenean imperdiet molestie pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eu tellus. Nulla diam eros, sodales ut, sodales nec, tincidunt ac, nunc. Nunc lacinia faucibus ipsum. Vivamus vel neque in erat fermentum luctus. Nulla eget metus nec augue bibendum placerat. Vivamus tempus. Praesent congue ornare ipsum. Etiam mattis feugiat justo. + +Aliquam dui. Aenean commodo tortor vitae nulla. Morbi et ipsum. Mauris ac ipsum. Nam vel risus ut lectus mollis viverra. Curabitur elementum mollis est. Nullam elit. Vestibulum suscipit pretium enim. Vestibulum ut massa. Proin nec felis. Maecenas gravida, arcu nec consequat sagittis, eros tellus scelerisque mauris, vitae accumsan quam quam ut nunc. Integer eget ante eu velit laoreet malesuada. Nunc sagittis, mauris vitae pharetra volutpat, tellus tellus eleifend eros, sit amet rutrum ipsum nisi a velit. Praesent varius leo eu erat. Vivamus consequat placerat purus. Donec pretium elementum nibh. Proin at elit non sem aliquet mattis. Sed ullamcorper ipsum sit amet elit. + +Mauris in metus. Suspendisse magna lorem, faucibus vel, tincidunt quis, scelerisque non, tellus. Fusce quis lorem. Proin a lacus sit amet mauris iaculis pulvinar. Suspendisse rhoncus eros nec mi. Praesent euismod, turpis vitae rutrum pretium, odio metus volutpat neque, eget tempus sapien neque sed erat. Donec fermentum purus at lectus. Nullam sem. Fusce vel mi quis erat lobortis posuere. Aenean eget urna. Suspendisse ligula. Duis in nisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Curabitur vulputate lectus id pede. Phasellus eu velit. Etiam venenatis adipiscing nibh. Aliquam cursus pulvinar tellus. Vestibulum neque. Mauris nec justo et erat semper pellentesque. Fusce mattis dictum dolor. Etiam eget purus eu massa varius elementum. Pellentesque massa. Ut ultricies diam sed ipsum. Nullam diam. Pellentesque id magna id libero tristique aliquam. + +Ut eleifend, purus id placerat venenatis, urna augue aliquet ligula, in ultricies leo risus et tellus. Mauris et nulla id urna tristique tempus. Ut facilisis, urna eu vestibulum rhoncus, lacus eros consectetuer metus, et rutrum dui lectus in purus. Nunc vel nisl non ipsum tincidunt mollis. Nam quam lacus, ornare vitae, rhoncus non, congue sed, odio. Proin nibh dui, porta vel, venenatis non, pellentesque ut, nisi. Sed tristique felis a magna. Suspendisse eget tellus. Cras gravida imperdiet velit. Integer hendrerit risus. Proin orci. Aliquam ullamcorper mauris quis mauris. Nunc lacinia vestibulum metus. Duis tellus. Nullam faucibus, leo ac vulputate sollicitudin, leo dolor faucibus erat, quis bibendum orci odio non arcu. + +Nullam accumsan mattis dolor. Donec et dui. Praesent a felis mollis lacus semper lacinia. Curabitur pellentesque luctus est. Proin nulla dui, condimentum vel, faucibus non, interdum ac, erat. Maecenas scelerisque, lectus id volutpat accumsan, sapien tortor pellentesque dui, sed semper magna sem ut leo. Proin nulla. Nullam dapibus ullamcorper sem. Suspendisse vehicula metus in nunc. Pellentesque non quam vel arcu ultrices ullamcorper. Phasellus quis felis sit amet tellus ullamcorper fermentum. Sed vehicula sollicitudin urna. Curabitur pharetra scelerisque risus. Pellentesque id massa quis metus aliquam imperdiet. In nunc lacus, feugiat in, gravida eget, venenatis ut, tellus. Suspendisse potenti. Nam consequat adipiscing dui. In nulla nisi, feugiat ut, fermentum vel, gravida nec, tortor. In sed augue. + +Etiam ullamcorper augue at enim. Integer dignissim. Aliquam pulvinar congue nulla. Morbi enim massa, fringilla a, accumsan eget, condimentum nec, erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean pharetra. Etiam porttitor purus a metus. Aliquam interdum sem eget justo. Quisque volutpat luctus est. Aenean augue. Phasellus dui lectus, ultrices nec, commodo vel, auctor vel, nisi. Ut ultrices pellentesque nisi. Integer ac velit et sem imperdiet luctus. Fusce vitae turpis id augue mollis consectetuer. + +Maecenas nec lacus. Maecenas condimentum odio eu felis. Mauris ut nisl viverra erat faucibus adipiscing. Etiam egestas. Nunc et dolor vitae risus dignissim commodo. Morbi lectus velit, tincidunt nec, aliquet vel, mattis vitae, ligula. Maecenas ultricies semper dolor. Suspendisse malesuada. Integer mattis elit. Donec accumsan, lacus facilisis varius tempus, nulla elit porta erat, et rutrum elit sem sit amet dui. + +Maecenas mollis mi non nulla. Vivamus turpis. Suspendisse a metus. In quis mi in turpis congue auctor. Maecenas lacus. Suspendisse sollicitudin. Phasellus porta nunc non nisl pulvinar egestas. Sed nulla. Vestibulum ac mi. Mauris ultricies condimentum neque. Nulla tempus justo vel massa. Nulla suscipit congue arcu. Praesent id turpis. Mauris nibh pede, euismod semper, molestie ac, rhoncus vitae, ante. Maecenas erat felis, viverra sollicitudin, sagittis eget, pellentesque nec, orci. Fusce ultrices consequat lacus. Aliquam erat magna, feugiat at, viverra a, mollis non, turpis. + +Donec mi. Nam dictum pellentesque sem. Donec mollis rhoncus elit. Phasellus rhoncus pede sit amet risus. Donec eget augue. Maecenas non lectus. Phasellus sollicitudin nisi nec felis. Aliquam pretium, est eget semper convallis, nibh nunc sollicitudin purus, id tempor pede dui vel magna. Vivamus ac lorem. Etiam nisl tortor, adipiscing dictum, elementum in, facilisis sed, nibh. Proin mauris. Proin rutrum massa eget sem. Curabitur tempor adipiscing elit. Curabitur purus tellus, fermentum eget, aliquet vitae, convallis ac, mauris. + +Integer consequat velit eu eros tincidunt vehicula. Nullam lorem sapien, rhoncus non, mattis quis, ultricies sit amet, enim. Curabitur commodo, libero in euismod suscipit, sem purus fringilla enim, ac molestie tortor orci et velit. Donec pede. Etiam placerat condimentum turpis. Phasellus egestas enim nec magna. Vivamus condimentum, nulla vel luctus tristique, eros risus vestibulum nulla, in vehicula arcu ipsum at felis. Donec aliquam elit at augue. Quisque a eros eu ligula accumsan dictum. Etiam vehicula turpis quis libero. Aliquam non mi. Donec et leo. Proin leo libero, aliquam tincidunt, congue nec, adipiscing porta, enim. Nulla lobortis, tortor sit amet imperdiet ullamcorper, dolor orci malesuada pede, sed gravida nibh urna vel lorem. Sed pharetra malesuada eros. Quisque euismod aliquet erat. Suspendisse aliquet mattis purus. + +Nunc id nulla quis justo congue sollicitudin. Praesent erat turpis, rhoncus eu, pretium eu, pellentesque a, nibh. Vivamus tempus. Cras nec risus at turpis imperdiet lobortis. Ut mattis. Maecenas est felis, pellentesque non, imperdiet sed, eleifend tincidunt, lorem. In tincidunt. Sed vel leo. Donec et urna in turpis hendrerit blandit. Donec condimentum accumsan est. Ut pharetra, metus vitae mattis consectetuer, leo quam vulputate odio, nec laoreet nisi velit eu erat. Integer lectus augue, egestas in, interdum eu, venenatis vel, sapien. Quisque et est vitae eros laoreet lobortis. Nullam ut risus non nulla placerat adipiscing. Praesent dapibus. Etiam a felis. Ut sodales consequat mauris. Duis lorem felis, luctus a, tristique in, molestie at, risus. Sed vehicula bibendum tellus. Nam consequat euismod lacus. + +Aenean tortor elit, gravida nec, fermentum eu, lobortis id, ipsum. Maecenas eu purus. Cras ac turpis ut nisi iaculis rhoncus. Nulla purus metus, dignissim nec, tincidunt vitae, dapibus eu, nibh. Fusce lobortis, nunc at viverra eleifend, justo turpis scelerisque eros, ac pellentesque metus nisl at purus. Sed elementum tellus sed enim interdum blandit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer ultricies aliquet odio. Mauris eget nunc a ipsum ultrices sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean accumsan. Donec sapien lectus, congue at, porta id, hendrerit vitae, nisl. Curabitur vel quam vel neque accumsan laoreet. Morbi sapien est, pretium in, consectetuer ac, mollis ut, libero. Donec tincidunt adipiscing metus. Nunc vestibulum egestas augue. Donec scelerisque dui ut sem. Suspendisse vel metus id est molestie iaculis. + +Vivamus pharetra, elit eu malesuada blandit, diam tortor mollis dui, sed pulvinar massa nunc et magna. Sed placerat elit auctor tortor. Nulla ac erat. Pellentesque consectetuer, dui convallis tincidunt condimentum, sem odio volutpat libero, non elementum felis neque nec odio. Maecenas hendrerit eros id diam. Mauris vel purus ac orci convallis convallis. Sed sit amet lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque dictum varius lacus. Mauris eget nisl. Suspendisse placerat, nulla non ornare dignissim, nisl diam sagittis tellus, in semper nisi dolor at nibh. Duis ullamcorper viverra felis. Integer a tellus. Suspendisse eget nunc. Aenean diam est, accumsan id, suscipit interdum, fringilla vitae, justo. Proin pede. Maecenas at neque in neque vestibulum eleifend. + +Vestibulum nulla lorem, porttitor eget, euismod ac, aliquam at, nisl. Maecenas et est eget massa varius lobortis. In mi. Duis porttitor fermentum purus. Donec cursus imperdiet ligula. Morbi et ligula et ante molestie vehicula. Mauris sed dolor. Sed imperdiet felis ut sem. Sed vitae neque elementum leo auctor fermentum. Duis feugiat ullamcorper erat. Aenean purus. Morbi fermentum vestibulum est. Pellentesque venenatis mauris. Phasellus pulvinar. Integer ipsum lectus, iaculis a, lacinia id, accumsan id, arcu. Phasellus at est. Fusce neque quam, ultricies id, iaculis vel, dapibus vitae, lacus. In lobortis convallis ante. Nulla nunc purus, vulputate in, hendrerit et, blandit et, ligula. + +Pellentesque leo metus, sagittis in, molestie vitae, dictum in, pede. Morbi pretium felis nec quam. Pellentesque mattis ante sed quam sagittis dapibus. Suspendisse sapien. Praesent bibendum iaculis tortor. Duis a nisl. Aenean mi. Donec dictum arcu in est. Morbi interdum vulputate ipsum. Aenean sit amet magna non nisl tristique posuere. Phasellus velit metus, tempor ac, fermentum eget, condimentum non, velit. Vestibulum sit posuere. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras aliquet massa nec dui. Cras arcu nunc, hendrerit ac, eleifend eu, ullamcorper nec, tellus. Sed pharetra purus sit amet quam. Curabitur mollis. Nam vitae pede. Etiam risus massa, vehicula sit amet, pharetra nec, sollicitudin ut, dui. Donec egestas justo at quam. Proin nisl risus, vestibulum nec, pretium vitae, tristique ac, lorem. Aliquam erat volutpat. Cras sed nibh. Pellentesque sollicitudin euismod augue. + +Etiam fringilla sollicitudin orci. Mauris cursus elit quis lacus. Cras tortor. In adipiscing, lectus id auctor vestibulum, neque pede accumsan dolor, non imperdiet magna diam accumsan velit. Suspendisse at libero ut nisi blandit sagittis. Phasellus non mauris. Fusce elementum sagittis sem. Suspendisse aliquam eleifend tellus. Proin ligula lorem, imperdiet quis, venenatis id, iaculis mollis, nisl. Etiam convallis pede at massa. Morbi accumsan dui et mauris. + +Sed sed orci. Nunc purus. Suspendisse potenti. Ut luctus fringilla mauris. Donec nibh. Phasellus porta. Phasellus sit amet odio sed magna sodales pharetra. Cras lectus. Suspendisse libero ipsum, commodo nec, facilisis in, suscipit lobortis, ligula. Duis massa nulla, semper et, consequat nec, pharetra eu, elit. Vivamus ultricies aliquam odio. Vestibulum sit amet massa. Sed consequat lacus sed urna. Etiam faucibus felis vel orci. Phasellus ullamcorper. Aenean consectetuer lacus at libero. + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis facilisis, ligula vitae condimentum scelerisque, velit orci gravida felis, vel ultricies quam mi non diam. Vivamus auctor metus non libero. Praesent ligula nisi, commodo condimentum, molestie et, viverra et, justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus sollicitudin. Nunc blandit cursus ipsum. Aenean nec ligula ut tellus sodales mattis. Integer sem. Aliquam id ligula. Sed tortor mauris, blandit vitae, cursus vel, elementum et, nulla. Aliquam scelerisque metus et nisl. Duis adipiscing magna at neque. Quisque vulputate eleifend nunc. Aliquam eget elit. Phasellus dui odio, bibendum sagittis, vestibulum id, dignissim imperdiet, orci. Nullam eu felis non nunc lacinia sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Suspendisse pellentesque, libero mattis ultricies accumsan, tortor tortor malesuada sem, et sodales libero odio ac ipsum. Vivamus quis magna nec est suscipit lobortis. Cras tempus posuere nunc. Quisque ut enim a felis egestas semper. Sed pharetra mattis neque. Fusce turpis nunc, congue sed, consequat non, congue sed, nulla. Suspendisse varius lorem id risus porta vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce sed purus. In a felis. Integer egestas auctor orci. Mauris ultrices suscipit nisl. Nullam purus. + +Cras tempor adipiscing ipsum. Ut quis mi. Maecenas in justo ut nulla congue pharetra. Pellentesque ut libero eu dolor venenatis suscipit. Praesent feugiat consectetuer nibh. Morbi faucibus sem non felis. In hendrerit arcu ac massa. In accumsan ultrices mi. Proin malesuada auctor felis. Curabitur interdum. Sed diam ipsum, ultricies in, tempor sit amet, viverra imperdiet, elit. Morbi molestie nisi. Mauris ipsum. Fusce dictum mollis magna. Duis commodo dignissim nulla. Vestibulum augue enim, ultricies quis, iaculis nec, tincidunt vitae, diam. Mauris lacinia tempus ipsum. Sed at mauris. Ut lorem. Donec libero. + +Duis iaculis lacinia lectus. Aenean convallis eros ac ante. Sed quis orci nec risus auctor fringilla. Phasellus facilisis elementum nisi. In hac habitasse platea dictumst. Nunc porta lacus nec ante. Morbi mauris erat, adipiscing in, pulvinar nec, lobortis nec, odio. Ut eleifend lectus sed quam. Nullam mollis. In non turpis et nisl hendrerit blandit. Duis elementum. Nunc nec libero. Suspendisse vestibulum risus non pede. Morbi imperdiet odio sit amet libero. Sed sed massa vitae ipsum mattis tincidunt. Nulla nec tortor vitae libero volutpat tempus. Donec aliquam. + +Duis sed nunc. Curabitur turpis nulla, vehicula sed, luctus quis, elementum eget, felis. Maecenas et purus. Maecenas leo tellus, tincidunt a, facilisis vitae, lobortis sit amet, velit. Donec convallis sapien. Maecenas mollis odio eu nibh. Etiam gravida. Integer molestie, sapien eu molestie lacinia, nunc nibh aliquam ligula, eu sagittis tellus erat sollicitudin odio. Duis et risus. Phasellus nisi neque, placerat nec, condimentum non, ultrices eu, sem. Ut pede. Etiam nulla metus, volutpat id, convallis sed, suscipit vel, urna. Donec vel elit. Ut leo neque, venenatis faucibus, lacinia nec, tincidunt eu, enim. Cras id dui a libero pharetra dignissim. Donec eros leo, porta quis, laoreet ut, pellentesque volutpat, lectus. + +Nullam blandit. Aliquam erat volutpat. Fusce adipiscing enim. Suspendisse non dui quis ligula porta vestibulum. Donec eu tellus vel lorem pretium porttitor. Praesent luctus. Aliquam ac eros in massa dapibus tincidunt. Donec ut magna. Etiam auctor lacus sit amet lacus. Sed ultricies ipsum nec elit. Quisque a est in purus suscipit tristique. + +Aenean sed dui vel dolor pulvinar laoreet. Vivamus vehicula lorem in pede. Vivamus et diam. Integer ac odio vel diam hendrerit bibendum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a nisi. Phasellus tincidunt dui vitae augue. Duis faucibus, dui interdum fringilla tincidunt, odio elit vestibulum libero, ac molestie magna lectus id lacus. Aenean ligula. Nulla facilisi. + +Fusce vel sem eu velit fringilla ornare. Sed feugiat tincidunt felis. Nullam felis mi, euismod sit amet, mollis at, sodales eget, augue. Nam imperdiet nibh at velit. Sed ut erat. In dui. Nulla facilisi. Nullam augue libero, tincidunt nec, pretium eu, pulvinar in, dui. Morbi vitae felis. Pellentesque vel justo vel velit sagittis malesuada. Proin vehicula blandit massa. Etiam tincidunt pharetra urna. In metus est, auctor nec, blandit a, cursus nec, quam. Mauris ac metus a libero congue faucibus. Mauris mauris dolor, sodales in, cursus ut, sodales rutrum, eros. Quisque mauris eros, sagittis vitae, lobortis ut, eleifend id, nisi. + +Aenean neque. Vestibulum egestas pellentesque ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus sagittis justo vel risus. Sed pretium neque vitae urna. Pellentesque congue libero id lorem. Mauris leo lorem, blandit sit amet, convallis quis, consectetuer sed, eros. Mauris tincidunt, enim a gravida euismod, magna nulla fermentum libero, viverra egestas velit quam et tortor. Vivamus aliquet massa vitae justo. Nulla congue lacus ac elit. + +Phasellus commodo quam vel ligula. Proin non metus at eros pulvinar luctus. Mauris diam lorem, posuere quis, gravida et, tincidunt nec, ligula. Sed diam. Aliquam elit lectus, hendrerit ut, imperdiet sit amet, pretium sit amet, ipsum. Mauris vehicula nisl in dui. Curabitur eget quam ut magna elementum fermentum. Mauris scelerisque. Quisque laoreet. Etiam tempus turpis. Pellentesque augue quam, hendrerit sed, tincidunt at, pharetra at, nisl. Aliquam lacus. Suspendisse potenti. Aenean velit libero, ultrices in, lacinia eu, luctus vel, ante. Etiam dictum mi in felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce gravida dapibus nisl. Cras vitae nisl. + +Maecenas dignissim, ligula non porta cursus, enim nunc malesuada sem, eu porttitor nulla urna eu quam. Fusce eros. Aliquam eros. Nam auctor. Nulla molestie porta est. Suspendisse potenti. Vivamus molestie lorem sed erat. Sed eget ipsum. Integer aliquam pulvinar nulla. Cras aliquet sem ut nunc. Fusce faucibus tempus lectus. Cras sodales, nisi ac facilisis ultrices, eros arcu dapibus sapien, et ultrices mauris tellus non dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras cursus varius metus. Ut turpis. Vivamus eget tortor. + +Sed laoreet, velit non accumsan cursus, nunc urna posuere justo, in dictum lectus pede id ante. Cras vulputate. Cras congue dui sed elit. Proin lacus sem, ultrices at, consequat in, tempor quis, metus. Proin vel arcu. Nam euismod hendrerit elit. Ut erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed posuere. Morbi eros urna, semper at, semper non, convallis quis, velit. Maecenas orci. Vestibulum lobortis tristique metus. Vestibulum lorem nulla, sollicitudin vitae, condimentum quis, auctor ut, dui. Vivamus vestibulum magna ut nisi. Curabitur eleifend dui vel nunc. Curabitur mauris lacus, malesuada sit amet, suscipit sed, rutrum luctus, tellus. Integer facilisis urna vitae lectus. + +Aenean quam leo, lobortis quis, malesuada eu, vulputate vitae, nisl. Praesent eget eros. Ut fermentum turpis id quam. Nam tortor. Praesent nec orci. Nulla bibendum adipiscing augue. Ut commodo, magna id malesuada gravida, augue odio malesuada mi, porta malesuada elit est vitae diam. Mauris non nulla. Suspendisse tincidunt, nunc ultricies porta venenatis, mi pede tincidunt libero, eget varius ante libero ut ligula. Curabitur pretium porttitor tortor. + +Maecenas vitae elit eget nisi dapibus dictum. Nunc in libero. Nulla dictum orci eu erat auctor lobortis. Phasellus risus. Suspendisse potenti. Suspendisse potenti. Praesent adipiscing consequat elit. Integer id augue. Praesent in justo nec magna dapibus pulvinar. Duis nisl. Suspendisse ac odio. Vivamus imperdiet. Donec non velit sit amet risus dignissim congue. Nam aliquet posuere velit. Cras turpis. Morbi malesuada dignissim mi. + +Sed leo neque, varius quis, venenatis sed, pharetra sed, est. Morbi blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam semper pellentesque mi. Ut vel lorem. Nunc mi tortor, laoreet at, faucibus eu, tincidunt sit amet, erat. Duis tempor malesuada ipsum. Phasellus aliquet. Donec et elit. Pellentesque purus. Vestibulum rutrum semper nibh. Nulla facilisi. Phasellus et enim sit amet ante vestibulum vehicula. Phasellus id nisl. Donec mollis leo at eros. Mauris pellentesque neque at purus. Morbi quis dolor at ipsum scelerisque sodales. Etiam volutpat turpis a metus. In hac habitasse platea dictumst. Nunc lorem lorem, vestibulum ac, euismod eget, ullamcorper dignissim, velit. + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ultrices, nibh vel aliquam vestibulum, eros enim venenatis dui, id iaculis enim nunc vel massa. Morbi eleifend orci et massa. Aliquam erat volutpat. Nulla mollis egestas turpis. In sodales nunc eget tortor. Sed ipsum eros, tempor quis, aliquet vitae, imperdiet non, lorem. Pellentesque quis elit id mi luctus dapibus. Sed nunc arcu, rhoncus nec, convallis quis, cursus at, neque. Mauris convallis purus at erat. Pellentesque vestibulum. Vivamus fringilla elit at arcu. Nullam aliquet enim nec arcu. Nam id tortor. Nulla quis nunc. Ut arcu. Suspendisse potenti. Pellentesque ullamcorper ligula id arcu. + +Nam non libero vitae nisl scelerisque fringilla. Quisque varius ante id metus rhoncus fringilla. Nulla facilisi. Praesent eleifend porttitor ligula. Etiam quis dolor non augue commodo auctor. Donec a mi. Vestibulum tempor. Donec felis urna, auctor at, cursus dictum, gravida id, arcu. Aenean dictum malesuada dolor. Vivamus mattis. Phasellus eu pede. Fusce adipiscing justo fringilla metus. Etiam ante. Integer mollis massa quis nunc. Integer dictum neque luctus enim. + +Sed eu libero. Integer tempor ligula in velit. Ut tincidunt lacinia sem. Nullam vel risus. Sed sodales ante a dolor. Curabitur eros. Sed sodales. Sed non metus. Vestibulum elementum faucibus ante. Nulla vel nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In hac habitasse platea dictumst. Nunc nec lorem ut ipsum lacinia iaculis. Duis erat. Aliquam erat. Cras iaculis. In hac habitasse platea dictumst. + +Nullam ante. Cras vitae est. Pellentesque vel metus a ligula dapibus mattis. Duis feugiat aliquet felis. Etiam id nisl quis est dignissim condimentum. Suspendisse potenti. Morbi velit lorem, ornare quis, pellentesque vel, placerat eget, tortor. Vestibulum tincidunt molestie libero. Nulla nulla enim, malesuada id, ullamcorper vitae, dictum at, purus. Donec dignissim odio ut enim. Suspendisse at lectus. + +Praesent lobortis augue vel lectus. Ut in ligula ut felis congue suscipit. Quisque dignissim tortor ut mi. Fusce magna nisi, eleifend ac, ornare vel, porttitor vitae, quam. Vestibulum sodales justo quis turpis. Fusce urna nisi, rhoncus quis, condimentum vel, dictum eu, nunc. Fusce sed nibh vitae odio posuere adipiscing. Sed porta elit quis dolor. Nam libero nulla, auctor sed, tincidunt quis, faucibus sit amet, mi. Quisque orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam id sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vel eros. + +Vivamus luctus lobortis leo. Suspendisse vel elit a enim ullamcorper posuere. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec quis pede mattis lectus mollis adipiscing. Sed accumsan posuere erat. Praesent euismod tincidunt felis. Donec mi. Ut commodo arcu lacinia tellus. Aliquam a libero quis lectus semper viverra. Curabitur lacinia mauris at tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sit amet magna molestie orci suscipit fringilla. Fusce pretium metus non sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed hendrerit. Nulla felis. Suspendisse potenti. Aliquam blandit tristique neque. Curabitur quis erat vel nunc accumsan mollis. + +Duis sagittis, tellus ut aliquam fringilla, dolor mi ullamcorper nisl, ut tristique pede elit sed mauris. Curabitur id felis. Donec pulvinar lacus et lectus. Aliquam vulputate vulputate metus. Curabitur magna felis, adipiscing ac, accumsan vel, molestie quis, quam. Mauris elit arcu, pretium vitae, mollis sit amet, sollicitudin ut, mi. Donec imperdiet dignissim mi. Nullam sit amet tortor. Aliquam neque nulla, venenatis a, porta in, placerat tempus, lacus. Quisque vestibulum dui et lacus. Proin dignissim consectetuer purus. Etiam gravida tortor in nunc. Ut tempor tristique tortor. Sed laoreet tincidunt quam. Vestibulum porta turpis ut elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nibh dui, feugiat nec, laoreet id, malesuada eget, nisi. Ut neque massa, vehicula eu, commodo non, ultricies vitae, purus. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris euismod, felis vel tempor aliquet, tortor mauris malesuada nunc, vel fermentum sem diam id dui. Nam rutrum sapien eget odio. Aliquam sed libero non mi faucibus tempus. Fusce hendrerit, diam non volutpat rutrum, erat metus venenatis ligula, non scelerisque pede ligula vel quam. Morbi rhoncus eros ac dui feugiat elementum. Duis eu libero et tellus congue viverra. Morbi quam quam, elementum sed, ullamcorper imperdiet, commodo non, odio. Nam aliquet egestas urna. Mauris odio felis, varius eu, lacinia eu, condimentum a, lectus. Sed justo massa, pulvinar id, varius a, porttitor nec, libero. Etiam varius. Curabitur sodales, odio at posuere semper, eros nibh tincidunt lectus, vel rutrum sapien nisi in ligula. Suspendisse eget arcu. Phasellus imperdiet est ac sapien. Donec nulla tortor, placerat vel, tempus a, lobortis vel, nibh. Aliquam varius nisi. Nulla et enim. Fusce convallis laoreet lacus. + +Phasellus ipsum dolor, molestie quis, condimentum in, commodo eu, diam. Quisque bibendum lacinia dui. Nullam blandit vulputate orci. Ut lacinia massa vel augue. Aliquam gravida, quam quis imperdiet imperdiet, tellus diam pharetra erat, at pharetra lacus nibh egestas magna. Nulla sagittis lorem ut lorem. Duis condimentum, dui vitae aliquam posuere, diam quam convallis velit, ut gravida leo ipsum non risus. Ut fermentum sollicitudin erat. Donec sagittis scelerisque felis. Nunc arcu. Etiam tempus, magna sit amet suscipit euismod, eros sem rutrum dui, vitae sagittis nibh purus non lacus. Sed mollis arcu eget dolor. Donec ornare, arcu sit amet fermentum vulputate, risus enim fermentum libero, a lacinia dolor mi non velit. Etiam lobortis purus a elit. Nunc nulla dui, mattis quis, bibendum a, ultrices ac, augue. In aliquam vehicula turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Integer id nisl. Quisque dictum elementum odio. Aenean luctus. Sed eu sem a pede vulputate condimentum. Quisque magna. Donec aliquam mattis ipsum. Curabitur dictum sollicitudin sem. Aliquam pulvinar. Nunc sollicitudin risus a erat. Vivamus quis tellus sit amet nibh vestibulum consequat. Nulla pretium sollicitudin dolor. Aliquam iaculis tincidunt turpis. Phasellus ipsum leo, venenatis in, sagittis in, ornare at, nunc. + +Pellentesque ultrices, dui eu iaculis luctus, tellus augue volutpat sapien, in dignissim urna felis ut mi. Sed arcu dui, dignissim id, porttitor ut, imperdiet vitae, ante. Nulla dui sem, commodo nec, sagittis et, lacinia et, pede. Etiam eleifend dui ut nisl. Donec ante mauris, tempus sit amet, varius vitae, gravida quis, mi. In scelerisque, felis vitae viverra sagittis, velit metus ultricies neque, quis imperdiet velit elit et magna. Suspendisse potenti. Sed velit eros, euismod sed, condimentum nec, faucibus sed, sapien. Nam accumsan ligula sit amet neque. Aliquam erat volutpat. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam eu pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed eu felis sed tortor tempor fermentum. Phasellus commodo sem vel nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lectus elit, pharetra sit amet, accumsan sed, tincidunt et, mauris. Duis dapibus pharetra sem. Integer in justo. Praesent eros. Vestibulum ac ante. Aliquam scelerisque sem pellentesque nibh consectetuer sodales. Aliquam consectetuer odio. Duis lectus odio, luctus eu, commodo quis, mollis vitae, velit. Cras nec nunc non elit iaculis mattis. Aenean justo neque, sollicitudin eget, ullamcorper eget, egestas id, sem. In eu risus. Sed egestas. + +Integer at neque. Sed pretium scelerisque nulla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce ut pede. Etiam vitae quam a urna varius imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vehicula. Fusce ullamcorper nibh non erat. Quisque in neque. Praesent est. Pellentesque arcu. + +Proin posuere. Suspendisse potenti. Integer felis lacus, aliquam sed, vulputate in, mollis vel, tellus. Integer vehicula bibendum est. Nunc non dolor in tellus mattis facilisis. Integer vestibulum, augue at commodo aliquam, dui est mattis ligula, sit amet adipiscing orci sem vitae magna. Praesent enim velit, malesuada at, congue nec, luctus in, justo. Sed varius. Morbi pharetra. Donec eu massa nec tellus vulputate pulvinar. Ut commodo turpis non sem. Ut convallis ullamcorper risus. Etiam interdum pede id nisi. Cras magna sapien, suscipit a, laoreet non, rhoncus et, felis. Integer orci lorem, vestibulum dictum, ullamcorper a, porttitor et, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc et magna. Sed bibendum tellus in diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vitae tortor. Integer magna. Duis venenatis, leo ac tempor laoreet, elit nulla pharetra pede, non fermentum nunc odio a odio. Proin non velit. Sed imperdiet augue quis nisl. Integer condimentum nisl nec libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus placerat libero. Duis congue dictum magna. Aliquam dapibus bibendum enim. Nunc eleifend pede vel ipsum. + +Etiam vitae velit. Mauris erat nunc, malesuada ut, feugiat ac, placerat condimentum, augue. Nam volutpat. Aliquam vehicula ipsum id odio. Vivamus sollicitudin turpis id sapien. Fusce a felis vitae odio convallis blandit. Curabitur vitae eros id eros porta pretium. Nulla in magna eget urna lacinia convallis. Aliquam mattis venenatis purus. Sed sed mi eget erat tristique porta. Donec auctor dolor a erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In nec ligula. Nunc eleifend. Vestibulum quis nisi eget elit porttitor congue. Maecenas faucibus, magna eget adipiscing tincidunt, dolor ante malesuada elit, non elementum lacus turpis in pede. + +Ut malesuada mi nec metus. Praesent auctor augue ac nisl ultricies facilisis. Nam purus sapien, pellentesque dignissim, posuere eu, cursus id, diam. Quisque sollicitudin, elit a pellentesque scelerisque, lorem risus auctor quam, quis consequat tellus neque id urna. Suspendisse diam tortor, eleifend dignissim, egestas ut, luctus in, ante. Duis ante. Maecenas luctus. Curabitur cursus pharetra urna. Maecenas imperdiet, erat non elementum euismod, tortor odio euismod lectus, ac facilisis sem nibh vitae nulla. Nunc gravida. Morbi sollicitudin odio quis lacus. Aliquam a nibh non urna porta imperdiet. Aliquam erat volutpat. In iaculis lacinia velit. Sed libero lacus, tristique eu, lacinia ac, aliquet eget, urna. + +Etiam at nisl. Phasellus faucibus luctus lectus. Ut placerat vulputate dolor. Phasellus vel velit. Morbi viverra. Phasellus orci. Integer dignissim mattis mauris. Pellentesque posuere leo posuere quam. Quisque nec magna at diam viverra pellentesque. Suspendisse velit arcu, ultricies quis, congue a, venenatis eget, lacus. Integer sagittis hendrerit dolor. Fusce tincidunt ante a sem. + +Maecenas consectetuer, justo sed rhoncus venenatis, nibh arcu rutrum dolor, sed condimentum libero libero et ipsum. Vivamus mattis justo ut lorem tincidunt lobortis. Ut non velit id neque aliquet accumsan. Sed tempus viverra nulla. Curabitur ullamcorper, neque quis dapibus scelerisque, felis diam gravida orci, non cursus quam neque vitae elit. Etiam pharetra tincidunt lacus. Duis euismod fringilla est. Etiam ornare tincidunt lectus. Proin in turpis. Nunc blandit blandit turpis. Aenean ut augue. Duis orci justo, tincidunt eu, rutrum sed, rutrum et, turpis. Curabitur facilisis odio in ante. In hac habitasse platea dictumst. Sed eros est, pellentesque at, tincidunt eu, ultrices quis, metus. Morbi sit amet justo. Maecenas ac arcu. Mauris dignissim. + +Pellentesque ultricies rutrum orci. Aenean ornare. Vivamus eu risus vel mauris lobortis dictum. Sed et turpis auctor mi rhoncus pulvinar. Sed nec nunc a purus tempor viverra. Pellentesque suscipit. Donec tristique risus non nibh. Etiam nisl magna, sollicitudin ut, ultrices sit amet, egestas eu, nulla. Aliquam erat volutpat. Vestibulum pharetra. Sed egestas, metus sit amet lobortis consequat, erat elit imperdiet libero, eu interdum quam massa eget dolor. Suspendisse vitae odio. Proin blandit mauris iaculis metus. + +Vivamus vestibulum. Etiam et nisl. Aliquam in diam vel elit placerat suscipit. Duis sodales purus ac nibh. Nulla in odio eget enim luctus blandit. Curabitur ultrices ipsum non neque egestas eleifend. Sed turpis. Proin consectetuer. Vivamus mattis. In aliquet. + +Nunc id eros. Donec venenatis, nulla et mattis luctus, ante leo semper justo, non adipiscing odio risus sed lacus. Praesent vitae risus congue libero congue tempus. Phasellus ac eros. Nulla vehicula, lorem in aliquet suscipit, arcu erat egestas sem, quis lobortis quam ante eu massa. Curabitur non massa. Sed bibendum lacinia odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus volutpat blandit lacus. Proin porta, tellus ut auctor laoreet, lectus eros fermentum lectus, id sagittis arcu justo in turpis. Phasellus consequat. Nam pellentesque, mi id viverra convallis, nunc libero placerat leo, eleifend porta sem nisl vitae sapien. Pellentesque ligula libero, tristique non, porttitor rutrum, porttitor non, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer dictum tellus a tortor. Vivamus felis nunc, molestie non, rhoncus quis, pharetra id, dui. Donec risus metus, fringilla vel, aliquet eu, placerat id, neque. + +Suspendisse ipsum. Vivamus lectus. Sed viverra, massa eget convallis mattis, quam turpis consectetuer nunc, eget posuere magna sem id velit. In nec mauris. Aenean a purus sed quam lobortis fringilla. Proin ultricies lacinia ante. Sed adipiscing erat quis velit. Nullam vitae nisl id justo sollicitudin molestie. Nulla facilisi. Sed nec urna sed nisl fringilla dapibus. Nulla at diam. Aliquam eget nibh. Nunc ac nisi sit amet tellus egestas tempus. Nam scelerisque urna et neque. Donec est orci, sagittis non, vulputate a, commodo et, augue. Ut dapibus tortor. Ut nunc. Donec dictum dapibus odio. Nam ultricies ullamcorper ligula. Pellentesque accumsan varius leo. + +Morbi euismod laoreet erat. Vivamus quis ipsum. Morbi euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel purus. Nullam at magna. Curabitur lacus lorem, iaculis quis, dapibus non, volutpat vel, nulla. Donec ut arcu rhoncus dolor pretium dictum. Nullam vel metus. Ut arcu. Pellentesque nisi nunc, placerat eget, tincidunt vel, pharetra non, nunc. Integer tincidunt ultricies lectus. Integer semper, purus sed ultrices feugiat, nulla pede sollicitudin erat, vel auctor nulla ipsum vel lectus. Aenean mi. + +Nullam sed nisi et arcu imperdiet fermentum. Mauris nec metus. In ac dolor. In mi arcu, congue ac, pharetra nec, scelerisque sit amet, magna. Curabitur lacus. Curabitur et elit. Aliquam ullamcorper nunc eu elit. Sed convallis dolor at velit. Vestibulum dapibus, augue id consectetuer placerat, nunc massa blandit sapien, id aliquam elit nisi id mi. Phasellus sapien est, gravida eu, bibendum ut, adipiscing quis, est. Ut molestie quam vitae odio. Donec quis risus id erat faucibus sollicitudin. Nam id felis. Mauris sed enim vitae leo accumsan pretium. + +Nam justo. Donec turpis nisl, commodo et, interdum ac, consectetuer non, massa. Fusce sem metus, laoreet nec, posuere id, imperdiet in, velit. Donec vulputate justo eget turpis. Nulla pede. Morbi tincidunt. Fusce aliquet, quam et aliquam fringilla, ante ante iaculis dui, nec aliquam arcu purus sed erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus suscipit quam et est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; + +Integer sed tellus. Sed sed velit ultricies leo rutrum laoreet. Sed non eros ac purus sagittis feugiat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed hendrerit ligula sit amet nibh. Maecenas turpis. Morbi consectetuer, dolor et adipiscing imperdiet, ante neque feugiat dolor, at porta quam neque quis ligula. Mauris semper velit sit amet ipsum. Pellentesque tempus, purus in rutrum consequat, enim erat vehicula massa, id accumsan leo sapien nec purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In dolor. Integer facilisis libero sit amet pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut varius aliquet enim. Nulla facilisi. Curabitur consectetuer, odio eu pretium tincidunt, nunc nisi aliquet neque, vel imperdiet elit massa sit amet turpis. Pellentesque tempus, orci volutpat blandit fringilla, odio sem posuere ante, vitae bibendum urna lorem vitae eros. Praesent viverra rhoncus arcu. Sed auctor, est sit amet mollis mollis, quam quam gravida sapien, in commodo metus nulla auctor enim. Donec facilisis. + +Proin tincidunt, sapien eget ultricies adipiscing, est odio dictum arcu, ut mollis erat dui sit amet velit. Morbi est sem, interdum at, congue a, elementum vitae, metus. Suspendisse id augue. Mauris enim sem, pulvinar eget, tempus a, tempus sit amet, sapien. Fusce vestibulum consectetuer dui. Pellentesque erat. Sed dignissim placerat odio. Maecenas semper rhoncus lectus. Phasellus pretium. Duis libero elit, eleifend nec, egestas ut, cursus sed, felis. Nam nisl arcu, aliquet et, facilisis eu, luctus ut, risus. Etiam ultrices, dolor sed volutpat malesuada, turpis arcu imperdiet tortor, euismod commodo libero massa ut quam. Integer molestie purus non elit. Ut venenatis semper tortor. Etiam bibendum egestas ipsum. Mauris sollicitudin sem nec nibh. Nulla pretium metus eu metus. Pellentesque sit amet sem. + +Suspendisse ac nisi. Ut leo. Vestibulum hendrerit pretium dolor. Nunc feugiat malesuada purus. Cras et nibh. Curabitur nunc erat, malesuada vitae, laoreet ac, ultricies in, purus. Vivamus tellus arcu, sodales eu, facilisis a, lacinia nec, nunc. Pellentesque id velit. In eu nibh. Nunc nec erat. Sed dictum neque ut nisl. + +Morbi lectus tellus, tincidunt ac, porttitor ac, tristique in, eros. Donec luctus luctus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ut est et enim scelerisque accumsan. Donec ligula felis, lacinia quis, pellentesque in, semper vestibulum, elit. Mauris eget orci a felis congue vehicula. Ut sollicitudin. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam id dolor ut lorem dignissim venenatis. Suspendisse vitae sapien. Proin non magna ut eros viverra pulvinar. Donec quis odio. Nullam non arcu vel lorem suscipit aliquam. Aliquam rutrum turpis in leo. + +Ut luctus nibh tristique erat. Suspendisse bibendum odio vitae tortor. Donec lacinia. Cras sodales felis luctus nulla. Nam eleifend sagittis ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse vel neque. Morbi aliquet vehicula magna. Aenean at odio. Duis pellentesque magna. Nulla at tortor ut diam dictum faucibus. Mauris quis velit. Donec non tellus vitae lorem fringilla porttitor. Fusce ut sapien quis tortor feugiat sagittis. Donec viverra sem vitae sapien. Praesent sodales, lacus in fringilla viverra, odio augue adipiscing urna, vitae interdum ante sem non nisi. Nullam tortor lorem, eleifend ac, mollis non, laoreet ac, risus. Integer ornare leo sed justo. Quisque cursus, sem non facilisis bibendum, nisi mi varius felis, fermentum feugiat lorem eros laoreet risus. + +Quisque sit amet est et lorem vehicula lacinia. Donec nec tortor. Cras odio. Nam scelerisque vulputate urna. Praesent dui. Etiam nec nisl lobortis ipsum aliquet tempus. Maecenas pretium sollicitudin mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus augue massa, congue eget, convallis eget, tristique sit amet, eros. Sed consequat nisi eu felis. Pellentesque justo. Suspendisse non augue. In dignissim lobortis mauris. Mauris sagittis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + +Sed adipiscing. Donec a tellus vitae est cursus vehicula. Nam ante sem, sodales id, fringilla vel, condimentum vel, nulla. Quisque sodales. Etiam imperdiet elit id odio. Aliquam erat volutpat. Maecenas porta tempor arcu. Nulla sem augue, pellentesque ac, consequat ut, condimentum euismod, risus. Sed aliquam tincidunt mi. In interdum lobortis orci. + +Sed vehicula hendrerit purus. Etiam a diam. Curabitur convallis. Suspendisse a nisi. Donec id magna in quam sollicitudin ultricies. Donec viverra. Quisque volutpat est sed sem. Aliquam justo. Vestibulum tortor massa, porttitor sed, varius quis, iaculis quis, odio. Aliquam eget neque. + +Mauris nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum eu quam in neque ultrices pellentesque. Cras in dolor quis quam varius hendrerit. Aliquam nisi lacus, lobortis eu, convallis sit amet, facilisis ut, mi. Aliquam at neque. Cras sagittis elementum justo. Vestibulum ut lectus aliquet purus malesuada volutpat. Duis at lacus adipiscing libero tincidunt vestibulum. Morbi a libero. Cras purus. Morbi ut augue et purus interdum scelerisque. Integer a dui. In hac habitasse platea dictumst. Duis pharetra metus eget mauris. Aliquam interdum ullamcorper massa. + +Etiam ornare. Nullam euismod. Aenean consequat gravida ligula. Aliquam est. Proin vitae lacus. Praesent a eros sit amet dui luctus commodo. Phasellus vehicula arcu eget dolor. Praesent fermentum congue leo. Aliquam volutpat purus ut lorem. Fusce hendrerit enim at leo. Aliquam rhoncus nisl. Vivamus dictum egestas mi. Suspendisse pellentesque bibendum dolor. Pellentesque tincidunt, turpis semper pellentesque condimentum, ipsum metus sodales ligula, id volutpat diam turpis ut elit. + +Praesent sed lacus. Nam eleifend molestie mauris. Donec dapibus fermentum massa. Donec viverra faucibus purus. Curabitur congue, libero vitae viverra pellentesque, diam velit sodales enim, sed suscipit lectus nisi nec neque. Vestibulum malesuada, lacus at cursus congue, velit lectus tristique dolor, sit amet sodales neque ipsum a libero. Vestibulum et quam. Curabitur placerat. Curabitur nunc arcu, euismod nec, vulputate hendrerit, aliquet eget, quam. Curabitur vel enim. Suspendisse potenti. + +Nunc consequat orci ut lacus. Fusce velit dolor, dapibus sed, blandit sit amet, rhoncus id, risus. Duis urna nibh, scelerisque quis, dapibus a, scelerisque sed, nibh. Donec luctus. Ut eu mauris cursus diam lacinia rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam vehicula molestie justo. Maecenas imperdiet pede sed mi. Suspendisse nulla dolor, hendrerit eget, hendrerit id, dictum vel, leo. Duis accumsan. Curabitur in felis. Nunc lorem. Ut leo dolor, laoreet nec, vulputate at, eleifend in, nulla. Quisque nunc purus, varius eget, accumsan nec, aliquet et, nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras adipiscing viverra dolor. Mauris porttitor ultrices purus. Nulla facilisi. Praesent faucibus ante vitae mauris. + +Praesent lacinia lectus sed nisl. In tempus congue mauris. Integer facilisis ornare enim. Nulla id massa. Donec commodo diam at tellus. Nam dapibus viverra est. Nam tellus. Praesent a libero. In faucibus est eget nibh. Nulla eros orci, imperdiet non, blandit non, tempor eget, mi. Pellentesque convallis. + +Quisque eget mi ac leo euismod faucibus. Phasellus rhoncus purus id dui. Vestibulum malesuada eleifend ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque blandit mattis odio. Suspendisse consequat, lectus ac semper sollicitudin, mi velit dictum augue, ac tempus dolor erat sit amet dui. Proin hendrerit, felis quis volutpat posuere, diam odio malesuada odio, a interdum orci diam quis sapien. Pellentesque odio odio, viverra vel, gravida eu, molestie sed, nulla. Phasellus mauris pede, commodo ut, euismod eu, hendrerit eu, est. In hac habitasse platea dictumst. Nulla elementum lacus eu augue. Sed erat. Proin porta. Maecenas quis mi. Phasellus at enim ac justo gravida ultrices. Cras leo. + +Integer ut arcu. Donec sed magna. Proin felis. In iaculis, ligula id fringilla pretium, nibh diam accumsan tellus, eget accumsan metus dui varius turpis. Phasellus orci metus, eleifend sed, tempor ac, scelerisque ac, urna. Integer viverra neque a mauris. Mauris porttitor dolor eu velit. Integer odio elit, vestibulum ut, volutpat id, rhoncus commodo, urna. Etiam placerat pharetra erat. Ut tempor est. Integer dignissim blandit tellus. Morbi nibh dolor, scelerisque id, commodo malesuada, mattis at, mi. Cras tincidunt commodo purus. In tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ullamcorper. Ut hendrerit. Morbi ultrices. + +Praesent iaculis, eros ac egestas sodales, urna leo fermentum ligula, sit amet aliquam velit sem non purus. Donec rutrum arcu quis purus. Nam posuere, lacus at consequat placerat, nulla pede posuere orci, non euismod turpis dui quis nisl. Proin porta adipiscing nibh. Donec tristique dolor at tellus. Donec neque massa, auctor id, faucibus vitae, ullamcorper vel, nisi. Proin molestie neque sed massa. Nam tempor. Morbi aliquam sapien at tellus. Fusce quis risus et mi pretium pulvinar. Fusce sit amet ligula. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse eu enim et felis scelerisque lobortis. Praesent bibendum. Vivamus vehicula. Integer at nibh sed velit rhoncus molestie. Cras lacus. Sed ullamcorper eros vel erat. Fusce eu tortor sit amet diam euismod sagittis. Nunc quis lacus id nibh convallis varius. Suspendisse vitae mi. Vestibulum tristique. Donec malesuada ipsum id neque. Nullam sed lacus. Duis egestas, justo ut congue ornare, augue sapien luctus diam, at accumsan erat sapien ut libero. Phasellus vel nulla. Suspendisse arcu tellus, porttitor a, pharetra faucibus, aliquam sit amet, massa. Nulla porttitor tincidunt lorem. Nunc dolor odio, sagittis in, lobortis vel, volutpat sed, nibh. + +Quisque blandit leo ut sapien tempus facilisis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean ultricies porttitor justo. Fusce rutrum eros ut urna. Proin quis quam eget dui aliquam accumsan. Donec suscipit eleifend elit. Pellentesque mattis, felis sodales iaculis imperdiet, lacus sem convallis augue, sit amet aliquet arcu purus fringilla risus. In eu odio id magna pharetra ornare. Aliquam interdum pulvinar ipsum. Sed neque. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam sit amet nisi. Ut at augue. Mauris volutpat blandit ligula. Nulla eu metus. Vestibulum eget elit. Praesent posuere. Vestibulum id sem non lectus mollis tincidunt. Aliquam id felis at ante ornare tempor. Nulla lacus turpis, feugiat vitae, cursus quis, consectetuer non, mauris. Fusce lacus massa, porttitor ut, molestie ut, venenatis a, lorem. Praesent sit amet orci. Mauris rhoncus felis vitae felis adipiscing imperdiet. Maecenas mollis diam nec leo. + +Fusce enim ipsum, ultrices eu, molestie id, elementum id, sapien. Integer a urna. Nam velit libero, venenatis eget, tempor sit amet, feugiat vitae, ante. Fusce nunc. Sed semper nisl nec risus. In sed libero. Proin tortor neque, tincidunt ac, tempor ac, pharetra quis, velit. Duis lectus augue, ultricies vel, consequat id, iaculis id, ante. Vivamus auctor metus a ante. Curabitur arcu nisi, facilisis at, laoreet in, consectetuer sed, mauris. Quisque placerat diam sed dui. Vivamus pretium condimentum lorem. Curabitur laoreet. Aenean orci ligula, cursus eget, lacinia non, faucibus vel, lorem. + +Aliquam erat volutpat. Curabitur eros dolor, congue a, condimentum sed, luctus ut, nibh. Maecenas non tortor nec turpis commodo pellentesque. Praesent euismod placerat mi. Suspendisse potenti. Phasellus ut neque vitae orci mattis iaculis. Integer eget tellus. Donec at ante. Nam lacinia leo eget erat. Maecenas euismod magna congue tortor. Morbi nec massa eu enim malesuada sollicitudin. Sed accumsan. Nullam ipsum. Ut odio. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque id velit. Nam odio sem, aliquet ut, tempus sit amet, euismod et, nunc. + +Pellentesque libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent mauris nunc, varius ut, convallis molestie, luctus sit amet, leo. Sed dictum lorem et arcu. Nunc venenatis pellentesque massa. Nulla facilisi. Phasellus in tortor eget risus scelerisque vulputate. Sed nibh elit, sagittis ac, condimentum nec, convallis et, justo. Fusce volutpat metus. Nunc auctor. Vestibulum leo eros, pellentesque ac, mollis ultrices, rhoncus non, dolor. Mauris vehicula placerat nisl. Vestibulum bibendum, arcu quis congue elementum, velit nunc eleifend turpis, id luctus risus nisl sit amet tellus. Phasellus pede neque, blandit non, commodo vitae, ultricies eget, magna. Aliquam erat volutpat. + +Nulla facilisi. Aliquam ac ante. Cras risus. Morbi mauris lacus, posuere eu, blandit et, pharetra at, mi. Proin ac purus. Duis cursus nisl rutrum quam. Aliquam a odio non magna pellentesque ultricies. Maecenas ac massa quis sapien ullamcorper tempus. Cras cursus velit sed sapien. Proin nulla. Vivamus sodales aliquam nibh. Etiam et erat ut ante lacinia euismod. Fusce nisi. Proin quis nulla. + +Quisque venenatis, eros sed laoreet sollicitudin, orci ante pellentesque nisl, sit amet viverra quam erat non risus. Cras eget libero. Sed elit magna, semper eu, fringilla in, dignissim sodales, erat. Vivamus feugiat sem vel dui. Donec convallis sollicitudin diam. Cras sed purus. Donec felis eros, semper eget, tempor consectetuer, sagittis quis, nisl. Duis in ante. Cras non turpis. Nulla tempor velit aliquet turpis molestie placerat. Proin elementum fermentum mauris. Vivamus sed orci lacinia dui placerat venenatis. Vestibulum feugiat, tellus in volutpat rutrum, magna nisi ullamcorper eros, id pulvinar neque erat ut lacus. Vivamus sed augue. Nulla facilisi. Maecenas ante augue, elementum ut, sodales vitae, condimentum nec, lorem. Duis pede orci, fringilla at, eleifend nec, pretium in, erat. Nam sagittis, turpis vitae convallis pharetra, odio sem scelerisque lacus, nec lobortis dui diam vel eros. In semper gravida neque. + +Integer nunc. Ut pretium ipsum sit amet elit. In nec arcu. Sed vestibulum vulputate ipsum. Pellentesque tincidunt. Nulla gravida dolor in tellus. Cras vehicula, dolor ut pellentesque aliquam, erat enim auctor massa, vehicula lobortis odio eros quis quam. Proin dapibus neque in enim. Proin elit. Integer rhoncus tincidunt elit. Fusce lorem metus, semper ac, volutpat vitae, facilisis ut, tellus. Donec vel turpis vitae nisi pharetra porttitor. Maecenas tortor. Fusce mi. Nullam nec turpis. Sed sodales vestibulum nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Pellentesque dolor dolor, laoreet eu, aliquet quis, scelerisque sit amet, arcu. In hac habitasse platea dictumst. Nullam cursus urna eget elit. Quisque blandit sapien ac ante. Proin nulla eros, gravida volutpat, sodales vel, mollis eu, massa. Nulla tristique sollicitudin nisl. Curabitur vitae lorem vitae velit egestas ornare. Aenean eget eros. Aliquam erat volutpat. Fusce a urna id odio aliquet convallis. Curabitur sit amet nisl posuere leo posuere dapibus. Duis metus erat, luctus vel, rhoncus at, convallis sit amet, enim. Vivamus hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam eget elit. + +Nullam a nunc. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In metus urna, tincidunt et, lacinia sit amet, lobortis vitae, ligula. Proin et mauris vitae mi accumsan pellentesque. Etiam quam purus, hendrerit sed, feugiat vitae, euismod eget, tortor. Ut aliquam magna vitae justo. Suspendisse non justo vel velit condimentum tempus. Duis tempus ipsum vitae tellus. Proin in massa. Etiam ullamcorper dictum tellus. Proin aliquet felis at leo laoreet pulvinar. Vestibulum arcu purus, malesuada sit amet, cursus eu, placerat sit amet, nunc. Nam massa odio, sollicitudin in, adipiscing a, aliquam nec, risus. Aliquam blandit hendrerit libero. Mauris gravida. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur a nibh. Ut interdum fermentum neque. Pellentesque sed nunc. Mauris vehicula nisi et nunc. Praesent lorem. Donec semper. Integer eu lacus in est aliquam hendrerit. Vestibulum eget neque. Sed semper luctus velit. Curabitur nibh augue, congue eu, hendrerit id, congue et, enim. Integer placerat aliquam lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae eros. Donec vel nisl. + +In vestibulum facilisis urna. Ut risus. Mauris pharetra. Pellentesque mattis. Integer suscipit aliquam ipsum. Duis blandit, sapien et ultricies condimentum, felis mi elementum pede, nec sagittis metus mauris quis quam. Quisque accumsan arcu vel nulla. Cras sem sapien, porttitor id, ultricies sagittis, luctus eu, nulla. Integer quis eros. Morbi sed urna a tellus vehicula vulputate. Etiam nec augue eget felis semper tristique. Quisque ut dolor vel risus dictum consequat. Sed eget dolor sed nunc lacinia aliquet. Suspendisse ac tortor in ipsum posuere venenatis. Sed eget erat. Nulla faucibus. Duis laoreet, massa porttitor aliquet egestas, ipsum lectus rhoncus quam, in adipiscing eros sem ut tellus. Pellentesque feugiat tempus quam. Vivamus id dolor eget sapien consectetuer tempor. Aliquam erat volutpat. + +Nulla iaculis fermentum libero. Curabitur faucibus, massa malesuada cursus tincidunt, erat sem eleifend mauris, sed fringilla mi ante ac purus. Duis elementum lectus. Nunc ornare arcu eu tortor. Vestibulum vel dolor at purus lacinia fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas tincidunt, eros a egestas pellentesque, risus risus dictum libero, id aliquet metus justo in massa. Proin a tellus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed purus. Sed non pede. Aenean massa sapien, sodales sit amet, consequat dictum, eleifend vitae, tortor. Donec ultrices lacinia elit. + +Morbi adipiscing sodales dolor. Ut ullamcorper ultricies est. In venenatis tempus augue. Suspendisse tortor dolor, accumsan et, suscipit a, tincidunt ut, libero. Aliquam scelerisque magna sed felis. Quisque ut nunc a magna vulputate placerat. Aliquam rhoncus vehicula dui. Sed tortor. Nullam sit amet diam. Nunc sed eros. Sed et odio tincidunt elit gravida convallis. Curabitur quis tortor a lacus semper varius. Mauris at augue non mi sollicitudin aliquam. Integer ullamcorper. Pellentesque suscipit quam non purus. Aliquam ac eros at arcu ullamcorper consectetuer. Suspendisse pretium mattis leo. + +Duis at nunc. Sed dolor est, varius ac, porta et, tincidunt hendrerit, risus. Vivamus ut magna. Praesent ut mauris. In purus lacus, mattis sed, vestibulum nec, tempor at, nisl. Cras ullamcorper venenatis tellus. Ut dolor. Maecenas malesuada, pede a pulvinar mattis, arcu diam vehicula risus, quis porttitor augue massa in velit. Nunc congue. Morbi velit metus, rhoncus et, aliquam consectetuer, ultricies malesuada, ligula. Sed velit nisl, sagittis vitae, pharetra a, posuere sed, massa. Nulla facilisi. In varius, ligula id lobortis sodales, augue orci fermentum tellus, eu pulvinar risus ligula a sapien. Morbi laoreet ipsum non mi. Nam cursus lorem ut mi. Vivamus magna enim, posuere non, semper quis, sodales eu, arcu. Etiam mi purus, pretium feugiat, varius sed, pellentesque eget, ligula. In leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vitae orci eu orci sollicitudin feugiat. + +Praesent purus massa, euismod vitae, tempus nec, consequat hendrerit, metus. Aenean felis est, egestas vitae, accumsan eget, pellentesque in, sapien. Duis dapibus pede non sapien. Nunc urna. Integer vel libero. Duis augue arcu, dapibus non, facilisis vitae, posuere ut, eros. Donec vitae nunc sit amet arcu imperdiet dictum. Morbi eleifend, lorem eu consectetuer vestibulum, diam nunc ornare arcu, ac tempor felis dolor eget eros. Phasellus massa sem, sollicitudin ac, sodales gravida, luctus a, quam. Nam neque quam, viverra at, venenatis quis, sagittis non, enim. + +Nulla facilisi. Pellentesque egestas lacinia est. Sed tincidunt, pede sed tincidunt vestibulum, urna dolor adipiscing purus, vitae fringilla felis elit in nibh. Nulla sed nisi. Mauris suscipit scelerisque arcu. Etiam non enim vel eros accumsan malesuada. Nunc tincidunt commodo mauris. In tincidunt risus quis urna. Nulla diam tortor, aliquet et, tincidunt quis, sollicitudin ac, tortor. Cras nisl neque, vulputate suscipit, molestie quis, pulvinar at, nulla. Nullam ac metus nec odio posuere varius. Cras sed pede nec dui posuere bibendum. Duis euismod ullamcorper libero. Aliquam faucibus pulvinar turpis. + +In ut neque id nunc feugiat commodo. Curabitur dignissim, felis at sollicitudin lacinia, enim elit suscipit neque, sed luctus lorem ipsum in leo. Duis dapibus, odio quis auctor commodo, nisl odio mattis tellus, nec tincidunt turpis diam in arcu. Curabitur a sem. Nullam volutpat magna. Pellentesque sagittis, neque consequat pretium cursus, dolor lacus consectetuer arcu, sed laoreet est urna et metus. Suspendisse placerat, dui a porta tempor, lorem dui lobortis neque, sed venenatis diam enim id eros. Etiam et nisl non lectus faucibus consectetuer. Morbi scelerisque, sem nec tempus ullamcorper, ipsum diam feugiat lorem, a fringilla sapien elit quis nibh. Nullam diam urna, viverra sed, pharetra rhoncus, tincidunt vel, orci. Integer accumsan mattis erat. Nam dictum. Mauris nec leo. Nulla iaculis. Nulla nisl mi, dapibus quis, vehicula a, cursus eget, odio. + +Phasellus dapibus euismod nibh. Vivamus imperdiet ante in ligula. Pellentesque accumsan. In imperdiet, dui a auctor fringilla, metus nisi cursus dolor, vel luctus ligula lorem vitae mauris. Praesent mattis vestibulum elit. Aliquam enim lacus, pulvinar non, lacinia sit amet, eleifend non, velit. Vestibulum ac leo. Mauris imperdiet justo ac lectus. Sed molestie lectus sed dui. Sed fermentum tempus mauris. Nam ornare orci ac tellus. Ut malesuada, lacus id lacinia accumsan, diam elit adipiscing metus, et bibendum sapien nibh blandit orci. Suspendisse ipsum tellus, sagittis quis, vestibulum non, vulputate eu, eros. Praesent at nulla id pede scelerisque ultricies. Cras blandit pretium tellus. Maecenas dapibus condimentum augue. Phasellus tincidunt pharetra lorem. Morbi non eros. Sed tempor, nisl a tincidunt tincidunt, eros diam dictum sem, vel dignissim ante diam sed magna. Praesent non ligula id metus molestie consectetuer. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse vel mi. Curabitur ante nulla, rutrum a, convallis vel, vehicula ac, nunc. Nunc sagittis, enim sit amet auctor rutrum, mauris arcu vulputate neque, et euismod est felis quis ante. Vestibulum turpis tellus, hendrerit in, lacinia commodo, ullamcorper gravida, risus. Mauris rhoncus lacinia risus. Maecenas sollicitudin erat vitae nunc. Praesent pretium pellentesque augue. Donec interdum. Praesent ac eros vitae erat lobortis fringilla. Aenean consequat tellus. Nulla accumsan bibendum felis. Maecenas pretium ante id nisi. Aenean mi arcu, semper sed, mattis eu, venenatis sit amet, arcu. Donec aliquet euismod leo. Proin magna justo, tristique a, semper ac, sollicitudin a, ligula. Morbi velit. Aliquam vel nisi. + +In a lorem ut nunc feugiat congue. Donec fermentum bibendum dui. Proin varius est quis velit. Donec aliquet sem accumsan mi. Sed placerat. Nullam ac nisi a massa lobortis suscipit. Nunc id leo. Aliquam et massa. Nullam vestibulum elementum metus. In consectetuer nisi vel justo. Maecenas eget purus sed massa varius pellentesque. Phasellus faucibus felis quis felis. Aenean odio arcu, blandit quis, facilisis in, imperdiet eu, lorem. Nam posuere pulvinar mi. Fusce tristique, mauris et consectetuer ultricies, mauris lectus tempor justo, at fringilla est est sed nisi. Quisque faucibus. Sed in tortor tincidunt est lacinia iaculis. Maecenas a massa. Pellentesque a nibh at purus porta hendrerit. + +Nullam turpis. Fusce ac sem sed odio pellentesque imperdiet. Curabitur in arcu. Praesent lacus lacus, feugiat id, pulvinar in, tincidunt sed, neque. Maecenas viverra odio eget tortor. Integer aliquam, lorem rutrum venenatis dignissim, ligula magna malesuada arcu, vel feugiat lorem ipsum quis massa. Morbi ante. Vestibulum mauris libero, ullamcorper quis, ultrices quis, facilisis non, massa. Maecenas imperdiet. Aliquam erat volutpat. Pellentesque dignissim gravida lectus. In nibh odio, auctor eget, dapibus quis, dignissim venenatis, arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis pellentesque ligula quis massa. Curabitur condimentum, justo eget ornare luctus, lorem ligula sagittis pede, a porta nunc nunc in neque. Quisque felis mauris, condimentum vitae, auctor vitae, tincidunt quis, pede. Nunc lacinia ante in leo. Pellentesque libero. Aenean a ligula et nunc vestibulum consectetuer. + +Fusce ornare. Praesent id urna. Integer venenatis, quam non sagittis accumsan, ante nibh sagittis augue, sollicitudin adipiscing dolor velit eu erat. Proin quis enim eu purus vehicula aliquam. Nulla vel enim vel elit sollicitudin fringilla. Aliquam erat volutpat. Sed suscipit felis ut turpis. Etiam rutrum risus imperdiet est. Aliquam a tellus at tellus commodo dapibus. Mauris rutrum magna et odio. In at dolor. Curabitur vehicula lectus in tortor. Fusce justo purus, luctus vitae, mollis in, pharetra ac, purus. Nullam posuere interdum justo. Curabitur vitae lacus vel leo congue pulvinar. + +Aenean eleifend nibh varius tortor. Suspendisse vel eros. Proin nec diam a tortor ultrices ornare. Aliquam scelerisque feugiat justo. Vivamus ante urna, adipiscing vitae, porttitor eu, sodales et, felis. Suspendisse potenti. Curabitur ac massa in nisl sagittis mollis. Nam quam ligula, consectetuer eget, iaculis at, varius eu, leo. Duis dolor ligula, tincidunt at, ullamcorper sed, accumsan aliquam, ligula. Phasellus vulputate, lorem at tincidunt pharetra, risus lectus lacinia magna, quis rutrum enim magna at sem. In hac habitasse platea dictumst. Duis id sem a mauris sollicitudin tincidunt. Etiam eu purus eu arcu fringilla adipiscing. Vivamus ornare tempus diam. Proin turpis quam, lacinia non, egestas at, commodo eget, pede. Praesent vulputate risus in est. Nulla facilisi. + +Ut elementum lacinia purus. Proin vitae arcu ac nulla convallis aliquam. Nulla congue, libero id pellentesque mattis, quam lectus porttitor diam, a scelerisque dui libero in sapien. Nullam felis diam, vehicula vel, molestie ut, vestibulum aliquam, sapien. Donec convallis, est ut elementum volutpat, mauris ipsum gravida sem, commodo facilisis sapien lectus semper lectus. Quisque porttitor eros ut nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam mattis risus sed odio. Vestibulum et odio. In hac habitasse platea dictumst. Nam tristique massa ut ligula. Quisque nibh tellus, vehicula sit amet, adipiscing at, convallis nec, ligula. Vestibulum pretium, mi nec fringilla bibendum, dui nunc sodales pede, a semper magna nibh non diam. Donec massa nunc, viverra vel, consectetuer porta, dapibus non, ipsum. Duis nisl mauris, cursus vel, semper non, sollicitudin bibendum, felis. Vestibulum eu neque. + +Cras nec dolor. Donec laoreet tempus lectus. Cras sed tortor interdum lacus eleifend dignissim. Maecenas sit amet elit. Nullam quis dolor vel dui pharetra luctus. In sit amet quam sit amet pede ultrices ultrices. Maecenas diam. Integer urna. Curabitur dictum, velit sed placerat suscipit, erat turpis fermentum justo, sed interdum neque sem et nibh. Vivamus consequat convallis magna. Nam aliquam, est ac bibendum commodo, magna est dictum mi, vitae malesuada elit magna vitae odio. Maecenas tempor vulputate tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus dui. Etiam accumsan pede congue tortor. + +Morbi tempor libero ac lorem. In aliquet varius magna. In arcu. Phasellus odio. Fusce tincidunt aliquet felis. Quisque velit. Sed luctus. Aliquam feugiat fringilla mi. Aliquam molestie viverra risus. Proin arcu. Vestibulum lobortis tempus nisi. Praesent a arcu in velit viverra rutrum. + +In sed lectus. Donec risus dolor, blandit sit amet, elementum convallis, pharetra quis, pede. Integer ornare. Aenean egestas dapibus justo. Sed quam leo, posuere at, elementum vitae, commodo eget, est. Aliquam molestie rhoncus enim. Curabitur iaculis ultrices pede. Morbi aliquet rutrum lacus. Aliquam quam. Sed commodo, turpis in pharetra posuere, mi risus imperdiet erat, a vestibulum massa tellus vehicula sem. Mauris fringilla ultrices nunc. Nam nisi enim, eleifend sit amet, ultrices sed, fermentum non, augue. Proin congue lobortis nisi. Maecenas hendrerit. Nam sed nisl. Nunc elementum odio eu risus. In metus. Phasellus gravida pretium ligula. Nulla vitae neque. Nam nisi tortor, ornare non, blandit at, cursus eu, tortor. + +Duis bibendum ipsum in nunc cursus molestie. Nunc orci. Nullam nec ante non est dignissim viverra. Mauris blandit, velit id feugiat pretium, elit magna pellentesque dolor, at sagittis lacus velit egestas magna. Pellentesque cursus, diam consectetuer sagittis fringilla, tortor nisi adipiscing nunc, eu varius lacus risus ac elit. Mauris id nisi quis leo euismod venenatis. Pellentesque ac ante. Mauris arcu sapien, tempor at, porttitor id, condimentum ut, dui. Etiam fermentum ultricies augue. Cras ut eros at justo ultricies iaculis. Duis dignissim, nisl et facilisis fermentum, erat purus molestie tellus, quis tempus ipsum lectus at elit. Nulla vitae lorem. + +Aenean vel sem et diam semper congue. In bibendum diam quis tellus. Nunc facilisis ultricies nibh. Cras nunc enim, feugiat sed, ultrices vitae, sagittis vitae, ipsum. Fusce vitae nulla. Donec pellentesque, velit in porttitor eleifend, est neque lobortis velit, sit amet rutrum ante tortor nec dolor. Donec vehicula. Nulla facilisi. Sed egestas ultrices nibh. Donec elit lectus, convallis porttitor, aliquet dapibus, feugiat eget, ligula. Sed consectetuer justo. Maecenas a sapien sit amet nisi dapibus lobortis. Vivamus luctus lorem non nulla. Sed eget erat vitae libero interdum posuere. Cras pulvinar. Nullam imperdiet, dolor tempor dignissim blandit, dui sapien rhoncus neque, id malesuada augue magna sit amet urna. Duis sed mauris. + +Morbi accumsan. Sed mauris augue, fringilla non, auctor ut, auctor et, orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus ut pede. Donec viverra enim vel lorem. Pellentesque neque mauris, interdum eu, venenatis id, condimentum eu, sapien. Donec ipsum arcu, lacinia adipiscing, laoreet et, cursus vel, velit. Ut sagittis mauris quis risus. Integer eu odio vitae lacus viverra accumsan. Morbi leo ante, dignissim sed, varius quis, volutpat vitae, nisi. Nulla placerat interdum elit. Donec neque dui, sagittis vitae, sollicitudin quis, commodo vitae, neque. Nulla quis ligula ornare ligula dictum ornare. Mauris rutrum rutrum neque. Aenean vehicula tempus est. Donec varius scelerisque pede. Donec placerat vulputate leo. Nullam nunc nisl, posuere non, feugiat vitae, pellentesque quis, mauris. In dui neque, cursus eget, sagittis eget, dapibus vitae, mi. Proin eget est. + +Fusce porta est. Mauris magna. Aliquam ipsum lacus, ultricies id, vestibulum luctus, accumsan ut, ante. Sed mauris. Sed adipiscing leo sit amet magna. Suspendisse potenti. Nunc massa elit, fringilla eget, egestas vitae, luctus vitae, dolor. Phasellus quis nulla eu nisi interdum sollicitudin. Nullam id tellus. Integer iaculis dolor ac purus. Sed vel mi. Curabitur non magna sit amet justo condimentum vulputate. Quisque tincidunt pede eu nisl. Vivamus lobortis. Nunc metus metus, congue sed, tincidunt sed, pretium at, odio. Donec a arcu. In sem justo, vehicula sed, varius id, volutpat at, risus. Praesent iaculis massa. In arcu elit, hendrerit eget, ullamcorper in, porta id, tellus. Donec sagittis hendrerit diam. + +Suspendisse potenti. Sed et diam et augue sagittis lobortis. Phasellus dolor. Ut et arcu eget ante tempor posuere. Aliquam fermentum scelerisque dui. Mauris at purus. Donec erat sem, vestibulum nec, faucibus ac, mattis a, leo. Suspendisse adipiscing lacinia sem. Nullam orci arcu, dictum et, faucibus viverra, dapibus et, neque. Cras nunc diam, adipiscing non, sollicitudin in, interdum vel, massa. Mauris sagittis, justo at tristique tempus, mauris mauris aliquam ante, sit amet posuere diam dui eget ligula. In dignissim, nisl ut lacinia condimentum, erat justo porttitor nulla, non gravida ligula magna eget massa. Vestibulum vitae ligula at mi vestibulum suscipit. Duis laoreet. Nulla commodo libero sit amet lorem. Ut elementum sem. Integer vel dolor. Nam facilisis mi quis sem ultrices sagittis. Sed quis quam at metus molestie bibendum. + +Proin dui enim, lacinia a, feugiat ac, placerat vitae, pede. Quisque egestas, leo eget aliquam pretium, libero justo tincidunt eros, ut egestas augue pede elementum nibh. Curabitur mollis sodales enim. Donec augue. Phasellus id ipsum posuere dui pretium faucibus. Mauris luctus ante semper nisi interdum adipiscing. Duis dapibus, odio quis viverra rhoncus, justo quam bibendum dolor, id dapibus velit erat vel erat. Fusce sit amet nisl venenatis quam ultrices condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec rhoncus scelerisque ligula. Vestibulum mi odio, accumsan et, adipiscing eget, ornare ut, quam. Nullam blandit molestie mauris. Curabitur dignissim mauris et lorem. Suspendisse a justo. Nam mattis faucibus arcu. Duis blandit enim non massa. + +Nullam lorem. In hac habitasse platea dictumst. Mauris consectetuer posuere mauris. Maecenas tincidunt mauris in eros. Nulla eu metus eu orci sollicitudin faucibus. Suspendisse aliquam mauris id est. Cras blandit dui et urna. Nulla arcu. Sed a urna. Nulla dapibus vehicula tortor. Donec risus. Sed quam metus, egestas eu, cursus ut, viverra non, odio. Ut justo justo, malesuada sit amet, blandit suscipit, molestie in, justo. Vestibulum consequat, quam ac feugiat tincidunt, ipsum libero eleifend odio, non eleifend pede ipsum non ante. Nullam a metus. + +Nam ac nisi at felis cursus mattis. Pellentesque consequat sem quis orci. Quisque tempus. Aenean imperdiet molestie pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eu tellus. Nulla diam eros, sodales ut, sodales nec, tincidunt ac, nunc. Nunc lacinia faucibus ipsum. Vivamus vel neque in erat fermentum luctus. Nulla eget metus nec augue bibendum placerat. Vivamus tempus. Praesent congue ornare ipsum. Etiam mattis feugiat justo. + +Aliquam dui. Aenean commodo tortor vitae nulla. Morbi et ipsum. Mauris ac ipsum. Nam vel risus ut lectus mollis viverra. Curabitur elementum mollis est. Nullam elit. Vestibulum suscipit pretium enim. Vestibulum ut massa. Proin nec felis. Maecenas gravida, arcu nec consequat sagittis, eros tellus scelerisque mauris, vitae accumsan quam quam ut nunc. Integer eget ante eu velit laoreet malesuada. Nunc sagittis, mauris vitae pharetra volutpat, tellus tellus eleifend eros, sit amet rutrum ipsum nisi a velit. Praesent varius leo eu erat. Vivamus consequat placerat purus. Donec pretium elementum nibh. Proin at elit non sem aliquet mattis. Sed ullamcorper ipsum sit amet elit. + +Mauris in metus. Suspendisse magna lorem, faucibus vel, tincidunt quis, scelerisque non, tellus. Fusce quis lorem. Proin a lacus sit amet mauris iaculis pulvinar. Suspendisse rhoncus eros nec mi. Praesent euismod, turpis vitae rutrum pretium, odio metus volutpat neque, eget tempus sapien neque sed erat. Donec fermentum purus at lectus. Nullam sem. Fusce vel mi quis erat lobortis posuere. Aenean eget urna. Suspendisse ligula. Duis in nisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Curabitur vulputate lectus id pede. Phasellus eu velit. Etiam venenatis adipiscing nibh. Aliquam cursus pulvinar tellus. Vestibulum neque. Mauris nec justo et erat semper pellentesque. Fusce mattis dictum dolor. Etiam eget purus eu massa varius elementum. Pellentesque massa. Ut ultricies diam sed ipsum. Nullam diam. Pellentesque id magna id libero tristique aliquam. + +Ut eleifend, purus id placerat venenatis, urna augue aliquet ligula, in ultricies leo risus et tellus. Mauris et nulla id urna tristique tempus. Ut facilisis, urna eu vestibulum rhoncus, lacus eros consectetuer metus, et rutrum dui lectus in purus. Nunc vel nisl non ipsum tincidunt mollis. Nam quam lacus, ornare vitae, rhoncus non, congue sed, odio. Proin nibh dui, porta vel, venenatis non, pellentesque ut, nisi. Sed tristique felis a magna. Suspendisse eget tellus. Cras gravida imperdiet velit. Integer hendrerit risus. Proin orci. Aliquam ullamcorper mauris quis mauris. Nunc lacinia vestibulum metus. Duis tellus. Nullam faucibus, leo ac vulputate sollicitudin, leo dolor faucibus erat, quis bibendum orci odio non arcu. + +Nullam accumsan mattis dolor. Donec et dui. Praesent a felis mollis lacus semper lacinia. Curabitur pellentesque luctus est. Proin nulla dui, condimentum vel, faucibus non, interdum ac, erat. Maecenas scelerisque, lectus id volutpat accumsan, sapien tortor pellentesque dui, sed semper magna sem ut leo. Proin nulla. Nullam dapibus ullamcorper sem. Suspendisse vehicula metus in nunc. Pellentesque non quam vel arcu ultrices ullamcorper. Phasellus quis felis sit amet tellus ullamcorper fermentum. Sed vehicula sollicitudin urna. Curabitur pharetra scelerisque risus. Pellentesque id massa quis metus aliquam imperdiet. In nunc lacus, feugiat in, gravida eget, venenatis ut, tellus. Suspendisse potenti. Nam consequat adipiscing dui. In nulla nisi, feugiat ut, fermentum vel, gravida nec, tortor. In sed augue. + +Etiam ullamcorper augue at enim. Integer dignissim. Aliquam pulvinar congue nulla. Morbi enim massa, fringilla a, accumsan eget, condimentum nec, erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean pharetra. Etiam porttitor purus a metus. Aliquam interdum sem eget justo. Quisque volutpat luctus est. Aenean augue. Phasellus dui lectus, ultrices nec, commodo vel, auctor vel, nisi. Ut ultrices pellentesque nisi. Integer ac velit et sem imperdiet luctus. Fusce vitae turpis id augue mollis consectetuer. + +Maecenas nec lacus. Maecenas condimentum odio eu felis. Mauris ut nisl viverra erat faucibus adipiscing. Etiam egestas. Nunc et dolor vitae risus dignissim commodo. Morbi lectus velit, tincidunt nec, aliquet vel, mattis vitae, ligula. Maecenas ultricies semper dolor. Suspendisse malesuada. Integer mattis elit. Donec accumsan, lacus facilisis varius tempus, nulla elit porta erat, et rutrum elit sem sit amet dui. + +Maecenas mollis mi non nulla. Vivamus turpis. Suspendisse a metus. In quis mi in turpis congue auctor. Maecenas lacus. Suspendisse sollicitudin. Phasellus porta nunc non nisl pulvinar egestas. Sed nulla. Vestibulum ac mi. Mauris ultricies condimentum neque. Nulla tempus justo vel massa. Nulla suscipit congue arcu. Praesent id turpis. Mauris nibh pede, euismod semper, molestie ac, rhoncus vitae, ante. Maecenas erat felis, viverra sollicitudin, sagittis eget, pellentesque nec, orci. Fusce ultrices consequat lacus. Aliquam erat magna, feugiat at, viverra a, mollis non, turpis. + +Donec mi. Nam dictum pellentesque sem. Donec mollis rhoncus elit. Phasellus rhoncus pede sit amet risus. Donec eget augue. Maecenas non lectus. Phasellus sollicitudin nisi nec felis. Aliquam pretium, est eget semper convallis, nibh nunc sollicitudin purus, id tempor pede dui vel magna. Vivamus ac lorem. Etiam nisl tortor, adipiscing dictum, elementum in, facilisis sed, nibh. Proin mauris. Proin rutrum massa eget sem. Curabitur tempor adipiscing elit. Curabitur purus tellus, fermentum eget, aliquet vitae, convallis ac, mauris. + +Integer consequat velit eu eros tincidunt vehicula. Nullam lorem sapien, rhoncus non, mattis quis, ultricies sit amet, enim. Curabitur commodo, libero in euismod suscipit, sem purus fringilla enim, ac molestie tortor orci et velit. Donec pede. Etiam placerat condimentum turpis. Phasellus egestas enim nec magna. Vivamus condimentum, nulla vel luctus tristique, eros risus vestibulum nulla, in vehicula arcu ipsum at felis. Donec aliquam elit at augue. Quisque a eros eu ligula accumsan dictum. Etiam vehicula turpis quis libero. Aliquam non mi. Donec et leo. Proin leo libero, aliquam tincidunt, congue nec, adipiscing porta, enim. Nulla lobortis, tortor sit amet imperdiet ullamcorper, dolor orci malesuada pede, sed gravida nibh urna vel lorem. Sed pharetra malesuada eros. Quisque euismod aliquet erat. Suspendisse aliquet mattis purus. + +Nunc id nulla quis justo congue sollicitudin. Praesent erat turpis, rhoncus eu, pretium eu, pellentesque a, nibh. Vivamus tempus. Cras nec risus at turpis imperdiet lobortis. Ut mattis. Maecenas est felis, pellentesque non, imperdiet sed, eleifend tincidunt, lorem. In tincidunt. Sed vel leo. Donec et urna in turpis hendrerit blandit. Donec condimentum accumsan est. Ut pharetra, metus vitae mattis consectetuer, leo quam vulputate odio, nec laoreet nisi velit eu erat. Integer lectus augue, egestas in, interdum eu, venenatis vel, sapien. Quisque et est vitae eros laoreet lobortis. Nullam ut risus non nulla placerat adipiscing. Praesent dapibus. Etiam a felis. Ut sodales consequat mauris. Duis lorem felis, luctus a, tristique in, molestie at, risus. Sed vehicula bibendum tellus. Nam consequat euismod lacus. + +Aenean tortor elit, gravida nec, fermentum eu, lobortis id, ipsum. Maecenas eu purus. Cras ac turpis ut nisi iaculis rhoncus. Nulla purus metus, dignissim nec, tincidunt vitae, dapibus eu, nibh. Fusce lobortis, nunc at viverra eleifend, justo turpis scelerisque eros, ac pellentesque metus nisl at purus. Sed elementum tellus sed enim interdum blandit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer ultricies aliquet odio. Mauris eget nunc a ipsum ultrices sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean accumsan. Donec sapien lectus, congue at, porta id, hendrerit vitae, nisl. Curabitur vel quam vel neque accumsan laoreet. Morbi sapien est, pretium in, consectetuer ac, mollis ut, libero. Donec tincidunt adipiscing metus. Nunc vestibulum egestas augue. Donec scelerisque dui ut sem. Suspendisse vel metus id est molestie iaculis. + +Vivamus pharetra, elit eu malesuada blandit, diam tortor mollis dui, sed pulvinar massa nunc et magna. Sed placerat elit auctor tortor. Nulla ac erat. Pellentesque consectetuer, dui convallis tincidunt condimentum, sem odio volutpat libero, non elementum felis neque nec odio. Maecenas hendrerit eros id diam. Mauris vel purus ac orci convallis convallis. Sed sit amet lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque dictum varius lacus. Mauris eget nisl. Suspendisse placerat, nulla non ornare dignissim, nisl diam sagittis tellus, in semper nisi dolor at nibh. Duis ullamcorper viverra felis. Integer a tellus. Suspendisse eget nunc. Aenean diam est, accumsan id, suscipit interdum, fringilla vitae, justo. Proin pede. Maecenas at neque in neque vestibulum eleifend. + +Vestibulum nulla lorem, porttitor eget, euismod ac, aliquam at, nisl. Maecenas et est eget massa varius lobortis. In mi. Duis porttitor fermentum purus. Donec cursus imperdiet ligula. Morbi et ligula et ante molestie vehicula. Mauris sed dolor. Sed imperdiet felis ut sem. Sed vitae neque elementum leo auctor fermentum. Duis feugiat ullamcorper erat. Aenean purus. Morbi fermentum vestibulum est. Pellentesque venenatis mauris. Phasellus pulvinar. Integer ipsum lectus, iaculis a, lacinia id, accumsan id, arcu. Phasellus at est. Fusce neque quam, ultricies id, iaculis vel, dapibus vitae, lacus. In lobortis convallis ante. Nulla nunc purus, vulputate in, hendrerit et, blandit et, ligula. + +Pellentesque leo metus, sagittis in, molestie vitae, dictum in, pede. Morbi pretium felis nec quam. Pellentesque mattis ante sed quam sagittis dapibus. Suspendisse sapien. Praesent bibendum iaculis tortor. Duis a nisl. Aenean mi. Donec dictum arcu in est. Morbi interdum vulputate ipsum. Aenean sit amet magna non nisl tristique posuere. Phasellus velit metus, tempor ac, fermentum eget, condimentum non, velit. Vestibulum sit posuere. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras aliquet massa nec dui. Cras arcu nunc, hendrerit ac, eleifend eu, ullamcorper nec, tellus. Sed pharetra purus sit amet quam. Curabitur mollis. Nam vitae pede. Etiam risus massa, vehicula sit amet, pharetra nec, sollicitudin ut, dui. Donec egestas justo at quam. Proin nisl risus, vestibulum nec, pretium vitae, tristique ac, lorem. Aliquam erat volutpat. Cras sed nibh. Pellentesque sollicitudin euismod augue. + +Etiam fringilla sollicitudin orci. Mauris cursus elit quis lacus. Cras tortor. In adipiscing, lectus id auctor vestibulum, neque pede accumsan dolor, non imperdiet magna diam accumsan velit. Suspendisse at libero ut nisi blandit sagittis. Phasellus non mauris. Fusce elementum sagittis sem. Suspendisse aliquam eleifend tellus. Proin ligula lorem, imperdiet quis, venenatis id, iaculis mollis, nisl. Etiam convallis pede at massa. Morbi accumsan dui et mauris. + +Sed sed orci. Nunc purus. Suspendisse potenti. Ut luctus fringilla mauris. Donec nibh. Phasellus porta. Phasellus sit amet odio sed magna sodales pharetra. Cras lectus. Suspendisse libero ipsum, commodo nec, facilisis in, suscipit lobortis, ligula. Duis massa nulla, semper et, consequat nec, pharetra eu, elit. Vivamus ultricies aliquam odio. Vestibulum sit amet massa. Sed consequat lacus sed urna. Etiam faucibus felis vel orci. Phasellus ullamcorper. Aenean consectetuer lacus at libero. + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis facilisis, ligula vitae condimentum scelerisque, velit orci gravida felis, vel ultricies quam mi non diam. Vivamus auctor metus non libero. Praesent ligula nisi, commodo condimentum, molestie et, viverra et, justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus sollicitudin. Nunc blandit cursus ipsum. Aenean nec ligula ut tellus sodales mattis. Integer sem. Aliquam id ligula. Sed tortor mauris, blandit vitae, cursus vel, elementum et, nulla. Aliquam scelerisque metus et nisl. Duis adipiscing magna at neque. Quisque vulputate eleifend nunc. Aliquam eget elit. Phasellus dui odio, bibendum sagittis, vestibulum id, dignissim imperdiet, orci. Nullam eu felis non nunc lacinia sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Suspendisse pellentesque, libero mattis ultricies accumsan, tortor tortor malesuada sem, et sodales libero odio ac ipsum. Vivamus quis magna nec est suscipit lobortis. Cras tempus posuere nunc. Quisque ut enim a felis egestas semper. Sed pharetra mattis neque. Fusce turpis nunc, congue sed, consequat non, congue sed, nulla. Suspendisse varius lorem id risus porta vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce sed purus. In a felis. Integer egestas auctor orci. Mauris ultrices suscipit nisl. Nullam purus. + +Cras tempor adipiscing ipsum. Ut quis mi. Maecenas in justo ut nulla congue pharetra. Pellentesque ut libero eu dolor venenatis suscipit. Praesent feugiat consectetuer nibh. Morbi faucibus sem non felis. In hendrerit arcu ac massa. In accumsan ultrices mi. Proin malesuada auctor felis. Curabitur interdum. Sed diam ipsum, ultricies in, tempor sit amet, viverra imperdiet, elit. Morbi molestie nisi. Mauris ipsum. Fusce dictum mollis magna. Duis commodo dignissim nulla. Vestibulum augue enim, ultricies quis, iaculis nec, tincidunt vitae, diam. Mauris lacinia tempus ipsum. Sed at mauris. Ut lorem. Donec libero. + +Duis iaculis lacinia lectus. Aenean convallis eros ac ante. Sed quis orci nec risus auctor fringilla. Phasellus facilisis elementum nisi. In hac habitasse platea dictumst. Nunc porta lacus nec ante. Morbi mauris erat, adipiscing in, pulvinar nec, lobortis nec, odio. Ut eleifend lectus sed quam. Nullam mollis. In non turpis et nisl hendrerit blandit. Duis elementum. Nunc nec libero. Suspendisse vestibulum risus non pede. Morbi imperdiet odio sit amet libero. Sed sed massa vitae ipsum mattis tincidunt. Nulla nec tortor vitae libero volutpat tempus. Donec aliquam. + +Duis sed nunc. Curabitur turpis nulla, vehicula sed, luctus quis, elementum eget, felis. Maecenas et purus. Maecenas leo tellus, tincidunt a, facilisis vitae, lobortis sit amet, velit. Donec convallis sapien. Maecenas mollis odio eu nibh. Etiam gravida. Integer molestie, sapien eu molestie lacinia, nunc nibh aliquam ligula, eu sagittis tellus erat sollicitudin odio. Duis et risus. Phasellus nisi neque, placerat nec, condimentum non, ultrices eu, sem. Ut pede. Etiam nulla metus, volutpat id, convallis sed, suscipit vel, urna. Donec vel elit. Ut leo neque, venenatis faucibus, lacinia nec, tincidunt eu, enim. Cras id dui a libero pharetra dignissim. Donec eros leo, porta quis, laoreet ut, pellentesque volutpat, lectus. + +Nullam blandit. Aliquam erat volutpat. Fusce adipiscing enim. Suspendisse non dui quis ligula porta vestibulum. Donec eu tellus vel lorem pretium porttitor. Praesent luctus. Aliquam ac eros in massa dapibus tincidunt. Donec ut magna. Etiam auctor lacus sit amet lacus. Sed ultricies ipsum nec elit. Quisque a est in purus suscipit tristique. + +Aenean sed dui vel dolor pulvinar laoreet. Vivamus vehicula lorem in pede. Vivamus et diam. Integer ac odio vel diam hendrerit bibendum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a nisi. Phasellus tincidunt dui vitae augue. Duis faucibus, dui interdum fringilla tincidunt, odio elit vestibulum libero, ac molestie magna lectus id lacus. Aenean ligula. Nulla facilisi. + +Fusce vel sem eu velit fringilla ornare. Sed feugiat tincidunt felis. Nullam felis mi, euismod sit amet, mollis at, sodales eget, augue. Nam imperdiet nibh at velit. Sed ut erat. In dui. Nulla facilisi. Nullam augue libero, tincidunt nec, pretium eu, pulvinar in, dui. Morbi vitae felis. Pellentesque vel justo vel velit sagittis malesuada. Proin vehicula blandit massa. Etiam tincidunt pharetra urna. In metus est, auctor nec, blandit a, cursus nec, quam. Mauris ac metus a libero congue faucibus. Mauris mauris dolor, sodales in, cursus ut, sodales rutrum, eros. Quisque mauris eros, sagittis vitae, lobortis ut, eleifend id, nisi. + +Aenean neque. Vestibulum egestas pellentesque ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus sagittis justo vel risus. Sed pretium neque vitae urna. Pellentesque congue libero id lorem. Mauris leo lorem, blandit sit amet, convallis quis, consectetuer sed, eros. Mauris tincidunt, enim a gravida euismod, magna nulla fermentum libero, viverra egestas velit quam et tortor. Vivamus aliquet massa vitae justo. Nulla congue lacus ac elit. + +Phasellus commodo quam vel ligula. Proin non metus at eros pulvinar luctus. Mauris diam lorem, posuere quis, gravida et, tincidunt nec, ligula. Sed diam. Aliquam elit lectus, hendrerit ut, imperdiet sit amet, pretium sit amet, ipsum. Mauris vehicula nisl in dui. Curabitur eget quam ut magna elementum fermentum. Mauris scelerisque. Quisque laoreet. Etiam tempus turpis. Pellentesque augue quam, hendrerit sed, tincidunt at, pharetra at, nisl. Aliquam lacus. Suspendisse potenti. Aenean velit libero, ultrices in, lacinia eu, luctus vel, ante. Etiam dictum mi in felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce gravida dapibus nisl. Cras vitae nisl. + +Maecenas dignissim, ligula non porta cursus, enim nunc malesuada sem, eu porttitor nulla urna eu quam. Fusce eros. Aliquam eros. Nam auctor. Nulla molestie porta est. Suspendisse potenti. Vivamus molestie lorem sed erat. Sed eget ipsum. Integer aliquam pulvinar nulla. Cras aliquet sem ut nunc. Fusce faucibus tempus lectus. Cras sodales, nisi ac facilisis ultrices, eros arcu dapibus sapien, et ultrices mauris tellus non dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras cursus varius metus. Ut turpis. Vivamus eget tortor. + +Sed laoreet, velit non accumsan cursus, nunc urna posuere justo, in dictum lectus pede id ante. Cras vulputate. Cras congue dui sed elit. Proin lacus sem, ultrices at, consequat in, tempor quis, metus. Proin vel arcu. Nam euismod hendrerit elit. Ut erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed posuere. Morbi eros urna, semper at, semper non, convallis quis, velit. Maecenas orci. Vestibulum lobortis tristique metus. Vestibulum lorem nulla, sollicitudin vitae, condimentum quis, auctor ut, dui. Vivamus vestibulum magna ut nisi. Curabitur eleifend dui vel nunc. Curabitur mauris lacus, malesuada sit amet, suscipit sed, rutrum luctus, tellus. Integer facilisis urna vitae lectus. + +Aenean quam leo, lobortis quis, malesuada eu, vulputate vitae, nisl. Praesent eget eros. Ut fermentum turpis id quam. Nam tortor. Praesent nec orci. Nulla bibendum adipiscing augue. Ut commodo, magna id malesuada gravida, augue odio malesuada mi, porta malesuada elit est vitae diam. Mauris non nulla. Suspendisse tincidunt, nunc ultricies porta venenatis, mi pede tincidunt libero, eget varius ante libero ut ligula. Curabitur pretium porttitor tortor. + +Maecenas vitae elit eget nisi dapibus dictum. Nunc in libero. Nulla dictum orci eu erat auctor lobortis. Phasellus risus. Suspendisse potenti. Suspendisse potenti. Praesent adipiscing consequat elit. Integer id augue. Praesent in justo nec magna dapibus pulvinar. Duis nisl. Suspendisse ac odio. Vivamus imperdiet. Donec non velit sit amet risus dignissim congue. Nam aliquet posuere velit. Cras turpis. Morbi malesuada dignissim mi. + +Sed leo neque, varius quis, venenatis sed, pharetra sed, est. Morbi blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam semper pellentesque mi. Ut vel lorem. Nunc mi tortor, laoreet at, faucibus eu, tincidunt sit amet, erat. Duis tempor malesuada ipsum. Phasellus aliquet. Donec et elit. Pellentesque purus. Vestibulum rutrum semper nibh. Nulla facilisi. Phasellus et enim sit amet ante vestibulum vehicula. Phasellus id nisl. Donec mollis leo at eros. Mauris pellentesque neque at purus. Morbi quis dolor at ipsum scelerisque sodales. Etiam volutpat turpis a metus. In hac habitasse platea dictumst. Nunc lorem lorem, vestibulum ac, euismod eget, ullamcorper dignissim, velit. + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ultrices, nibh vel aliquam vestibulum, eros enim venenatis dui, id iaculis enim nunc vel massa. Morbi eleifend orci et massa. Aliquam erat volutpat. Nulla mollis egestas turpis. In sodales nunc eget tortor. Sed ipsum eros, tempor quis, aliquet vitae, imperdiet non, lorem. Pellentesque quis elit id mi luctus dapibus. Sed nunc arcu, rhoncus nec, convallis quis, cursus at, neque. Mauris convallis purus at erat. Pellentesque vestibulum. Vivamus fringilla elit at arcu. Nullam aliquet enim nec arcu. Nam id tortor. Nulla quis nunc. Ut arcu. Suspendisse potenti. Pellentesque ullamcorper ligula id arcu. + +Nam non libero vitae nisl scelerisque fringilla. Quisque varius ante id metus rhoncus fringilla. Nulla facilisi. Praesent eleifend porttitor ligula. Etiam quis dolor non augue commodo auctor. Donec a mi. Vestibulum tempor. Donec felis urna, auctor at, cursus dictum, gravida id, arcu. Aenean dictum malesuada dolor. Vivamus mattis. Phasellus eu pede. Fusce adipiscing justo fringilla metus. Etiam ante. Integer mollis massa quis nunc. Integer dictum neque luctus enim. + +Sed eu libero. Integer tempor ligula in velit. Ut tincidunt lacinia sem. Nullam vel risus. Sed sodales ante a dolor. Curabitur eros. Sed sodales. Sed non metus. Vestibulum elementum faucibus ante. Nulla vel nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In hac habitasse platea dictumst. Nunc nec lorem ut ipsum lacinia iaculis. Duis erat. Aliquam erat. Cras iaculis. In hac habitasse platea dictumst. + +Nullam ante. Cras vitae est. Pellentesque vel metus a ligula dapibus mattis. Duis feugiat aliquet felis. Etiam id nisl quis est dignissim condimentum. Suspendisse potenti. Morbi velit lorem, ornare quis, pellentesque vel, placerat eget, tortor. Vestibulum tincidunt molestie libero. Nulla nulla enim, malesuada id, ullamcorper vitae, dictum at, purus. Donec dignissim odio ut enim. Suspendisse at lectus. + +Praesent lobortis augue vel lectus. Ut in ligula ut felis congue suscipit. Quisque dignissim tortor ut mi. Fusce magna nisi, eleifend ac, ornare vel, porttitor vitae, quam. Vestibulum sodales justo quis turpis. Fusce urna nisi, rhoncus quis, condimentum vel, dictum eu, nunc. Fusce sed nibh vitae odio posuere adipiscing. Sed porta elit quis dolor. Nam libero nulla, auctor sed, tincidunt quis, faucibus sit amet, mi. Quisque orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam id sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vel eros. + +Vivamus luctus lobortis leo. Suspendisse vel elit a enim ullamcorper posuere. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec quis pede mattis lectus mollis adipiscing. Sed accumsan posuere erat. Praesent euismod tincidunt felis. Donec mi. Ut commodo arcu lacinia tellus. Aliquam a libero quis lectus semper viverra. Curabitur lacinia mauris at tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sit amet magna molestie orci suscipit fringilla. Fusce pretium metus non sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed hendrerit. Nulla felis. Suspendisse potenti. Aliquam blandit tristique neque. Curabitur quis erat vel nunc accumsan mollis. + +Duis sagittis, tellus ut aliquam fringilla, dolor mi ullamcorper nisl, ut tristique pede elit sed mauris. Curabitur id felis. Donec pulvinar lacus et lectus. Aliquam vulputate vulputate metus. Curabitur magna felis, adipiscing ac, accumsan vel, molestie quis, quam. Mauris elit arcu, pretium vitae, mollis sit amet, sollicitudin ut, mi. Donec imperdiet dignissim mi. Nullam sit amet tortor. Aliquam neque nulla, venenatis a, porta in, placerat tempus, lacus. Quisque vestibulum dui et lacus. Proin dignissim consectetuer purus. Etiam gravida tortor in nunc. Ut tempor tristique tortor. Sed laoreet tincidunt quam. Vestibulum porta turpis ut elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nibh dui, feugiat nec, laoreet id, malesuada eget, nisi. Ut neque massa, vehicula eu, commodo non, ultricies vitae, purus. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris euismod, felis vel tempor aliquet, tortor mauris malesuada nunc, vel fermentum sem diam id dui. Nam rutrum sapien eget odio. Aliquam sed libero non mi faucibus tempus. Fusce hendrerit, diam non volutpat rutrum, erat metus venenatis ligula, non scelerisque pede ligula vel quam. Morbi rhoncus eros ac dui feugiat elementum. Duis eu libero et tellus congue viverra. Morbi quam quam, elementum sed, ullamcorper imperdiet, commodo non, odio. Nam aliquet egestas urna. Mauris odio felis, varius eu, lacinia eu, condimentum a, lectus. Sed justo massa, pulvinar id, varius a, porttitor nec, libero. Etiam varius. Curabitur sodales, odio at posuere semper, eros nibh tincidunt lectus, vel rutrum sapien nisi in ligula. Suspendisse eget arcu. Phasellus imperdiet est ac sapien. Donec nulla tortor, placerat vel, tempus a, lobortis vel, nibh. Aliquam varius nisi. Nulla et enim. Fusce convallis laoreet lacus. + +Phasellus ipsum dolor, molestie quis, condimentum in, commodo eu, diam. Quisque bibendum lacinia dui. Nullam blandit vulputate orci. Ut lacinia massa vel augue. Aliquam gravida, quam quis imperdiet imperdiet, tellus diam pharetra erat, at pharetra lacus nibh egestas magna. Nulla sagittis lorem ut lorem. Duis condimentum, dui vitae aliquam posuere, diam quam convallis velit, ut gravida leo ipsum non risus. Ut fermentum sollicitudin erat. Donec sagittis scelerisque felis. Nunc arcu. Etiam tempus, magna sit amet suscipit euismod, eros sem rutrum dui, vitae sagittis nibh purus non lacus. Sed mollis arcu eget dolor. Donec ornare, arcu sit amet fermentum vulputate, risus enim fermentum libero, a lacinia dolor mi non velit. Etiam lobortis purus a elit. Nunc nulla dui, mattis quis, bibendum a, ultrices ac, augue. In aliquam vehicula turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Integer id nisl. Quisque dictum elementum odio. Aenean luctus. Sed eu sem a pede vulputate condimentum. Quisque magna. Donec aliquam mattis ipsum. Curabitur dictum sollicitudin sem. Aliquam pulvinar. Nunc sollicitudin risus a erat. Vivamus quis tellus sit amet nibh vestibulum consequat. Nulla pretium sollicitudin dolor. Aliquam iaculis tincidunt turpis. Phasellus ipsum leo, venenatis in, sagittis in, ornare at, nunc. + +Pellentesque ultrices, dui eu iaculis luctus, tellus augue volutpat sapien, in dignissim urna felis ut mi. Sed arcu dui, dignissim id, porttitor ut, imperdiet vitae, ante. Nulla dui sem, commodo nec, sagittis et, lacinia et, pede. Etiam eleifend dui ut nisl. Donec ante mauris, tempus sit amet, varius vitae, gravida quis, mi. In scelerisque, felis vitae viverra sagittis, velit metus ultricies neque, quis imperdiet velit elit et magna. Suspendisse potenti. Sed velit eros, euismod sed, condimentum nec, faucibus sed, sapien. Nam accumsan ligula sit amet neque. Aliquam erat volutpat. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam eu pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed eu felis sed tortor tempor fermentum. Phasellus commodo sem vel nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lectus elit, pharetra sit amet, accumsan sed, tincidunt et, mauris. Duis dapibus pharetra sem. Integer in justo. Praesent eros. Vestibulum ac ante. Aliquam scelerisque sem pellentesque nibh consectetuer sodales. Aliquam consectetuer odio. Duis lectus odio, luctus eu, commodo quis, mollis vitae, velit. Cras nec nunc non elit iaculis mattis. Aenean justo neque, sollicitudin eget, ullamcorper eget, egestas id, sem. In eu risus. Sed egestas. + +Integer at neque. Sed pretium scelerisque nulla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce ut pede. Etiam vitae quam a urna varius imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vehicula. Fusce ullamcorper nibh non erat. Quisque in neque. Praesent est. Pellentesque arcu. + +Proin posuere. Suspendisse potenti. Integer felis lacus, aliquam sed, vulputate in, mollis vel, tellus. Integer vehicula bibendum est. Nunc non dolor in tellus mattis facilisis. Integer vestibulum, augue at commodo aliquam, dui est mattis ligula, sit amet adipiscing orci sem vitae magna. Praesent enim velit, malesuada at, congue nec, luctus in, justo. Sed varius. Morbi pharetra. Donec eu massa nec tellus vulputate pulvinar. Ut commodo turpis non sem. Ut convallis ullamcorper risus. Etiam interdum pede id nisi. Cras magna sapien, suscipit a, laoreet non, rhoncus et, felis. Integer orci lorem, vestibulum dictum, ullamcorper a, porttitor et, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc et magna. Sed bibendum tellus in diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vitae tortor. Integer magna. Duis venenatis, leo ac tempor laoreet, elit nulla pharetra pede, non fermentum nunc odio a odio. Proin non velit. Sed imperdiet augue quis nisl. Integer condimentum nisl nec libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus placerat libero. Duis congue dictum magna. Aliquam dapibus bibendum enim. Nunc eleifend pede vel ipsum. + +Etiam vitae velit. Mauris erat nunc, malesuada ut, feugiat ac, placerat condimentum, augue. Nam volutpat. Aliquam vehicula ipsum id odio. Vivamus sollicitudin turpis id sapien. Fusce a felis vitae odio convallis blandit. Curabitur vitae eros id eros porta pretium. Nulla in magna eget urna lacinia convallis. Aliquam mattis venenatis purus. Sed sed mi eget erat tristique porta. Donec auctor dolor a erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In nec ligula. Nunc eleifend. Vestibulum quis nisi eget elit porttitor congue. Maecenas faucibus, magna eget adipiscing tincidunt, dolor ante malesuada elit, non elementum lacus turpis in pede. + +Ut malesuada mi nec metus. Praesent auctor augue ac nisl ultricies facilisis. Nam purus sapien, pellentesque dignissim, posuere eu, cursus id, diam. Quisque sollicitudin, elit a pellentesque scelerisque, lorem risus auctor quam, quis consequat tellus neque id urna. Suspendisse diam tortor, eleifend dignissim, egestas ut, luctus in, ante. Duis ante. Maecenas luctus. Curabitur cursus pharetra urna. Maecenas imperdiet, erat non elementum euismod, tortor odio euismod lectus, ac facilisis sem nibh vitae nulla. Nunc gravida. Morbi sollicitudin odio quis lacus. Aliquam a nibh non urna porta imperdiet. Aliquam erat volutpat. In iaculis lacinia velit. Sed libero lacus, tristique eu, lacinia ac, aliquet eget, urna. + +Etiam at nisl. Phasellus faucibus luctus lectus. Ut placerat vulputate dolor. Phasellus vel velit. Morbi viverra. Phasellus orci. Integer dignissim mattis mauris. Pellentesque posuere leo posuere quam. Quisque nec magna at diam viverra pellentesque. Suspendisse velit arcu, ultricies quis, congue a, venenatis eget, lacus. Integer sagittis hendrerit dolor. Fusce tincidunt ante a sem. + +Maecenas consectetuer, justo sed rhoncus venenatis, nibh arcu rutrum dolor, sed condimentum libero libero et ipsum. Vivamus mattis justo ut lorem tincidunt lobortis. Ut non velit id neque aliquet accumsan. Sed tempus viverra nulla. Curabitur ullamcorper, neque quis dapibus scelerisque, felis diam gravida orci, non cursus quam neque vitae elit. Etiam pharetra tincidunt lacus. Duis euismod fringilla est. Etiam ornare tincidunt lectus. Proin in turpis. Nunc blandit blandit turpis. Aenean ut augue. Duis orci justo, tincidunt eu, rutrum sed, rutrum et, turpis. Curabitur facilisis odio in ante. In hac habitasse platea dictumst. Sed eros est, pellentesque at, tincidunt eu, ultrices quis, metus. Morbi sit amet justo. Maecenas ac arcu. Mauris dignissim. + +Pellentesque ultricies rutrum orci. Aenean ornare. Vivamus eu risus vel mauris lobortis dictum. Sed et turpis auctor mi rhoncus pulvinar. Sed nec nunc a purus tempor viverra. Pellentesque suscipit. Donec tristique risus non nibh. Etiam nisl magna, sollicitudin ut, ultrices sit amet, egestas eu, nulla. Aliquam erat volutpat. Vestibulum pharetra. Sed egestas, metus sit amet lobortis consequat, erat elit imperdiet libero, eu interdum quam massa eget dolor. Suspendisse vitae odio. Proin blandit mauris iaculis metus. + +Vivamus vestibulum. Etiam et nisl. Aliquam in diam vel elit placerat suscipit. Duis sodales purus ac nibh. Nulla in odio eget enim luctus blandit. Curabitur ultrices ipsum non neque egestas eleifend. Sed turpis. Proin consectetuer. Vivamus mattis. In aliquet. + +Nunc id eros. Donec venenatis, nulla et mattis luctus, ante leo semper justo, non adipiscing odio risus sed lacus. Praesent vitae risus congue libero congue tempus. Phasellus ac eros. Nulla vehicula, lorem in aliquet suscipit, arcu erat egestas sem, quis lobortis quam ante eu massa. Curabitur non massa. Sed bibendum lacinia odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus volutpat blandit lacus. Proin porta, tellus ut auctor laoreet, lectus eros fermentum lectus, id sagittis arcu justo in turpis. Phasellus consequat. Nam pellentesque, mi id viverra convallis, nunc libero placerat leo, eleifend porta sem nisl vitae sapien. Pellentesque ligula libero, tristique non, porttitor rutrum, porttitor non, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer dictum tellus a tortor. Vivamus felis nunc, molestie non, rhoncus quis, pharetra id, dui. Donec risus metus, fringilla vel, aliquet eu, placerat id, neque. + +Suspendisse ipsum. Vivamus lectus. Sed viverra, massa eget convallis mattis, quam turpis consectetuer nunc, eget posuere magna sem id velit. In nec mauris. Aenean a purus sed quam lobortis fringilla. Proin ultricies lacinia ante. Sed adipiscing erat quis velit. Nullam vitae nisl id justo sollicitudin molestie. Nulla facilisi. Sed nec urna sed nisl fringilla dapibus. Nulla at diam. Aliquam eget nibh. Nunc ac nisi sit amet tellus egestas tempus. Nam scelerisque urna et neque. Donec est orci, sagittis non, vulputate a, commodo et, augue. Ut dapibus tortor. Ut nunc. Donec dictum dapibus odio. Nam ultricies ullamcorper ligula. Pellentesque accumsan varius leo. + +Morbi euismod laoreet erat. Vivamus quis ipsum. Morbi euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel purus. Nullam at magna. Curabitur lacus lorem, iaculis quis, dapibus non, volutpat vel, nulla. Donec ut arcu rhoncus dolor pretium dictum. Nullam vel metus. Ut arcu. Pellentesque nisi nunc, placerat eget, tincidunt vel, pharetra non, nunc. Integer tincidunt ultricies lectus. Integer semper, purus sed ultrices feugiat, nulla pede sollicitudin erat, vel auctor nulla ipsum vel lectus. Aenean mi. + +Nullam sed nisi et arcu imperdiet fermentum. Mauris nec metus. In ac dolor. In mi arcu, congue ac, pharetra nec, scelerisque sit amet, magna. Curabitur lacus. Curabitur et elit. Aliquam ullamcorper nunc eu elit. Sed convallis dolor at velit. Vestibulum dapibus, augue id consectetuer placerat, nunc massa blandit sapien, id aliquam elit nisi id mi. Phasellus sapien est, gravida eu, bibendum ut, adipiscing quis, est. Ut molestie quam vitae odio. Donec quis risus id erat faucibus sollicitudin. Nam id felis. Mauris sed enim vitae leo accumsan pretium. + +Nam justo. Donec turpis nisl, commodo et, interdum ac, consectetuer non, massa. Fusce sem metus, laoreet nec, posuere id, imperdiet in, velit. Donec vulputate justo eget turpis. Nulla pede. Morbi tincidunt. Fusce aliquet, quam et aliquam fringilla, ante ante iaculis dui, nec aliquam arcu purus sed erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus suscipit quam et est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; + +Integer sed tellus. Sed sed velit ultricies leo rutrum laoreet. Sed non eros ac purus sagittis feugiat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed hendrerit ligula sit amet nibh. Maecenas turpis. Morbi consectetuer, dolor et adipiscing imperdiet, ante neque feugiat dolor, at porta quam neque quis ligula. Mauris semper velit sit amet ipsum. Pellentesque tempus, purus in rutrum consequat, enim erat vehicula massa, id accumsan leo sapien nec purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In dolor. Integer facilisis libero sit amet pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut varius aliquet enim. Nulla facilisi. Curabitur consectetuer, odio eu pretium tincidunt, nunc nisi aliquet neque, vel imperdiet elit massa sit amet turpis. Pellentesque tempus, orci volutpat blandit fringilla, odio sem posuere ante, vitae bibendum urna lorem vitae eros. Praesent viverra rhoncus arcu. Sed auctor, est sit amet mollis mollis, quam quam gravida sapien, in commodo metus nulla auctor enim. Donec facilisis. + +Proin tincidunt, sapien eget ultricies adipiscing, est odio dictum arcu, ut mollis erat dui sit amet velit. Morbi est sem, interdum at, congue a, elementum vitae, metus. Suspendisse id augue. Mauris enim sem, pulvinar eget, tempus a, tempus sit amet, sapien. Fusce vestibulum consectetuer dui. Pellentesque erat. Sed dignissim placerat odio. Maecenas semper rhoncus lectus. Phasellus pretium. Duis libero elit, eleifend nec, egestas ut, cursus sed, felis. Nam nisl arcu, aliquet et, facilisis eu, luctus ut, risus. Etiam ultrices, dolor sed volutpat malesuada, turpis arcu imperdiet tortor, euismod commodo libero massa ut quam. Integer molestie purus non elit. Ut venenatis semper tortor. Etiam bibendum egestas ipsum. Mauris sollicitudin sem nec nibh. Nulla pretium metus eu metus. Pellentesque sit amet sem. + +Suspendisse ac nisi. Ut leo. Vestibulum hendrerit pretium dolor. Nunc feugiat malesuada purus. Cras et nibh. Curabitur nunc erat, malesuada vitae, laoreet ac, ultricies in, purus. Vivamus tellus arcu, sodales eu, facilisis a, lacinia nec, nunc. Pellentesque id velit. In eu nibh. Nunc nec erat. Sed dictum neque ut nisl. + +Morbi lectus tellus, tincidunt ac, porttitor ac, tristique in, eros. Donec luctus luctus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ut est et enim scelerisque accumsan. Donec ligula felis, lacinia quis, pellentesque in, semper vestibulum, elit. Mauris eget orci a felis congue vehicula. Ut sollicitudin. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam id dolor ut lorem dignissim venenatis. Suspendisse vitae sapien. Proin non magna ut eros viverra pulvinar. Donec quis odio. Nullam non arcu vel lorem suscipit aliquam. Aliquam rutrum turpis in leo. + +Ut luctus nibh tristique erat. Suspendisse bibendum odio vitae tortor. Donec lacinia. Cras sodales felis luctus nulla. Nam eleifend sagittis ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse vel neque. Morbi aliquet vehicula magna. Aenean at odio. Duis pellentesque magna. Nulla at tortor ut diam dictum faucibus. Mauris quis velit. Donec non tellus vitae lorem fringilla porttitor. Fusce ut sapien quis tortor feugiat sagittis. Donec viverra sem vitae sapien. Praesent sodales, lacus in fringilla viverra, odio augue adipiscing urna, vitae interdum ante sem non nisi. Nullam tortor lorem, eleifend ac, mollis non, laoreet ac, risus. Integer ornare leo sed justo. Quisque cursus, sem non facilisis bibendum, nisi mi varius felis, fermentum feugiat lorem eros laoreet risus. + +Quisque sit amet est et lorem vehicula lacinia. Donec nec tortor. Cras odio. Nam scelerisque vulputate urna. Praesent dui. Etiam nec nisl lobortis ipsum aliquet tempus. Maecenas pretium sollicitudin mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus augue massa, congue eget, convallis eget, tristique sit amet, eros. Sed consequat nisi eu felis. Pellentesque justo. Suspendisse non augue. In dignissim lobortis mauris. Mauris sagittis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + +Sed adipiscing. Donec a tellus vitae est cursus vehicula. Nam ante sem, sodales id, fringilla vel, condimentum vel, nulla. Quisque sodales. Etiam imperdiet elit id odio. Aliquam erat volutpat. Maecenas porta tempor arcu. Nulla sem augue, pellentesque ac, consequat ut, condimentum euismod, risus. Sed aliquam tincidunt mi. In interdum lobortis orci. + +Sed vehicula hendrerit purus. Etiam a diam. Curabitur convallis. Suspendisse a nisi. Donec id magna in quam sollicitudin ultricies. Donec viverra. Quisque volutpat est sed sem. Aliquam justo. Vestibulum tortor massa, porttitor sed, varius quis, iaculis quis, odio. Aliquam eget neque. + +Mauris nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum eu quam in neque ultrices pellentesque. Cras in dolor quis quam varius hendrerit. Aliquam nisi lacus, lobortis eu, convallis sit amet, facilisis ut, mi. Aliquam at neque. Cras sagittis elementum justo. Vestibulum ut lectus aliquet purus malesuada volutpat. Duis at lacus adipiscing libero tincidunt vestibulum. Morbi a libero. Cras purus. Morbi ut augue et purus interdum scelerisque. Integer a dui. In hac habitasse platea dictumst. Duis pharetra metus eget mauris. Aliquam interdum ullamcorper massa. + +Etiam ornare. Nullam euismod. Aenean consequat gravida ligula. Aliquam est. Proin vitae lacus. Praesent a eros sit amet dui luctus commodo. Phasellus vehicula arcu eget dolor. Praesent fermentum congue leo. Aliquam volutpat purus ut lorem. Fusce hendrerit enim at leo. Aliquam rhoncus nisl. Vivamus dictum egestas mi. Suspendisse pellentesque bibendum dolor. Pellentesque tincidunt, turpis semper pellentesque condimentum, ipsum metus sodales ligula, id volutpat diam turpis ut elit. + +Praesent sed lacus. Nam eleifend molestie mauris. Donec dapibus fermentum massa. Donec viverra faucibus purus. Curabitur congue, libero vitae viverra pellentesque, diam velit sodales enim, sed suscipit lectus nisi nec neque. Vestibulum malesuada, lacus at cursus congue, velit lectus tristique dolor, sit amet sodales neque ipsum a libero. Vestibulum et quam. Curabitur placerat. Curabitur nunc arcu, euismod nec, vulputate hendrerit, aliquet eget, quam. Curabitur vel enim. Suspendisse potenti. + +Nunc consequat orci ut lacus. Fusce velit dolor, dapibus sed, blandit sit amet, rhoncus id, risus. Duis urna nibh, scelerisque quis, dapibus a, scelerisque sed, nibh. Donec luctus. Ut eu mauris cursus diam lacinia rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam vehicula molestie justo. Maecenas imperdiet pede sed mi. Suspendisse nulla dolor, hendrerit eget, hendrerit id, dictum vel, leo. Duis accumsan. Curabitur in felis. Nunc lorem. Ut leo dolor, laoreet nec, vulputate at, eleifend in, nulla. Quisque nunc purus, varius eget, accumsan nec, aliquet et, nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras adipiscing viverra dolor. Mauris porttitor ultrices purus. Nulla facilisi. Praesent faucibus ante vitae mauris. + +Praesent lacinia lectus sed nisl. In tempus congue mauris. Integer facilisis ornare enim. Nulla id massa. Donec commodo diam at tellus. Nam dapibus viverra est. Nam tellus. Praesent a libero. In faucibus est eget nibh. Nulla eros orci, imperdiet non, blandit non, tempor eget, mi. Pellentesque convallis. + +Quisque eget mi ac leo euismod faucibus. Phasellus rhoncus purus id dui. Vestibulum malesuada eleifend ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque blandit mattis odio. Suspendisse consequat, lectus ac semper sollicitudin, mi velit dictum augue, ac tempus dolor erat sit amet dui. Proin hendrerit, felis quis volutpat posuere, diam odio malesuada odio, a interdum orci diam quis sapien. Pellentesque odio odio, viverra vel, gravida eu, molestie sed, nulla. Phasellus mauris pede, commodo ut, euismod eu, hendrerit eu, est. In hac habitasse platea dictumst. Nulla elementum lacus eu augue. Sed erat. Proin porta. Maecenas quis mi. Phasellus at enim ac justo gravida ultrices. Cras leo. + +Integer ut arcu. Donec sed magna. Proin felis. In iaculis, ligula id fringilla pretium, nibh diam accumsan tellus, eget accumsan metus dui varius turpis. Phasellus orci metus, eleifend sed, tempor ac, scelerisque ac, urna. Integer viverra neque a mauris. Mauris porttitor dolor eu velit. Integer odio elit, vestibulum ut, volutpat id, rhoncus commodo, urna. Etiam placerat pharetra erat. Ut tempor est. Integer dignissim blandit tellus. Morbi nibh dolor, scelerisque id, commodo malesuada, mattis at, mi. Cras tincidunt commodo purus. In tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ullamcorper. Ut hendrerit. Morbi ultrices. + +Praesent iaculis, eros ac egestas sodales, urna leo fermentum ligula, sit amet aliquam velit sem non purus. Donec rutrum arcu quis purus. Nam posuere, lacus at consequat placerat, nulla pede posuere orci, non euismod turpis dui quis nisl. Proin porta adipiscing nibh. Donec tristique dolor at tellus. Donec neque massa, auctor id, faucibus vitae, ullamcorper vel, nisi. Proin molestie neque sed massa. Nam tempor. Morbi aliquam sapien at tellus. Fusce quis risus et mi pretium pulvinar. Fusce sit amet ligula. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse eu enim et felis scelerisque lobortis. Praesent bibendum. Vivamus vehicula. Integer at nibh sed velit rhoncus molestie. Cras lacus. Sed ullamcorper eros vel erat. Fusce eu tortor sit amet diam euismod sagittis. Nunc quis lacus id nibh convallis varius. Suspendisse vitae mi. Vestibulum tristique. Donec malesuada ipsum id neque. Nullam sed lacus. Duis egestas, justo ut congue ornare, augue sapien luctus diam, at accumsan erat sapien ut libero. Phasellus vel nulla. Suspendisse arcu tellus, porttitor a, pharetra faucibus, aliquam sit amet, massa. Nulla porttitor tincidunt lorem. Nunc dolor odio, sagittis in, lobortis vel, volutpat sed, nibh. + +Quisque blandit leo ut sapien tempus facilisis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean ultricies porttitor justo. Fusce rutrum eros ut urna. Proin quis quam eget dui aliquam accumsan. Donec suscipit eleifend elit. Pellentesque mattis, felis sodales iaculis imperdiet, lacus sem convallis augue, sit amet aliquet arcu purus fringilla risus. In eu odio id magna pharetra ornare. Aliquam interdum pulvinar ipsum. Sed neque. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam sit amet nisi. Ut at augue. Mauris volutpat blandit ligula. Nulla eu metus. Vestibulum eget elit. Praesent posuere. Vestibulum id sem non lectus mollis tincidunt. Aliquam id felis at ante ornare tempor. Nulla lacus turpis, feugiat vitae, cursus quis, consectetuer non, mauris. Fusce lacus massa, porttitor ut, molestie ut, venenatis a, lorem. Praesent sit amet orci. Mauris rhoncus felis vitae felis adipiscing imperdiet. Maecenas mollis diam nec leo. + +Fusce enim ipsum, ultrices eu, molestie id, elementum id, sapien. Integer a urna. Nam velit libero, venenatis eget, tempor sit amet, feugiat vitae, ante. Fusce nunc. Sed semper nisl nec risus. In sed libero. Proin tortor neque, tincidunt ac, tempor ac, pharetra quis, velit. Duis lectus augue, ultricies vel, consequat id, iaculis id, ante. Vivamus auctor metus a ante. Curabitur arcu nisi, facilisis at, laoreet in, consectetuer sed, mauris. Quisque placerat diam sed dui. Vivamus pretium condimentum lorem. Curabitur laoreet. Aenean orci ligula, cursus eget, lacinia non, faucibus vel, lorem. + +Aliquam erat volutpat. Curabitur eros dolor, congue a, condimentum sed, luctus ut, nibh. Maecenas non tortor nec turpis commodo pellentesque. Praesent euismod placerat mi. Suspendisse potenti. Phasellus ut neque vitae orci mattis iaculis. Integer eget tellus. Donec at ante. Nam lacinia leo eget erat. Maecenas euismod magna congue tortor. Morbi nec massa eu enim malesuada sollicitudin. Sed accumsan. Nullam ipsum. Ut odio. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque id velit. Nam odio sem, aliquet ut, tempus sit amet, euismod et, nunc. + +Pellentesque libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent mauris nunc, varius ut, convallis molestie, luctus sit amet, leo. Sed dictum lorem et arcu. Nunc venenatis pellentesque massa. Nulla facilisi. Phasellus in tortor eget risus scelerisque vulputate. Sed nibh elit, sagittis ac, condimentum nec, convallis et, justo. Fusce volutpat metus. Nunc auctor. Vestibulum leo eros, pellentesque ac, mollis ultrices, rhoncus non, dolor. Mauris vehicula placerat nisl. Vestibulum bibendum, arcu quis congue elementum, velit nunc eleifend turpis, id luctus risus nisl sit amet tellus. Phasellus pede neque, blandit non, commodo vitae, ultricies eget, magna. Aliquam erat volutpat. + +Nulla facilisi. Aliquam ac ante. Cras risus. Morbi mauris lacus, posuere eu, blandit et, pharetra at, mi. Proin ac purus. Duis cursus nisl rutrum quam. Aliquam a odio non magna pellentesque ultricies. Maecenas ac massa quis sapien ullamcorper tempus. Cras cursus velit sed sapien. Proin nulla. Vivamus sodales aliquam nibh. Etiam et erat ut ante lacinia euismod. Fusce nisi. Proin quis nulla. + +Quisque venenatis, eros sed laoreet sollicitudin, orci ante pellentesque nisl, sit amet viverra quam erat non risus. Cras eget libero. Sed elit magna, semper eu, fringilla in, dignissim sodales, erat. Vivamus feugiat sem vel dui. Donec convallis sollicitudin diam. Cras sed purus. Donec felis eros, semper eget, tempor consectetuer, sagittis quis, nisl. Duis in ante. Cras non turpis. Nulla tempor velit aliquet turpis molestie placerat. Proin elementum fermentum mauris. Vivamus sed orci lacinia dui placerat venenatis. Vestibulum feugiat, tellus in volutpat rutrum, magna nisi ullamcorper eros, id pulvinar neque erat ut lacus. Vivamus sed augue. Nulla facilisi. Maecenas ante augue, elementum ut, sodales vitae, condimentum nec, lorem. Duis pede orci, fringilla at, eleifend nec, pretium in, erat. Nam sagittis, turpis vitae convallis pharetra, odio sem scelerisque lacus, nec lobortis dui diam vel eros. In semper gravida neque. + +Integer nunc. Ut pretium ipsum sit amet elit. In nec arcu. Sed vestibulum vulputate ipsum. Pellentesque tincidunt. Nulla gravida dolor in tellus. Cras vehicula, dolor ut pellentesque aliquam, erat enim auctor massa, vehicula lobortis odio eros quis quam. Proin dapibus neque in enim. Proin elit. Integer rhoncus tincidunt elit. Fusce lorem metus, semper ac, volutpat vitae, facilisis ut, tellus. Donec vel turpis vitae nisi pharetra porttitor. Maecenas tortor. Fusce mi. Nullam nec turpis. Sed sodales vestibulum nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Pellentesque dolor dolor, laoreet eu, aliquet quis, scelerisque sit amet, arcu. In hac habitasse platea dictumst. Nullam cursus urna eget elit. Quisque blandit sapien ac ante. Proin nulla eros, gravida volutpat, sodales vel, mollis eu, massa. Nulla tristique sollicitudin nisl. Curabitur vitae lorem vitae velit egestas ornare. Aenean eget eros. Aliquam erat volutpat. Fusce a urna id odio aliquet convallis. Curabitur sit amet nisl posuere leo posuere dapibus. Duis metus erat, luctus vel, rhoncus at, convallis sit amet, enim. Vivamus hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam eget elit. + +Nullam a nunc. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In metus urna, tincidunt et, lacinia sit amet, lobortis vitae, ligula. Proin et mauris vitae mi accumsan pellentesque. Etiam quam purus, hendrerit sed, feugiat vitae, euismod eget, tortor. Ut aliquam magna vitae justo. Suspendisse non justo vel velit condimentum tempus. Duis tempus ipsum vitae tellus. Proin in massa. Etiam ullamcorper dictum tellus. Proin aliquet felis at leo laoreet pulvinar. Vestibulum arcu purus, malesuada sit amet, cursus eu, placerat sit amet, nunc. Nam massa odio, sollicitudin in, adipiscing a, aliquam nec, risus. Aliquam blandit hendrerit libero. Mauris gravida. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur a nibh. Ut interdum fermentum neque. Pellentesque sed nunc. Mauris vehicula nisi et nunc. Praesent lorem. Donec semper. Integer eu lacus in est aliquam hendrerit. Vestibulum eget neque. Sed semper luctus velit. Curabitur nibh augue, congue eu, hendrerit id, congue et, enim. Integer placerat aliquam lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae eros. Donec vel nisl. + +In vestibulum facilisis urna. Ut risus. Mauris pharetra. Pellentesque mattis. Integer suscipit aliquam ipsum. Duis blandit, sapien et ultricies condimentum, felis mi elementum pede, nec sagittis metus mauris quis quam. Quisque accumsan arcu vel nulla. Cras sem sapien, porttitor id, ultricies sagittis, luctus eu, nulla. Integer quis eros. Morbi sed urna a tellus vehicula vulputate. Etiam nec augue eget felis semper tristique. Quisque ut dolor vel risus dictum consequat. Sed eget dolor sed nunc lacinia aliquet. Suspendisse ac tortor in ipsum posuere venenatis. Sed eget erat. Nulla faucibus. Duis laoreet, massa porttitor aliquet egestas, ipsum lectus rhoncus quam, in adipiscing eros sem ut tellus. Pellentesque feugiat tempus quam. Vivamus id dolor eget sapien consectetuer tempor. Aliquam erat volutpat. + +Nulla iaculis fermentum libero. Curabitur faucibus, massa malesuada cursus tincidunt, erat sem eleifend mauris, sed fringilla mi ante ac purus. Duis elementum lectus. Nunc ornare arcu eu tortor. Vestibulum vel dolor at purus lacinia fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas tincidunt, eros a egestas pellentesque, risus risus dictum libero, id aliquet metus justo in massa. Proin a tellus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed purus. Sed non pede. Aenean massa sapien, sodales sit amet, consequat dictum, eleifend vitae, tortor. Donec ultrices lacinia elit. + +Morbi adipiscing sodales dolor. Ut ullamcorper ultricies est. In venenatis tempus augue. Suspendisse tortor dolor, accumsan et, suscipit a, tincidunt ut, libero. Aliquam scelerisque magna sed felis. Quisque ut nunc a magna vulputate placerat. Aliquam rhoncus vehicula dui. Sed tortor. Nullam sit amet diam. Nunc sed eros. Sed et odio tincidunt elit gravida convallis. Curabitur quis tortor a lacus semper varius. Mauris at augue non mi sollicitudin aliquam. Integer ullamcorper. Pellentesque suscipit quam non purus. Aliquam ac eros at arcu ullamcorper consectetuer. Suspendisse pretium mattis leo. + +Duis at nunc. Sed dolor est, varius ac, porta et, tincidunt hendrerit, risus. Vivamus ut magna. Praesent ut mauris. In purus lacus, mattis sed, vestibulum nec, tempor at, nisl. Cras ullamcorper venenatis tellus. Ut dolor. Maecenas malesuada, pede a pulvinar mattis, arcu diam vehicula risus, quis porttitor augue massa in velit. Nunc congue. Morbi velit metus, rhoncus et, aliquam consectetuer, ultricies malesuada, ligula. Sed velit nisl, sagittis vitae, pharetra a, posuere sed, massa. Nulla facilisi. In varius, ligula id lobortis sodales, augue orci fermentum tellus, eu pulvinar risus ligula a sapien. Morbi laoreet ipsum non mi. Nam cursus lorem ut mi. Vivamus magna enim, posuere non, semper quis, sodales eu, arcu. Etiam mi purus, pretium feugiat, varius sed, pellentesque eget, ligula. In leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vitae orci eu orci sollicitudin feugiat. + +Praesent purus massa, euismod vitae, tempus nec, consequat hendrerit, metus. Aenean felis est, egestas vitae, accumsan eget, pellentesque in, sapien. Duis dapibus pede non sapien. Nunc urna. Integer vel libero. Duis augue arcu, dapibus non, facilisis vitae, posuere ut, eros. Donec vitae nunc sit amet arcu imperdiet dictum. Morbi eleifend, lorem eu consectetuer vestibulum, diam nunc ornare arcu, ac tempor felis dolor eget eros. Phasellus massa sem, sollicitudin ac, sodales gravida, luctus a, quam. Nam neque quam, viverra at, venenatis quis, sagittis non, enim. + +Nulla facilisi. Pellentesque egestas lacinia est. Sed tincidunt, pede sed tincidunt vestibulum, urna dolor adipiscing purus, vitae fringilla felis elit in nibh. Nulla sed nisi. Mauris suscipit scelerisque arcu. Etiam non enim vel eros accumsan malesuada. Nunc tincidunt commodo mauris. In tincidunt risus quis urna. Nulla diam tortor, aliquet et, tincidunt quis, sollicitudin ac, tortor. Cras nisl neque, vulputate suscipit, molestie quis, pulvinar at, nulla. Nullam ac metus nec odio posuere varius. Cras sed pede nec dui posuere bibendum. Duis euismod ullamcorper libero. Aliquam faucibus pulvinar turpis. + +In ut neque id nunc feugiat commodo. Curabitur dignissim, felis at sollicitudin lacinia, enim elit suscipit neque, sed luctus lorem ipsum in leo. Duis dapibus, odio quis auctor commodo, nisl odio mattis tellus, nec tincidunt turpis diam in arcu. Curabitur a sem. Nullam volutpat magna. Pellentesque sagittis, neque consequat pretium cursus, dolor lacus consectetuer arcu, sed laoreet est urna et metus. Suspendisse placerat, dui a porta tempor, lorem dui lobortis neque, sed venenatis diam enim id eros. Etiam et nisl non lectus faucibus consectetuer. Morbi scelerisque, sem nec tempus ullamcorper, ipsum diam feugiat lorem, a fringilla sapien elit quis nibh. Nullam diam urna, viverra sed, pharetra rhoncus, tincidunt vel, orci. Integer accumsan mattis erat. Nam dictum. Mauris nec leo. Nulla iaculis. Nulla nisl mi, dapibus quis, vehicula a, cursus eget, odio. + +Phasellus dapibus euismod nibh. Vivamus imperdiet ante in ligula. Pellentesque accumsan. In imperdiet, dui a auctor fringilla, metus nisi cursus dolor, vel luctus ligula lorem vitae mauris. Praesent mattis vestibulum elit. Aliquam enim lacus, pulvinar non, lacinia sit amet, eleifend non, velit. Vestibulum ac leo. Mauris imperdiet justo ac lectus. Sed molestie lectus sed dui. Sed fermentum tempus mauris. Nam ornare orci ac tellus. Ut malesuada, lacus id lacinia accumsan, diam elit adipiscing metus, et bibendum sapien nibh blandit orci. Suspendisse ipsum tellus, sagittis quis, vestibulum non, vulputate eu, eros. Praesent at nulla id pede scelerisque ultricies. Cras blandit pretium tellus. Maecenas dapibus condimentum augue. Phasellus tincidunt pharetra lorem. Morbi non eros. Sed tempor, nisl a tincidunt tincidunt, eros diam dictum sem, vel dignissim ante diam sed magna. Praesent non ligula id metus molestie consectetuer. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse vel mi. Curabitur ante nulla, rutrum a, convallis vel, vehicula ac, nunc. Nunc sagittis, enim sit amet auctor rutrum, mauris arcu vulputate neque, et euismod est felis quis ante. Vestibulum turpis tellus, hendrerit in, lacinia commodo, ullamcorper gravida, risus. Mauris rhoncus lacinia risus. Maecenas sollicitudin erat vitae nunc. Praesent pretium pellentesque augue. Donec interdum. Praesent ac eros vitae erat lobortis fringilla. Aenean consequat tellus. Nulla accumsan bibendum felis. Maecenas pretium ante id nisi. Aenean mi arcu, semper sed, mattis eu, venenatis sit amet, arcu. Donec aliquet euismod leo. Proin magna justo, tristique a, semper ac, sollicitudin a, ligula. Morbi velit. Aliquam vel nisi. + +In a lorem ut nunc feugiat congue. Donec fermentum bibendum dui. Proin varius est quis velit. Donec aliquet sem accumsan mi. Sed placerat. Nullam ac nisi a massa lobortis suscipit. Nunc id leo. Aliquam et massa. Nullam vestibulum elementum metus. In consectetuer nisi vel justo. Maecenas eget purus sed massa varius pellentesque. Phasellus faucibus felis quis felis. Aenean odio arcu, blandit quis, facilisis in, imperdiet eu, lorem. Nam posuere pulvinar mi. Fusce tristique, mauris et consectetuer ultricies, mauris lectus tempor justo, at fringilla est est sed nisi. Quisque faucibus. Sed in tortor tincidunt est lacinia iaculis. Maecenas a massa. Pellentesque a nibh at purus porta hendrerit. + +Nullam turpis. Fusce ac sem sed odio pellentesque imperdiet. Curabitur in arcu. Praesent lacus lacus, feugiat id, pulvinar in, tincidunt sed, neque. Maecenas viverra odio eget tortor. Integer aliquam, lorem rutrum venenatis dignissim, ligula magna malesuada arcu, vel feugiat lorem ipsum quis massa. Morbi ante. Vestibulum mauris libero, ullamcorper quis, ultrices quis, facilisis non, massa. Maecenas imperdiet. Aliquam erat volutpat. Pellentesque dignissim gravida lectus. In nibh odio, auctor eget, dapibus quis, dignissim venenatis, arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis pellentesque ligula quis massa. Curabitur condimentum, justo eget ornare luctus, lorem ligula sagittis pede, a porta nunc nunc in neque. Quisque felis mauris, condimentum vitae, auctor vitae, tincidunt quis, pede. Nunc lacinia ante in leo. Pellentesque libero. Aenean a ligula et nunc vestibulum consectetuer. + +Fusce ornare. Praesent id urna. Integer venenatis, quam non sagittis accumsan, ante nibh sagittis augue, sollicitudin adipiscing dolor velit eu erat. Proin quis enim eu purus vehicula aliquam. Nulla vel enim vel elit sollicitudin fringilla. Aliquam erat volutpat. Sed suscipit felis ut turpis. Etiam rutrum risus imperdiet est. Aliquam a tellus at tellus commodo dapibus. Mauris rutrum magna et odio. In at dolor. Curabitur vehicula lectus in tortor. Fusce justo purus, luctus vitae, mollis in, pharetra ac, purus. Nullam posuere interdum justo. Curabitur vitae lacus vel leo congue pulvinar. + +Aenean eleifend nibh varius tortor. Suspendisse vel eros. Proin nec diam a tortor ultrices ornare. Aliquam scelerisque feugiat justo. Vivamus ante urna, adipiscing vitae, porttitor eu, sodales et, felis. Suspendisse potenti. Curabitur ac massa in nisl sagittis mollis. Nam quam ligula, consectetuer eget, iaculis at, varius eu, leo. Duis dolor ligula, tincidunt at, ullamcorper sed, accumsan aliquam, ligula. Phasellus vulputate, lorem at tincidunt pharetra, risus lectus lacinia magna, quis rutrum enim magna at sem. In hac habitasse platea dictumst. Duis id sem a mauris sollicitudin tincidunt. Etiam eu purus eu arcu fringilla adipiscing. Vivamus ornare tempus diam. Proin turpis quam, lacinia non, egestas at, commodo eget, pede. Praesent vulputate risus in est. Nulla facilisi. + +Ut elementum lacinia purus. Proin vitae arcu ac nulla convallis aliquam. Nulla congue, libero id pellentesque mattis, quam lectus porttitor diam, a scelerisque dui libero in sapien. Nullam felis diam, vehicula vel, molestie ut, vestibulum aliquam, sapien. Donec convallis, est ut elementum volutpat, mauris ipsum gravida sem, commodo facilisis sapien lectus semper lectus. Quisque porttitor eros ut nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam mattis risus sed odio. Vestibulum et odio. In hac habitasse platea dictumst. Nam tristique massa ut ligula. Quisque nibh tellus, vehicula sit amet, adipiscing at, convallis nec, ligula. Vestibulum pretium, mi nec fringilla bibendum, dui nunc sodales pede, a semper magna nibh non diam. Donec massa nunc, viverra vel, consectetuer porta, dapibus non, ipsum. Duis nisl mauris, cursus vel, semper non, sollicitudin bibendum, felis. Vestibulum eu neque. + +Cras nec dolor. Donec laoreet tempus lectus. Cras sed tortor interdum lacus eleifend dignissim. Maecenas sit amet elit. Nullam quis dolor vel dui pharetra luctus. In sit amet quam sit amet pede ultrices ultrices. Maecenas diam. Integer urna. Curabitur dictum, velit sed placerat suscipit, erat turpis fermentum justo, sed interdum neque sem et nibh. Vivamus consequat convallis magna. Nam aliquam, est ac bibendum commodo, magna est dictum mi, vitae malesuada elit magna vitae odio. Maecenas tempor vulputate tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus dui. Etiam accumsan pede congue tortor. + +Morbi tempor libero ac lorem. In aliquet varius magna. In arcu. Phasellus odio. Fusce tincidunt aliquet felis. Quisque velit. Sed luctus. Aliquam feugiat fringilla mi. Aliquam molestie viverra risus. Proin arcu. Vestibulum lobortis tempus nisi. Praesent a arcu in velit viverra rutrum. + +In sed lectus. Donec risus dolor, blandit sit amet, elementum convallis, pharetra quis, pede. Integer ornare. Aenean egestas dapibus justo. Sed quam leo, posuere at, elementum vitae, commodo eget, est. Aliquam molestie rhoncus enim. Curabitur iaculis ultrices pede. Morbi aliquet rutrum lacus. Aliquam quam. Sed commodo, turpis in pharetra posuere, mi risus imperdiet erat, a vestibulum massa tellus vehicula sem. Mauris fringilla ultrices nunc. Nam nisi enim, eleifend sit amet, ultrices sed, fermentum non, augue. Proin congue lobortis nisi. Maecenas hendrerit. Nam sed nisl. Nunc elementum odio eu risus. In metus. Phasellus gravida pretium ligula. Nulla vitae neque. Nam nisi tortor, ornare non, blandit at, cursus eu, tortor. + +Duis bibendum ipsum in nunc cursus molestie. Nunc orci. Nullam nec ante non est dignissim viverra. Mauris blandit, velit id feugiat pretium, elit magna pellentesque dolor, at sagittis lacus velit egestas magna. Pellentesque cursus, diam consectetuer sagittis fringilla, tortor nisi adipiscing nunc, eu varius lacus risus ac elit. Mauris id nisi quis leo euismod venenatis. Pellentesque ac ante. Mauris arcu sapien, tempor at, porttitor id, condimentum ut, dui. Etiam fermentum ultricies augue. Cras ut eros at justo ultricies iaculis. Duis dignissim, nisl et facilisis fermentum, erat purus molestie tellus, quis tempus ipsum lectus at elit. Nulla vitae lorem. + +Aenean vel sem et diam semper congue. In bibendum diam quis tellus. Nunc facilisis ultricies nibh. Cras nunc enim, feugiat sed, ultrices vitae, sagittis vitae, ipsum. Fusce vitae nulla. Donec pellentesque, velit in porttitor eleifend, est neque lobortis velit, sit amet rutrum ante tortor nec dolor. Donec vehicula. Nulla facilisi. Sed egestas ultrices nibh. Donec elit lectus, convallis porttitor, aliquet dapibus, feugiat eget, ligula. Sed consectetuer justo. Maecenas a sapien sit amet nisi dapibus lobortis. Vivamus luctus lorem non nulla. Sed eget erat vitae libero interdum posuere. Cras pulvinar. Nullam imperdiet, dolor tempor dignissim blandit, dui sapien rhoncus neque, id malesuada augue magna sit amet urna. Duis sed mauris. + +Morbi accumsan. Sed mauris augue, fringilla non, auctor ut, auctor et, orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus ut pede. Donec viverra enim vel lorem. Pellentesque neque mauris, interdum eu, venenatis id, condimentum eu, sapien. Donec ipsum arcu, lacinia adipiscing, laoreet et, cursus vel, velit. Ut sagittis mauris quis risus. Integer eu odio vitae lacus viverra accumsan. Morbi leo ante, dignissim sed, varius quis, volutpat vitae, nisi. Nulla placerat interdum elit. Donec neque dui, sagittis vitae, sollicitudin quis, commodo vitae, neque. Nulla quis ligula ornare ligula dictum ornare. Mauris rutrum rutrum neque. Aenean vehicula tempus est. Donec varius scelerisque pede. Donec placerat vulputate leo. Nullam nunc nisl, posuere non, feugiat vitae, pellentesque quis, mauris. In dui neque, cursus eget, sagittis eget, dapibus vitae, mi. Proin eget est. + +Fusce porta est. Mauris magna. Aliquam ipsum lacus, ultricies id, vestibulum luctus, accumsan ut, ante. Sed mauris. Sed adipiscing leo sit amet magna. Suspendisse potenti. Nunc massa elit, fringilla eget, egestas vitae, luctus vitae, dolor. Phasellus quis nulla eu nisi interdum sollicitudin. Nullam id tellus. Integer iaculis dolor ac purus. Sed vel mi. Curabitur non magna sit amet justo condimentum vulputate. Quisque tincidunt pede eu nisl. Vivamus lobortis. Nunc metus metus, congue sed, tincidunt sed, pretium at, odio. Donec a arcu. In sem justo, vehicula sed, varius id, volutpat at, risus. Praesent iaculis massa. In arcu elit, hendrerit eget, ullamcorper in, porta id, tellus. Donec sagittis hendrerit diam. + +Suspendisse potenti. Sed et diam et augue sagittis lobortis. Phasellus dolor. Ut et arcu eget ante tempor posuere. Aliquam fermentum scelerisque dui. Mauris at purus. Donec erat sem, vestibulum nec, faucibus ac, mattis a, leo. Suspendisse adipiscing lacinia sem. Nullam orci arcu, dictum et, faucibus viverra, dapibus et, neque. Cras nunc diam, adipiscing non, sollicitudin in, interdum vel, massa. Mauris sagittis, justo at tristique tempus, mauris mauris aliquam ante, sit amet posuere diam dui eget ligula. In dignissim, nisl ut lacinia condimentum, erat justo porttitor nulla, non gravida ligula magna eget massa. Vestibulum vitae ligula at mi vestibulum suscipit. Duis laoreet. Nulla commodo libero sit amet lorem. Ut elementum sem. Integer vel dolor. Nam facilisis mi quis sem ultrices sagittis. Sed quis quam at metus molestie bibendum. + +Proin dui enim, lacinia a, feugiat ac, placerat vitae, pede. Quisque egestas, leo eget aliquam pretium, libero justo tincidunt eros, ut egestas augue pede elementum nibh. Curabitur mollis sodales enim. Donec augue. Phasellus id ipsum posuere dui pretium faucibus. Mauris luctus ante semper nisi interdum adipiscing. Duis dapibus, odio quis viverra rhoncus, justo quam bibendum dolor, id dapibus velit erat vel erat. Fusce sit amet nisl venenatis quam ultrices condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec rhoncus scelerisque ligula. Vestibulum mi odio, accumsan et, adipiscing eget, ornare ut, quam. Nullam blandit molestie mauris. Curabitur dignissim mauris et lorem. Suspendisse a justo. Nam mattis faucibus arcu. Duis blandit enim non massa. + +Nullam lorem. In hac habitasse platea dictumst. Mauris consectetuer posuere mauris. Maecenas tincidunt mauris in eros. Nulla eu metus eu orci sollicitudin faucibus. Suspendisse aliquam mauris id est. Cras blandit dui et urna. Nulla arcu. Sed a urna. Nulla dapibus vehicula tortor. Donec risus. Sed quam metus, egestas eu, cursus ut, viverra non, odio. Ut justo justo, malesuada sit amet, blandit suscipit, molestie in, justo. Vestibulum consequat, quam ac feugiat tincidunt, ipsum libero eleifend odio, non eleifend pede ipsum non ante. Nullam a metus. + +Nam ac nisi at felis cursus mattis. Pellentesque consequat sem quis orci. Quisque tempus. Aenean imperdiet molestie pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eu tellus. Nulla diam eros, sodales ut, sodales nec, tincidunt ac, nunc. Nunc lacinia faucibus ipsum. Vivamus vel neque in erat fermentum luctus. Nulla eget metus nec augue bibendum placerat. Vivamus tempus. Praesent congue ornare ipsum. Etiam mattis feugiat justo. + +Aliquam dui. Aenean commodo tortor vitae nulla. Morbi et ipsum. Mauris ac ipsum. Nam vel risus ut lectus mollis viverra. Curabitur elementum mollis est. Nullam elit. Vestibulum suscipit pretium enim. Vestibulum ut massa. Proin nec felis. Maecenas gravida, arcu nec consequat sagittis, eros tellus scelerisque mauris, vitae accumsan quam quam ut nunc. Integer eget ante eu velit laoreet malesuada. Nunc sagittis, mauris vitae pharetra volutpat, tellus tellus eleifend eros, sit amet rutrum ipsum nisi a velit. Praesent varius leo eu erat. Vivamus consequat placerat purus. Donec pretium elementum nibh. Proin at elit non sem aliquet mattis. Sed ullamcorper ipsum sit amet elit. + +Mauris in metus. Suspendisse magna lorem, faucibus vel, tincidunt quis, scelerisque non, tellus. Fusce quis lorem. Proin a lacus sit amet mauris iaculis pulvinar. Suspendisse rhoncus eros nec mi. Praesent euismod, turpis vitae rutrum pretium, odio metus volutpat neque, eget tempus sapien neque sed erat. Donec fermentum purus at lectus. Nullam sem. Fusce vel mi quis erat lobortis posuere. Aenean eget urna. Suspendisse ligula. Duis in nisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Curabitur vulputate lectus id pede. Phasellus eu velit. Etiam venenatis adipiscing nibh. Aliquam cursus pulvinar tellus. Vestibulum neque. Mauris nec justo et erat semper pellentesque. Fusce mattis dictum dolor. Etiam eget purus eu massa varius elementum. Pellentesque massa. Ut ultricies diam sed ipsum. Nullam diam. Pellentesque id magna id libero tristique aliquam. + +Ut eleifend, purus id placerat venenatis, urna augue aliquet ligula, in ultricies leo risus et tellus. Mauris et nulla id urna tristique tempus. Ut facilisis, urna eu vestibulum rhoncus, lacus eros consectetuer metus, et rutrum dui lectus in purus. Nunc vel nisl non ipsum tincidunt mollis. Nam quam lacus, ornare vitae, rhoncus non, congue sed, odio. Proin nibh dui, porta vel, venenatis non, pellentesque ut, nisi. Sed tristique felis a magna. Suspendisse eget tellus. Cras gravida imperdiet velit. Integer hendrerit risus. Proin orci. Aliquam ullamcorper mauris quis mauris. Nunc lacinia vestibulum metus. Duis tellus. Nullam faucibus, leo ac vulputate sollicitudin, leo dolor faucibus erat, quis bibendum orci odio non arcu. + +Nullam accumsan mattis dolor. Donec et dui. Praesent a felis mollis lacus semper lacinia. Curabitur pellentesque luctus est. Proin nulla dui, condimentum vel, faucibus non, interdum ac, erat. Maecenas scelerisque, lectus id volutpat accumsan, sapien tortor pellentesque dui, sed semper magna sem ut leo. Proin nulla. Nullam dapibus ullamcorper sem. Suspendisse vehicula metus in nunc. Pellentesque non quam vel arcu ultrices ullamcorper. Phasellus quis felis sit amet tellus ullamcorper fermentum. Sed vehicula sollicitudin urna. Curabitur pharetra scelerisque risus. Pellentesque id massa quis metus aliquam imperdiet. In nunc lacus, feugiat in, gravida eget, venenatis ut, tellus. Suspendisse potenti. Nam consequat adipiscing dui. In nulla nisi, feugiat ut, fermentum vel, gravida nec, tortor. In sed augue. + +Etiam ullamcorper augue at enim. Integer dignissim. Aliquam pulvinar congue nulla. Morbi enim massa, fringilla a, accumsan eget, condimentum nec, erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean pharetra. Etiam porttitor purus a metus. Aliquam interdum sem eget justo. Quisque volutpat luctus est. Aenean augue. Phasellus dui lectus, ultrices nec, commodo vel, auctor vel, nisi. Ut ultrices pellentesque nisi. Integer ac velit et sem imperdiet luctus. Fusce vitae turpis id augue mollis consectetuer. + +Maecenas nec lacus. Maecenas condimentum odio eu felis. Mauris ut nisl viverra erat faucibus adipiscing. Etiam egestas. Nunc et dolor vitae risus dignissim commodo. Morbi lectus velit, tincidunt nec, aliquet vel, mattis vitae, ligula. Maecenas ultricies semper dolor. Suspendisse malesuada. Integer mattis elit. Donec accumsan, lacus facilisis varius tempus, nulla elit porta erat, et rutrum elit sem sit amet dui. + +Maecenas mollis mi non nulla. Vivamus turpis. Suspendisse a metus. In quis mi in turpis congue auctor. Maecenas lacus. Suspendisse sollicitudin. Phasellus porta nunc non nisl pulvinar egestas. Sed nulla. Vestibulum ac mi. Mauris ultricies condimentum neque. Nulla tempus justo vel massa. Nulla suscipit congue arcu. Praesent id turpis. Mauris nibh pede, euismod semper, molestie ac, rhoncus vitae, ante. Maecenas erat felis, viverra sollicitudin, sagittis eget, pellentesque nec, orci. Fusce ultrices consequat lacus. Aliquam erat magna, feugiat at, viverra a, mollis non, turpis. + +Donec mi. Nam dictum pellentesque sem. Donec mollis rhoncus elit. Phasellus rhoncus pede sit amet risus. Donec eget augue. Maecenas non lectus. Phasellus sollicitudin nisi nec felis. Aliquam pretium, est eget semper convallis, nibh nunc sollicitudin purus, id tempor pede dui vel magna. Vivamus ac lorem. Etiam nisl tortor, adipiscing dictum, elementum in, facilisis sed, nibh. Proin mauris. Proin rutrum massa eget sem. Curabitur tempor adipiscing elit. Curabitur purus tellus, fermentum eget, aliquet vitae, convallis ac, mauris. + +Integer consequat velit eu eros tincidunt vehicula. Nullam lorem sapien, rhoncus non, mattis quis, ultricies sit amet, enim. Curabitur commodo, libero in euismod suscipit, sem purus fringilla enim, ac molestie tortor orci et velit. Donec pede. Etiam placerat condimentum turpis. Phasellus egestas enim nec magna. Vivamus condimentum, nulla vel luctus tristique, eros risus vestibulum nulla, in vehicula arcu ipsum at felis. Donec aliquam elit at augue. Quisque a eros eu ligula accumsan dictum. Etiam vehicula turpis quis libero. Aliquam non mi. Donec et leo. Proin leo libero, aliquam tincidunt, congue nec, adipiscing porta, enim. Nulla lobortis, tortor sit amet imperdiet ullamcorper, dolor orci malesuada pede, sed gravida nibh urna vel lorem. Sed pharetra malesuada eros. Quisque euismod aliquet erat. Suspendisse aliquet mattis purus. + +Nunc id nulla quis justo congue sollicitudin. Praesent erat turpis, rhoncus eu, pretium eu, pellentesque a, nibh. Vivamus tempus. Cras nec risus at turpis imperdiet lobortis. Ut mattis. Maecenas est felis, pellentesque non, imperdiet sed, eleifend tincidunt, lorem. In tincidunt. Sed vel leo. Donec et urna in turpis hendrerit blandit. Donec condimentum accumsan est. Ut pharetra, metus vitae mattis consectetuer, leo quam vulputate odio, nec laoreet nisi velit eu erat. Integer lectus augue, egestas in, interdum eu, venenatis vel, sapien. Quisque et est vitae eros laoreet lobortis. Nullam ut risus non nulla placerat adipiscing. Praesent dapibus. Etiam a felis. Ut sodales consequat mauris. Duis lorem felis, luctus a, tristique in, molestie at, risus. Sed vehicula bibendum tellus. Nam consequat euismod lacus. + +Aenean tortor elit, gravida nec, fermentum eu, lobortis id, ipsum. Maecenas eu purus. Cras ac turpis ut nisi iaculis rhoncus. Nulla purus metus, dignissim nec, tincidunt vitae, dapibus eu, nibh. Fusce lobortis, nunc at viverra eleifend, justo turpis scelerisque eros, ac pellentesque metus nisl at purus. Sed elementum tellus sed enim interdum blandit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer ultricies aliquet odio. Mauris eget nunc a ipsum ultrices sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean accumsan. Donec sapien lectus, congue at, porta id, hendrerit vitae, nisl. Curabitur vel quam vel neque accumsan laoreet. Morbi sapien est, pretium in, consectetuer ac, mollis ut, libero. Donec tincidunt adipiscing metus. Nunc vestibulum egestas augue. Donec scelerisque dui ut sem. Suspendisse vel metus id est molestie iaculis. + +Vivamus pharetra, elit eu malesuada blandit, diam tortor mollis dui, sed pulvinar massa nunc et magna. Sed placerat elit auctor tortor. Nulla ac erat. Pellentesque consectetuer, dui convallis tincidunt condimentum, sem odio volutpat libero, non elementum felis neque nec odio. Maecenas hendrerit eros id diam. Mauris vel purus ac orci convallis convallis. Sed sit amet lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque dictum varius lacus. Mauris eget nisl. Suspendisse placerat, nulla non ornare dignissim, nisl diam sagittis tellus, in semper nisi dolor at nibh. Duis ullamcorper viverra felis. Integer a tellus. Suspendisse eget nunc. Aenean diam est, accumsan id, suscipit interdum, fringilla vitae, justo. Proin pede. Maecenas at neque in neque vestibulum eleifend. + +Vestibulum nulla lorem, porttitor eget, euismod ac, aliquam at, nisl. Maecenas et est eget massa varius lobortis. In mi. Duis porttitor fermentum purus. Donec cursus imperdiet ligula. Morbi et ligula et ante molestie vehicula. Mauris sed dolor. Sed imperdiet felis ut sem. Sed vitae neque elementum leo auctor fermentum. Duis feugiat ullamcorper erat. Aenean purus. Morbi fermentum vestibulum est. Pellentesque venenatis mauris. Phasellus pulvinar. Integer ipsum lectus, iaculis a, lacinia id, accumsan id, arcu. Phasellus at est. Fusce neque quam, ultricies id, iaculis vel, dapibus vitae, lacus. In lobortis convallis ante. Nulla nunc purus, vulputate in, hendrerit et, blandit et, ligula. + +Pellentesque leo metus, sagittis in, molestie vitae, dictum in, pede. Morbi pretium felis nec quam. Pellentesque mattis ante sed quam sagittis dapibus. Suspendisse sapien. Praesent bibendum iaculis tortor. Duis a nisl. Aenean mi. Donec dictum arcu in est. Morbi interdum vulputate ipsum. Aenean sit amet magna non nisl tristique posuere. Phasellus velit metus, tempor ac, fermentum eget, condimentum non, velit. Vestibulum sit posuere. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras aliquet massa nec dui. Cras arcu nunc, hendrerit ac, eleifend eu, ullamcorper nec, tellus. Sed pharetra purus sit amet quam. Curabitur mollis. Nam vitae pede. Etiam risus massa, vehicula sit amet, pharetra nec, sollicitudin ut, dui. Donec egestas justo at quam. Proin nisl risus, vestibulum nec, pretium vitae, tristique ac, lorem. Aliquam erat volutpat. Cras sed nibh. Pellentesque sollicitudin euismod augue. + +Etiam fringilla sollicitudin orci. Mauris cursus elit quis lacus. Cras tortor. In adipiscing, lectus id auctor vestibulum, neque pede accumsan dolor, non imperdiet magna diam accumsan velit. Suspendisse at libero ut nisi blandit sagittis. Phasellus non mauris. Fusce elementum sagittis sem. Suspendisse aliquam eleifend tellus. Proin ligula lorem, imperdiet quis, venenatis id, iaculis mollis, nisl. Etiam convallis pede at massa. Morbi accumsan dui et mauris. + +Sed sed orci. Nunc purus. Suspendisse potenti. Ut luctus fringilla mauris. Donec nibh. Phasellus porta. Phasellus sit amet odio sed magna sodales pharetra. Cras lectus. Suspendisse libero ipsum, commodo nec, facilisis in, suscipit lobortis, ligula. Duis massa nulla, semper et, consequat nec, pharetra eu, elit. Vivamus ultricies aliquam odio. Vestibulum sit amet massa. Sed consequat lacus sed urna. Etiam faucibus felis vel orci. Phasellus ullamcorper. Aenean consectetuer lacus at libero. + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis facilisis, ligula vitae condimentum scelerisque, velit orci gravida felis, vel ultricies quam mi non diam. Vivamus auctor metus non libero. Praesent ligula nisi, commodo condimentum, molestie et, viverra et, justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus sollicitudin. Nunc blandit cursus ipsum. Aenean nec ligula ut tellus sodales mattis. Integer sem. Aliquam id ligula. Sed tortor mauris, blandit vitae, cursus vel, elementum et, nulla. Aliquam scelerisque metus et nisl. Duis adipiscing magna at neque. Quisque vulputate eleifend nunc. Aliquam eget elit. Phasellus dui odio, bibendum sagittis, vestibulum id, dignissim imperdiet, orci. Nullam eu felis non nunc lacinia sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Suspendisse pellentesque, libero mattis ultricies accumsan, tortor tortor malesuada sem, et sodales libero odio ac ipsum. Vivamus quis magna nec est suscipit lobortis. Cras tempus posuere nunc. Quisque ut enim a felis egestas semper. Sed pharetra mattis neque. Fusce turpis nunc, congue sed, consequat non, congue sed, nulla. Suspendisse varius lorem id risus porta vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce sed purus. In a felis. Integer egestas auctor orci. Mauris ultrices suscipit nisl. Nullam purus. + +Cras tempor adipiscing ipsum. Ut quis mi. Maecenas in justo ut nulla congue pharetra. Pellentesque ut libero eu dolor venenatis suscipit. Praesent feugiat consectetuer nibh. Morbi faucibus sem non felis. In hendrerit arcu ac massa. In accumsan ultrices mi. Proin malesuada auctor felis. Curabitur interdum. Sed diam ipsum, ultricies in, tempor sit amet, viverra imperdiet, elit. Morbi molestie nisi. Mauris ipsum. Fusce dictum mollis magna. Duis commodo dignissim nulla. Vestibulum augue enim, ultricies quis, iaculis nec, tincidunt vitae, diam. Mauris lacinia tempus ipsum. Sed at mauris. Ut lorem. Donec libero. + +Duis iaculis lacinia lectus. Aenean convallis eros ac ante. Sed quis orci nec risus auctor fringilla. Phasellus facilisis elementum nisi. In hac habitasse platea dictumst. Nunc porta lacus nec ante. Morbi mauris erat, adipiscing in, pulvinar nec, lobortis nec, odio. Ut eleifend lectus sed quam. Nullam mollis. In non turpis et nisl hendrerit blandit. Duis elementum. Nunc nec libero. Suspendisse vestibulum risus non pede. Morbi imperdiet odio sit amet libero. Sed sed massa vitae ipsum mattis tincidunt. Nulla nec tortor vitae libero volutpat tempus. Donec aliquam. + +Duis sed nunc. Curabitur turpis nulla, vehicula sed, luctus quis, elementum eget, felis. Maecenas et purus. Maecenas leo tellus, tincidunt a, facilisis vitae, lobortis sit amet, velit. Donec convallis sapien. Maecenas mollis odio eu nibh. Etiam gravida. Integer molestie, sapien eu molestie lacinia, nunc nibh aliquam ligula, eu sagittis tellus erat sollicitudin odio. Duis et risus. Phasellus nisi neque, placerat nec, condimentum non, ultrices eu, sem. Ut pede. Etiam nulla metus, volutpat id, convallis sed, suscipit vel, urna. Donec vel elit. Ut leo neque, venenatis faucibus, lacinia nec, tincidunt eu, enim. Cras id dui a libero pharetra dignissim. Donec eros leo, porta quis, laoreet ut, pellentesque volutpat, lectus. + +Nullam blandit. Aliquam erat volutpat. Fusce adipiscing enim. Suspendisse non dui quis ligula porta vestibulum. Donec eu tellus vel lorem pretium porttitor. Praesent luctus. Aliquam ac eros in massa dapibus tincidunt. Donec ut magna. Etiam auctor lacus sit amet lacus. Sed ultricies ipsum nec elit. Quisque a est in purus suscipit tristique. + +Aenean sed dui vel dolor pulvinar laoreet. Vivamus vehicula lorem in pede. Vivamus et diam. Integer ac odio vel diam hendrerit bibendum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a nisi. Phasellus tincidunt dui vitae augue. Duis faucibus, dui interdum fringilla tincidunt, odio elit vestibulum libero, ac molestie magna lectus id lacus. Aenean ligula. Nulla facilisi. + +Fusce vel sem eu velit fringilla ornare. Sed feugiat tincidunt felis. Nullam felis mi, euismod sit amet, mollis at, sodales eget, augue. Nam imperdiet nibh at velit. Sed ut erat. In dui. Nulla facilisi. Nullam augue libero, tincidunt nec, pretium eu, pulvinar in, dui. Morbi vitae felis. Pellentesque vel justo vel velit sagittis malesuada. Proin vehicula blandit massa. Etiam tincidunt pharetra urna. In metus est, auctor nec, blandit a, cursus nec, quam. Mauris ac metus a libero congue faucibus. Mauris mauris dolor, sodales in, cursus ut, sodales rutrum, eros. Quisque mauris eros, sagittis vitae, lobortis ut, eleifend id, nisi. + +Aenean neque. Vestibulum egestas pellentesque ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus sagittis justo vel risus. Sed pretium neque vitae urna. Pellentesque congue libero id lorem. Mauris leo lorem, blandit sit amet, convallis quis, consectetuer sed, eros. Mauris tincidunt, enim a gravida euismod, magna nulla fermentum libero, viverra egestas velit quam et tortor. Vivamus aliquet massa vitae justo. Nulla congue lacus ac elit. + +Phasellus commodo quam vel ligula. Proin non metus at eros pulvinar luctus. Mauris diam lorem, posuere quis, gravida et, tincidunt nec, ligula. Sed diam. Aliquam elit lectus, hendrerit ut, imperdiet sit amet, pretium sit amet, ipsum. Mauris vehicula nisl in dui. Curabitur eget quam ut magna elementum fermentum. Mauris scelerisque. Quisque laoreet. Etiam tempus turpis. Pellentesque augue quam, hendrerit sed, tincidunt at, pharetra at, nisl. Aliquam lacus. Suspendisse potenti. Aenean velit libero, ultrices in, lacinia eu, luctus vel, ante. Etiam dictum mi in felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce gravida dapibus nisl. Cras vitae nisl. + +Maecenas dignissim, ligula non porta cursus, enim nunc malesuada sem, eu porttitor nulla urna eu quam. Fusce eros. Aliquam eros. Nam auctor. Nulla molestie porta est. Suspendisse potenti. Vivamus molestie lorem sed erat. Sed eget ipsum. Integer aliquam pulvinar nulla. Cras aliquet sem ut nunc. Fusce faucibus tempus lectus. Cras sodales, nisi ac facilisis ultrices, eros arcu dapibus sapien, et ultrices mauris tellus non dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras cursus varius metus. Ut turpis. Vivamus eget tortor. + +Sed laoreet, velit non accumsan cursus, nunc urna posuere justo, in dictum lectus pede id ante. Cras vulputate. Cras congue dui sed elit. Proin lacus sem, ultrices at, consequat in, tempor quis, metus. Proin vel arcu. Nam euismod hendrerit elit. Ut erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed posuere. Morbi eros urna, semper at, semper non, convallis quis, velit. Maecenas orci. Vestibulum lobortis tristique metus. Vestibulum lorem nulla, sollicitudin vitae, condimentum quis, auctor ut, dui. Vivamus vestibulum magna ut nisi. Curabitur eleifend dui vel nunc. Curabitur mauris lacus, malesuada sit amet, suscipit sed, rutrum luctus, tellus. Integer facilisis urna vitae lectus. + +Aenean quam leo, lobortis quis, malesuada eu, vulputate vitae, nisl. Praesent eget eros. Ut fermentum turpis id quam. Nam tortor. Praesent nec orci. Nulla bibendum adipiscing augue. Ut commodo, magna id malesuada gravida, augue odio malesuada mi, porta malesuada elit est vitae diam. Mauris non nulla. Suspendisse tincidunt, nunc ultricies porta venenatis, mi pede tincidunt libero, eget varius ante libero ut ligula. Curabitur pretium porttitor tortor. + +Maecenas vitae elit eget nisi dapibus dictum. Nunc in libero. Nulla dictum orci eu erat auctor lobortis. Phasellus risus. Suspendisse potenti. Suspendisse potenti. Praesent adipiscing consequat elit. Integer id augue. Praesent in justo nec magna dapibus pulvinar. Duis nisl. Suspendisse ac odio. Vivamus imperdiet. Donec non velit sit amet risus dignissim congue. Nam aliquet posuere velit. Cras turpis. Morbi malesuada dignissim mi. + +Sed leo neque, varius quis, venenatis sed, pharetra sed, est. Morbi blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam semper pellentesque mi. Ut vel lorem. Nunc mi tortor, laoreet at, faucibus eu, tincidunt sit amet, erat. Duis tempor malesuada ipsum. Phasellus aliquet. Donec et elit. Pellentesque purus. Vestibulum rutrum semper nibh. Nulla facilisi. Phasellus et enim sit amet ante vestibulum vehicula. Phasellus id nisl. Donec mollis leo at eros. Mauris pellentesque neque at purus. Morbi quis dolor at ipsum scelerisque sodales. Etiam volutpat turpis a metus. In hac habitasse platea dictumst. Nunc lorem lorem, vestibulum ac, euismod eget, ullamcorper dignissim, velit. + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ultrices, nibh vel aliquam vestibulum, eros enim venenatis dui, id iaculis enim nunc vel massa. Morbi eleifend orci et massa. Aliquam erat volutpat. Nulla mollis egestas turpis. In sodales nunc eget tortor. Sed ipsum eros, tempor quis, aliquet vitae, imperdiet non, lorem. Pellentesque quis elit id mi luctus dapibus. Sed nunc arcu, rhoncus nec, convallis quis, cursus at, neque. Mauris convallis purus at erat. Pellentesque vestibulum. Vivamus fringilla elit at arcu. Nullam aliquet enim nec arcu. Nam id tortor. Nulla quis nunc. Ut arcu. Suspendisse potenti. Pellentesque ullamcorper ligula id arcu. + +Nam non libero vitae nisl scelerisque fringilla. Quisque varius ante id metus rhoncus fringilla. Nulla facilisi. Praesent eleifend porttitor ligula. Etiam quis dolor non augue commodo auctor. Donec a mi. Vestibulum tempor. Donec felis urna, auctor at, cursus dictum, gravida id, arcu. Aenean dictum malesuada dolor. Vivamus mattis. Phasellus eu pede. Fusce adipiscing justo fringilla metus. Etiam ante. Integer mollis massa quis nunc. Integer dictum neque luctus enim. + +Sed eu libero. Integer tempor ligula in velit. Ut tincidunt lacinia sem. Nullam vel risus. Sed sodales ante a dolor. Curabitur eros. Sed sodales. Sed non metus. Vestibulum elementum faucibus ante. Nulla vel nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In hac habitasse platea dictumst. Nunc nec lorem ut ipsum lacinia iaculis. Duis erat. Aliquam erat. Cras iaculis. In hac habitasse platea dictumst. + +Nullam ante. Cras vitae est. Pellentesque vel metus a ligula dapibus mattis. Duis feugiat aliquet felis. Etiam id nisl quis est dignissim condimentum. Suspendisse potenti. Morbi velit lorem, ornare quis, pellentesque vel, placerat eget, tortor. Vestibulum tincidunt molestie libero. Nulla nulla enim, malesuada id, ullamcorper vitae, dictum at, purus. Donec dignissim odio ut enim. Suspendisse at lectus. + +Praesent lobortis augue vel lectus. Ut in ligula ut felis congue suscipit. Quisque dignissim tortor ut mi. Fusce magna nisi, eleifend ac, ornare vel, porttitor vitae, quam. Vestibulum sodales justo quis turpis. Fusce urna nisi, rhoncus quis, condimentum vel, dictum eu, nunc. Fusce sed nibh vitae odio posuere adipiscing. Sed porta elit quis dolor. Nam libero nulla, auctor sed, tincidunt quis, faucibus sit amet, mi. Quisque orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam id sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vel eros. + +Vivamus luctus lobortis leo. Suspendisse vel elit a enim ullamcorper posuere. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec quis pede mattis lectus mollis adipiscing. Sed accumsan posuere erat. Praesent euismod tincidunt felis. Donec mi. Ut commodo arcu lacinia tellus. Aliquam a libero quis lectus semper viverra. Curabitur lacinia mauris at tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sit amet magna molestie orci suscipit fringilla. Fusce pretium metus non sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed hendrerit. Nulla felis. Suspendisse potenti. Aliquam blandit tristique neque. Curabitur quis erat vel nunc accumsan mollis. + +Duis sagittis, tellus ut aliquam fringilla, dolor mi ullamcorper nisl, ut tristique pede elit sed mauris. Curabitur id felis. Donec pulvinar lacus et lectus. Aliquam vulputate vulputate metus. Curabitur magna felis, adipiscing ac, accumsan vel, molestie quis, quam. Mauris elit arcu, pretium vitae, mollis sit amet, sollicitudin ut, mi. Donec imperdiet dignissim mi. Nullam sit amet tortor. Aliquam neque nulla, venenatis a, porta in, placerat tempus, lacus. Quisque vestibulum dui et lacus. Proin dignissim consectetuer purus. Etiam gravida tortor in nunc. Ut tempor tristique tortor. Sed laoreet tincidunt quam. Vestibulum porta turpis ut elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nibh dui, feugiat nec, laoreet id, malesuada eget, nisi. Ut neque massa, vehicula eu, commodo non, ultricies vitae, purus. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris euismod, felis vel tempor aliquet, tortor mauris malesuada nunc, vel fermentum sem diam id dui. Nam rutrum sapien eget odio. Aliquam sed libero non mi faucibus tempus. Fusce hendrerit, diam non volutpat rutrum, erat metus venenatis ligula, non scelerisque pede ligula vel quam. Morbi rhoncus eros ac dui feugiat elementum. Duis eu libero et tellus congue viverra. Morbi quam quam, elementum sed, ullamcorper imperdiet, commodo non, odio. Nam aliquet egestas urna. Mauris odio felis, varius eu, lacinia eu, condimentum a, lectus. Sed justo massa, pulvinar id, varius a, porttitor nec, libero. Etiam varius. Curabitur sodales, odio at posuere semper, eros nibh tincidunt lectus, vel rutrum sapien nisi in ligula. Suspendisse eget arcu. Phasellus imperdiet est ac sapien. Donec nulla tortor, placerat vel, tempus a, lobortis vel, nibh. Aliquam varius nisi. Nulla et enim. Fusce convallis laoreet lacus. + +Phasellus ipsum dolor, molestie quis, condimentum in, commodo eu, diam. Quisque bibendum lacinia dui. Nullam blandit vulputate orci. Ut lacinia massa vel augue. Aliquam gravida, quam quis imperdiet imperdiet, tellus diam pharetra erat, at pharetra lacus nibh egestas magna. Nulla sagittis lorem ut lorem. Duis condimentum, dui vitae aliquam posuere, diam quam convallis velit, ut gravida leo ipsum non risus. Ut fermentum sollicitudin erat. Donec sagittis scelerisque felis. Nunc arcu. Etiam tempus, magna sit amet suscipit euismod, eros sem rutrum dui, vitae sagittis nibh purus non lacus. Sed mollis arcu eget dolor. Donec ornare, arcu sit amet fermentum vulputate, risus enim fermentum libero, a lacinia dolor mi non velit. Etiam lobortis purus a elit. Nunc nulla dui, mattis quis, bibendum a, ultrices ac, augue. In aliquam vehicula turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Integer id nisl. Quisque dictum elementum odio. Aenean luctus. Sed eu sem a pede vulputate condimentum. Quisque magna. Donec aliquam mattis ipsum. Curabitur dictum sollicitudin sem. Aliquam pulvinar. Nunc sollicitudin risus a erat. Vivamus quis tellus sit amet nibh vestibulum consequat. Nulla pretium sollicitudin dolor. Aliquam iaculis tincidunt turpis. Phasellus ipsum leo, venenatis in, sagittis in, ornare at, nunc. + +Pellentesque ultrices, dui eu iaculis luctus, tellus augue volutpat sapien, in dignissim urna felis ut mi. Sed arcu dui, dignissim id, porttitor ut, imperdiet vitae, ante. Nulla dui sem, commodo nec, sagittis et, lacinia et, pede. Etiam eleifend dui ut nisl. Donec ante mauris, tempus sit amet, varius vitae, gravida quis, mi. In scelerisque, felis vitae viverra sagittis, velit metus ultricies neque, quis imperdiet velit elit et magna. Suspendisse potenti. Sed velit eros, euismod sed, condimentum nec, faucibus sed, sapien. Nam accumsan ligula sit amet neque. Aliquam erat volutpat. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam eu pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed eu felis sed tortor tempor fermentum. Phasellus commodo sem vel nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lectus elit, pharetra sit amet, accumsan sed, tincidunt et, mauris. Duis dapibus pharetra sem. Integer in justo. Praesent eros. Vestibulum ac ante. Aliquam scelerisque sem pellentesque nibh consectetuer sodales. Aliquam consectetuer odio. Duis lectus odio, luctus eu, commodo quis, mollis vitae, velit. Cras nec nunc non elit iaculis mattis. Aenean justo neque, sollicitudin eget, ullamcorper eget, egestas id, sem. In eu risus. Sed egestas. + +Integer at neque. Sed pretium scelerisque nulla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce ut pede. Etiam vitae quam a urna varius imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vehicula. Fusce ullamcorper nibh non erat. Quisque in neque. Praesent est. Pellentesque arcu. + +Proin posuere. Suspendisse potenti. Integer felis lacus, aliquam sed, vulputate in, mollis vel, tellus. Integer vehicula bibendum est. Nunc non dolor in tellus mattis facilisis. Integer vestibulum, augue at commodo aliquam, dui est mattis ligula, sit amet adipiscing orci sem vitae magna. Praesent enim velit, malesuada at, congue nec, luctus in, justo. Sed varius. Morbi pharetra. Donec eu massa nec tellus vulputate pulvinar. Ut commodo turpis non sem. Ut convallis ullamcorper risus. Etiam interdum pede id nisi. Cras magna sapien, suscipit a, laoreet non, rhoncus et, felis. Integer orci lorem, vestibulum dictum, ullamcorper a, porttitor et, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc et magna. Sed bibendum tellus in diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vitae tortor. Integer magna. Duis venenatis, leo ac tempor laoreet, elit nulla pharetra pede, non fermentum nunc odio a odio. Proin non velit. Sed imperdiet augue quis nisl. Integer condimentum nisl nec libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus placerat libero. Duis congue dictum magna. Aliquam dapibus bibendum enim. Nunc eleifend pede vel ipsum. + +Etiam vitae velit. Mauris erat nunc, malesuada ut, feugiat ac, placerat condimentum, augue. Nam volutpat. Aliquam vehicula ipsum id odio. Vivamus sollicitudin turpis id sapien. Fusce a felis vitae odio convallis blandit. Curabitur vitae eros id eros porta pretium. Nulla in magna eget urna lacinia convallis. Aliquam mattis venenatis purus. Sed sed mi eget erat tristique porta. Donec auctor dolor a erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In nec ligula. Nunc eleifend. Vestibulum quis nisi eget elit porttitor congue. Maecenas faucibus, magna eget adipiscing tincidunt, dolor ante malesuada elit, non elementum lacus turpis in pede. + +Ut malesuada mi nec metus. Praesent auctor augue ac nisl ultricies facilisis. Nam purus sapien, pellentesque dignissim, posuere eu, cursus id, diam. Quisque sollicitudin, elit a pellentesque scelerisque, lorem risus auctor quam, quis consequat tellus neque id urna. Suspendisse diam tortor, eleifend dignissim, egestas ut, luctus in, ante. Duis ante. Maecenas luctus. Curabitur cursus pharetra urna. Maecenas imperdiet, erat non elementum euismod, tortor odio euismod lectus, ac facilisis sem nibh vitae nulla. Nunc gravida. Morbi sollicitudin odio quis lacus. Aliquam a nibh non urna porta imperdiet. Aliquam erat volutpat. In iaculis lacinia velit. Sed libero lacus, tristique eu, lacinia ac, aliquet eget, urna. + +Etiam at nisl. Phasellus faucibus luctus lectus. Ut placerat vulputate dolor. Phasellus vel velit. Morbi viverra. Phasellus orci. Integer dignissim mattis mauris. Pellentesque posuere leo posuere quam. Quisque nec magna at diam viverra pellentesque. Suspendisse velit arcu, ultricies quis, congue a, venenatis eget, lacus. Integer sagittis hendrerit dolor. Fusce tincidunt ante a sem. + +Maecenas consectetuer, justo sed rhoncus venenatis, nibh arcu rutrum dolor, sed condimentum libero libero et ipsum. Vivamus mattis justo ut lorem tincidunt lobortis. Ut non velit id neque aliquet accumsan. Sed tempus viverra nulla. Curabitur ullamcorper, neque quis dapibus scelerisque, felis diam gravida orci, non cursus quam neque vitae elit. Etiam pharetra tincidunt lacus. Duis euismod fringilla est. Etiam ornare tincidunt lectus. Proin in turpis. Nunc blandit blandit turpis. Aenean ut augue. Duis orci justo, tincidunt eu, rutrum sed, rutrum et, turpis. Curabitur facilisis odio in ante. In hac habitasse platea dictumst. Sed eros est, pellentesque at, tincidunt eu, ultrices quis, metus. Morbi sit amet justo. Maecenas ac arcu. Mauris dignissim. + +Pellentesque ultricies rutrum orci. Aenean ornare. Vivamus eu risus vel mauris lobortis dictum. Sed et turpis auctor mi rhoncus pulvinar. Sed nec nunc a purus tempor viverra. Pellentesque suscipit. Donec tristique risus non nibh. Etiam nisl magna, sollicitudin ut, ultrices sit amet, egestas eu, nulla. Aliquam erat volutpat. Vestibulum pharetra. Sed egestas, metus sit amet lobortis consequat, erat elit imperdiet libero, eu interdum quam massa eget dolor. Suspendisse vitae odio. Proin blandit mauris iaculis metus. + +Vivamus vestibulum. Etiam et nisl. Aliquam in diam vel elit placerat suscipit. Duis sodales purus ac nibh. Nulla in odio eget enim luctus blandit. Curabitur ultrices ipsum non neque egestas eleifend. Sed turpis. Proin consectetuer. Vivamus mattis. In aliquet. + +Nunc id eros. Donec venenatis, nulla et mattis luctus, ante leo semper justo, non adipiscing odio risus sed lacus. Praesent vitae risus congue libero congue tempus. Phasellus ac eros. Nulla vehicula, lorem in aliquet suscipit, arcu erat egestas sem, quis lobortis quam ante eu massa. Curabitur non massa. Sed bibendum lacinia odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus volutpat blandit lacus. Proin porta, tellus ut auctor laoreet, lectus eros fermentum lectus, id sagittis arcu justo in turpis. Phasellus consequat. Nam pellentesque, mi id viverra convallis, nunc libero placerat leo, eleifend porta sem nisl vitae sapien. Pellentesque ligula libero, tristique non, porttitor rutrum, porttitor non, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer dictum tellus a tortor. Vivamus felis nunc, molestie non, rhoncus quis, pharetra id, dui. Donec risus metus, fringilla vel, aliquet eu, placerat id, neque. + +Suspendisse ipsum. Vivamus lectus. Sed viverra, massa eget convallis mattis, quam turpis consectetuer nunc, eget posuere magna sem id velit. In nec mauris. Aenean a purus sed quam lobortis fringilla. Proin ultricies lacinia ante. Sed adipiscing erat quis velit. Nullam vitae nisl id justo sollicitudin molestie. Nulla facilisi. Sed nec urna sed nisl fringilla dapibus. Nulla at diam. Aliquam eget nibh. Nunc ac nisi sit amet tellus egestas tempus. Nam scelerisque urna et neque. Donec est orci, sagittis non, vulputate a, commodo et, augue. Ut dapibus tortor. Ut nunc. Donec dictum dapibus odio. Nam ultricies ullamcorper ligula. Pellentesque accumsan varius leo. + +Morbi euismod laoreet erat. Vivamus quis ipsum. Morbi euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel purus. Nullam at magna. Curabitur lacus lorem, iaculis quis, dapibus non, volutpat vel, nulla. Donec ut arcu rhoncus dolor pretium dictum. Nullam vel metus. Ut arcu. Pellentesque nisi nunc, placerat eget, tincidunt vel, pharetra non, nunc. Integer tincidunt ultricies lectus. Integer semper, purus sed ultrices feugiat, nulla pede sollicitudin erat, vel auctor nulla ipsum vel lectus. Aenean mi. + +Nullam sed nisi et arcu imperdiet fermentum. Mauris nec metus. In ac dolor. In mi arcu, congue ac, pharetra nec, scelerisque sit amet, magna. Curabitur lacus. Curabitur et elit. Aliquam ullamcorper nunc eu elit. Sed convallis dolor at velit. Vestibulum dapibus, augue id consectetuer placerat, nunc massa blandit sapien, id aliquam elit nisi id mi. Phasellus sapien est, gravida eu, bibendum ut, adipiscing quis, est. Ut molestie quam vitae odio. Donec quis risus id erat faucibus sollicitudin. Nam id felis. Mauris sed enim vitae leo accumsan pretium. + +Nam justo. Donec turpis nisl, commodo et, interdum ac, consectetuer non, massa. Fusce sem metus, laoreet nec, posuere id, imperdiet in, velit. Donec vulputate justo eget turpis. Nulla pede. Morbi tincidunt. Fusce aliquet, quam et aliquam fringilla, ante ante iaculis dui, nec aliquam arcu purus sed erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus suscipit quam et est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; + +Integer sed tellus. Sed sed velit ultricies leo rutrum laoreet. Sed non eros ac purus sagittis feugiat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed hendrerit ligula sit amet nibh. Maecenas turpis. Morbi consectetuer, dolor et adipiscing imperdiet, ante neque feugiat dolor, at porta quam neque quis ligula. Mauris semper velit sit amet ipsum. Pellentesque tempus, purus in rutrum consequat, enim erat vehicula massa, id accumsan leo sapien nec purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In dolor. Integer facilisis libero sit amet pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut varius aliquet enim. Nulla facilisi. Curabitur consectetuer, odio eu pretium tincidunt, nunc nisi aliquet neque, vel imperdiet elit massa sit amet turpis. Pellentesque tempus, orci volutpat blandit fringilla, odio sem posuere ante, vitae bibendum urna lorem vitae eros. Praesent viverra rhoncus arcu. Sed auctor, est sit amet mollis mollis, quam quam gravida sapien, in commodo metus nulla auctor enim. Donec facilisis. + +Proin tincidunt, sapien eget ultricies adipiscing, est odio dictum arcu, ut mollis erat dui sit amet velit. Morbi est sem, interdum at, congue a, elementum vitae, metus. Suspendisse id augue. Mauris enim sem, pulvinar eget, tempus a, tempus sit amet, sapien. Fusce vestibulum consectetuer dui. Pellentesque erat. Sed dignissim placerat odio. Maecenas semper rhoncus lectus. Phasellus pretium. Duis libero elit, eleifend nec, egestas ut, cursus sed, felis. Nam nisl arcu, aliquet et, facilisis eu, luctus ut, risus. Etiam ultrices, dolor sed volutpat malesuada, turpis arcu imperdiet tortor, euismod commodo libero massa ut quam. Integer molestie purus non elit. Ut venenatis semper tortor. Etiam bibendum egestas ipsum. Mauris sollicitudin sem nec nibh. Nulla pretium metus eu metus. Pellentesque sit amet sem. + +Suspendisse ac nisi. Ut leo. Vestibulum hendrerit pretium dolor. Nunc feugiat malesuada purus. Cras et nibh. Curabitur nunc erat, malesuada vitae, laoreet ac, ultricies in, purus. Vivamus tellus arcu, sodales eu, facilisis a, lacinia nec, nunc. Pellentesque id velit. In eu nibh. Nunc nec erat. Sed dictum neque ut nisl. + +Morbi lectus tellus, tincidunt ac, porttitor ac, tristique in, eros. Donec luctus luctus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ut est et enim scelerisque accumsan. Donec ligula felis, lacinia quis, pellentesque in, semper vestibulum, elit. Mauris eget orci a felis congue vehicula. Ut sollicitudin. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam id dolor ut lorem dignissim venenatis. Suspendisse vitae sapien. Proin non magna ut eros viverra pulvinar. Donec quis odio. Nullam non arcu vel lorem suscipit aliquam. Aliquam rutrum turpis in leo. + +Ut luctus nibh tristique erat. Suspendisse bibendum odio vitae tortor. Donec lacinia. Cras sodales felis luctus nulla. Nam eleifend sagittis ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse vel neque. Morbi aliquet vehicula magna. Aenean at odio. Duis pellentesque magna. Nulla at tortor ut diam dictum faucibus. Mauris quis velit. Donec non tellus vitae lorem fringilla porttitor. Fusce ut sapien quis tortor feugiat sagittis. Donec viverra sem vitae sapien. Praesent sodales, lacus in fringilla viverra, odio augue adipiscing urna, vitae interdum ante sem non nisi. Nullam tortor lorem, eleifend ac, mollis non, laoreet ac, risus. Integer ornare leo sed justo. Quisque cursus, sem non facilisis bibendum, nisi mi varius felis, fermentum feugiat lorem eros laoreet risus. + +Quisque sit amet est et lorem vehicula lacinia. Donec nec tortor. Cras odio. Nam scelerisque vulputate urna. Praesent dui. Etiam nec nisl lobortis ipsum aliquet tempus. Maecenas pretium sollicitudin mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus augue massa, congue eget, convallis eget, tristique sit amet, eros. Sed consequat nisi eu felis. Pellentesque justo. Suspendisse non augue. In dignissim lobortis mauris. Mauris sagittis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + +Sed adipiscing. Donec a tellus vitae est cursus vehicula. Nam ante sem, sodales id, fringilla vel, condimentum vel, nulla. Quisque sodales. Etiam imperdiet elit id odio. Aliquam erat volutpat. Maecenas porta tempor arcu. Nulla sem augue, pellentesque ac, consequat ut, condimentum euismod, risus. Sed aliquam tincidunt mi. In interdum lobortis orci. + +Sed vehicula hendrerit purus. Etiam a diam. Curabitur convallis. Suspendisse a nisi. Donec id magna in quam sollicitudin ultricies. Donec viverra. Quisque volutpat est sed sem. Aliquam justo. Vestibulum tortor massa, porttitor sed, varius quis, iaculis quis, odio. Aliquam eget neque. + +Mauris nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum eu quam in neque ultrices pellentesque. Cras in dolor quis quam varius hendrerit. Aliquam nisi lacus, lobortis eu, convallis sit amet, facilisis ut, mi. Aliquam at neque. Cras sagittis elementum justo. Vestibulum ut lectus aliquet purus malesuada volutpat. Duis at lacus adipiscing libero tincidunt vestibulum. Morbi a libero. Cras purus. Morbi ut augue et purus interdum scelerisque. Integer a dui. In hac habitasse platea dictumst. Duis pharetra metus eget mauris. Aliquam interdum ullamcorper massa. + +Etiam ornare. Nullam euismod. Aenean consequat gravida ligula. Aliquam est. Proin vitae lacus. Praesent a eros sit amet dui luctus commodo. Phasellus vehicula arcu eget dolor. Praesent fermentum congue leo. Aliquam volutpat purus ut lorem. Fusce hendrerit enim at leo. Aliquam rhoncus nisl. Vivamus dictum egestas mi. Suspendisse pellentesque bibendum dolor. Pellentesque tincidunt, turpis semper pellentesque condimentum, ipsum metus sodales ligula, id volutpat diam turpis ut elit. + +Praesent sed lacus. Nam eleifend molestie mauris. Donec dapibus fermentum massa. Donec viverra faucibus purus. Curabitur congue, libero vitae viverra pellentesque, diam velit sodales enim, sed suscipit lectus nisi nec neque. Vestibulum malesuada, lacus at cursus congue, velit lectus tristique dolor, sit amet sodales neque ipsum a libero. Vestibulum et quam. Curabitur placerat. Curabitur nunc arcu, euismod nec, vulputate hendrerit, aliquet eget, quam. Curabitur vel enim. Suspendisse potenti. + +Nunc consequat orci ut lacus. Fusce velit dolor, dapibus sed, blandit sit amet, rhoncus id, risus. Duis urna nibh, scelerisque quis, dapibus a, scelerisque sed, nibh. Donec luctus. Ut eu mauris cursus diam lacinia rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam vehicula molestie justo. Maecenas imperdiet pede sed mi. Suspendisse nulla dolor, hendrerit eget, hendrerit id, dictum vel, leo. Duis accumsan. Curabitur in felis. Nunc lorem. Ut leo dolor, laoreet nec, vulputate at, eleifend in, nulla. Quisque nunc purus, varius eget, accumsan nec, aliquet et, nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras adipiscing viverra dolor. Mauris porttitor ultrices purus. Nulla facilisi. Praesent faucibus ante vitae mauris. + +Praesent lacinia lectus sed nisl. In tempus congue mauris. Integer facilisis ornare enim. Nulla id massa. Donec commodo diam at tellus. Nam dapibus viverra est. Nam tellus. Praesent a libero. In faucibus est eget nibh. Nulla eros orci, imperdiet non, blandit non, tempor eget, mi. Pellentesque convallis. + +Quisque eget mi ac leo euismod faucibus. Phasellus rhoncus purus id dui. Vestibulum malesuada eleifend ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque blandit mattis odio. Suspendisse consequat, lectus ac semper sollicitudin, mi velit dictum augue, ac tempus dolor erat sit amet dui. Proin hendrerit, felis quis volutpat posuere, diam odio malesuada odio, a interdum orci diam quis sapien. Pellentesque odio odio, viverra vel, gravida eu, molestie sed, nulla. Phasellus mauris pede, commodo ut, euismod eu, hendrerit eu, est. In hac habitasse platea dictumst. Nulla elementum lacus eu augue. Sed erat. Proin porta. Maecenas quis mi. Phasellus at enim ac justo gravida ultrices. Cras leo. + +Integer ut arcu. Donec sed magna. Proin felis. In iaculis, ligula id fringilla pretium, nibh diam accumsan tellus, eget accumsan metus dui varius turpis. Phasellus orci metus, eleifend sed, tempor ac, scelerisque ac, urna. Integer viverra neque a mauris. Mauris porttitor dolor eu velit. Integer odio elit, vestibulum ut, volutpat id, rhoncus commodo, urna. Etiam placerat pharetra erat. Ut tempor est. Integer dignissim blandit tellus. Morbi nibh dolor, scelerisque id, commodo malesuada, mattis at, mi. Cras tincidunt commodo purus. In tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ullamcorper. Ut hendrerit. Morbi ultrices. + +Praesent iaculis, eros ac egestas sodales, urna leo fermentum ligula, sit amet aliquam velit sem non purus. Donec rutrum arcu quis purus. Nam posuere, lacus at consequat placerat, nulla pede posuere orci, non euismod turpis dui quis nisl. Proin porta adipiscing nibh. Donec tristique dolor at tellus. Donec neque massa, auctor id, faucibus vitae, ullamcorper vel, nisi. Proin molestie neque sed massa. Nam tempor. Morbi aliquam sapien at tellus. Fusce quis risus et mi pretium pulvinar. Fusce sit amet ligula. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse eu enim et felis scelerisque lobortis. Praesent bibendum. Vivamus vehicula. Integer at nibh sed velit rhoncus molestie. Cras lacus. Sed ullamcorper eros vel erat. Fusce eu tortor sit amet diam euismod sagittis. Nunc quis lacus id nibh convallis varius. Suspendisse vitae mi. Vestibulum tristique. Donec malesuada ipsum id neque. Nullam sed lacus. Duis egestas, justo ut congue ornare, augue sapien luctus diam, at accumsan erat sapien ut libero. Phasellus vel nulla. Suspendisse arcu tellus, porttitor a, pharetra faucibus, aliquam sit amet, massa. Nulla porttitor tincidunt lorem. Nunc dolor odio, sagittis in, lobortis vel, volutpat sed, nibh. + +Quisque blandit leo ut sapien tempus facilisis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean ultricies porttitor justo. Fusce rutrum eros ut urna. Proin quis quam eget dui aliquam accumsan. Donec suscipit eleifend elit. Pellentesque mattis, felis sodales iaculis imperdiet, lacus sem convallis augue, sit amet aliquet arcu purus fringilla risus. In eu odio id magna pharetra ornare. Aliquam interdum pulvinar ipsum. Sed neque. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam sit amet nisi. Ut at augue. Mauris volutpat blandit ligula. Nulla eu metus. Vestibulum eget elit. Praesent posuere. Vestibulum id sem non lectus mollis tincidunt. Aliquam id felis at ante ornare tempor. Nulla lacus turpis, feugiat vitae, cursus quis, consectetuer non, mauris. Fusce lacus massa, porttitor ut, molestie ut, venenatis a, lorem. Praesent sit amet orci. Mauris rhoncus felis vitae felis adipiscing imperdiet. Maecenas mollis diam nec leo. + +Fusce enim ipsum, ultrices eu, molestie id, elementum id, sapien. Integer a urna. Nam velit libero, venenatis eget, tempor sit amet, feugiat vitae, ante. Fusce nunc. Sed semper nisl nec risus. In sed libero. Proin tortor neque, tincidunt ac, tempor ac, pharetra quis, velit. Duis lectus augue, ultricies vel, consequat id, iaculis id, ante. Vivamus auctor metus a ante. Curabitur arcu nisi, facilisis at, laoreet in, consectetuer sed, mauris. Quisque placerat diam sed dui. Vivamus pretium condimentum lorem. Curabitur laoreet. Aenean orci ligula, cursus eget, lacinia non, faucibus vel, lorem. + +Aliquam erat volutpat. Curabitur eros dolor, congue a, condimentum sed, luctus ut, nibh. Maecenas non tortor nec turpis commodo pellentesque. Praesent euismod placerat mi. Suspendisse potenti. Phasellus ut neque vitae orci mattis iaculis. Integer eget tellus. Donec at ante. Nam lacinia leo eget erat. Maecenas euismod magna congue tortor. Morbi nec massa eu enim malesuada sollicitudin. Sed accumsan. Nullam ipsum. Ut odio. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque id velit. Nam odio sem, aliquet ut, tempus sit amet, euismod et, nunc. + +Pellentesque libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent mauris nunc, varius ut, convallis molestie, luctus sit amet, leo. Sed dictum lorem et arcu. Nunc venenatis pellentesque massa. Nulla facilisi. Phasellus in tortor eget risus scelerisque vulputate. Sed nibh elit, sagittis ac, condimentum nec, convallis et, justo. Fusce volutpat metus. Nunc auctor. Vestibulum leo eros, pellentesque ac, mollis ultrices, rhoncus non, dolor. Mauris vehicula placerat nisl. Vestibulum bibendum, arcu quis congue elementum, velit nunc eleifend turpis, id luctus risus nisl sit amet tellus. Phasellus pede neque, blandit non, commodo vitae, ultricies eget, magna. Aliquam erat volutpat. + +Nulla facilisi. Aliquam ac ante. Cras risus. Morbi mauris lacus, posuere eu, blandit et, pharetra at, mi. Proin ac purus. Duis cursus nisl rutrum quam. Aliquam a odio non magna pellentesque ultricies. Maecenas ac massa quis sapien ullamcorper tempus. Cras cursus velit sed sapien. Proin nulla. Vivamus sodales aliquam nibh. Etiam et erat ut ante lacinia euismod. Fusce nisi. Proin quis nulla. + +Quisque venenatis, eros sed laoreet sollicitudin, orci ante pellentesque nisl, sit amet viverra quam erat non risus. Cras eget libero. Sed elit magna, semper eu, fringilla in, dignissim sodales, erat. Vivamus feugiat sem vel dui. Donec convallis sollicitudin diam. Cras sed purus. Donec felis eros, semper eget, tempor consectetuer, sagittis quis, nisl. Duis in ante. Cras non turpis. Nulla tempor velit aliquet turpis molestie placerat. Proin elementum fermentum mauris. Vivamus sed orci lacinia dui placerat venenatis. Vestibulum feugiat, tellus in volutpat rutrum, magna nisi ullamcorper eros, id pulvinar neque erat ut lacus. Vivamus sed augue. Nulla facilisi. Maecenas ante augue, elementum ut, sodales vitae, condimentum nec, lorem. Duis pede orci, fringilla at, eleifend nec, pretium in, erat. Nam sagittis, turpis vitae convallis pharetra, odio sem scelerisque lacus, nec lobortis dui diam vel eros. In semper gravida neque. + +Integer nunc. Ut pretium ipsum sit amet elit. In nec arcu. Sed vestibulum vulputate ipsum. Pellentesque tincidunt. Nulla gravida dolor in tellus. Cras vehicula, dolor ut pellentesque aliquam, erat enim auctor massa, vehicula lobortis odio eros quis quam. Proin dapibus neque in enim. Proin elit. Integer rhoncus tincidunt elit. Fusce lorem metus, semper ac, volutpat vitae, facilisis ut, tellus. Donec vel turpis vitae nisi pharetra porttitor. Maecenas tortor. Fusce mi. Nullam nec turpis. Sed sodales vestibulum nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Pellentesque dolor dolor, laoreet eu, aliquet quis, scelerisque sit amet, arcu. In hac habitasse platea dictumst. Nullam cursus urna eget elit. Quisque blandit sapien ac ante. Proin nulla eros, gravida volutpat, sodales vel, mollis eu, massa. Nulla tristique sollicitudin nisl. Curabitur vitae lorem vitae velit egestas ornare. Aenean eget eros. Aliquam erat volutpat. Fusce a urna id odio aliquet convallis. Curabitur sit amet nisl posuere leo posuere dapibus. Duis metus erat, luctus vel, rhoncus at, convallis sit amet, enim. Vivamus hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam eget elit. + +Nullam a nunc. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In metus urna, tincidunt et, lacinia sit amet, lobortis vitae, ligula. Proin et mauris vitae mi accumsan pellentesque. Etiam quam purus, hendrerit sed, feugiat vitae, euismod eget, tortor. Ut aliquam magna vitae justo. Suspendisse non justo vel velit condimentum tempus. Duis tempus ipsum vitae tellus. Proin in massa. Etiam ullamcorper dictum tellus. Proin aliquet felis at leo laoreet pulvinar. Vestibulum arcu purus, malesuada sit amet, cursus eu, placerat sit amet, nunc. Nam massa odio, sollicitudin in, adipiscing a, aliquam nec, risus. Aliquam blandit hendrerit libero. Mauris gravida. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur a nibh. Ut interdum fermentum neque. Pellentesque sed nunc. Mauris vehicula nisi et nunc. Praesent lorem. Donec semper. Integer eu lacus in est aliquam hendrerit. Vestibulum eget neque. Sed semper luctus velit. Curabitur nibh augue, congue eu, hendrerit id, congue et, enim. Integer placerat aliquam lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae eros. Donec vel nisl. + +In vestibulum facilisis urna. Ut risus. Mauris pharetra. Pellentesque mattis. Integer suscipit aliquam ipsum. Duis blandit, sapien et ultricies condimentum, felis mi elementum pede, nec sagittis metus mauris quis quam. Quisque accumsan arcu vel nulla. Cras sem sapien, porttitor id, ultricies sagittis, luctus eu, nulla. Integer quis eros. Morbi sed urna a tellus vehicula vulputate. Etiam nec augue eget felis semper tristique. Quisque ut dolor vel risus dictum consequat. Sed eget dolor sed nunc lacinia aliquet. Suspendisse ac tortor in ipsum posuere venenatis. Sed eget erat. Nulla faucibus. Duis laoreet, massa porttitor aliquet egestas, ipsum lectus rhoncus quam, in adipiscing eros sem ut tellus. Pellentesque feugiat tempus quam. Vivamus id dolor eget sapien consectetuer tempor. Aliquam erat volutpat. + +Nulla iaculis fermentum libero. Curabitur faucibus, massa malesuada cursus tincidunt, erat sem eleifend mauris, sed fringilla mi ante ac purus. Duis elementum lectus. Nunc ornare arcu eu tortor. Vestibulum vel dolor at purus lacinia fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas tincidunt, eros a egestas pellentesque, risus risus dictum libero, id aliquet metus justo in massa. Proin a tellus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed purus. Sed non pede. Aenean massa sapien, sodales sit amet, consequat dictum, eleifend vitae, tortor. Donec ultrices lacinia elit. + +Morbi adipiscing sodales dolor. Ut ullamcorper ultricies est. In venenatis tempus augue. Suspendisse tortor dolor, accumsan et, suscipit a, tincidunt ut, libero. Aliquam scelerisque magna sed felis. Quisque ut nunc a magna vulputate placerat. Aliquam rhoncus vehicula dui. Sed tortor. Nullam sit amet diam. Nunc sed eros. Sed et odio tincidunt elit gravida convallis. Curabitur quis tortor a lacus semper varius. Mauris at augue non mi sollicitudin aliquam. Integer ullamcorper. Pellentesque suscipit quam non purus. Aliquam ac eros at arcu ullamcorper consectetuer. Suspendisse pretium mattis leo. + +Duis at nunc. Sed dolor est, varius ac, porta et, tincidunt hendrerit, risus. Vivamus ut magna. Praesent ut mauris. In purus lacus, mattis sed, vestibulum nec, tempor at, nisl. Cras ullamcorper venenatis tellus. Ut dolor. Maecenas malesuada, pede a pulvinar mattis, arcu diam vehicula risus, quis porttitor augue massa in velit. Nunc congue. Morbi velit metus, rhoncus et, aliquam consectetuer, ultricies malesuada, ligula. Sed velit nisl, sagittis vitae, pharetra a, posuere sed, massa. Nulla facilisi. In varius, ligula id lobortis sodales, augue orci fermentum tellus, eu pulvinar risus ligula a sapien. Morbi laoreet ipsum non mi. Nam cursus lorem ut mi. Vivamus magna enim, posuere non, semper quis, sodales eu, arcu. Etiam mi purus, pretium feugiat, varius sed, pellentesque eget, ligula. In leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vitae orci eu orci sollicitudin feugiat. + +Praesent purus massa, euismod vitae, tempus nec, consequat hendrerit, metus. Aenean felis est, egestas vitae, accumsan eget, pellentesque in, sapien. Duis dapibus pede non sapien. Nunc urna. Integer vel libero. Duis augue arcu, dapibus non, facilisis vitae, posuere ut, eros. Donec vitae nunc sit amet arcu imperdiet dictum. Morbi eleifend, lorem eu consectetuer vestibulum, diam nunc ornare arcu, ac tempor felis dolor eget eros. Phasellus massa sem, sollicitudin ac, sodales gravida, luctus a, quam. Nam neque quam, viverra at, venenatis quis, sagittis non, enim. + +Nulla facilisi. Pellentesque egestas lacinia est. Sed tincidunt, pede sed tincidunt vestibulum, urna dolor adipiscing purus, vitae fringilla felis elit in nibh. Nulla sed nisi. Mauris suscipit scelerisque arcu. Etiam non enim vel eros accumsan malesuada. Nunc tincidunt commodo mauris. In tincidunt risus quis urna. Nulla diam tortor, aliquet et, tincidunt quis, sollicitudin ac, tortor. Cras nisl neque, vulputate suscipit, molestie quis, pulvinar at, nulla. Nullam ac metus nec odio posuere varius. Cras sed pede nec dui posuere bibendum. Duis euismod ullamcorper libero. Aliquam faucibus pulvinar turpis. + +In ut neque id nunc feugiat commodo. Curabitur dignissim, felis at sollicitudin lacinia, enim elit suscipit neque, sed luctus lorem ipsum in leo. Duis dapibus, odio quis auctor commodo, nisl odio mattis tellus, nec tincidunt turpis diam in arcu. Curabitur a sem. Nullam volutpat magna. Pellentesque sagittis, neque consequat pretium cursus, dolor lacus consectetuer arcu, sed laoreet est urna et metus. Suspendisse placerat, dui a porta tempor, lorem dui lobortis neque, sed venenatis diam enim id eros. Etiam et nisl non lectus faucibus consectetuer. Morbi scelerisque, sem nec tempus ullamcorper, ipsum diam feugiat lorem, a fringilla sapien elit quis nibh. Nullam diam urna, viverra sed, pharetra rhoncus, tincidunt vel, orci. Integer accumsan mattis erat. Nam dictum. Mauris nec leo. Nulla iaculis. Nulla nisl mi, dapibus quis, vehicula a, cursus eget, odio. + +Phasellus dapibus euismod nibh. Vivamus imperdiet ante in ligula. Pellentesque accumsan. In imperdiet, dui a auctor fringilla, metus nisi cursus dolor, vel luctus ligula lorem vitae mauris. Praesent mattis vestibulum elit. Aliquam enim lacus, pulvinar non, lacinia sit amet, eleifend non, velit. Vestibulum ac leo. Mauris imperdiet justo ac lectus. Sed molestie lectus sed dui. Sed fermentum tempus mauris. Nam ornare orci ac tellus. Ut malesuada, lacus id lacinia accumsan, diam elit adipiscing metus, et bibendum sapien nibh blandit orci. Suspendisse ipsum tellus, sagittis quis, vestibulum non, vulputate eu, eros. Praesent at nulla id pede scelerisque ultricies. Cras blandit pretium tellus. Maecenas dapibus condimentum augue. Phasellus tincidunt pharetra lorem. Morbi non eros. Sed tempor, nisl a tincidunt tincidunt, eros diam dictum sem, vel dignissim ante diam sed magna. Praesent non ligula id metus molestie consectetuer. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse vel mi. Curabitur ante nulla, rutrum a, convallis vel, vehicula ac, nunc. Nunc sagittis, enim sit amet auctor rutrum, mauris arcu vulputate neque, et euismod est felis quis ante. Vestibulum turpis tellus, hendrerit in, lacinia commodo, ullamcorper gravida, risus. Mauris rhoncus lacinia risus. Maecenas sollicitudin erat vitae nunc. Praesent pretium pellentesque augue. Donec interdum. Praesent ac eros vitae erat lobortis fringilla. Aenean consequat tellus. Nulla accumsan bibendum felis. Maecenas pretium ante id nisi. Aenean mi arcu, semper sed, mattis eu, venenatis sit amet, arcu. Donec aliquet euismod leo. Proin magna justo, tristique a, semper ac, sollicitudin a, ligula. Morbi velit. Aliquam vel nisi. + +In a lorem ut nunc feugiat congue. Donec fermentum bibendum dui. Proin varius est quis velit. Donec aliquet sem accumsan mi. Sed placerat. Nullam ac nisi a massa lobortis suscipit. Nunc id leo. Aliquam et massa. Nullam vestibulum elementum metus. In consectetuer nisi vel justo. Maecenas eget purus sed massa varius pellentesque. Phasellus faucibus felis quis felis. Aenean odio arcu, blandit quis, facilisis in, imperdiet eu, lorem. Nam posuere pulvinar mi. Fusce tristique, mauris et consectetuer ultricies, mauris lectus tempor justo, at fringilla est est sed nisi. Quisque faucibus. Sed in tortor tincidunt est lacinia iaculis. Maecenas a massa. Pellentesque a nibh at purus porta hendrerit. + +Nullam turpis. Fusce ac sem sed odio pellentesque imperdiet. Curabitur in arcu. Praesent lacus lacus, feugiat id, pulvinar in, tincidunt sed, neque. Maecenas viverra odio eget tortor. Integer aliquam, lorem rutrum venenatis dignissim, ligula magna malesuada arcu, vel feugiat lorem ipsum quis massa. Morbi ante. Vestibulum mauris libero, ullamcorper quis, ultrices quis, facilisis non, massa. Maecenas imperdiet. Aliquam erat volutpat. Pellentesque dignissim gravida lectus. In nibh odio, auctor eget, dapibus quis, dignissim venenatis, arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis pellentesque ligula quis massa. Curabitur condimentum, justo eget ornare luctus, lorem ligula sagittis pede, a porta nunc nunc in neque. Quisque felis mauris, condimentum vitae, auctor vitae, tincidunt quis, pede. Nunc lacinia ante in leo. Pellentesque libero. Aenean a ligula et nunc vestibulum consectetuer. + +Fusce ornare. Praesent id urna. Integer venenatis, quam non sagittis accumsan, ante nibh sagittis augue, sollicitudin adipiscing dolor velit eu erat. Proin quis enim eu purus vehicula aliquam. Nulla vel enim vel elit sollicitudin fringilla. Aliquam erat volutpat. Sed suscipit felis ut turpis. Etiam rutrum risus imperdiet est. Aliquam a tellus at tellus commodo dapibus. Mauris rutrum magna et odio. In at dolor. Curabitur vehicula lectus in tortor. Fusce justo purus, luctus vitae, mollis in, pharetra ac, purus. Nullam posuere interdum justo. Curabitur vitae lacus vel leo congue pulvinar. + +Aenean eleifend nibh varius tortor. Suspendisse vel eros. Proin nec diam a tortor ultrices ornare. Aliquam scelerisque feugiat justo. Vivamus ante urna, adipiscing vitae, porttitor eu, sodales et, felis. Suspendisse potenti. Curabitur ac massa in nisl sagittis mollis. Nam quam ligula, consectetuer eget, iaculis at, varius eu, leo. Duis dolor ligula, tincidunt at, ullamcorper sed, accumsan aliquam, ligula. Phasellus vulputate, lorem at tincidunt pharetra, risus lectus lacinia magna, quis rutrum enim magna at sem. In hac habitasse platea dictumst. Duis id sem a mauris sollicitudin tincidunt. Etiam eu purus eu arcu fringilla adipiscing. Vivamus ornare tempus diam. Proin turpis quam, lacinia non, egestas at, commodo eget, pede. Praesent vulputate risus in est. Nulla facilisi. + +Ut elementum lacinia purus. Proin vitae arcu ac nulla convallis aliquam. Nulla congue, libero id pellentesque mattis, quam lectus porttitor diam, a scelerisque dui libero in sapien. Nullam felis diam, vehicula vel, molestie ut, vestibulum aliquam, sapien. Donec convallis, est ut elementum volutpat, mauris ipsum gravida sem, commodo facilisis sapien lectus semper lectus. Quisque porttitor eros ut nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam mattis risus sed odio. Vestibulum et odio. In hac habitasse platea dictumst. Nam tristique massa ut ligula. Quisque nibh tellus, vehicula sit amet, adipiscing at, convallis nec, ligula. Vestibulum pretium, mi nec fringilla bibendum, dui nunc sodales pede, a semper magna nibh non diam. Donec massa nunc, viverra vel, consectetuer porta, dapibus non, ipsum. Duis nisl mauris, cursus vel, semper non, sollicitudin bibendum, felis. Vestibulum eu neque. + +Cras nec dolor. Donec laoreet tempus lectus. Cras sed tortor interdum lacus eleifend dignissim. Maecenas sit amet elit. Nullam quis dolor vel dui pharetra luctus. In sit amet quam sit amet pede ultrices ultrices. Maecenas diam. Integer urna. Curabitur dictum, velit sed placerat suscipit, erat turpis fermentum justo, sed interdum neque sem et nibh. Vivamus consequat convallis magna. Nam aliquam, est ac bibendum commodo, magna est dictum mi, vitae malesuada elit magna vitae odio. Maecenas tempor vulputate tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus dui. Etiam accumsan pede congue tortor. + +Morbi tempor libero ac lorem. In aliquet varius magna. In arcu. Phasellus odio. Fusce tincidunt aliquet felis. Quisque velit. Sed luctus. Aliquam feugiat fringilla mi. Aliquam molestie viverra risus. Proin arcu. Vestibulum lobortis tempus nisi. Praesent a arcu in velit viverra rutrum. + +In sed lectus. Donec risus dolor, blandit sit amet, elementum convallis, pharetra quis, pede. Integer ornare. Aenean egestas dapibus justo. Sed quam leo, posuere at, elementum vitae, commodo eget, est. Aliquam molestie rhoncus enim. Curabitur iaculis ultrices pede. Morbi aliquet rutrum lacus. Aliquam quam. Sed commodo, turpis in pharetra posuere, mi risus imperdiet erat, a vestibulum massa tellus vehicula sem. Mauris fringilla ultrices nunc. Nam nisi enim, eleifend sit amet, ultrices sed, fermentum non, augue. Proin congue lobortis nisi. Maecenas hendrerit. Nam sed nisl. Nunc elementum odio eu risus. In metus. Phasellus gravida pretium ligula. Nulla vitae neque. Nam nisi tortor, ornare non, blandit at, cursus eu, tortor. + +Duis bibendum ipsum in nunc cursus molestie. Nunc orci. Nullam nec ante non est dignissim viverra. Mauris blandit, velit id feugiat pretium, elit magna pellentesque dolor, at sagittis lacus velit egestas magna. Pellentesque cursus, diam consectetuer sagittis fringilla, tortor nisi adipiscing nunc, eu varius lacus risus ac elit. Mauris id nisi quis leo euismod venenatis. Pellentesque ac ante. Mauris arcu sapien, tempor at, porttitor id, condimentum ut, dui. Etiam fermentum ultricies augue. Cras ut eros at justo ultricies iaculis. Duis dignissim, nisl et facilisis fermentum, erat purus molestie tellus, quis tempus ipsum lectus at elit. Nulla vitae lorem. + +Aenean vel sem et diam semper congue. In bibendum diam quis tellus. Nunc facilisis ultricies nibh. Cras nunc enim, feugiat sed, ultrices vitae, sagittis vitae, ipsum. Fusce vitae nulla. Donec pellentesque, velit in porttitor eleifend, est neque lobortis velit, sit amet rutrum ante tortor nec dolor. Donec vehicula. Nulla facilisi. Sed egestas ultrices nibh. Donec elit lectus, convallis porttitor, aliquet dapibus, feugiat eget, ligula. Sed consectetuer justo. Maecenas a sapien sit amet nisi dapibus lobortis. Vivamus luctus lorem non nulla. Sed eget erat vitae libero interdum posuere. Cras pulvinar. Nullam imperdiet, dolor tempor dignissim blandit, dui sapien rhoncus neque, id malesuada augue magna sit amet urna. Duis sed mauris. + +Morbi accumsan. Sed mauris augue, fringilla non, auctor ut, auctor et, orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus ut pede. Donec viverra enim vel lorem. Pellentesque neque mauris, interdum eu, venenatis id, condimentum eu, sapien. Donec ipsum arcu, lacinia adipiscing, laoreet et, cursus vel, velit. Ut sagittis mauris quis risus. Integer eu odio vitae lacus viverra accumsan. Morbi leo ante, dignissim sed, varius quis, volutpat vitae, nisi. Nulla placerat interdum elit. Donec neque dui, sagittis vitae, sollicitudin quis, commodo vitae, neque. Nulla quis ligula ornare ligula dictum ornare. Mauris rutrum rutrum neque. Aenean vehicula tempus est. Donec varius scelerisque pede. Donec placerat vulputate leo. Nullam nunc nisl, posuere non, feugiat vitae, pellentesque quis, mauris. In dui neque, cursus eget, sagittis eget, dapibus vitae, mi. Proin eget est. + +Fusce porta est. Mauris magna. Aliquam ipsum lacus, ultricies id, vestibulum luctus, accumsan ut, ante. Sed mauris. Sed adipiscing leo sit amet magna. Suspendisse potenti. Nunc massa elit, fringilla eget, egestas vitae, luctus vitae, dolor. Phasellus quis nulla eu nisi interdum sollicitudin. Nullam id tellus. Integer iaculis dolor ac purus. Sed vel mi. Curabitur non magna sit amet justo condimentum vulputate. Quisque tincidunt pede eu nisl. Vivamus lobortis. Nunc metus metus, congue sed, tincidunt sed, pretium at, odio. Donec a arcu. In sem justo, vehicula sed, varius id, volutpat at, risus. Praesent iaculis massa. In arcu elit, hendrerit eget, ullamcorper in, porta id, tellus. Donec sagittis hendrerit diam. + +Suspendisse potenti. Sed et diam et augue sagittis lobortis. Phasellus dolor. Ut et arcu eget ante tempor posuere. Aliquam fermentum scelerisque dui. Mauris at purus. Donec erat sem, vestibulum nec, faucibus ac, mattis a, leo. Suspendisse adipiscing lacinia sem. Nullam orci arcu, dictum et, faucibus viverra, dapibus et, neque. Cras nunc diam, adipiscing non, sollicitudin in, interdum vel, massa. Mauris sagittis, justo at tristique tempus, mauris mauris aliquam ante, sit amet posuere diam dui eget ligula. In dignissim, nisl ut lacinia condimentum, erat justo porttitor nulla, non gravida ligula magna eget massa. Vestibulum vitae ligula at mi vestibulum suscipit. Duis laoreet. Nulla commodo libero sit amet lorem. Ut elementum sem. Integer vel dolor. Nam facilisis mi quis sem ultrices sagittis. Sed quis quam at metus molestie bibendum. + +Proin dui enim, lacinia a, feugiat ac, placerat vitae, pede. Quisque egestas, leo eget aliquam pretium, libero justo tincidunt eros, ut egestas augue pede elementum nibh. Curabitur mollis sodales enim. Donec augue. Phasellus id ipsum posuere dui pretium faucibus. Mauris luctus ante semper nisi interdum adipiscing. Duis dapibus, odio quis viverra rhoncus, justo quam bibendum dolor, id dapibus velit erat vel erat. Fusce sit amet nisl venenatis quam ultrices condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec rhoncus scelerisque ligula. Vestibulum mi odio, accumsan et, adipiscing eget, ornare ut, quam. Nullam blandit molestie mauris. Curabitur dignissim mauris et lorem. Suspendisse a justo. Nam mattis faucibus arcu. Duis blandit enim non massa. + +Nullam lorem. In hac habitasse platea dictumst. Mauris consectetuer posuere mauris. Maecenas tincidunt mauris in eros. Nulla eu metus eu orci sollicitudin faucibus. Suspendisse aliquam mauris id est. Cras blandit dui et urna. Nulla arcu. Sed a urna. Nulla dapibus vehicula tortor. Donec risus. Sed quam metus, egestas eu, cursus ut, viverra non, odio. Ut justo justo, malesuada sit amet, blandit suscipit, molestie in, justo. Vestibulum consequat, quam ac feugiat tincidunt, ipsum libero eleifend odio, non eleifend pede ipsum non ante. Nullam a metus. + +Nam ac nisi at felis cursus mattis. Pellentesque consequat sem quis orci. Quisque tempus. Aenean imperdiet molestie pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eu tellus. Nulla diam eros, sodales ut, sodales nec, tincidunt ac, nunc. Nunc lacinia faucibus ipsum. Vivamus vel neque in erat fermentum luctus. Nulla eget metus nec augue bibendum placerat. Vivamus tempus. Praesent congue ornare ipsum. Etiam mattis feugiat justo. + +Aliquam dui. Aenean commodo tortor vitae nulla. Morbi et ipsum. Mauris ac ipsum. Nam vel risus ut lectus mollis viverra. Curabitur elementum mollis est. Nullam elit. Vestibulum suscipit pretium enim. Vestibulum ut massa. Proin nec felis. Maecenas gravida, arcu nec consequat sagittis, eros tellus scelerisque mauris, vitae accumsan quam quam ut nunc. Integer eget ante eu velit laoreet malesuada. Nunc sagittis, mauris vitae pharetra volutpat, tellus tellus eleifend eros, sit amet rutrum ipsum nisi a velit. Praesent varius leo eu erat. Vivamus consequat placerat purus. Donec pretium elementum nibh. Proin at elit non sem aliquet mattis. Sed ullamcorper ipsum sit amet elit. + +Mauris in metus. Suspendisse magna lorem, faucibus vel, tincidunt quis, scelerisque non, tellus. Fusce quis lorem. Proin a lacus sit amet mauris iaculis pulvinar. Suspendisse rhoncus eros nec mi. Praesent euismod, turpis vitae rutrum pretium, odio metus volutpat neque, eget tempus sapien neque sed erat. Donec fermentum purus at lectus. Nullam sem. Fusce vel mi quis erat lobortis posuere. Aenean eget urna. Suspendisse ligula. Duis in nisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Curabitur vulputate lectus id pede. Phasellus eu velit. Etiam venenatis adipiscing nibh. Aliquam cursus pulvinar tellus. Vestibulum neque. Mauris nec justo et erat semper pellentesque. Fusce mattis dictum dolor. Etiam eget purus eu massa varius elementum. Pellentesque massa. Ut ultricies diam sed ipsum. Nullam diam. Pellentesque id magna id libero tristique aliquam. + +Ut eleifend, purus id placerat venenatis, urna augue aliquet ligula, in ultricies leo risus et tellus. Mauris et nulla id urna tristique tempus. Ut facilisis, urna eu vestibulum rhoncus, lacus eros consectetuer metus, et rutrum dui lectus in purus. Nunc vel nisl non ipsum tincidunt mollis. Nam quam lacus, ornare vitae, rhoncus non, congue sed, odio. Proin nibh dui, porta vel, venenatis non, pellentesque ut, nisi. Sed tristique felis a magna. Suspendisse eget tellus. Cras gravida imperdiet velit. Integer hendrerit risus. Proin orci. Aliquam ullamcorper mauris quis mauris. Nunc lacinia vestibulum metus. Duis tellus. Nullam faucibus, leo ac vulputate sollicitudin, leo dolor faucibus erat, quis bibendum orci odio non arcu. + +Nullam accumsan mattis dolor. Donec et dui. Praesent a felis mollis lacus semper lacinia. Curabitur pellentesque luctus est. Proin nulla dui, condimentum vel, faucibus non, interdum ac, erat. Maecenas scelerisque, lectus id volutpat accumsan, sapien tortor pellentesque dui, sed semper magna sem ut leo. Proin nulla. Nullam dapibus ullamcorper sem. Suspendisse vehicula metus in nunc. Pellentesque non quam vel arcu ultrices ullamcorper. Phasellus quis felis sit amet tellus ullamcorper fermentum. Sed vehicula sollicitudin urna. Curabitur pharetra scelerisque risus. Pellentesque id massa quis metus aliquam imperdiet. In nunc lacus, feugiat in, gravida eget, venenatis ut, tellus. Suspendisse potenti. Nam consequat adipiscing dui. In nulla nisi, feugiat ut, fermentum vel, gravida nec, tortor. In sed augue. + +Etiam ullamcorper augue at enim. Integer dignissim. Aliquam pulvinar congue nulla. Morbi enim massa, fringilla a, accumsan eget, condimentum nec, erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean pharetra. Etiam porttitor purus a metus. Aliquam interdum sem eget justo. Quisque volutpat luctus est. Aenean augue. Phasellus dui lectus, ultrices nec, commodo vel, auctor vel, nisi. Ut ultrices pellentesque nisi. Integer ac velit et sem imperdiet luctus. Fusce vitae turpis id augue mollis consectetuer. + +Maecenas nec lacus. Maecenas condimentum odio eu felis. Mauris ut nisl viverra erat faucibus adipiscing. Etiam egestas. Nunc et dolor vitae risus dignissim commodo. Morbi lectus velit, tincidunt nec, aliquet vel, mattis vitae, ligula. Maecenas ultricies semper dolor. Suspendisse malesuada. Integer mattis elit. Donec accumsan, lacus facilisis varius tempus, nulla elit porta erat, et rutrum elit sem sit amet dui. + +Maecenas mollis mi non nulla. Vivamus turpis. Suspendisse a metus. In quis mi in turpis congue auctor. Maecenas lacus. Suspendisse sollicitudin. Phasellus porta nunc non nisl pulvinar egestas. Sed nulla. Vestibulum ac mi. Mauris ultricies condimentum neque. Nulla tempus justo vel massa. Nulla suscipit congue arcu. Praesent id turpis. Mauris nibh pede, euismod semper, molestie ac, rhoncus vitae, ante. Maecenas erat felis, viverra sollicitudin, sagittis eget, pellentesque nec, orci. Fusce ultrices consequat lacus. Aliquam erat magna, feugiat at, viverra a, mollis non, turpis. + +Donec mi. Nam dictum pellentesque sem. Donec mollis rhoncus elit. Phasellus rhoncus pede sit amet risus. Donec eget augue. Maecenas non lectus. Phasellus sollicitudin nisi nec felis. Aliquam pretium, est eget semper convallis, nibh nunc sollicitudin purus, id tempor pede dui vel magna. Vivamus ac lorem. Etiam nisl tortor, adipiscing dictum, elementum in, facilisis sed, nibh. Proin mauris. Proin rutrum massa eget sem. Curabitur tempor adipiscing elit. Curabitur purus tellus, fermentum eget, aliquet vitae, convallis ac, mauris. + +Integer consequat velit eu eros tincidunt vehicula. Nullam lorem sapien, rhoncus non, mattis quis, ultricies sit amet, enim. Curabitur commodo, libero in euismod suscipit, sem purus fringilla enim, ac molestie tortor orci et velit. Donec pede. Etiam placerat condimentum turpis. Phasellus egestas enim nec magna. Vivamus condimentum, nulla vel luctus tristique, eros risus vestibulum nulla, in vehicula arcu ipsum at felis. Donec aliquam elit at augue. Quisque a eros eu ligula accumsan dictum. Etiam vehicula turpis quis libero. Aliquam non mi. Donec et leo. Proin leo libero, aliquam tincidunt, congue nec, adipiscing porta, enim. Nulla lobortis, tortor sit amet imperdiet ullamcorper, dolor orci malesuada pede, sed gravida nibh urna vel lorem. Sed pharetra malesuada eros. Quisque euismod aliquet erat. Suspendisse aliquet mattis purus. + +Nunc id nulla quis justo congue sollicitudin. Praesent erat turpis, rhoncus eu, pretium eu, pellentesque a, nibh. Vivamus tempus. Cras nec risus at turpis imperdiet lobortis. Ut mattis. Maecenas est felis, pellentesque non, imperdiet sed, eleifend tincidunt, lorem. In tincidunt. Sed vel leo. Donec et urna in turpis hendrerit blandit. Donec condimentum accumsan est. Ut pharetra, metus vitae mattis consectetuer, leo quam vulputate odio, nec laoreet nisi velit eu erat. Integer lectus augue, egestas in, interdum eu, venenatis vel, sapien. Quisque et est vitae eros laoreet lobortis. Nullam ut risus non nulla placerat adipiscing. Praesent dapibus. Etiam a felis. Ut sodales consequat mauris. Duis lorem felis, luctus a, tristique in, molestie at, risus. Sed vehicula bibendum tellus. Nam consequat euismod lacus. + +Aenean tortor elit, gravida nec, fermentum eu, lobortis id, ipsum. Maecenas eu purus. Cras ac turpis ut nisi iaculis rhoncus. Nulla purus metus, dignissim nec, tincidunt vitae, dapibus eu, nibh. Fusce lobortis, nunc at viverra eleifend, justo turpis scelerisque eros, ac pellentesque metus nisl at purus. Sed elementum tellus sed enim interdum blandit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer ultricies aliquet odio. Mauris eget nunc a ipsum ultrices sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean accumsan. Donec sapien lectus, congue at, porta id, hendrerit vitae, nisl. Curabitur vel quam vel neque accumsan laoreet. Morbi sapien est, pretium in, consectetuer ac, mollis ut, libero. Donec tincidunt adipiscing metus. Nunc vestibulum egestas augue. Donec scelerisque dui ut sem. Suspendisse vel metus id est molestie iaculis. + +Vivamus pharetra, elit eu malesuada blandit, diam tortor mollis dui, sed pulvinar massa nunc et magna. Sed placerat elit auctor tortor. Nulla ac erat. Pellentesque consectetuer, dui convallis tincidunt condimentum, sem odio volutpat libero, non elementum felis neque nec odio. Maecenas hendrerit eros id diam. Mauris vel purus ac orci convallis convallis. Sed sit amet lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque dictum varius lacus. Mauris eget nisl. Suspendisse placerat, nulla non ornare dignissim, nisl diam sagittis tellus, in semper nisi dolor at nibh. Duis ullamcorper viverra felis. Integer a tellus. Suspendisse eget nunc. Aenean diam est, accumsan id, suscipit interdum, fringilla vitae, justo. Proin pede. Maecenas at neque in neque vestibulum eleifend. + +Vestibulum nulla lorem, porttitor eget, euismod ac, aliquam at, nisl. Maecenas et est eget massa varius lobortis. In mi. Duis porttitor fermentum purus. Donec cursus imperdiet ligula. Morbi et ligula et ante molestie vehicula. Mauris sed dolor. Sed imperdiet felis ut sem. Sed vitae neque elementum leo auctor fermentum. Duis feugiat ullamcorper erat. Aenean purus. Morbi fermentum vestibulum est. Pellentesque venenatis mauris. Phasellus pulvinar. Integer ipsum lectus, iaculis a, lacinia id, accumsan id, arcu. Phasellus at est. Fusce neque quam, ultricies id, iaculis vel, dapibus vitae, lacus. In lobortis convallis ante. Nulla nunc purus, vulputate in, hendrerit et, blandit et, ligula. + +Pellentesque leo metus, sagittis in, molestie vitae, dictum in, pede. Morbi pretium felis nec quam. Pellentesque mattis ante sed quam sagittis dapibus. Suspendisse sapien. Praesent bibendum iaculis tortor. Duis a nisl. Aenean mi. Donec dictum arcu in est. Morbi interdum vulputate ipsum. Aenean sit amet magna non nisl tristique posuere. Phasellus velit metus, tempor ac, fermentum eget, condimentum non, velit. Vestibulum sit posuere. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras aliquet massa nec dui. Cras arcu nunc, hendrerit ac, eleifend eu, ullamcorper nec, tellus. Sed pharetra purus sit amet quam. Curabitur mollis. Nam vitae pede. Etiam risus massa, vehicula sit amet, pharetra nec, sollicitudin ut, dui. Donec egestas justo at quam. Proin nisl risus, vestibulum nec, pretium vitae, tristique ac, lorem. Aliquam erat volutpat. Cras sed nibh. Pellentesque sollicitudin euismod augue. + +Etiam fringilla sollicitudin orci. Mauris cursus elit quis lacus. Cras tortor. In adipiscing, lectus id auctor vestibulum, neque pede accumsan dolor, non imperdiet magna diam accumsan velit. Suspendisse at libero ut nisi blandit sagittis. Phasellus non mauris. Fusce elementum sagittis sem. Suspendisse aliquam eleifend tellus. Proin ligula lorem, imperdiet quis, venenatis id, iaculis mollis, nisl. Etiam convallis pede at massa. Morbi accumsan dui et mauris. + +Sed sed orci. Nunc purus. Suspendisse potenti. Ut luctus fringilla mauris. Donec nibh. Phasellus porta. Phasellus sit amet odio sed magna sodales pharetra. Cras lectus. Suspendisse libero ipsum, commodo nec, facilisis in, suscipit lobortis, ligula. Duis massa nulla, semper et, consequat nec, pharetra eu, elit. Vivamus ultricies aliquam odio. Vestibulum sit amet massa. Sed consequat lacus sed urna. Etiam faucibus felis vel orci. Phasellus ullamcorper. Aenean consectetuer lacus at libero. + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis facilisis, ligula vitae condimentum scelerisque, velit orci gravida felis, vel ultricies quam mi non diam. Vivamus auctor metus non libero. Praesent ligula nisi, commodo condimentum, molestie et, viverra et, justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus sollicitudin. Nunc blandit cursus ipsum. Aenean nec ligula ut tellus sodales mattis. Integer sem. Aliquam id ligula. Sed tortor mauris, blandit vitae, cursus vel, elementum et, nulla. Aliquam scelerisque metus et nisl. Duis adipiscing magna at neque. Quisque vulputate eleifend nunc. Aliquam eget elit. Phasellus dui odio, bibendum sagittis, vestibulum id, dignissim imperdiet, orci. Nullam eu felis non nunc lacinia sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Suspendisse pellentesque, libero mattis ultricies accumsan, tortor tortor malesuada sem, et sodales libero odio ac ipsum. Vivamus quis magna nec est suscipit lobortis. Cras tempus posuere nunc. Quisque ut enim a felis egestas semper. Sed pharetra mattis neque. Fusce turpis nunc, congue sed, consequat non, congue sed, nulla. Suspendisse varius lorem id risus porta vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce sed purus. In a felis. Integer egestas auctor orci. Mauris ultrices suscipit nisl. Nullam purus. + +Cras tempor adipiscing ipsum. Ut quis mi. Maecenas in justo ut nulla congue pharetra. Pellentesque ut libero eu dolor venenatis suscipit. Praesent feugiat consectetuer nibh. Morbi faucibus sem non felis. In hendrerit arcu ac massa. In accumsan ultrices mi. Proin malesuada auctor felis. Curabitur interdum. Sed diam ipsum, ultricies in, tempor sit amet, viverra imperdiet, elit. Morbi molestie nisi. Mauris ipsum. Fusce dictum mollis magna. Duis commodo dignissim nulla. Vestibulum augue enim, ultricies quis, iaculis nec, tincidunt vitae, diam. Mauris lacinia tempus ipsum. Sed at mauris. Ut lorem. Donec libero. + +Duis iaculis lacinia lectus. Aenean convallis eros ac ante. Sed quis orci nec risus auctor fringilla. Phasellus facilisis elementum nisi. In hac habitasse platea dictumst. Nunc porta lacus nec ante. Morbi mauris erat, adipiscing in, pulvinar nec, lobortis nec, odio. Ut eleifend lectus sed quam. Nullam mollis. In non turpis et nisl hendrerit blandit. Duis elementum. Nunc nec libero. Suspendisse vestibulum risus non pede. Morbi imperdiet odio sit amet libero. Sed sed massa vitae ipsum mattis tincidunt. Nulla nec tortor vitae libero volutpat tempus. Donec aliquam. + +Duis sed nunc. Curabitur turpis nulla, vehicula sed, luctus quis, elementum eget, felis. Maecenas et purus. Maecenas leo tellus, tincidunt a, facilisis vitae, lobortis sit amet, velit. Donec convallis sapien. Maecenas mollis odio eu nibh. Etiam gravida. Integer molestie, sapien eu molestie lacinia, nunc nibh aliquam ligula, eu sagittis tellus erat sollicitudin odio. Duis et risus. Phasellus nisi neque, placerat nec, condimentum non, ultrices eu, sem. Ut pede. Etiam nulla metus, volutpat id, convallis sed, suscipit vel, urna. Donec vel elit. Ut leo neque, venenatis faucibus, lacinia nec, tincidunt eu, enim. Cras id dui a libero pharetra dignissim. Donec eros leo, porta quis, laoreet ut, pellentesque volutpat, lectus. + +Nullam blandit. Aliquam erat volutpat. Fusce adipiscing enim. Suspendisse non dui quis ligula porta vestibulum. Donec eu tellus vel lorem pretium porttitor. Praesent luctus. Aliquam ac eros in massa dapibus tincidunt. Donec ut magna. Etiam auctor lacus sit amet lacus. Sed ultricies ipsum nec elit. Quisque a est in purus suscipit tristique. + +Aenean sed dui vel dolor pulvinar laoreet. Vivamus vehicula lorem in pede. Vivamus et diam. Integer ac odio vel diam hendrerit bibendum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a nisi. Phasellus tincidunt dui vitae augue. Duis faucibus, dui interdum fringilla tincidunt, odio elit vestibulum libero, ac molestie magna lectus id lacus. Aenean ligula. Nulla facilisi. + +Fusce vel sem eu velit fringilla ornare. Sed feugiat tincidunt felis. Nullam felis mi, euismod sit amet, mollis at, sodales eget, augue. Nam imperdiet nibh at velit. Sed ut erat. In dui. Nulla facilisi. Nullam augue libero, tincidunt nec, pretium eu, pulvinar in, dui. Morbi vitae felis. Pellentesque vel justo vel velit sagittis malesuada. Proin vehicula blandit massa. Etiam tincidunt pharetra urna. In metus est, auctor nec, blandit a, cursus nec, quam. Mauris ac metus a libero congue faucibus. Mauris mauris dolor, sodales in, cursus ut, sodales rutrum, eros. Quisque mauris eros, sagittis vitae, lobortis ut, eleifend id, nisi. + +Aenean neque. Vestibulum egestas pellentesque ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus sagittis justo vel risus. Sed pretium neque vitae urna. Pellentesque congue libero id lorem. Mauris leo lorem, blandit sit amet, convallis quis, consectetuer sed, eros. Mauris tincidunt, enim a gravida euismod, magna nulla fermentum libero, viverra egestas velit quam et tortor. Vivamus aliquet massa vitae justo. Nulla congue lacus ac elit. + +Phasellus commodo quam vel ligula. Proin non metus at eros pulvinar luctus. Mauris diam lorem, posuere quis, gravida et, tincidunt nec, ligula. Sed diam. Aliquam elit lectus, hendrerit ut, imperdiet sit amet, pretium sit amet, ipsum. Mauris vehicula nisl in dui. Curabitur eget quam ut magna elementum fermentum. Mauris scelerisque. Quisque laoreet. Etiam tempus turpis. Pellentesque augue quam, hendrerit sed, tincidunt at, pharetra at, nisl. Aliquam lacus. Suspendisse potenti. Aenean velit libero, ultrices in, lacinia eu, luctus vel, ante. Etiam dictum mi in felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce gravida dapibus nisl. Cras vitae nisl. + +Maecenas dignissim, ligula non porta cursus, enim nunc malesuada sem, eu porttitor nulla urna eu quam. Fusce eros. Aliquam eros. Nam auctor. Nulla molestie porta est. Suspendisse potenti. Vivamus molestie lorem sed erat. Sed eget ipsum. Integer aliquam pulvinar nulla. Cras aliquet sem ut nunc. Fusce faucibus tempus lectus. Cras sodales, nisi ac facilisis ultrices, eros arcu dapibus sapien, et ultrices mauris tellus non dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras cursus varius metus. Ut turpis. Vivamus eget tortor. + +Sed laoreet, velit non accumsan cursus, nunc urna posuere justo, in dictum lectus pede id ante. Cras vulputate. Cras congue dui sed elit. Proin lacus sem, ultrices at, consequat in, tempor quis, metus. Proin vel arcu. Nam euismod hendrerit elit. Ut erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed posuere. Morbi eros urna, semper at, semper non, convallis quis, velit. Maecenas orci. Vestibulum lobortis tristique metus. Vestibulum lorem nulla, sollicitudin vitae, condimentum quis, auctor ut, dui. Vivamus vestibulum magna ut nisi. Curabitur eleifend dui vel nunc. Curabitur mauris lacus, malesuada sit amet, suscipit sed, rutrum luctus, tellus. Integer facilisis urna vitae lectus. + +Aenean quam leo, lobortis quis, malesuada eu, vulputate vitae, nisl. Praesent eget eros. Ut fermentum turpis id quam. Nam tortor. Praesent nec orci. Nulla bibendum adipiscing augue. Ut commodo, magna id malesuada gravida, augue odio malesuada mi, porta malesuada elit est vitae diam. Mauris non nulla. Suspendisse tincidunt, nunc ultricies porta venenatis, mi pede tincidunt libero, eget varius ante libero ut ligula. Curabitur pretium porttitor tortor. + +Maecenas vitae elit eget nisi dapibus dictum. Nunc in libero. Nulla dictum orci eu erat auctor lobortis. Phasellus risus. Suspendisse potenti. Suspendisse potenti. Praesent adipiscing consequat elit. Integer id augue. Praesent in justo nec magna dapibus pulvinar. Duis nisl. Suspendisse ac odio. Vivamus imperdiet. Donec non velit sit amet risus dignissim congue. Nam aliquet posuere velit. Cras turpis. Morbi malesuada dignissim mi. + +Sed leo neque, varius quis, venenatis sed, pharetra sed, est. Morbi blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam semper pellentesque mi. Ut vel lorem. Nunc mi tortor, laoreet at, faucibus eu, tincidunt sit amet, erat. Duis tempor malesuada ipsum. Phasellus aliquet. Donec et elit. Pellentesque purus. Vestibulum rutrum semper nibh. Nulla facilisi. Phasellus et enim sit amet ante vestibulum vehicula. Phasellus id nisl. Donec mollis leo at eros. Mauris pellentesque neque at purus. Morbi quis dolor at ipsum scelerisque sodales. Etiam volutpat turpis a metus. In hac habitasse platea dictumst. Nunc lorem lorem, vestibulum ac, euismod eget, ullamcorper dignissim, velit. + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ultrices, nibh vel aliquam vestibulum, eros enim venenatis dui, id iaculis enim nunc vel massa. Morbi eleifend orci et massa. Aliquam erat volutpat. Nulla mollis egestas turpis. In sodales nunc eget tortor. Sed ipsum eros, tempor quis, aliquet vitae, imperdiet non, lorem. Pellentesque quis elit id mi luctus dapibus. Sed nunc arcu, rhoncus nec, convallis quis, cursus at, neque. Mauris convallis purus at erat. Pellentesque vestibulum. Vivamus fringilla elit at arcu. Nullam aliquet enim nec arcu. Nam id tortor. Nulla quis nunc. Ut arcu. Suspendisse potenti. Pellentesque ullamcorper ligula id arcu. + +Nam non libero vitae nisl scelerisque fringilla. Quisque varius ante id metus rhoncus fringilla. Nulla facilisi. Praesent eleifend porttitor ligula. Etiam quis dolor non augue commodo auctor. Donec a mi. Vestibulum tempor. Donec felis urna, auctor at, cursus dictum, gravida id, arcu. Aenean dictum malesuada dolor. Vivamus mattis. Phasellus eu pede. Fusce adipiscing justo fringilla metus. Etiam ante. Integer mollis massa quis nunc. Integer dictum neque luctus enim. + +Sed eu libero. Integer tempor ligula in velit. Ut tincidunt lacinia sem. Nullam vel risus. Sed sodales ante a dolor. Curabitur eros. Sed sodales. Sed non metus. Vestibulum elementum faucibus ante. Nulla vel nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In hac habitasse platea dictumst. Nunc nec lorem ut ipsum lacinia iaculis. Duis erat. Aliquam erat. Cras iaculis. In hac habitasse platea dictumst. + +Nullam ante. Cras vitae est. Pellentesque vel metus a ligula dapibus mattis. Duis feugiat aliquet felis. Etiam id nisl quis est dignissim condimentum. Suspendisse potenti. Morbi velit lorem, ornare quis, pellentesque vel, placerat eget, tortor. Vestibulum tincidunt molestie libero. Nulla nulla enim, malesuada id, ullamcorper vitae, dictum at, purus. Donec dignissim odio ut enim. Suspendisse at lectus. + +Praesent lobortis augue vel lectus. Ut in ligula ut felis congue suscipit. Quisque dignissim tortor ut mi. Fusce magna nisi, eleifend ac, ornare vel, porttitor vitae, quam. Vestibulum sodales justo quis turpis. Fusce urna nisi, rhoncus quis, condimentum vel, dictum eu, nunc. Fusce sed nibh vitae odio posuere adipiscing. Sed porta elit quis dolor. Nam libero nulla, auctor sed, tincidunt quis, faucibus sit amet, mi. Quisque orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam id sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vel eros. + +Vivamus luctus lobortis leo. Suspendisse vel elit a enim ullamcorper posuere. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec quis pede mattis lectus mollis adipiscing. Sed accumsan posuere erat. Praesent euismod tincidunt felis. Donec mi. Ut commodo arcu lacinia tellus. Aliquam a libero quis lectus semper viverra. Curabitur lacinia mauris at tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sit amet magna molestie orci suscipit fringilla. Fusce pretium metus non sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed hendrerit. Nulla felis. Suspendisse potenti. Aliquam blandit tristique neque. Curabitur quis erat vel nunc accumsan mollis. + +Duis sagittis, tellus ut aliquam fringilla, dolor mi ullamcorper nisl, ut tristique pede elit sed mauris. Curabitur id felis. Donec pulvinar lacus et lectus. Aliquam vulputate vulputate metus. Curabitur magna felis, adipiscing ac, accumsan vel, molestie quis, quam. Mauris elit arcu, pretium vitae, mollis sit amet, sollicitudin ut, mi. Donec imperdiet dignissim mi. Nullam sit amet tortor. Aliquam neque nulla, venenatis a, porta in, placerat tempus, lacus. Quisque vestibulum dui et lacus. Proin dignissim consectetuer purus. Etiam gravida tortor in nunc. Ut tempor tristique tortor. Sed laoreet tincidunt quam. Vestibulum porta turpis ut elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nibh dui, feugiat nec, laoreet id, malesuada eget, nisi. Ut neque massa, vehicula eu, commodo non, ultricies vitae, purus. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris euismod, felis vel tempor aliquet, tortor mauris malesuada nunc, vel fermentum sem diam id dui. Nam rutrum sapien eget odio. Aliquam sed libero non mi faucibus tempus. Fusce hendrerit, diam non volutpat rutrum, erat metus venenatis ligula, non scelerisque pede ligula vel quam. Morbi rhoncus eros ac dui feugiat elementum. Duis eu libero et tellus congue viverra. Morbi quam quam, elementum sed, ullamcorper imperdiet, commodo non, odio. Nam aliquet egestas urna. Mauris odio felis, varius eu, lacinia eu, condimentum a, lectus. Sed justo massa, pulvinar id, varius a, porttitor nec, libero. Etiam varius. Curabitur sodales, odio at posuere semper, eros nibh tincidunt lectus, vel rutrum sapien nisi in ligula. Suspendisse eget arcu. Phasellus imperdiet est ac sapien. Donec nulla tortor, placerat vel, tempus a, lobortis vel, nibh. Aliquam varius nisi. Nulla et enim. Fusce convallis laoreet lacus. + +Phasellus ipsum dolor, molestie quis, condimentum in, commodo eu, diam. Quisque bibendum lacinia dui. Nullam blandit vulputate orci. Ut lacinia massa vel augue. Aliquam gravida, quam quis imperdiet imperdiet, tellus diam pharetra erat, at pharetra lacus nibh egestas magna. Nulla sagittis lorem ut lorem. Duis condimentum, dui vitae aliquam posuere, diam quam convallis velit, ut gravida leo ipsum non risus. Ut fermentum sollicitudin erat. Donec sagittis scelerisque felis. Nunc arcu. Etiam tempus, magna sit amet suscipit euismod, eros sem rutrum dui, vitae sagittis nibh purus non lacus. Sed mollis arcu eget dolor. Donec ornare, arcu sit amet fermentum vulputate, risus enim fermentum libero, a lacinia dolor mi non velit. Etiam lobortis purus a elit. Nunc nulla dui, mattis quis, bibendum a, ultrices ac, augue. In aliquam vehicula turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Integer id nisl. Quisque dictum elementum odio. Aenean luctus. Sed eu sem a pede vulputate condimentum. Quisque magna. Donec aliquam mattis ipsum. Curabitur dictum sollicitudin sem. Aliquam pulvinar. Nunc sollicitudin risus a erat. Vivamus quis tellus sit amet nibh vestibulum consequat. Nulla pretium sollicitudin dolor. Aliquam iaculis tincidunt turpis. Phasellus ipsum leo, venenatis in, sagittis in, ornare at, nunc. + +Pellentesque ultrices, dui eu iaculis luctus, tellus augue volutpat sapien, in dignissim urna felis ut mi. Sed arcu dui, dignissim id, porttitor ut, imperdiet vitae, ante. Nulla dui sem, commodo nec, sagittis et, lacinia et, pede. Etiam eleifend dui ut nisl. Donec ante mauris, tempus sit amet, varius vitae, gravida quis, mi. In scelerisque, felis vitae viverra sagittis, velit metus ultricies neque, quis imperdiet velit elit et magna. Suspendisse potenti. Sed velit eros, euismod sed, condimentum nec, faucibus sed, sapien. Nam accumsan ligula sit amet neque. Aliquam erat volutpat. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam eu pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed eu felis sed tortor tempor fermentum. Phasellus commodo sem vel nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lectus elit, pharetra sit amet, accumsan sed, tincidunt et, mauris. Duis dapibus pharetra sem. Integer in justo. Praesent eros. Vestibulum ac ante. Aliquam scelerisque sem pellentesque nibh consectetuer sodales. Aliquam consectetuer odio. Duis lectus odio, luctus eu, commodo quis, mollis vitae, velit. Cras nec nunc non elit iaculis mattis. Aenean justo neque, sollicitudin eget, ullamcorper eget, egestas id, sem. In eu risus. Sed egestas. + +Integer at neque. Sed pretium scelerisque nulla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce ut pede. Etiam vitae quam a urna varius imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vehicula. Fusce ullamcorper nibh non erat. Quisque in neque. Praesent est. Pellentesque arcu. + +Proin posuere. Suspendisse potenti. Integer felis lacus, aliquam sed, vulputate in, mollis vel, tellus. Integer vehicula bibendum est. Nunc non dolor in tellus mattis facilisis. Integer vestibulum, augue at commodo aliquam, dui est mattis ligula, sit amet adipiscing orci sem vitae magna. Praesent enim velit, malesuada at, congue nec, luctus in, justo. Sed varius. Morbi pharetra. Donec eu massa nec tellus vulputate pulvinar. Ut commodo turpis non sem. Ut convallis ullamcorper risus. Etiam interdum pede id nisi. Cras magna sapien, suscipit a, laoreet non, rhoncus et, felis. Integer orci lorem, vestibulum dictum, ullamcorper a, porttitor et, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc et magna. Sed bibendum tellus in diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vitae tortor. Integer magna. Duis venenatis, leo ac tempor laoreet, elit nulla pharetra pede, non fermentum nunc odio a odio. Proin non velit. Sed imperdiet augue quis nisl. Integer condimentum nisl nec libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus placerat libero. Duis congue dictum magna. Aliquam dapibus bibendum enim. Nunc eleifend pede vel ipsum. + +Etiam vitae velit. Mauris erat nunc, malesuada ut, feugiat ac, placerat condimentum, augue. Nam volutpat. Aliquam vehicula ipsum id odio. Vivamus sollicitudin turpis id sapien. Fusce a felis vitae odio convallis blandit. Curabitur vitae eros id eros porta pretium. Nulla in magna eget urna lacinia convallis. Aliquam mattis venenatis purus. Sed sed mi eget erat tristique porta. Donec auctor dolor a erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In nec ligula. Nunc eleifend. Vestibulum quis nisi eget elit porttitor congue. Maecenas faucibus, magna eget adipiscing tincidunt, dolor ante malesuada elit, non elementum lacus turpis in pede. + +Ut malesuada mi nec metus. Praesent auctor augue ac nisl ultricies facilisis. Nam purus sapien, pellentesque dignissim, posuere eu, cursus id, diam. Quisque sollicitudin, elit a pellentesque scelerisque, lorem risus auctor quam, quis consequat tellus neque id urna. Suspendisse diam tortor, eleifend dignissim, egestas ut, luctus in, ante. Duis ante. Maecenas luctus. Curabitur cursus pharetra urna. Maecenas imperdiet, erat non elementum euismod, tortor odio euismod lectus, ac facilisis sem nibh vitae nulla. Nunc gravida. Morbi sollicitudin odio quis lacus. Aliquam a nibh non urna porta imperdiet. Aliquam erat volutpat. In iaculis lacinia velit. Sed libero lacus, tristique eu, lacinia ac, aliquet eget, urna. + +Etiam at nisl. Phasellus faucibus luctus lectus. Ut placerat vulputate dolor. Phasellus vel velit. Morbi viverra. Phasellus orci. Integer dignissim mattis mauris. Pellentesque posuere leo posuere quam. Quisque nec magna at diam viverra pellentesque. Suspendisse velit arcu, ultricies quis, congue a, venenatis eget, lacus. Integer sagittis hendrerit dolor. Fusce tincidunt ante a sem. + +Maecenas consectetuer, justo sed rhoncus venenatis, nibh arcu rutrum dolor, sed condimentum libero libero et ipsum. Vivamus mattis justo ut lorem tincidunt lobortis. Ut non velit id neque aliquet accumsan. Sed tempus viverra nulla. Curabitur ullamcorper, neque quis dapibus scelerisque, felis diam gravida orci, non cursus quam neque vitae elit. Etiam pharetra tincidunt lacus. Duis euismod fringilla est. Etiam ornare tincidunt lectus. Proin in turpis. Nunc blandit blandit turpis. Aenean ut augue. Duis orci justo, tincidunt eu, rutrum sed, rutrum et, turpis. Curabitur facilisis odio in ante. In hac habitasse platea dictumst. Sed eros est, pellentesque at, tincidunt eu, ultrices quis, metus. Morbi sit amet justo. Maecenas ac arcu. Mauris dignissim. + +Pellentesque ultricies rutrum orci. Aenean ornare. Vivamus eu risus vel mauris lobortis dictum. Sed et turpis auctor mi rhoncus pulvinar. Sed nec nunc a purus tempor viverra. Pellentesque suscipit. Donec tristique risus non nibh. Etiam nisl magna, sollicitudin ut, ultrices sit amet, egestas eu, nulla. Aliquam erat volutpat. Vestibulum pharetra. Sed egestas, metus sit amet lobortis consequat, erat elit imperdiet libero, eu interdum quam massa eget dolor. Suspendisse vitae odio. Proin blandit mauris iaculis metus. + +Vivamus vestibulum. Etiam et nisl. Aliquam in diam vel elit placerat suscipit. Duis sodales purus ac nibh. Nulla in odio eget enim luctus blandit. Curabitur ultrices ipsum non neque egestas eleifend. Sed turpis. Proin consectetuer. Vivamus mattis. In aliquet. + +Nunc id eros. Donec venenatis, nulla et mattis luctus, ante leo semper justo, non adipiscing odio risus sed lacus. Praesent vitae risus congue libero congue tempus. Phasellus ac eros. Nulla vehicula, lorem in aliquet suscipit, arcu erat egestas sem, quis lobortis quam ante eu massa. Curabitur non massa. Sed bibendum lacinia odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus volutpat blandit lacus. Proin porta, tellus ut auctor laoreet, lectus eros fermentum lectus, id sagittis arcu justo in turpis. Phasellus consequat. Nam pellentesque, mi id viverra convallis, nunc libero placerat leo, eleifend porta sem nisl vitae sapien. Pellentesque ligula libero, tristique non, porttitor rutrum, porttitor non, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer dictum tellus a tortor. Vivamus felis nunc, molestie non, rhoncus quis, pharetra id, dui. Donec risus metus, fringilla vel, aliquet eu, placerat id, neque. + +Suspendisse ipsum. Vivamus lectus. Sed viverra, massa eget convallis mattis, quam turpis consectetuer nunc, eget posuere magna sem id velit. In nec mauris. Aenean a purus sed quam lobortis fringilla. Proin ultricies lacinia ante. Sed adipiscing erat quis velit. Nullam vitae nisl id justo sollicitudin molestie. Nulla facilisi. Sed nec urna sed nisl fringilla dapibus. Nulla at diam. Aliquam eget nibh. Nunc ac nisi sit amet tellus egestas tempus. Nam scelerisque urna et neque. Donec est orci, sagittis non, vulputate a, commodo et, augue. Ut dapibus tortor. Ut nunc. Donec dictum dapibus odio. Nam ultricies ullamcorper ligula. Pellentesque accumsan varius leo. + +Morbi euismod laoreet erat. Vivamus quis ipsum. Morbi euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel purus. Nullam at magna. Curabitur lacus lorem, iaculis quis, dapibus non, volutpat vel, nulla. Donec ut arcu rhoncus dolor pretium dictum. Nullam vel metus. Ut arcu. Pellentesque nisi nunc, placerat eget, tincidunt vel, pharetra non, nunc. Integer tincidunt ultricies lectus. Integer semper, purus sed ultrices feugiat, nulla pede sollicitudin erat, vel auctor nulla ipsum vel lectus. Aenean mi. + +Nullam sed nisi et arcu imperdiet fermentum. Mauris nec metus. In ac dolor. In mi arcu, congue ac, pharetra nec, scelerisque sit amet, magna. Curabitur lacus. Curabitur et elit. Aliquam ullamcorper nunc eu elit. Sed convallis dolor at velit. Vestibulum dapibus, augue id consectetuer placerat, nunc massa blandit sapien, id aliquam elit nisi id mi. Phasellus sapien est, gravida eu, bibendum ut, adipiscing quis, est. Ut molestie quam vitae odio. Donec quis risus id erat faucibus sollicitudin. Nam id felis. Mauris sed enim vitae leo accumsan pretium. + +Nam justo. Donec turpis nisl, commodo et, interdum ac, consectetuer non, massa. Fusce sem metus, laoreet nec, posuere id, imperdiet in, velit. Donec vulputate justo eget turpis. Nulla pede. Morbi tincidunt. Fusce aliquet, quam et aliquam fringilla, ante ante iaculis dui, nec aliquam arcu purus sed erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus suscipit quam et est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; + +Integer sed tellus. Sed sed velit ultricies leo rutrum laoreet. Sed non eros ac purus sagittis feugiat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed hendrerit ligula sit amet nibh. Maecenas turpis. Morbi consectetuer, dolor et adipiscing imperdiet, ante neque feugiat dolor, at porta quam neque quis ligula. Mauris semper velit sit amet ipsum. Pellentesque tempus, purus in rutrum consequat, enim erat vehicula massa, id accumsan leo sapien nec purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In dolor. Integer facilisis libero sit amet pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut varius aliquet enim. Nulla facilisi. Curabitur consectetuer, odio eu pretium tincidunt, nunc nisi aliquet neque, vel imperdiet elit massa sit amet turpis. Pellentesque tempus, orci volutpat blandit fringilla, odio sem posuere ante, vitae bibendum urna lorem vitae eros. Praesent viverra rhoncus arcu. Sed auctor, est sit amet mollis mollis, quam quam gravida sapien, in commodo metus nulla auctor enim. Donec facilisis. + +Proin tincidunt, sapien eget ultricies adipiscing, est odio dictum arcu, ut mollis erat dui sit amet velit. Morbi est sem, interdum at, congue a, elementum vitae, metus. Suspendisse id augue. Mauris enim sem, pulvinar eget, tempus a, tempus sit amet, sapien. Fusce vestibulum consectetuer dui. Pellentesque erat. Sed dignissim placerat odio. Maecenas semper rhoncus lectus. Phasellus pretium. Duis libero elit, eleifend nec, egestas ut, cursus sed, felis. Nam nisl arcu, aliquet et, facilisis eu, luctus ut, risus. Etiam ultrices, dolor sed volutpat malesuada, turpis arcu imperdiet tortor, euismod commodo libero massa ut quam. Integer molestie purus non elit. Ut venenatis semper tortor. Etiam bibendum egestas ipsum. Mauris sollicitudin sem nec nibh. Nulla pretium metus eu metus. Pellentesque sit amet sem. + +Suspendisse ac nisi. Ut leo. Vestibulum hendrerit pretium dolor. Nunc feugiat malesuada purus. Cras et nibh. Curabitur nunc erat, malesuada vitae, laoreet ac, ultricies in, purus. Vivamus tellus arcu, sodales eu, facilisis a, lacinia nec, nunc. Pellentesque id velit. In eu nibh. Nunc nec erat. Sed dictum neque ut nisl. + +Morbi lectus tellus, tincidunt ac, porttitor ac, tristique in, eros. Donec luctus luctus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ut est et enim scelerisque accumsan. Donec ligula felis, lacinia quis, pellentesque in, semper vestibulum, elit. Mauris eget orci a felis congue vehicula. Ut sollicitudin. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam id dolor ut lorem dignissim venenatis. Suspendisse vitae sapien. Proin non magna ut eros viverra pulvinar. Donec quis odio. Nullam non arcu vel lorem suscipit aliquam. Aliquam rutrum turpis in leo. + +Ut luctus nibh tristique erat. Suspendisse bibendum odio vitae tortor. Donec lacinia. Cras sodales felis luctus nulla. Nam eleifend sagittis ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse vel neque. Morbi aliquet vehicula magna. Aenean at odio. Duis pellentesque magna. Nulla at tortor ut diam dictum faucibus. Mauris quis velit. Donec non tellus vitae lorem fringilla porttitor. Fusce ut sapien quis tortor feugiat sagittis. Donec viverra sem vitae sapien. Praesent sodales, lacus in fringilla viverra, odio augue adipiscing urna, vitae interdum ante sem non nisi. Nullam tortor lorem, eleifend ac, mollis non, laoreet ac, risus. Integer ornare leo sed justo. Quisque cursus, sem non facilisis bibendum, nisi mi varius felis, fermentum feugiat lorem eros laoreet risus. + +Quisque sit amet est et lorem vehicula lacinia. Donec nec tortor. Cras odio. Nam scelerisque vulputate urna. Praesent dui. Etiam nec nisl lobortis ipsum aliquet tempus. Maecenas pretium sollicitudin mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus augue massa, congue eget, convallis eget, tristique sit amet, eros. Sed consequat nisi eu felis. Pellentesque justo. Suspendisse non augue. In dignissim lobortis mauris. Mauris sagittis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + +Sed adipiscing. Donec a tellus vitae est cursus vehicula. Nam ante sem, sodales id, fringilla vel, condimentum vel, nulla. Quisque sodales. Etiam imperdiet elit id odio. Aliquam erat volutpat. Maecenas porta tempor arcu. Nulla sem augue, pellentesque ac, consequat ut, condimentum euismod, risus. Sed aliquam tincidunt mi. In interdum lobortis orci. + +Sed vehicula hendrerit purus. Etiam a diam. Curabitur convallis. Suspendisse a nisi. Donec id magna in quam sollicitudin ultricies. Donec viverra. Quisque volutpat est sed sem. Aliquam justo. Vestibulum tortor massa, porttitor sed, varius quis, iaculis quis, odio. Aliquam eget neque. + +Mauris nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum eu quam in neque ultrices pellentesque. Cras in dolor quis quam varius hendrerit. Aliquam nisi lacus, lobortis eu, convallis sit amet, facilisis ut, mi. Aliquam at neque. Cras sagittis elementum justo. Vestibulum ut lectus aliquet purus malesuada volutpat. Duis at lacus adipiscing libero tincidunt vestibulum. Morbi a libero. Cras purus. Morbi ut augue et purus interdum scelerisque. Integer a dui. In hac habitasse platea dictumst. Duis pharetra metus eget mauris. Aliquam interdum ullamcorper massa. + +Etiam ornare. Nullam euismod. Aenean consequat gravida ligula. Aliquam est. Proin vitae lacus. Praesent a eros sit amet dui luctus commodo. Phasellus vehicula arcu eget dolor. Praesent fermentum congue leo. Aliquam volutpat purus ut lorem. Fusce hendrerit enim at leo. Aliquam rhoncus nisl. Vivamus dictum egestas mi. Suspendisse pellentesque bibendum dolor. Pellentesque tincidunt, turpis semper pellentesque condimentum, ipsum metus sodales ligula, id volutpat diam turpis ut elit. + +Praesent sed lacus. Nam eleifend molestie mauris. Donec dapibus fermentum massa. Donec viverra faucibus purus. Curabitur congue, libero vitae viverra pellentesque, diam velit sodales enim, sed suscipit lectus nisi nec neque. Vestibulum malesuada, lacus at cursus congue, velit lectus tristique dolor, sit amet sodales neque ipsum a libero. Vestibulum et quam. Curabitur placerat. Curabitur nunc arcu, euismod nec, vulputate hendrerit, aliquet eget, quam. Curabitur vel enim. Suspendisse potenti. + +Nunc consequat orci ut lacus. Fusce velit dolor, dapibus sed, blandit sit amet, rhoncus id, risus. Duis urna nibh, scelerisque quis, dapibus a, scelerisque sed, nibh. Donec luctus. Ut eu mauris cursus diam lacinia rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam vehicula molestie justo. Maecenas imperdiet pede sed mi. Suspendisse nulla dolor, hendrerit eget, hendrerit id, dictum vel, leo. Duis accumsan. Curabitur in felis. Nunc lorem. Ut leo dolor, laoreet nec, vulputate at, eleifend in, nulla. Quisque nunc purus, varius eget, accumsan nec, aliquet et, nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras adipiscing viverra dolor. Mauris porttitor ultrices purus. Nulla facilisi. Praesent faucibus ante vitae mauris. + +Praesent lacinia lectus sed nisl. In tempus congue mauris. Integer facilisis ornare enim. Nulla id massa. Donec commodo diam at tellus. Nam dapibus viverra est. Nam tellus. Praesent a libero. In faucibus est eget nibh. Nulla eros orci, imperdiet non, blandit non, tempor eget, mi. Pellentesque convallis. + +Quisque eget mi ac leo euismod faucibus. Phasellus rhoncus purus id dui. Vestibulum malesuada eleifend ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque blandit mattis odio. Suspendisse consequat, lectus ac semper sollicitudin, mi velit dictum augue, ac tempus dolor erat sit amet dui. Proin hendrerit, felis quis volutpat posuere, diam odio malesuada odio, a interdum orci diam quis sapien. Pellentesque odio odio, viverra vel, gravida eu, molestie sed, nulla. Phasellus mauris pede, commodo ut, euismod eu, hendrerit eu, est. In hac habitasse platea dictumst. Nulla elementum lacus eu augue. Sed erat. Proin porta. Maecenas quis mi. Phasellus at enim ac justo gravida ultrices. Cras leo. + +Integer ut arcu. Donec sed magna. Proin felis. In iaculis, ligula id fringilla pretium, nibh diam accumsan tellus, eget accumsan metus dui varius turpis. Phasellus orci metus, eleifend sed, tempor ac, scelerisque ac, urna. Integer viverra neque a mauris. Mauris porttitor dolor eu velit. Integer odio elit, vestibulum ut, volutpat id, rhoncus commodo, urna. Etiam placerat pharetra erat. Ut tempor est. Integer dignissim blandit tellus. Morbi nibh dolor, scelerisque id, commodo malesuada, mattis at, mi. Cras tincidunt commodo purus. In tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ullamcorper. Ut hendrerit. Morbi ultrices. + +Praesent iaculis, eros ac egestas sodales, urna leo fermentum ligula, sit amet aliquam velit sem non purus. Donec rutrum arcu quis purus. Nam posuere, lacus at consequat placerat, nulla pede posuere orci, non euismod turpis dui quis nisl. Proin porta adipiscing nibh. Donec tristique dolor at tellus. Donec neque massa, auctor id, faucibus vitae, ullamcorper vel, nisi. Proin molestie neque sed massa. Nam tempor. Morbi aliquam sapien at tellus. Fusce quis risus et mi pretium pulvinar. Fusce sit amet ligula. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse eu enim et felis scelerisque lobortis. Praesent bibendum. Vivamus vehicula. Integer at nibh sed velit rhoncus molestie. Cras lacus. Sed ullamcorper eros vel erat. Fusce eu tortor sit amet diam euismod sagittis. Nunc quis lacus id nibh convallis varius. Suspendisse vitae mi. Vestibulum tristique. Donec malesuada ipsum id neque. Nullam sed lacus. Duis egestas, justo ut congue ornare, augue sapien luctus diam, at accumsan erat sapien ut libero. Phasellus vel nulla. Suspendisse arcu tellus, porttitor a, pharetra faucibus, aliquam sit amet, massa. Nulla porttitor tincidunt lorem. Nunc dolor odio, sagittis in, lobortis vel, volutpat sed, nibh. + +Quisque blandit leo ut sapien tempus facilisis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean ultricies porttitor justo. Fusce rutrum eros ut urna. Proin quis quam eget dui aliquam accumsan. Donec suscipit eleifend elit. Pellentesque mattis, felis sodales iaculis imperdiet, lacus sem convallis augue, sit amet aliquet arcu purus fringilla risus. In eu odio id magna pharetra ornare. Aliquam interdum pulvinar ipsum. Sed neque. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam sit amet nisi. Ut at augue. Mauris volutpat blandit ligula. Nulla eu metus. Vestibulum eget elit. Praesent posuere. Vestibulum id sem non lectus mollis tincidunt. Aliquam id felis at ante ornare tempor. Nulla lacus turpis, feugiat vitae, cursus quis, consectetuer non, mauris. Fusce lacus massa, porttitor ut, molestie ut, venenatis a, lorem. Praesent sit amet orci. Mauris rhoncus felis vitae felis adipiscing imperdiet. Maecenas mollis diam nec leo. + +Fusce enim ipsum, ultrices eu, molestie id, elementum id, sapien. Integer a urna. Nam velit libero, venenatis eget, tempor sit amet, feugiat vitae, ante. Fusce nunc. Sed semper nisl nec risus. In sed libero. Proin tortor neque, tincidunt ac, tempor ac, pharetra quis, velit. Duis lectus augue, ultricies vel, consequat id, iaculis id, ante. Vivamus auctor metus a ante. Curabitur arcu nisi, facilisis at, laoreet in, consectetuer sed, mauris. Quisque placerat diam sed dui. Vivamus pretium condimentum lorem. Curabitur laoreet. Aenean orci ligula, cursus eget, lacinia non, faucibus vel, lorem. + +Aliquam erat volutpat. Curabitur eros dolor, congue a, condimentum sed, luctus ut, nibh. Maecenas non tortor nec turpis commodo pellentesque. Praesent euismod placerat mi. Suspendisse potenti. Phasellus ut neque vitae orci mattis iaculis. Integer eget tellus. Donec at ante. Nam lacinia leo eget erat. Maecenas euismod magna congue tortor. Morbi nec massa eu enim malesuada sollicitudin. Sed accumsan. Nullam ipsum. Ut odio. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque id velit. Nam odio sem, aliquet ut, tempus sit amet, euismod et, nunc. + +Pellentesque libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent mauris nunc, varius ut, convallis molestie, luctus sit amet, leo. Sed dictum lorem et arcu. Nunc venenatis pellentesque massa. Nulla facilisi. Phasellus in tortor eget risus scelerisque vulputate. Sed nibh elit, sagittis ac, condimentum nec, convallis et, justo. Fusce volutpat metus. Nunc auctor. Vestibulum leo eros, pellentesque ac, mollis ultrices, rhoncus non, dolor. Mauris vehicula placerat nisl. Vestibulum bibendum, arcu quis congue elementum, velit nunc eleifend turpis, id luctus risus nisl sit amet tellus. Phasellus pede neque, blandit non, commodo vitae, ultricies eget, magna. Aliquam erat volutpat. + +Nulla facilisi. Aliquam ac ante. Cras risus. Morbi mauris lacus, posuere eu, blandit et, pharetra at, mi. Proin ac purus. Duis cursus nisl rutrum quam. Aliquam a odio non magna pellentesque ultricies. Maecenas ac massa quis sapien ullamcorper tempus. Cras cursus velit sed sapien. Proin nulla. Vivamus sodales aliquam nibh. Etiam et erat ut ante lacinia euismod. Fusce nisi. Proin quis nulla. + +Quisque venenatis, eros sed laoreet sollicitudin, orci ante pellentesque nisl, sit amet viverra quam erat non risus. Cras eget libero. Sed elit magna, semper eu, fringilla in, dignissim sodales, erat. Vivamus feugiat sem vel dui. Donec convallis sollicitudin diam. Cras sed purus. Donec felis eros, semper eget, tempor consectetuer, sagittis quis, nisl. Duis in ante. Cras non turpis. Nulla tempor velit aliquet turpis molestie placerat. Proin elementum fermentum mauris. Vivamus sed orci lacinia dui placerat venenatis. Vestibulum feugiat, tellus in volutpat rutrum, magna nisi ullamcorper eros, id pulvinar neque erat ut lacus. Vivamus sed augue. Nulla facilisi. Maecenas ante augue, elementum ut, sodales vitae, condimentum nec, lorem. Duis pede orci, fringilla at, eleifend nec, pretium in, erat. Nam sagittis, turpis vitae convallis pharetra, odio sem scelerisque lacus, nec lobortis dui diam vel eros. In semper gravida neque. + +Integer nunc. Ut pretium ipsum sit amet elit. In nec arcu. Sed vestibulum vulputate ipsum. Pellentesque tincidunt. Nulla gravida dolor in tellus. Cras vehicula, dolor ut pellentesque aliquam, erat enim auctor massa, vehicula lobortis odio eros quis quam. Proin dapibus neque in enim. Proin elit. Integer rhoncus tincidunt elit. Fusce lorem metus, semper ac, volutpat vitae, facilisis ut, tellus. Donec vel turpis vitae nisi pharetra porttitor. Maecenas tortor. Fusce mi. Nullam nec turpis. Sed sodales vestibulum nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Pellentesque dolor dolor, laoreet eu, aliquet quis, scelerisque sit amet, arcu. In hac habitasse platea dictumst. Nullam cursus urna eget elit. Quisque blandit sapien ac ante. Proin nulla eros, gravida volutpat, sodales vel, mollis eu, massa. Nulla tristique sollicitudin nisl. Curabitur vitae lorem vitae velit egestas ornare. Aenean eget eros. Aliquam erat volutpat. Fusce a urna id odio aliquet convallis. Curabitur sit amet nisl posuere leo posuere dapibus. Duis metus erat, luctus vel, rhoncus at, convallis sit amet, enim. Vivamus hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam eget elit. + +Nullam a nunc. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In metus urna, tincidunt et, lacinia sit amet, lobortis vitae, ligula. Proin et mauris vitae mi accumsan pellentesque. Etiam quam purus, hendrerit sed, feugiat vitae, euismod eget, tortor. Ut aliquam magna vitae justo. Suspendisse non justo vel velit condimentum tempus. Duis tempus ipsum vitae tellus. Proin in massa. Etiam ullamcorper dictum tellus. Proin aliquet felis at leo laoreet pulvinar. Vestibulum arcu purus, malesuada sit amet, cursus eu, placerat sit amet, nunc. Nam massa odio, sollicitudin in, adipiscing a, aliquam nec, risus. Aliquam blandit hendrerit libero. Mauris gravida. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur a nibh. Ut interdum fermentum neque. Pellentesque sed nunc. Mauris vehicula nisi et nunc. Praesent lorem. Donec semper. Integer eu lacus in est aliquam hendrerit. Vestibulum eget neque. Sed semper luctus velit. Curabitur nibh augue, congue eu, hendrerit id, congue et, enim. Integer placerat aliquam lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae eros. Donec vel nisl. + +In vestibulum facilisis urna. Ut risus. Mauris pharetra. Pellentesque mattis. Integer suscipit aliquam ipsum. Duis blandit, sapien et ultricies condimentum, felis mi elementum pede, nec sagittis metus mauris quis quam. Quisque accumsan arcu vel nulla. Cras sem sapien, porttitor id, ultricies sagittis, luctus eu, nulla. Integer quis eros. Morbi sed urna a tellus vehicula vulputate. Etiam nec augue eget felis semper tristique. Quisque ut dolor vel risus dictum consequat. Sed eget dolor sed nunc lacinia aliquet. Suspendisse ac tortor in ipsum posuere venenatis. Sed eget erat. Nulla faucibus. Duis laoreet, massa porttitor aliquet egestas, ipsum lectus rhoncus quam, in adipiscing eros sem ut tellus. Pellentesque feugiat tempus quam. Vivamus id dolor eget sapien consectetuer tempor. Aliquam erat volutpat. + +Nulla iaculis fermentum libero. Curabitur faucibus, massa malesuada cursus tincidunt, erat sem eleifend mauris, sed fringilla mi ante ac purus. Duis elementum lectus. Nunc ornare arcu eu tortor. Vestibulum vel dolor at purus lacinia fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas tincidunt, eros a egestas pellentesque, risus risus dictum libero, id aliquet metus justo in massa. Proin a tellus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed purus. Sed non pede. Aenean massa sapien, sodales sit amet, consequat dictum, eleifend vitae, tortor. Donec ultrices lacinia elit. + +Morbi adipiscing sodales dolor. Ut ullamcorper ultricies est. In venenatis tempus augue. Suspendisse tortor dolor, accumsan et, suscipit a, tincidunt ut, libero. Aliquam scelerisque magna sed felis. Quisque ut nunc a magna vulputate placerat. Aliquam rhoncus vehicula dui. Sed tortor. Nullam sit amet diam. Nunc sed eros. Sed et odio tincidunt elit gravida convallis. Curabitur quis tortor a lacus semper varius. Mauris at augue non mi sollicitudin aliquam. Integer ullamcorper. Pellentesque suscipit quam non purus. Aliquam ac eros at arcu ullamcorper consectetuer. Suspendisse pretium mattis leo. + +Duis at nunc. Sed dolor est, varius ac, porta et, tincidunt hendrerit, risus. Vivamus ut magna. Praesent ut mauris. In purus lacus, mattis sed, vestibulum nec, tempor at, nisl. Cras ullamcorper venenatis tellus. Ut dolor. Maecenas malesuada, pede a pulvinar mattis, arcu diam vehicula risus, quis porttitor augue massa in velit. Nunc congue. Morbi velit metus, rhoncus et, aliquam consectetuer, ultricies malesuada, ligula. Sed velit nisl, sagittis vitae, pharetra a, posuere sed, massa. Nulla facilisi. In varius, ligula id lobortis sodales, augue orci fermentum tellus, eu pulvinar risus ligula a sapien. Morbi laoreet ipsum non mi. Nam cursus lorem ut mi. Vivamus magna enim, posuere non, semper quis, sodales eu, arcu. Etiam mi purus, pretium feugiat, varius sed, pellentesque eget, ligula. In leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vitae orci eu orci sollicitudin feugiat. + +Praesent purus massa, euismod vitae, tempus nec, consequat hendrerit, metus. Aenean felis est, egestas vitae, accumsan eget, pellentesque in, sapien. Duis dapibus pede non sapien. Nunc urna. Integer vel libero. Duis augue arcu, dapibus non, facilisis vitae, posuere ut, eros. Donec vitae nunc sit amet arcu imperdiet dictum. Morbi eleifend, lorem eu consectetuer vestibulum, diam nunc ornare arcu, ac tempor felis dolor eget eros. Phasellus massa sem, sollicitudin ac, sodales gravida, luctus a, quam. Nam neque quam, viverra at, venenatis quis, sagittis non, enim. + +Nulla facilisi. Pellentesque egestas lacinia est. Sed tincidunt, pede sed tincidunt vestibulum, urna dolor adipiscing purus, vitae fringilla felis elit in nibh. Nulla sed nisi. Mauris suscipit scelerisque arcu. Etiam non enim vel eros accumsan malesuada. Nunc tincidunt commodo mauris. In tincidunt risus quis urna. Nulla diam tortor, aliquet et, tincidunt quis, sollicitudin ac, tortor. Cras nisl neque, vulputate suscipit, molestie quis, pulvinar at, nulla. Nullam ac metus nec odio posuere varius. Cras sed pede nec dui posuere bibendum. Duis euismod ullamcorper libero. Aliquam faucibus pulvinar turpis. + +In ut neque id nunc feugiat commodo. Curabitur dignissim, felis at sollicitudin lacinia, enim elit suscipit neque, sed luctus lorem ipsum in leo. Duis dapibus, odio quis auctor commodo, nisl odio mattis tellus, nec tincidunt turpis diam in arcu. Curabitur a sem. Nullam volutpat magna. Pellentesque sagittis, neque consequat pretium cursus, dolor lacus consectetuer arcu, sed laoreet est urna et metus. Suspendisse placerat, dui a porta tempor, lorem dui lobortis neque, sed venenatis diam enim id eros. Etiam et nisl non lectus faucibus consectetuer. Morbi scelerisque, sem nec tempus ullamcorper, ipsum diam feugiat lorem, a fringilla sapien elit quis nibh. Nullam diam urna, viverra sed, pharetra rhoncus, tincidunt vel, orci. Integer accumsan mattis erat. Nam dictum. Mauris nec leo. Nulla iaculis. Nulla nisl mi, dapibus quis, vehicula a, cursus eget, odio. + +Phasellus dapibus euismod nibh. Vivamus imperdiet ante in ligula. Pellentesque accumsan. In imperdiet, dui a auctor fringilla, metus nisi cursus dolor, vel luctus ligula lorem vitae mauris. Praesent mattis vestibulum elit. Aliquam enim lacus, pulvinar non, lacinia sit amet, eleifend non, velit. Vestibulum ac leo. Mauris imperdiet justo ac lectus. Sed molestie lectus sed dui. Sed fermentum tempus mauris. Nam ornare orci ac tellus. Ut malesuada, lacus id lacinia accumsan, diam elit adipiscing metus, et bibendum sapien nibh blandit orci. Suspendisse ipsum tellus, sagittis quis, vestibulum non, vulputate eu, eros. Praesent at nulla id pede scelerisque ultricies. Cras blandit pretium tellus. Maecenas dapibus condimentum augue. Phasellus tincidunt pharetra lorem. Morbi non eros. Sed tempor, nisl a tincidunt tincidunt, eros diam dictum sem, vel dignissim ante diam sed magna. Praesent non ligula id metus molestie consectetuer. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse vel mi. Curabitur ante nulla, rutrum a, convallis vel, vehicula ac, nunc. Nunc sagittis, enim sit amet auctor rutrum, mauris arcu vulputate neque, et euismod est felis quis ante. Vestibulum turpis tellus, hendrerit in, lacinia commodo, ullamcorper gravida, risus. Mauris rhoncus lacinia risus. Maecenas sollicitudin erat vitae nunc. Praesent pretium pellentesque augue. Donec interdum. Praesent ac eros vitae erat lobortis fringilla. Aenean consequat tellus. Nulla accumsan bibendum felis. Maecenas pretium ante id nisi. Aenean mi arcu, semper sed, mattis eu, venenatis sit amet, arcu. Donec aliquet euismod leo. Proin magna justo, tristique a, semper ac, sollicitudin a, ligula. Morbi velit. Aliquam vel nisi. + +In a lorem ut nunc feugiat congue. Donec fermentum bibendum dui. Proin varius est quis velit. Donec aliquet sem accumsan mi. Sed placerat. Nullam ac nisi a massa lobortis suscipit. Nunc id leo. Aliquam et massa. Nullam vestibulum elementum metus. In consectetuer nisi vel justo. Maecenas eget purus sed massa varius pellentesque. Phasellus faucibus felis quis felis. Aenean odio arcu, blandit quis, facilisis in, imperdiet eu, lorem. Nam posuere pulvinar mi. Fusce tristique, mauris et consectetuer ultricies, mauris lectus tempor justo, at fringilla est est sed nisi. Quisque faucibus. Sed in tortor tincidunt est lacinia iaculis. Maecenas a massa. Pellentesque a nibh at purus porta hendrerit. + +Nullam turpis. Fusce ac sem sed odio pellentesque imperdiet. Curabitur in arcu. Praesent lacus lacus, feugiat id, pulvinar in, tincidunt sed, neque. Maecenas viverra odio eget tortor. Integer aliquam, lorem rutrum venenatis dignissim, ligula magna malesuada arcu, vel feugiat lorem ipsum quis massa. Morbi ante. Vestibulum mauris libero, ullamcorper quis, ultrices quis, facilisis non, massa. Maecenas imperdiet. Aliquam erat volutpat. Pellentesque dignissim gravida lectus. In nibh odio, auctor eget, dapibus quis, dignissim venenatis, arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis pellentesque ligula quis massa. Curabitur condimentum, justo eget ornare luctus, lorem ligula sagittis pede, a porta nunc nunc in neque. Quisque felis mauris, condimentum vitae, auctor vitae, tincidunt quis, pede. Nunc lacinia ante in leo. Pellentesque libero. Aenean a ligula et nunc vestibulum consectetuer. + +Fusce ornare. Praesent id urna. Integer venenatis, quam non sagittis accumsan, ante nibh sagittis augue, sollicitudin adipiscing dolor velit eu erat. Proin quis enim eu purus vehicula aliquam. Nulla vel enim vel elit sollicitudin fringilla. Aliquam erat volutpat. Sed suscipit felis ut turpis. Etiam rutrum risus imperdiet est. Aliquam a tellus at tellus commodo dapibus. Mauris rutrum magna et odio. In at dolor. Curabitur vehicula lectus in tortor. Fusce justo purus, luctus vitae, mollis in, pharetra ac, purus. Nullam posuere interdum justo. Curabitur vitae lacus vel leo congue pulvinar. + +Aenean eleifend nibh varius tortor. Suspendisse vel eros. Proin nec diam a tortor ultrices ornare. Aliquam scelerisque feugiat justo. Vivamus ante urna, adipiscing vitae, porttitor eu, sodales et, felis. Suspendisse potenti. Curabitur ac massa in nisl sagittis mollis. Nam quam ligula, consectetuer eget, iaculis at, varius eu, leo. Duis dolor ligula, tincidunt at, ullamcorper sed, accumsan aliquam, ligula. Phasellus vulputate, lorem at tincidunt pharetra, risus lectus lacinia magna, quis rutrum enim magna at sem. In hac habitasse platea dictumst. Duis id sem a mauris sollicitudin tincidunt. Etiam eu purus eu arcu fringilla adipiscing. Vivamus ornare tempus diam. Proin turpis quam, lacinia non, egestas at, commodo eget, pede. Praesent vulputate risus in est. Nulla facilisi. + +Ut elementum lacinia purus. Proin vitae arcu ac nulla convallis aliquam. Nulla congue, libero id pellentesque mattis, quam lectus porttitor diam, a scelerisque dui libero in sapien. Nullam felis diam, vehicula vel, molestie ut, vestibulum aliquam, sapien. Donec convallis, est ut elementum volutpat, mauris ipsum gravida sem, commodo facilisis sapien lectus semper lectus. Quisque porttitor eros ut nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam mattis risus sed odio. Vestibulum et odio. In hac habitasse platea dictumst. Nam tristique massa ut ligula. Quisque nibh tellus, vehicula sit amet, adipiscing at, convallis nec, ligula. Vestibulum pretium, mi nec fringilla bibendum, dui nunc sodales pede, a semper magna nibh non diam. Donec massa nunc, viverra vel, consectetuer porta, dapibus non, ipsum. Duis nisl mauris, cursus vel, semper non, sollicitudin bibendum, felis. Vestibulum eu neque. + +Cras nec dolor. Donec laoreet tempus lectus. Cras sed tortor interdum lacus eleifend dignissim. Maecenas sit amet elit. Nullam quis dolor vel dui pharetra luctus. In sit amet quam sit amet pede ultrices ultrices. Maecenas diam. Integer urna. Curabitur dictum, velit sed placerat suscipit, erat turpis fermentum justo, sed interdum neque sem et nibh. Vivamus consequat convallis magna. Nam aliquam, est ac bibendum commodo, magna est dictum mi, vitae malesuada elit magna vitae odio. Maecenas tempor vulputate tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus dui. Etiam accumsan pede congue tortor. + +Morbi tempor libero ac lorem. In aliquet varius magna. In arcu. Phasellus odio. Fusce tincidunt aliquet felis. Quisque velit. Sed luctus. Aliquam feugiat fringilla mi. Aliquam molestie viverra risus. Proin arcu. Vestibulum lobortis tempus nisi. Praesent a arcu in velit viverra rutrum. + +In sed lectus. Donec risus dolor, blandit sit amet, elementum convallis, pharetra quis, pede. Integer ornare. Aenean egestas dapibus justo. Sed quam leo, posuere at, elementum vitae, commodo eget, est. Aliquam molestie rhoncus enim. Curabitur iaculis ultrices pede. Morbi aliquet rutrum lacus. Aliquam quam. Sed commodo, turpis in pharetra posuere, mi risus imperdiet erat, a vestibulum massa tellus vehicula sem. Mauris fringilla ultrices nunc. Nam nisi enim, eleifend sit amet, ultrices sed, fermentum non, augue. Proin congue lobortis nisi. Maecenas hendrerit. Nam sed nisl. Nunc elementum odio eu risus. In metus. Phasellus gravida pretium ligula. Nulla vitae neque. Nam nisi tortor, ornare non, blandit at, cursus eu, tortor. + +Duis bibendum ipsum in nunc cursus molestie. Nunc orci. Nullam nec ante non est dignissim viverra. Mauris blandit, velit id feugiat pretium, elit magna pellentesque dolor, at sagittis lacus velit egestas magna. Pellentesque cursus, diam consectetuer sagittis fringilla, tortor nisi adipiscing nunc, eu varius lacus risus ac elit. Mauris id nisi quis leo euismod venenatis. Pellentesque ac ante. Mauris arcu sapien, tempor at, porttitor id, condimentum ut, dui. Etiam fermentum ultricies augue. Cras ut eros at justo ultricies iaculis. Duis dignissim, nisl et facilisis fermentum, erat purus molestie tellus, quis tempus ipsum lectus at elit. Nulla vitae lorem. + +Aenean vel sem et diam semper congue. In bibendum diam quis tellus. Nunc facilisis ultricies nibh. Cras nunc enim, feugiat sed, ultrices vitae, sagittis vitae, ipsum. Fusce vitae nulla. Donec pellentesque, velit in porttitor eleifend, est neque lobortis velit, sit amet rutrum ante tortor nec dolor. Donec vehicula. Nulla facilisi. Sed egestas ultrices nibh. Donec elit lectus, convallis porttitor, aliquet dapibus, feugiat eget, ligula. Sed consectetuer justo. Maecenas a sapien sit amet nisi dapibus lobortis. Vivamus luctus lorem non nulla. Sed eget erat vitae libero interdum posuere. Cras pulvinar. Nullam imperdiet, dolor tempor dignissim blandit, dui sapien rhoncus neque, id malesuada augue magna sit amet urna. Duis sed mauris. + +Morbi accumsan. Sed mauris augue, fringilla non, auctor ut, auctor et, orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus ut pede. Donec viverra enim vel lorem. Pellentesque neque mauris, interdum eu, venenatis id, condimentum eu, sapien. Donec ipsum arcu, lacinia adipiscing, laoreet et, cursus vel, velit. Ut sagittis mauris quis risus. Integer eu odio vitae lacus viverra accumsan. Morbi leo ante, dignissim sed, varius quis, volutpat vitae, nisi. Nulla placerat interdum elit. Donec neque dui, sagittis vitae, sollicitudin quis, commodo vitae, neque. Nulla quis ligula ornare ligula dictum ornare. Mauris rutrum rutrum neque. Aenean vehicula tempus est. Donec varius scelerisque pede. Donec placerat vulputate leo. Nullam nunc nisl, posuere non, feugiat vitae, pellentesque quis, mauris. In dui neque, cursus eget, sagittis eget, dapibus vitae, mi. Proin eget est. + +Fusce porta est. Mauris magna. Aliquam ipsum lacus, ultricies id, vestibulum luctus, accumsan ut, ante. Sed mauris. Sed adipiscing leo sit amet magna. Suspendisse potenti. Nunc massa elit, fringilla eget, egestas vitae, luctus vitae, dolor. Phasellus quis nulla eu nisi interdum sollicitudin. Nullam id tellus. Integer iaculis dolor ac purus. Sed vel mi. Curabitur non magna sit amet justo condimentum vulputate. Quisque tincidunt pede eu nisl. Vivamus lobortis. Nunc metus metus, congue sed, tincidunt sed, pretium at, odio. Donec a arcu. In sem justo, vehicula sed, varius id, volutpat at, risus. Praesent iaculis massa. In arcu elit, hendrerit eget, ullamcorper in, porta id, tellus. Donec sagittis hendrerit diam. + +Suspendisse potenti. Sed et diam et augue sagittis lobortis. Phasellus dolor. Ut et arcu eget ante tempor posuere. Aliquam fermentum scelerisque dui. Mauris at purus. Donec erat sem, vestibulum nec, faucibus ac, mattis a, leo. Suspendisse adipiscing lacinia sem. Nullam orci arcu, dictum et, faucibus viverra, dapibus et, neque. Cras nunc diam, adipiscing non, sollicitudin in, interdum vel, massa. Mauris sagittis, justo at tristique tempus, mauris mauris aliquam ante, sit amet posuere diam dui eget ligula. In dignissim, nisl ut lacinia condimentum, erat justo porttitor nulla, non gravida ligula magna eget massa. Vestibulum vitae ligula at mi vestibulum suscipit. Duis laoreet. Nulla commodo libero sit amet lorem. Ut elementum sem. Integer vel dolor. Nam facilisis mi quis sem ultrices sagittis. Sed quis quam at metus molestie bibendum. + +Proin dui enim, lacinia a, feugiat ac, placerat vitae, pede. Quisque egestas, leo eget aliquam pretium, libero justo tincidunt eros, ut egestas augue pede elementum nibh. Curabitur mollis sodales enim. Donec augue. Phasellus id ipsum posuere dui pretium faucibus. Mauris luctus ante semper nisi interdum adipiscing. Duis dapibus, odio quis viverra rhoncus, justo quam bibendum dolor, id dapibus velit erat vel erat. Fusce sit amet nisl venenatis quam ultrices condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec rhoncus scelerisque ligula. Vestibulum mi odio, accumsan et, adipiscing eget, ornare ut, quam. Nullam blandit molestie mauris. Curabitur dignissim mauris et lorem. Suspendisse a justo. Nam mattis faucibus arcu. Duis blandit enim non massa. + +Nullam lorem. In hac habitasse platea dictumst. Mauris consectetuer posuere mauris. Maecenas tincidunt mauris in eros. Nulla eu metus eu orci sollicitudin faucibus. Suspendisse aliquam mauris id est. Cras blandit dui et urna. Nulla arcu. Sed a urna. Nulla dapibus vehicula tortor. Donec risus. Sed quam metus, egestas eu, cursus ut, viverra non, odio. Ut justo justo, malesuada sit amet, blandit suscipit, molestie in, justo. Vestibulum consequat, quam ac feugiat tincidunt, ipsum libero eleifend odio, non eleifend pede ipsum non ante. Nullam a metus. + +Nam ac nisi at felis cursus mattis. Pellentesque consequat sem quis orci. Quisque tempus. Aenean imperdiet molestie pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eu tellus. Nulla diam eros, sodales ut, sodales nec, tincidunt ac, nunc. Nunc lacinia faucibus ipsum. Vivamus vel neque in erat fermentum luctus. Nulla eget metus nec augue bibendum placerat. Vivamus tempus. Praesent congue ornare ipsum. Etiam mattis feugiat justo. + +Aliquam dui. Aenean commodo tortor vitae nulla. Morbi et ipsum. Mauris ac ipsum. Nam vel risus ut lectus mollis viverra. Curabitur elementum mollis est. Nullam elit. Vestibulum suscipit pretium enim. Vestibulum ut massa. Proin nec felis. Maecenas gravida, arcu nec consequat sagittis, eros tellus scelerisque mauris, vitae accumsan quam quam ut nunc. Integer eget ante eu velit laoreet malesuada. Nunc sagittis, mauris vitae pharetra volutpat, tellus tellus eleifend eros, sit amet rutrum ipsum nisi a velit. Praesent varius leo eu erat. Vivamus consequat placerat purus. Donec pretium elementum nibh. Proin at elit non sem aliquet mattis. Sed ullamcorper ipsum sit amet elit. + +Mauris in metus. Suspendisse magna lorem, faucibus vel, tincidunt quis, scelerisque non, tellus. Fusce quis lorem. Proin a lacus sit amet mauris iaculis pulvinar. Suspendisse rhoncus eros nec mi. Praesent euismod, turpis vitae rutrum pretium, odio metus volutpat neque, eget tempus sapien neque sed erat. Donec fermentum purus at lectus. Nullam sem. Fusce vel mi quis erat lobortis posuere. Aenean eget urna. Suspendisse ligula. Duis in nisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Curabitur vulputate lectus id pede. Phasellus eu velit. Etiam venenatis adipiscing nibh. Aliquam cursus pulvinar tellus. Vestibulum neque. Mauris nec justo et erat semper pellentesque. Fusce mattis dictum dolor. Etiam eget purus eu massa varius elementum. Pellentesque massa. Ut ultricies diam sed ipsum. Nullam diam. Pellentesque id magna id libero tristique aliquam. + +Ut eleifend, purus id placerat venenatis, urna augue aliquet ligula, in ultricies leo risus et tellus. Mauris et nulla id urna tristique tempus. Ut facilisis, urna eu vestibulum rhoncus, lacus eros consectetuer metus, et rutrum dui lectus in purus. Nunc vel nisl non ipsum tincidunt mollis. Nam quam lacus, ornare vitae, rhoncus non, congue sed, odio. Proin nibh dui, porta vel, venenatis non, pellentesque ut, nisi. Sed tristique felis a magna. Suspendisse eget tellus. Cras gravida imperdiet velit. Integer hendrerit risus. Proin orci. Aliquam ullamcorper mauris quis mauris. Nunc lacinia vestibulum metus. Duis tellus. Nullam faucibus, leo ac vulputate sollicitudin, leo dolor faucibus erat, quis bibendum orci odio non arcu. + +Nullam accumsan mattis dolor. Donec et dui. Praesent a felis mollis lacus semper lacinia. Curabitur pellentesque luctus est. Proin nulla dui, condimentum vel, faucibus non, interdum ac, erat. Maecenas scelerisque, lectus id volutpat accumsan, sapien tortor pellentesque dui, sed semper magna sem ut leo. Proin nulla. Nullam dapibus ullamcorper sem. Suspendisse vehicula metus in nunc. Pellentesque non quam vel arcu ultrices ullamcorper. Phasellus quis felis sit amet tellus ullamcorper fermentum. Sed vehicula sollicitudin urna. Curabitur pharetra scelerisque risus. Pellentesque id massa quis metus aliquam imperdiet. In nunc lacus, feugiat in, gravida eget, venenatis ut, tellus. Suspendisse potenti. Nam consequat adipiscing dui. In nulla nisi, feugiat ut, fermentum vel, gravida nec, tortor. In sed augue. + +Etiam ullamcorper augue at enim. Integer dignissim. Aliquam pulvinar congue nulla. Morbi enim massa, fringilla a, accumsan eget, condimentum nec, erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean pharetra. Etiam porttitor purus a metus. Aliquam interdum sem eget justo. Quisque volutpat luctus est. Aenean augue. Phasellus dui lectus, ultrices nec, commodo vel, auctor vel, nisi. Ut ultrices pellentesque nisi. Integer ac velit et sem imperdiet luctus. Fusce vitae turpis id augue mollis consectetuer. + +Maecenas nec lacus. Maecenas condimentum odio eu felis. Mauris ut nisl viverra erat faucibus adipiscing. Etiam egestas. Nunc et dolor vitae risus dignissim commodo. Morbi lectus velit, tincidunt nec, aliquet vel, mattis vitae, ligula. Maecenas ultricies semper dolor. Suspendisse malesuada. Integer mattis elit. Donec accumsan, lacus facilisis varius tempus, nulla elit porta erat, et rutrum elit sem sit amet dui. + +Maecenas mollis mi non nulla. Vivamus turpis. Suspendisse a metus. In quis mi in turpis congue auctor. Maecenas lacus. Suspendisse sollicitudin. Phasellus porta nunc non nisl pulvinar egestas. Sed nulla. Vestibulum ac mi. Mauris ultricies condimentum neque. Nulla tempus justo vel massa. Nulla suscipit congue arcu. Praesent id turpis. Mauris nibh pede, euismod semper, molestie ac, rhoncus vitae, ante. Maecenas erat felis, viverra sollicitudin, sagittis eget, pellentesque nec, orci. Fusce ultrices consequat lacus. Aliquam erat magna, feugiat at, viverra a, mollis non, turpis. + +Donec mi. Nam dictum pellentesque sem. Donec mollis rhoncus elit. Phasellus rhoncus pede sit amet risus. Donec eget augue. Maecenas non lectus. Phasellus sollicitudin nisi nec felis. Aliquam pretium, est eget semper convallis, nibh nunc sollicitudin purus, id tempor pede dui vel magna. Vivamus ac lorem. Etiam nisl tortor, adipiscing dictum, elementum in, facilisis sed, nibh. Proin mauris. Proin rutrum massa eget sem. Curabitur tempor adipiscing elit. Curabitur purus tellus, fermentum eget, aliquet vitae, convallis ac, mauris. + +Integer consequat velit eu eros tincidunt vehicula. Nullam lorem sapien, rhoncus non, mattis quis, ultricies sit amet, enim. Curabitur commodo, libero in euismod suscipit, sem purus fringilla enim, ac molestie tortor orci et velit. Donec pede. Etiam placerat condimentum turpis. Phasellus egestas enim nec magna. Vivamus condimentum, nulla vel luctus tristique, eros risus vestibulum nulla, in vehicula arcu ipsum at felis. Donec aliquam elit at augue. Quisque a eros eu ligula accumsan dictum. Etiam vehicula turpis quis libero. Aliquam non mi. Donec et leo. Proin leo libero, aliquam tincidunt, congue nec, adipiscing porta, enim. Nulla lobortis, tortor sit amet imperdiet ullamcorper, dolor orci malesuada pede, sed gravida nibh urna vel lorem. Sed pharetra malesuada eros. Quisque euismod aliquet erat. Suspendisse aliquet mattis purus. + +Nunc id nulla quis justo congue sollicitudin. Praesent erat turpis, rhoncus eu, pretium eu, pellentesque a, nibh. Vivamus tempus. Cras nec risus at turpis imperdiet lobortis. Ut mattis. Maecenas est felis, pellentesque non, imperdiet sed, eleifend tincidunt, lorem. In tincidunt. Sed vel leo. Donec et urna in turpis hendrerit blandit. Donec condimentum accumsan est. Ut pharetra, metus vitae mattis consectetuer, leo quam vulputate odio, nec laoreet nisi velit eu erat. Integer lectus augue, egestas in, interdum eu, venenatis vel, sapien. Quisque et est vitae eros laoreet lobortis. Nullam ut risus non nulla placerat adipiscing. Praesent dapibus. Etiam a felis. Ut sodales consequat mauris. Duis lorem felis, luctus a, tristique in, molestie at, risus. Sed vehicula bibendum tellus. Nam consequat euismod lacus. + +Aenean tortor elit, gravida nec, fermentum eu, lobortis id, ipsum. Maecenas eu purus. Cras ac turpis ut nisi iaculis rhoncus. Nulla purus metus, dignissim nec, tincidunt vitae, dapibus eu, nibh. Fusce lobortis, nunc at viverra eleifend, justo turpis scelerisque eros, ac pellentesque metus nisl at purus. Sed elementum tellus sed enim interdum blandit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer ultricies aliquet odio. Mauris eget nunc a ipsum ultrices sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean accumsan. Donec sapien lectus, congue at, porta id, hendrerit vitae, nisl. Curabitur vel quam vel neque accumsan laoreet. Morbi sapien est, pretium in, consectetuer ac, mollis ut, libero. Donec tincidunt adipiscing metus. Nunc vestibulum egestas augue. Donec scelerisque dui ut sem. Suspendisse vel metus id est molestie iaculis. + +Vivamus pharetra, elit eu malesuada blandit, diam tortor mollis dui, sed pulvinar massa nunc et magna. Sed placerat elit auctor tortor. Nulla ac erat. Pellentesque consectetuer, dui convallis tincidunt condimentum, sem odio volutpat libero, non elementum felis neque nec odio. Maecenas hendrerit eros id diam. Mauris vel purus ac orci convallis convallis. Sed sit amet lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque dictum varius lacus. Mauris eget nisl. Suspendisse placerat, nulla non ornare dignissim, nisl diam sagittis tellus, in semper nisi dolor at nibh. Duis ullamcorper viverra felis. Integer a tellus. Suspendisse eget nunc. Aenean diam est, accumsan id, suscipit interdum, fringilla vitae, justo. Proin pede. Maecenas at neque in neque vestibulum eleifend. + +Vestibulum nulla lorem, porttitor eget, euismod ac, aliquam at, nisl. Maecenas et est eget massa varius lobortis. In mi. Duis porttitor fermentum purus. Donec cursus imperdiet ligula. Morbi et ligula et ante molestie vehicula. Mauris sed dolor. Sed imperdiet felis ut sem. Sed vitae neque elementum leo auctor fermentum. Duis feugiat ullamcorper erat. Aenean purus. Morbi fermentum vestibulum est. Pellentesque venenatis mauris. Phasellus pulvinar. Integer ipsum lectus, iaculis a, lacinia id, accumsan id, arcu. Phasellus at est. Fusce neque quam, ultricies id, iaculis vel, dapibus vitae, lacus. In lobortis convallis ante. Nulla nunc purus, vulputate in, hendrerit et, blandit et, ligula. + +Pellentesque leo metus, sagittis in, molestie vitae, dictum in, pede. Morbi pretium felis nec quam. Pellentesque mattis ante sed quam sagittis dapibus. Suspendisse sapien. Praesent bibendum iaculis tortor. Duis a nisl. Aenean mi. Donec dictum arcu in est. Morbi interdum vulputate ipsum. Aenean sit amet magna non nisl tristique posuere. Phasellus velit metus, tempor ac, fermentum eget, condimentum non, velit. Vestibulum sit posuere. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras aliquet massa nec dui. Cras arcu nunc, hendrerit ac, eleifend eu, ullamcorper nec, tellus. Sed pharetra purus sit amet quam. Curabitur mollis. Nam vitae pede. Etiam risus massa, vehicula sit amet, pharetra nec, sollicitudin ut, dui. Donec egestas justo at quam. Proin nisl risus, vestibulum nec, pretium vitae, tristique ac, lorem. Aliquam erat volutpat. Cras sed nibh. Pellentesque sollicitudin euismod augue. + +Etiam fringilla sollicitudin orci. Mauris cursus elit quis lacus. Cras tortor. In adipiscing, lectus id auctor vestibulum, neque pede accumsan dolor, non imperdiet magna diam accumsan velit. Suspendisse at libero ut nisi blandit sagittis. Phasellus non mauris. Fusce elementum sagittis sem. Suspendisse aliquam eleifend tellus. Proin ligula lorem, imperdiet quis, venenatis id, iaculis mollis, nisl. Etiam convallis pede at massa. Morbi accumsan dui et mauris. + +Sed sed orci. Nunc purus. Suspendisse potenti. Ut luctus fringilla mauris. Donec nibh. Phasellus porta. Phasellus sit amet odio sed magna sodales pharetra. Cras lectus. Suspendisse libero ipsum, commodo nec, facilisis in, suscipit lobortis, ligula. Duis massa nulla, semper et, consequat nec, pharetra eu, elit. Vivamus ultricies aliquam odio. Vestibulum sit amet massa. Sed consequat lacus sed urna. Etiam faucibus felis vel orci. Phasellus ullamcorper. Aenean consectetuer lacus at libero. + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis facilisis, ligula vitae condimentum scelerisque, velit orci gravida felis, vel ultricies quam mi non diam. Vivamus auctor metus non libero. Praesent ligula nisi, commodo condimentum, molestie et, viverra et, justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus sollicitudin. Nunc blandit cursus ipsum. Aenean nec ligula ut tellus sodales mattis. Integer sem. Aliquam id ligula. Sed tortor mauris, blandit vitae, cursus vel, elementum et, nulla. Aliquam scelerisque metus et nisl. Duis adipiscing magna at neque. Quisque vulputate eleifend nunc. Aliquam eget elit. Phasellus dui odio, bibendum sagittis, vestibulum id, dignissim imperdiet, orci. Nullam eu felis non nunc lacinia sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Suspendisse pellentesque, libero mattis ultricies accumsan, tortor tortor malesuada sem, et sodales libero odio ac ipsum. Vivamus quis magna nec est suscipit lobortis. Cras tempus posuere nunc. Quisque ut enim a felis egestas semper. Sed pharetra mattis neque. Fusce turpis nunc, congue sed, consequat non, congue sed, nulla. Suspendisse varius lorem id risus porta vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce sed purus. In a felis. Integer egestas auctor orci. Mauris ultrices suscipit nisl. Nullam purus. + +Cras tempor adipiscing ipsum. Ut quis mi. Maecenas in justo ut nulla congue pharetra. Pellentesque ut libero eu dolor venenatis suscipit. Praesent feugiat consectetuer nibh. Morbi faucibus sem non felis. In hendrerit arcu ac massa. In accumsan ultrices mi. Proin malesuada auctor felis. Curabitur interdum. Sed diam ipsum, ultricies in, tempor sit amet, viverra imperdiet, elit. Morbi molestie nisi. Mauris ipsum. Fusce dictum mollis magna. Duis commodo dignissim nulla. Vestibulum augue enim, ultricies quis, iaculis nec, tincidunt vitae, diam. Mauris lacinia tempus ipsum. Sed at mauris. Ut lorem. Donec libero. + +Duis iaculis lacinia lectus. Aenean convallis eros ac ante. Sed quis orci nec risus auctor fringilla. Phasellus facilisis elementum nisi. In hac habitasse platea dictumst. Nunc porta lacus nec ante. Morbi mauris erat, adipiscing in, pulvinar nec, lobortis nec, odio. Ut eleifend lectus sed quam. Nullam mollis. In non turpis et nisl hendrerit blandit. Duis elementum. Nunc nec libero. Suspendisse vestibulum risus non pede. Morbi imperdiet odio sit amet libero. Sed sed massa vitae ipsum mattis tincidunt. Nulla nec tortor vitae libero volutpat tempus. Donec aliquam. + +Duis sed nunc. Curabitur turpis nulla, vehicula sed, luctus quis, elementum eget, felis. Maecenas et purus. Maecenas leo tellus, tincidunt a, facilisis vitae, lobortis sit amet, velit. Donec convallis sapien. Maecenas mollis odio eu nibh. Etiam gravida. Integer molestie, sapien eu molestie lacinia, nunc nibh aliquam ligula, eu sagittis tellus erat sollicitudin odio. Duis et risus. Phasellus nisi neque, placerat nec, condimentum non, ultrices eu, sem. Ut pede. Etiam nulla metus, volutpat id, convallis sed, suscipit vel, urna. Donec vel elit. Ut leo neque, venenatis faucibus, lacinia nec, tincidunt eu, enim. Cras id dui a libero pharetra dignissim. Donec eros leo, porta quis, laoreet ut, pellentesque volutpat, lectus. + +Nullam blandit. Aliquam erat volutpat. Fusce adipiscing enim. Suspendisse non dui quis ligula porta vestibulum. Donec eu tellus vel lorem pretium porttitor. Praesent luctus. Aliquam ac eros in massa dapibus tincidunt. Donec ut magna. Etiam auctor lacus sit amet lacus. Sed ultricies ipsum nec elit. Quisque a est in purus suscipit tristique. + +Aenean sed dui vel dolor pulvinar laoreet. Vivamus vehicula lorem in pede. Vivamus et diam. Integer ac odio vel diam hendrerit bibendum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a nisi. Phasellus tincidunt dui vitae augue. Duis faucibus, dui interdum fringilla tincidunt, odio elit vestibulum libero, ac molestie magna lectus id lacus. Aenean ligula. Nulla facilisi. + +Fusce vel sem eu velit fringilla ornare. Sed feugiat tincidunt felis. Nullam felis mi, euismod sit amet, mollis at, sodales eget, augue. Nam imperdiet nibh at velit. Sed ut erat. In dui. Nulla facilisi. Nullam augue libero, tincidunt nec, pretium eu, pulvinar in, dui. Morbi vitae felis. Pellentesque vel justo vel velit sagittis malesuada. Proin vehicula blandit massa. Etiam tincidunt pharetra urna. In metus est, auctor nec, blandit a, cursus nec, quam. Mauris ac metus a libero congue faucibus. Mauris mauris dolor, sodales in, cursus ut, sodales rutrum, eros. Quisque mauris eros, sagittis vitae, lobortis ut, eleifend id, nisi. + +Aenean neque. Vestibulum egestas pellentesque ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus sagittis justo vel risus. Sed pretium neque vitae urna. Pellentesque congue libero id lorem. Mauris leo lorem, blandit sit amet, convallis quis, consectetuer sed, eros. Mauris tincidunt, enim a gravida euismod, magna nulla fermentum libero, viverra egestas velit quam et tortor. Vivamus aliquet massa vitae justo. Nulla congue lacus ac elit. + +Phasellus commodo quam vel ligula. Proin non metus at eros pulvinar luctus. Mauris diam lorem, posuere quis, gravida et, tincidunt nec, ligula. Sed diam. Aliquam elit lectus, hendrerit ut, imperdiet sit amet, pretium sit amet, ipsum. Mauris vehicula nisl in dui. Curabitur eget quam ut magna elementum fermentum. Mauris scelerisque. Quisque laoreet. Etiam tempus turpis. Pellentesque augue quam, hendrerit sed, tincidunt at, pharetra at, nisl. Aliquam lacus. Suspendisse potenti. Aenean velit libero, ultrices in, lacinia eu, luctus vel, ante. Etiam dictum mi in felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce gravida dapibus nisl. Cras vitae nisl. + +Maecenas dignissim, ligula non porta cursus, enim nunc malesuada sem, eu porttitor nulla urna eu quam. Fusce eros. Aliquam eros. Nam auctor. Nulla molestie porta est. Suspendisse potenti. Vivamus molestie lorem sed erat. Sed eget ipsum. Integer aliquam pulvinar nulla. Cras aliquet sem ut nunc. Fusce faucibus tempus lectus. Cras sodales, nisi ac facilisis ultrices, eros arcu dapibus sapien, et ultrices mauris tellus non dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras cursus varius metus. Ut turpis. Vivamus eget tortor. + +Sed laoreet, velit non accumsan cursus, nunc urna posuere justo, in dictum lectus pede id ante. Cras vulputate. Cras congue dui sed elit. Proin lacus sem, ultrices at, consequat in, tempor quis, metus. Proin vel arcu. Nam euismod hendrerit elit. Ut erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed posuere. Morbi eros urna, semper at, semper non, convallis quis, velit. Maecenas orci. Vestibulum lobortis tristique metus. Vestibulum lorem nulla, sollicitudin vitae, condimentum quis, auctor ut, dui. Vivamus vestibulum magna ut nisi. Curabitur eleifend dui vel nunc. Curabitur mauris lacus, malesuada sit amet, suscipit sed, rutrum luctus, tellus. Integer facilisis urna vitae lectus. + +Aenean quam leo, lobortis quis, malesuada eu, vulputate vitae, nisl. Praesent eget eros. Ut fermentum turpis id quam. Nam tortor. Praesent nec orci. Nulla bibendum adipiscing augue. Ut commodo, magna id malesuada gravida, augue odio malesuada mi, porta malesuada elit est vitae diam. Mauris non nulla. Suspendisse tincidunt, nunc ultricies porta venenatis, mi pede tincidunt libero, eget varius ante libero ut ligula. Curabitur pretium porttitor tortor. + +Maecenas vitae elit eget nisi dapibus dictum. Nunc in libero. Nulla dictum orci eu erat auctor lobortis. Phasellus risus. Suspendisse potenti. Suspendisse potenti. Praesent adipiscing consequat elit. Integer id augue. Praesent in justo nec magna dapibus pulvinar. Duis nisl. Suspendisse ac odio. Vivamus imperdiet. Donec non velit sit amet risus dignissim congue. Nam aliquet posuere velit. Cras turpis. Morbi malesuada dignissim mi. + +Sed leo neque, varius quis, venenatis sed, pharetra sed, est. Morbi blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam semper pellentesque mi. Ut vel lorem. Nunc mi tortor, laoreet at, faucibus eu, tincidunt sit amet, erat. Duis tempor malesuada ipsum. Phasellus aliquet. Donec et elit. Pellentesque purus. Vestibulum rutrum semper nibh. Nulla facilisi. Phasellus et enim sit amet ante vestibulum vehicula. Phasellus id nisl. Donec mollis leo at eros. Mauris pellentesque neque at purus. Morbi quis dolor at ipsum scelerisque sodales. Etiam volutpat turpis a metus. In hac habitasse platea dictumst. Nunc lorem lorem, vestibulum ac, euismod eget, ullamcorper dignissim, velit. + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ultrices, nibh vel aliquam vestibulum, eros enim venenatis dui, id iaculis enim nunc vel massa. Morbi eleifend orci et massa. Aliquam erat volutpat. Nulla mollis egestas turpis. In sodales nunc eget tortor. Sed ipsum eros, tempor quis, aliquet vitae, imperdiet non, lorem. Pellentesque quis elit id mi luctus dapibus. Sed nunc arcu, rhoncus nec, convallis quis, cursus at, neque. Mauris convallis purus at erat. Pellentesque vestibulum. Vivamus fringilla elit at arcu. Nullam aliquet enim nec arcu. Nam id tortor. Nulla quis nunc. Ut arcu. Suspendisse potenti. Pellentesque ullamcorper ligula id arcu. + +Nam non libero vitae nisl scelerisque fringilla. Quisque varius ante id metus rhoncus fringilla. Nulla facilisi. Praesent eleifend porttitor ligula. Etiam quis dolor non augue commodo auctor. Donec a mi. Vestibulum tempor. Donec felis urna, auctor at, cursus dictum, gravida id, arcu. Aenean dictum malesuada dolor. Vivamus mattis. Phasellus eu pede. Fusce adipiscing justo fringilla metus. Etiam ante. Integer mollis massa quis nunc. Integer dictum neque luctus enim. + +Sed eu libero. Integer tempor ligula in velit. Ut tincidunt lacinia sem. Nullam vel risus. Sed sodales ante a dolor. Curabitur eros. Sed sodales. Sed non metus. Vestibulum elementum faucibus ante. Nulla vel nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In hac habitasse platea dictumst. Nunc nec lorem ut ipsum lacinia iaculis. Duis erat. Aliquam erat. Cras iaculis. In hac habitasse platea dictumst. + +Nullam ante. Cras vitae est. Pellentesque vel metus a ligula dapibus mattis. Duis feugiat aliquet felis. Etiam id nisl quis est dignissim condimentum. Suspendisse potenti. Morbi velit lorem, ornare quis, pellentesque vel, placerat eget, tortor. Vestibulum tincidunt molestie libero. Nulla nulla enim, malesuada id, ullamcorper vitae, dictum at, purus. Donec dignissim odio ut enim. Suspendisse at lectus. + +Praesent lobortis augue vel lectus. Ut in ligula ut felis congue suscipit. Quisque dignissim tortor ut mi. Fusce magna nisi, eleifend ac, ornare vel, porttitor vitae, quam. Vestibulum sodales justo quis turpis. Fusce urna nisi, rhoncus quis, condimentum vel, dictum eu, nunc. Fusce sed nibh vitae odio posuere adipiscing. Sed porta elit quis dolor. Nam libero nulla, auctor sed, tincidunt quis, faucibus sit amet, mi. Quisque orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam id sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vel eros. + +Vivamus luctus lobortis leo. Suspendisse vel elit a enim ullamcorper posuere. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec quis pede mattis lectus mollis adipiscing. Sed accumsan posuere erat. Praesent euismod tincidunt felis. Donec mi. Ut commodo arcu lacinia tellus. Aliquam a libero quis lectus semper viverra. Curabitur lacinia mauris at tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sit amet magna molestie orci suscipit fringilla. Fusce pretium metus non sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed hendrerit. Nulla felis. Suspendisse potenti. Aliquam blandit tristique neque. Curabitur quis erat vel nunc accumsan mollis. + +Duis sagittis, tellus ut aliquam fringilla, dolor mi ullamcorper nisl, ut tristique pede elit sed mauris. Curabitur id felis. Donec pulvinar lacus et lectus. Aliquam vulputate vulputate metus. Curabitur magna felis, adipiscing ac, accumsan vel, molestie quis, quam. Mauris elit arcu, pretium vitae, mollis sit amet, sollicitudin ut, mi. Donec imperdiet dignissim mi. Nullam sit amet tortor. Aliquam neque nulla, venenatis a, porta in, placerat tempus, lacus. Quisque vestibulum dui et lacus. Proin dignissim consectetuer purus. Etiam gravida tortor in nunc. Ut tempor tristique tortor. Sed laoreet tincidunt quam. Vestibulum porta turpis ut elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nibh dui, feugiat nec, laoreet id, malesuada eget, nisi. Ut neque massa, vehicula eu, commodo non, ultricies vitae, purus. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris euismod, felis vel tempor aliquet, tortor mauris malesuada nunc, vel fermentum sem diam id dui. Nam rutrum sapien eget odio. Aliquam sed libero non mi faucibus tempus. Fusce hendrerit, diam non volutpat rutrum, erat metus venenatis ligula, non scelerisque pede ligula vel quam. Morbi rhoncus eros ac dui feugiat elementum. Duis eu libero et tellus congue viverra. Morbi quam quam, elementum sed, ullamcorper imperdiet, commodo non, odio. Nam aliquet egestas urna. Mauris odio felis, varius eu, lacinia eu, condimentum a, lectus. Sed justo massa, pulvinar id, varius a, porttitor nec, libero. Etiam varius. Curabitur sodales, odio at posuere semper, eros nibh tincidunt lectus, vel rutrum sapien nisi in ligula. Suspendisse eget arcu. Phasellus imperdiet est ac sapien. Donec nulla tortor, placerat vel, tempus a, lobortis vel, nibh. Aliquam varius nisi. Nulla et enim. Fusce convallis laoreet lacus. + +Phasellus ipsum dolor, molestie quis, condimentum in, commodo eu, diam. Quisque bibendum lacinia dui. Nullam blandit vulputate orci. Ut lacinia massa vel augue. Aliquam gravida, quam quis imperdiet imperdiet, tellus diam pharetra erat, at pharetra lacus nibh egestas magna. Nulla sagittis lorem ut lorem. Duis condimentum, dui vitae aliquam posuere, diam quam convallis velit, ut gravida leo ipsum non risus. Ut fermentum sollicitudin erat. Donec sagittis scelerisque felis. Nunc arcu. Etiam tempus, magna sit amet suscipit euismod, eros sem rutrum dui, vitae sagittis nibh purus non lacus. Sed mollis arcu eget dolor. Donec ornare, arcu sit amet fermentum vulputate, risus enim fermentum libero, a lacinia dolor mi non velit. Etiam lobortis purus a elit. Nunc nulla dui, mattis quis, bibendum a, ultrices ac, augue. In aliquam vehicula turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Integer id nisl. Quisque dictum elementum odio. Aenean luctus. Sed eu sem a pede vulputate condimentum. Quisque magna. Donec aliquam mattis ipsum. Curabitur dictum sollicitudin sem. Aliquam pulvinar. Nunc sollicitudin risus a erat. Vivamus quis tellus sit amet nibh vestibulum consequat. Nulla pretium sollicitudin dolor. Aliquam iaculis tincidunt turpis. Phasellus ipsum leo, venenatis in, sagittis in, ornare at, nunc. + +Pellentesque ultrices, dui eu iaculis luctus, tellus augue volutpat sapien, in dignissim urna felis ut mi. Sed arcu dui, dignissim id, porttitor ut, imperdiet vitae, ante. Nulla dui sem, commodo nec, sagittis et, lacinia et, pede. Etiam eleifend dui ut nisl. Donec ante mauris, tempus sit amet, varius vitae, gravida quis, mi. In scelerisque, felis vitae viverra sagittis, velit metus ultricies neque, quis imperdiet velit elit et magna. Suspendisse potenti. Sed velit eros, euismod sed, condimentum nec, faucibus sed, sapien. Nam accumsan ligula sit amet neque. Aliquam erat volutpat. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam eu pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed eu felis sed tortor tempor fermentum. Phasellus commodo sem vel nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lectus elit, pharetra sit amet, accumsan sed, tincidunt et, mauris. Duis dapibus pharetra sem. Integer in justo. Praesent eros. Vestibulum ac ante. Aliquam scelerisque sem pellentesque nibh consectetuer sodales. Aliquam consectetuer odio. Duis lectus odio, luctus eu, commodo quis, mollis vitae, velit. Cras nec nunc non elit iaculis mattis. Aenean justo neque, sollicitudin eget, ullamcorper eget, egestas id, sem. In eu risus. Sed egestas. + +Integer at neque. Sed pretium scelerisque nulla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce ut pede. Etiam vitae quam a urna varius imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vehicula. Fusce ullamcorper nibh non erat. Quisque in neque. Praesent est. Pellentesque arcu. + +Proin posuere. Suspendisse potenti. Integer felis lacus, aliquam sed, vulputate in, mollis vel, tellus. Integer vehicula bibendum est. Nunc non dolor in tellus mattis facilisis. Integer vestibulum, augue at commodo aliquam, dui est mattis ligula, sit amet adipiscing orci sem vitae magna. Praesent enim velit, malesuada at, congue nec, luctus in, justo. Sed varius. Morbi pharetra. Donec eu massa nec tellus vulputate pulvinar. Ut commodo turpis non sem. Ut convallis ullamcorper risus. Etiam interdum pede id nisi. Cras magna sapien, suscipit a, laoreet non, rhoncus et, felis. Integer orci lorem, vestibulum dictum, ullamcorper a, porttitor et, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc et magna. Sed bibendum tellus in diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vitae tortor. Integer magna. Duis venenatis, leo ac tempor laoreet, elit nulla pharetra pede, non fermentum nunc odio a odio. Proin non velit. Sed imperdiet augue quis nisl. Integer condimentum nisl nec libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus placerat libero. Duis congue dictum magna. Aliquam dapibus bibendum enim. Nunc eleifend pede vel ipsum. + +Etiam vitae velit. Mauris erat nunc, malesuada ut, feugiat ac, placerat condimentum, augue. Nam volutpat. Aliquam vehicula ipsum id odio. Vivamus sollicitudin turpis id sapien. Fusce a felis vitae odio convallis blandit. Curabitur vitae eros id eros porta pretium. Nulla in magna eget urna lacinia convallis. Aliquam mattis venenatis purus. Sed sed mi eget erat tristique porta. Donec auctor dolor a erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In nec ligula. Nunc eleifend. Vestibulum quis nisi eget elit porttitor congue. Maecenas faucibus, magna eget adipiscing tincidunt, dolor ante malesuada elit, non elementum lacus turpis in pede. + +Ut malesuada mi nec metus. Praesent auctor augue ac nisl ultricies facilisis. Nam purus sapien, pellentesque dignissim, posuere eu, cursus id, diam. Quisque sollicitudin, elit a pellentesque scelerisque, lorem risus auctor quam, quis consequat tellus neque id urna. Suspendisse diam tortor, eleifend dignissim, egestas ut, luctus in, ante. Duis ante. Maecenas luctus. Curabitur cursus pharetra urna. Maecenas imperdiet, erat non elementum euismod, tortor odio euismod lectus, ac facilisis sem nibh vitae nulla. Nunc gravida. Morbi sollicitudin odio quis lacus. Aliquam a nibh non urna porta imperdiet. Aliquam erat volutpat. In iaculis lacinia velit. Sed libero lacus, tristique eu, lacinia ac, aliquet eget, urna. + +Etiam at nisl. Phasellus faucibus luctus lectus. Ut placerat vulputate dolor. Phasellus vel velit. Morbi viverra. Phasellus orci. Integer dignissim mattis mauris. Pellentesque posuere leo posuere quam. Quisque nec magna at diam viverra pellentesque. Suspendisse velit arcu, ultricies quis, congue a, venenatis eget, lacus. Integer sagittis hendrerit dolor. Fusce tincidunt ante a sem. + +Maecenas consectetuer, justo sed rhoncus venenatis, nibh arcu rutrum dolor, sed condimentum libero libero et ipsum. Vivamus mattis justo ut lorem tincidunt lobortis. Ut non velit id neque aliquet accumsan. Sed tempus viverra nulla. Curabitur ullamcorper, neque quis dapibus scelerisque, felis diam gravida orci, non cursus quam neque vitae elit. Etiam pharetra tincidunt lacus. Duis euismod fringilla est. Etiam ornare tincidunt lectus. Proin in turpis. Nunc blandit blandit turpis. Aenean ut augue. Duis orci justo, tincidunt eu, rutrum sed, rutrum et, turpis. Curabitur facilisis odio in ante. In hac habitasse platea dictumst. Sed eros est, pellentesque at, tincidunt eu, ultrices quis, metus. Morbi sit amet justo. Maecenas ac arcu. Mauris dignissim. + +Pellentesque ultricies rutrum orci. Aenean ornare. Vivamus eu risus vel mauris lobortis dictum. Sed et turpis auctor mi rhoncus pulvinar. Sed nec nunc a purus tempor viverra. Pellentesque suscipit. Donec tristique risus non nibh. Etiam nisl magna, sollicitudin ut, ultrices sit amet, egestas eu, nulla. Aliquam erat volutpat. Vestibulum pharetra. Sed egestas, metus sit amet lobortis consequat, erat elit imperdiet libero, eu interdum quam massa eget dolor. Suspendisse vitae odio. Proin blandit mauris iaculis metus. + +Vivamus vestibulum. Etiam et nisl. Aliquam in diam vel elit placerat suscipit. Duis sodales purus ac nibh. Nulla in odio eget enim luctus blandit. Curabitur ultrices ipsum non neque egestas eleifend. Sed turpis. Proin consectetuer. Vivamus mattis. In aliquet. + +Nunc id eros. Donec venenatis, nulla et mattis luctus, ante leo semper justo, non adipiscing odio risus sed lacus. Praesent vitae risus congue libero congue tempus. Phasellus ac eros. Nulla vehicula, lorem in aliquet suscipit, arcu erat egestas sem, quis lobortis quam ante eu massa. Curabitur non massa. Sed bibendum lacinia odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus volutpat blandit lacus. Proin porta, tellus ut auctor laoreet, lectus eros fermentum lectus, id sagittis arcu justo in turpis. Phasellus consequat. Nam pellentesque, mi id viverra convallis, nunc libero placerat leo, eleifend porta sem nisl vitae sapien. Pellentesque ligula libero, tristique non, porttitor rutrum, porttitor non, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer dictum tellus a tortor. Vivamus felis nunc, molestie non, rhoncus quis, pharetra id, dui. Donec risus metus, fringilla vel, aliquet eu, placerat id, neque. + +Suspendisse ipsum. Vivamus lectus. Sed viverra, massa eget convallis mattis, quam turpis consectetuer nunc, eget posuere magna sem id velit. In nec mauris. Aenean a purus sed quam lobortis fringilla. Proin ultricies lacinia ante. Sed adipiscing erat quis velit. Nullam vitae nisl id justo sollicitudin molestie. Nulla facilisi. Sed nec urna sed nisl fringilla dapibus. Nulla at diam. Aliquam eget nibh. Nunc ac nisi sit amet tellus egestas tempus. Nam scelerisque urna et neque. Donec est orci, sagittis non, vulputate a, commodo et, augue. Ut dapibus tortor. Ut nunc. Donec dictum dapibus odio. Nam ultricies ullamcorper ligula. Pellentesque accumsan varius leo. + +Morbi euismod laoreet erat. Vivamus quis ipsum. Morbi euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel purus. Nullam at magna. Curabitur lacus lorem, iaculis quis, dapibus non, volutpat vel, nulla. Donec ut arcu rhoncus dolor pretium dictum. Nullam vel metus. Ut arcu. Pellentesque nisi nunc, placerat eget, tincidunt vel, pharetra non, nunc. Integer tincidunt ultricies lectus. Integer semper, purus sed ultrices feugiat, nulla pede sollicitudin erat, vel auctor nulla ipsum vel lectus. Aenean mi. + +Nullam sed nisi et arcu imperdiet fermentum. Mauris nec metus. In ac dolor. In mi arcu, congue ac, pharetra nec, scelerisque sit amet, magna. Curabitur lacus. Curabitur et elit. Aliquam ullamcorper nunc eu elit. Sed convallis dolor at velit. Vestibulum dapibus, augue id consectetuer placerat, nunc massa blandit sapien, id aliquam elit nisi id mi. Phasellus sapien est, gravida eu, bibendum ut, adipiscing quis, est. Ut molestie quam vitae odio. Donec quis risus id erat faucibus sollicitudin. Nam id felis. Mauris sed enim vitae leo accumsan pretium. + +Nam justo. Donec turpis nisl, commodo et, interdum ac, consectetuer non, massa. Fusce sem metus, laoreet nec, posuere id, imperdiet in, velit. Donec vulputate justo eget turpis. Nulla pede. Morbi tincidunt. Fusce aliquet, quam et aliquam fringilla, ante ante iaculis dui, nec aliquam arcu purus sed erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus suscipit quam et est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; + +Integer sed tellus. Sed sed velit ultricies leo rutrum laoreet. Sed non eros ac purus sagittis feugiat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed hendrerit ligula sit amet nibh. Maecenas turpis. Morbi consectetuer, dolor et adipiscing imperdiet, ante neque feugiat dolor, at porta quam neque quis ligula. Mauris semper velit sit amet ipsum. Pellentesque tempus, purus in rutrum consequat, enim erat vehicula massa, id accumsan leo sapien nec purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In dolor. Integer facilisis libero sit amet pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut varius aliquet enim. Nulla facilisi. Curabitur consectetuer, odio eu pretium tincidunt, nunc nisi aliquet neque, vel imperdiet elit massa sit amet turpis. Pellentesque tempus, orci volutpat blandit fringilla, odio sem posuere ante, vitae bibendum urna lorem vitae eros. Praesent viverra rhoncus arcu. Sed auctor, est sit amet mollis mollis, quam quam gravida sapien, in commodo metus nulla auctor enim. Donec facilisis. + +Proin tincidunt, sapien eget ultricies adipiscing, est odio dictum arcu, ut mollis erat dui sit amet velit. Morbi est sem, interdum at, congue a, elementum vitae, metus. Suspendisse id augue. Mauris enim sem, pulvinar eget, tempus a, tempus sit amet, sapien. Fusce vestibulum consectetuer dui. Pellentesque erat. Sed dignissim placerat odio. Maecenas semper rhoncus lectus. Phasellus pretium. Duis libero elit, eleifend nec, egestas ut, cursus sed, felis. Nam nisl arcu, aliquet et, facilisis eu, luctus ut, risus. Etiam ultrices, dolor sed volutpat malesuada, turpis arcu imperdiet tortor, euismod commodo libero massa ut quam. Integer molestie purus non elit. Ut venenatis semper tortor. Etiam bibendum egestas ipsum. Mauris sollicitudin sem nec nibh. Nulla pretium metus eu metus. Pellentesque sit amet sem. + +Suspendisse ac nisi. Ut leo. Vestibulum hendrerit pretium dolor. Nunc feugiat malesuada purus. Cras et nibh. Curabitur nunc erat, malesuada vitae, laoreet ac, ultricies in, purus. Vivamus tellus arcu, sodales eu, facilisis a, lacinia nec, nunc. Pellentesque id velit. In eu nibh. Nunc nec erat. Sed dictum neque ut nisl. + +Morbi lectus tellus, tincidunt ac, porttitor ac, tristique in, eros. Donec luctus luctus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ut est et enim scelerisque accumsan. Donec ligula felis, lacinia quis, pellentesque in, semper vestibulum, elit. Mauris eget orci a felis congue vehicula. Ut sollicitudin. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam id dolor ut lorem dignissim venenatis. Suspendisse vitae sapien. Proin non magna ut eros viverra pulvinar. Donec quis odio. Nullam non arcu vel lorem suscipit aliquam. Aliquam rutrum turpis in leo. + +Ut luctus nibh tristique erat. Suspendisse bibendum odio vitae tortor. Donec lacinia. Cras sodales felis luctus nulla. Nam eleifend sagittis ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse vel neque. Morbi aliquet vehicula magna. Aenean at odio. Duis pellentesque magna. Nulla at tortor ut diam dictum faucibus. Mauris quis velit. Donec non tellus vitae lorem fringilla porttitor. Fusce ut sapien quis tortor feugiat sagittis. Donec viverra sem vitae sapien. Praesent sodales, lacus in fringilla viverra, odio augue adipiscing urna, vitae interdum ante sem non nisi. Nullam tortor lorem, eleifend ac, mollis non, laoreet ac, risus. Integer ornare leo sed justo. Quisque cursus, sem non facilisis bibendum, nisi mi varius felis, fermentum feugiat lorem eros laoreet risus. + +Quisque sit amet est et lorem vehicula lacinia. Donec nec tortor. Cras odio. Nam scelerisque vulputate urna. Praesent dui. Etiam nec nisl lobortis ipsum aliquet tempus. Maecenas pretium sollicitudin mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus augue massa, congue eget, convallis eget, tristique sit amet, eros. Sed consequat nisi eu felis. Pellentesque justo. Suspendisse non augue. In dignissim lobortis mauris. Mauris sagittis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + +Sed adipiscing. Donec a tellus vitae est cursus vehicula. Nam ante sem, sodales id, fringilla vel, condimentum vel, nulla. Quisque sodales. Etiam imperdiet elit id odio. Aliquam erat volutpat. Maecenas porta tempor arcu. Nulla sem augue, pellentesque ac, consequat ut, condimentum euismod, risus. Sed aliquam tincidunt mi. In interdum lobortis orci. + +Sed vehicula hendrerit purus. Etiam a diam. Curabitur convallis. Suspendisse a nisi. Donec id magna in quam sollicitudin ultricies. Donec viverra. Quisque volutpat est sed sem. Aliquam justo. Vestibulum tortor massa, porttitor sed, varius quis, iaculis quis, odio. Aliquam eget neque. + +Mauris nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum eu quam in neque ultrices pellentesque. Cras in dolor quis quam varius hendrerit. Aliquam nisi lacus, lobortis eu, convallis sit amet, facilisis ut, mi. Aliquam at neque. Cras sagittis elementum justo. Vestibulum ut lectus aliquet purus malesuada volutpat. Duis at lacus adipiscing libero tincidunt vestibulum. Morbi a libero. Cras purus. Morbi ut augue et purus interdum scelerisque. Integer a dui. In hac habitasse platea dictumst. Duis pharetra metus eget mauris. Aliquam interdum ullamcorper massa. + +Etiam ornare. Nullam euismod. Aenean consequat gravida ligula. Aliquam est. Proin vitae lacus. Praesent a eros sit amet dui luctus commodo. Phasellus vehicula arcu eget dolor. Praesent fermentum congue leo. Aliquam volutpat purus ut lorem. Fusce hendrerit enim at leo. Aliquam rhoncus nisl. Vivamus dictum egestas mi. Suspendisse pellentesque bibendum dolor. Pellentesque tincidunt, turpis semper pellentesque condimentum, ipsum metus sodales ligula, id volutpat diam turpis ut elit. + +Praesent sed lacus. Nam eleifend molestie mauris. Donec dapibus fermentum massa. Donec viverra faucibus purus. Curabitur congue, libero vitae viverra pellentesque, diam velit sodales enim, sed suscipit lectus nisi nec neque. Vestibulum malesuada, lacus at cursus congue, velit lectus tristique dolor, sit amet sodales neque ipsum a libero. Vestibulum et quam. Curabitur placerat. Curabitur nunc arcu, euismod nec, vulputate hendrerit, aliquet eget, quam. Curabitur vel enim. Suspendisse potenti. + +Nunc consequat orci ut lacus. Fusce velit dolor, dapibus sed, blandit sit amet, rhoncus id, risus. Duis urna nibh, scelerisque quis, dapibus a, scelerisque sed, nibh. Donec luctus. Ut eu mauris cursus diam lacinia rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam vehicula molestie justo. Maecenas imperdiet pede sed mi. Suspendisse nulla dolor, hendrerit eget, hendrerit id, dictum vel, leo. Duis accumsan. Curabitur in felis. Nunc lorem. Ut leo dolor, laoreet nec, vulputate at, eleifend in, nulla. Quisque nunc purus, varius eget, accumsan nec, aliquet et, nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras adipiscing viverra dolor. Mauris porttitor ultrices purus. Nulla facilisi. Praesent faucibus ante vitae mauris. + +Praesent lacinia lectus sed nisl. In tempus congue mauris. Integer facilisis ornare enim. Nulla id massa. Donec commodo diam at tellus. Nam dapibus viverra est. Nam tellus. Praesent a libero. In faucibus est eget nibh. Nulla eros orci, imperdiet non, blandit non, tempor eget, mi. Pellentesque convallis. + +Quisque eget mi ac leo euismod faucibus. Phasellus rhoncus purus id dui. Vestibulum malesuada eleifend ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque blandit mattis odio. Suspendisse consequat, lectus ac semper sollicitudin, mi velit dictum augue, ac tempus dolor erat sit amet dui. Proin hendrerit, felis quis volutpat posuere, diam odio malesuada odio, a interdum orci diam quis sapien. Pellentesque odio odio, viverra vel, gravida eu, molestie sed, nulla. Phasellus mauris pede, commodo ut, euismod eu, hendrerit eu, est. In hac habitasse platea dictumst. Nulla elementum lacus eu augue. Sed erat. Proin porta. Maecenas quis mi. Phasellus at enim ac justo gravida ultrices. Cras leo. + +Integer ut arcu. Donec sed magna. Proin felis. In iaculis, ligula id fringilla pretium, nibh diam accumsan tellus, eget accumsan metus dui varius turpis. Phasellus orci metus, eleifend sed, tempor ac, scelerisque ac, urna. Integer viverra neque a mauris. Mauris porttitor dolor eu velit. Integer odio elit, vestibulum ut, volutpat id, rhoncus commodo, urna. Etiam placerat pharetra erat. Ut tempor est. Integer dignissim blandit tellus. Morbi nibh dolor, scelerisque id, commodo malesuada, mattis at, mi. Cras tincidunt commodo purus. In tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ullamcorper. Ut hendrerit. Morbi ultrices. + +Praesent iaculis, eros ac egestas sodales, urna leo fermentum ligula, sit amet aliquam velit sem non purus. Donec rutrum arcu quis purus. Nam posuere, lacus at consequat placerat, nulla pede posuere orci, non euismod turpis dui quis nisl. Proin porta adipiscing nibh. Donec tristique dolor at tellus. Donec neque massa, auctor id, faucibus vitae, ullamcorper vel, nisi. Proin molestie neque sed massa. Nam tempor. Morbi aliquam sapien at tellus. Fusce quis risus et mi pretium pulvinar. Fusce sit amet ligula. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse eu enim et felis scelerisque lobortis. Praesent bibendum. Vivamus vehicula. Integer at nibh sed velit rhoncus molestie. Cras lacus. Sed ullamcorper eros vel erat. Fusce eu tortor sit amet diam euismod sagittis. Nunc quis lacus id nibh convallis varius. Suspendisse vitae mi. Vestibulum tristique. Donec malesuada ipsum id neque. Nullam sed lacus. Duis egestas, justo ut congue ornare, augue sapien luctus diam, at accumsan erat sapien ut libero. Phasellus vel nulla. Suspendisse arcu tellus, porttitor a, pharetra faucibus, aliquam sit amet, massa. Nulla porttitor tincidunt lorem. Nunc dolor odio, sagittis in, lobortis vel, volutpat sed, nibh. + +Quisque blandit leo ut sapien tempus facilisis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean ultricies porttitor justo. Fusce rutrum eros ut urna. Proin quis quam eget dui aliquam accumsan. Donec suscipit eleifend elit. Pellentesque mattis, felis sodales iaculis imperdiet, lacus sem convallis augue, sit amet aliquet arcu purus fringilla risus. In eu odio id magna pharetra ornare. Aliquam interdum pulvinar ipsum. Sed neque. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam sit amet nisi. Ut at augue. Mauris volutpat blandit ligula. Nulla eu metus. Vestibulum eget elit. Praesent posuere. Vestibulum id sem non lectus mollis tincidunt. Aliquam id felis at ante ornare tempor. Nulla lacus turpis, feugiat vitae, cursus quis, consectetuer non, mauris. Fusce lacus massa, porttitor ut, molestie ut, venenatis a, lorem. Praesent sit amet orci. Mauris rhoncus felis vitae felis adipiscing imperdiet. Maecenas mollis diam nec leo. + +Fusce enim ipsum, ultrices eu, molestie id, elementum id, sapien. Integer a urna. Nam velit libero, venenatis eget, tempor sit amet, feugiat vitae, ante. Fusce nunc. Sed semper nisl nec risus. In sed libero. Proin tortor neque, tincidunt ac, tempor ac, pharetra quis, velit. Duis lectus augue, ultricies vel, consequat id, iaculis id, ante. Vivamus auctor metus a ante. Curabitur arcu nisi, facilisis at, laoreet in, consectetuer sed, mauris. Quisque placerat diam sed dui. Vivamus pretium condimentum lorem. Curabitur laoreet. Aenean orci ligula, cursus eget, lacinia non, faucibus vel, lorem. + +Aliquam erat volutpat. Curabitur eros dolor, congue a, condimentum sed, luctus ut, nibh. Maecenas non tortor nec turpis commodo pellentesque. Praesent euismod placerat mi. Suspendisse potenti. Phasellus ut neque vitae orci mattis iaculis. Integer eget tellus. Donec at ante. Nam lacinia leo eget erat. Maecenas euismod magna congue tortor. Morbi nec massa eu enim malesuada sollicitudin. Sed accumsan. Nullam ipsum. Ut odio. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque id velit. Nam odio sem, aliquet ut, tempus sit amet, euismod et, nunc. + +Pellentesque libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent mauris nunc, varius ut, convallis molestie, luctus sit amet, leo. Sed dictum lorem et arcu. Nunc venenatis pellentesque massa. Nulla facilisi. Phasellus in tortor eget risus scelerisque vulputate. Sed nibh elit, sagittis ac, condimentum nec, convallis et, justo. Fusce volutpat metus. Nunc auctor. Vestibulum leo eros, pellentesque ac, mollis ultrices, rhoncus non, dolor. Mauris vehicula placerat nisl. Vestibulum bibendum, arcu quis congue elementum, velit nunc eleifend turpis, id luctus risus nisl sit amet tellus. Phasellus pede neque, blandit non, commodo vitae, ultricies eget, magna. Aliquam erat volutpat. + +Nulla facilisi. Aliquam ac ante. Cras risus. Morbi mauris lacus, posuere eu, blandit et, pharetra at, mi. Proin ac purus. Duis cursus nisl rutrum quam. Aliquam a odio non magna pellentesque ultricies. Maecenas ac massa quis sapien ullamcorper tempus. Cras cursus velit sed sapien. Proin nulla. Vivamus sodales aliquam nibh. Etiam et erat ut ante lacinia euismod. Fusce nisi. Proin quis nulla. + +Quisque venenatis, eros sed laoreet sollicitudin, orci ante pellentesque nisl, sit amet viverra quam erat non risus. Cras eget libero. Sed elit magna, semper eu, fringilla in, dignissim sodales, erat. Vivamus feugiat sem vel dui. Donec convallis sollicitudin diam. Cras sed purus. Donec felis eros, semper eget, tempor consectetuer, sagittis quis, nisl. Duis in ante. Cras non turpis. Nulla tempor velit aliquet turpis molestie placerat. Proin elementum fermentum mauris. Vivamus sed orci lacinia dui placerat venenatis. Vestibulum feugiat, tellus in volutpat rutrum, magna nisi ullamcorper eros, id pulvinar neque erat ut lacus. Vivamus sed augue. Nulla facilisi. Maecenas ante augue, elementum ut, sodales vitae, condimentum nec, lorem. Duis pede orci, fringilla at, eleifend nec, pretium in, erat. Nam sagittis, turpis vitae convallis pharetra, odio sem scelerisque lacus, nec lobortis dui diam vel eros. In semper gravida neque. + +Integer nunc. Ut pretium ipsum sit amet elit. In nec arcu. Sed vestibulum vulputate ipsum. Pellentesque tincidunt. Nulla gravida dolor in tellus. Cras vehicula, dolor ut pellentesque aliquam, erat enim auctor massa, vehicula lobortis odio eros quis quam. Proin dapibus neque in enim. Proin elit. Integer rhoncus tincidunt elit. Fusce lorem metus, semper ac, volutpat vitae, facilisis ut, tellus. Donec vel turpis vitae nisi pharetra porttitor. Maecenas tortor. Fusce mi. Nullam nec turpis. Sed sodales vestibulum nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Pellentesque dolor dolor, laoreet eu, aliquet quis, scelerisque sit amet, arcu. In hac habitasse platea dictumst. Nullam cursus urna eget elit. Quisque blandit sapien ac ante. Proin nulla eros, gravida volutpat, sodales vel, mollis eu, massa. Nulla tristique sollicitudin nisl. Curabitur vitae lorem vitae velit egestas ornare. Aenean eget eros. Aliquam erat volutpat. Fusce a urna id odio aliquet convallis. Curabitur sit amet nisl posuere leo posuere dapibus. Duis metus erat, luctus vel, rhoncus at, convallis sit amet, enim. Vivamus hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam eget elit. + +Nullam a nunc. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In metus urna, tincidunt et, lacinia sit amet, lobortis vitae, ligula. Proin et mauris vitae mi accumsan pellentesque. Etiam quam purus, hendrerit sed, feugiat vitae, euismod eget, tortor. Ut aliquam magna vitae justo. Suspendisse non justo vel velit condimentum tempus. Duis tempus ipsum vitae tellus. Proin in massa. Etiam ullamcorper dictum tellus. Proin aliquet felis at leo laoreet pulvinar. Vestibulum arcu purus, malesuada sit amet, cursus eu, placerat sit amet, nunc. Nam massa odio, sollicitudin in, adipiscing a, aliquam nec, risus. Aliquam blandit hendrerit libero. Mauris gravida. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur a nibh. Ut interdum fermentum neque. Pellentesque sed nunc. Mauris vehicula nisi et nunc. Praesent lorem. Donec semper. Integer eu lacus in est aliquam hendrerit. Vestibulum eget neque. Sed semper luctus velit. Curabitur nibh augue, congue eu, hendrerit id, congue et, enim. Integer placerat aliquam lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae eros. Donec vel nisl. + +In vestibulum facilisis urna. Ut risus. Mauris pharetra. Pellentesque mattis. Integer suscipit aliquam ipsum. Duis blandit, sapien et ultricies condimentum, felis mi elementum pede, nec sagittis metus mauris quis quam. Quisque accumsan arcu vel nulla. Cras sem sapien, porttitor id, ultricies sagittis, luctus eu, nulla. Integer quis eros. Morbi sed urna a tellus vehicula vulputate. Etiam nec augue eget felis semper tristique. Quisque ut dolor vel risus dictum consequat. Sed eget dolor sed nunc lacinia aliquet. Suspendisse ac tortor in ipsum posuere venenatis. Sed eget erat. Nulla faucibus. Duis laoreet, massa porttitor aliquet egestas, ipsum lectus rhoncus quam, in adipiscing eros sem ut tellus. Pellentesque feugiat tempus quam. Vivamus id dolor eget sapien consectetuer tempor. Aliquam erat volutpat. + +Nulla iaculis fermentum libero. Curabitur faucibus, massa malesuada cursus tincidunt, erat sem eleifend mauris, sed fringilla mi ante ac purus. Duis elementum lectus. Nunc ornare arcu eu tortor. Vestibulum vel dolor at purus lacinia fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas tincidunt, eros a egestas pellentesque, risus risus dictum libero, id aliquet metus justo in massa. Proin a tellus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed purus. Sed non pede. Aenean massa sapien, sodales sit amet, consequat dictum, eleifend vitae, tortor. Donec ultrices lacinia elit. + +Morbi adipiscing sodales dolor. Ut ullamcorper ultricies est. In venenatis tempus augue. Suspendisse tortor dolor, accumsan et, suscipit a, tincidunt ut, libero. Aliquam scelerisque magna sed felis. Quisque ut nunc a magna vulputate placerat. Aliquam rhoncus vehicula dui. Sed tortor. Nullam sit amet diam. Nunc sed eros. Sed et odio tincidunt elit gravida convallis. Curabitur quis tortor a lacus semper varius. Mauris at augue non mi sollicitudin aliquam. Integer ullamcorper. Pellentesque suscipit quam non purus. Aliquam ac eros at arcu ullamcorper consectetuer. Suspendisse pretium mattis leo. + +Duis at nunc. Sed dolor est, varius ac, porta et, tincidunt hendrerit, risus. Vivamus ut magna. Praesent ut mauris. In purus lacus, mattis sed, vestibulum nec, tempor at, nisl. Cras ullamcorper venenatis tellus. Ut dolor. Maecenas malesuada, pede a pulvinar mattis, arcu diam vehicula risus, quis porttitor augue massa in velit. Nunc congue. Morbi velit metus, rhoncus et, aliquam consectetuer, ultricies malesuada, ligula. Sed velit nisl, sagittis vitae, pharetra a, posuere sed, massa. Nulla facilisi. In varius, ligula id lobortis sodales, augue orci fermentum tellus, eu pulvinar risus ligula a sapien. Morbi laoreet ipsum non mi. Nam cursus lorem ut mi. Vivamus magna enim, posuere non, semper quis, sodales eu, arcu. Etiam mi purus, pretium feugiat, varius sed, pellentesque eget, ligula. In leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vitae orci eu orci sollicitudin feugiat. + +Praesent purus massa, euismod vitae, tempus nec, consequat hendrerit, metus. Aenean felis est, egestas vitae, accumsan eget, pellentesque in, sapien. Duis dapibus pede non sapien. Nunc urna. Integer vel libero. Duis augue arcu, dapibus non, facilisis vitae, posuere ut, eros. Donec vitae nunc sit amet arcu imperdiet dictum. Morbi eleifend, lorem eu consectetuer vestibulum, diam nunc ornare arcu, ac tempor felis dolor eget eros. Phasellus massa sem, sollicitudin ac, sodales gravida, luctus a, quam. Nam neque quam, viverra at, venenatis quis, sagittis non, enim. + +Nulla facilisi. Pellentesque egestas lacinia est. Sed tincidunt, pede sed tincidunt vestibulum, urna dolor adipiscing purus, vitae fringilla felis elit in nibh. Nulla sed nisi. Mauris suscipit scelerisque arcu. Etiam non enim vel eros accumsan malesuada. Nunc tincidunt commodo mauris. In tincidunt risus quis urna. Nulla diam tortor, aliquet et, tincidunt quis, sollicitudin ac, tortor. Cras nisl neque, vulputate suscipit, molestie quis, pulvinar at, nulla. Nullam ac metus nec odio posuere varius. Cras sed pede nec dui posuere bibendum. Duis euismod ullamcorper libero. Aliquam faucibus pulvinar turpis. + +In ut neque id nunc feugiat commodo. Curabitur dignissim, felis at sollicitudin lacinia, enim elit suscipit neque, sed luctus lorem ipsum in leo. Duis dapibus, odio quis auctor commodo, nisl odio mattis tellus, nec tincidunt turpis diam in arcu. Curabitur a sem. Nullam volutpat magna. Pellentesque sagittis, neque consequat pretium cursus, dolor lacus consectetuer arcu, sed laoreet est urna et metus. Suspendisse placerat, dui a porta tempor, lorem dui lobortis neque, sed venenatis diam enim id eros. Etiam et nisl non lectus faucibus consectetuer. Morbi scelerisque, sem nec tempus ullamcorper, ipsum diam feugiat lorem, a fringilla sapien elit quis nibh. Nullam diam urna, viverra sed, pharetra rhoncus, tincidunt vel, orci. Integer accumsan mattis erat. Nam dictum. Mauris nec leo. Nulla iaculis. Nulla nisl mi, dapibus quis, vehicula a, cursus eget, odio. + +Phasellus dapibus euismod nibh. Vivamus imperdiet ante in ligula. Pellentesque accumsan. In imperdiet, dui a auctor fringilla, metus nisi cursus dolor, vel luctus ligula lorem vitae mauris. Praesent mattis vestibulum elit. Aliquam enim lacus, pulvinar non, lacinia sit amet, eleifend non, velit. Vestibulum ac leo. Mauris imperdiet justo ac lectus. Sed molestie lectus sed dui. Sed fermentum tempus mauris. Nam ornare orci ac tellus. Ut malesuada, lacus id lacinia accumsan, diam elit adipiscing metus, et bibendum sapien nibh blandit orci. Suspendisse ipsum tellus, sagittis quis, vestibulum non, vulputate eu, eros. Praesent at nulla id pede scelerisque ultricies. Cras blandit pretium tellus. Maecenas dapibus condimentum augue. Phasellus tincidunt pharetra lorem. Morbi non eros. Sed tempor, nisl a tincidunt tincidunt, eros diam dictum sem, vel dignissim ante diam sed magna. Praesent non ligula id metus molestie consectetuer. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse vel mi. Curabitur ante nulla, rutrum a, convallis vel, vehicula ac, nunc. Nunc sagittis, enim sit amet auctor rutrum, mauris arcu vulputate neque, et euismod est felis quis ante. Vestibulum turpis tellus, hendrerit in, lacinia commodo, ullamcorper gravida, risus. Mauris rhoncus lacinia risus. Maecenas sollicitudin erat vitae nunc. Praesent pretium pellentesque augue. Donec interdum. Praesent ac eros vitae erat lobortis fringilla. Aenean consequat tellus. Nulla accumsan bibendum felis. Maecenas pretium ante id nisi. Aenean mi arcu, semper sed, mattis eu, venenatis sit amet, arcu. Donec aliquet euismod leo. Proin magna justo, tristique a, semper ac, sollicitudin a, ligula. Morbi velit. Aliquam vel nisi. + +In a lorem ut nunc feugiat congue. Donec fermentum bibendum dui. Proin varius est quis velit. Donec aliquet sem accumsan mi. Sed placerat. Nullam ac nisi a massa lobortis suscipit. Nunc id leo. Aliquam et massa. Nullam vestibulum elementum metus. In consectetuer nisi vel justo. Maecenas eget purus sed massa varius pellentesque. Phasellus faucibus felis quis felis. Aenean odio arcu, blandit quis, facilisis in, imperdiet eu, lorem. Nam posuere pulvinar mi. Fusce tristique, mauris et consectetuer ultricies, mauris lectus tempor justo, at fringilla est est sed nisi. Quisque faucibus. Sed in tortor tincidunt est lacinia iaculis. Maecenas a massa. Pellentesque a nibh at purus porta hendrerit. + +Nullam turpis. Fusce ac sem sed odio pellentesque imperdiet. Curabitur in arcu. Praesent lacus lacus, feugiat id, pulvinar in, tincidunt sed, neque. Maecenas viverra odio eget tortor. Integer aliquam, lorem rutrum venenatis dignissim, ligula magna malesuada arcu, vel feugiat lorem ipsum quis massa. Morbi ante. Vestibulum mauris libero, ullamcorper quis, ultrices quis, facilisis non, massa. Maecenas imperdiet. Aliquam erat volutpat. Pellentesque dignissim gravida lectus. In nibh odio, auctor eget, dapibus quis, dignissim venenatis, arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis pellentesque ligula quis massa. Curabitur condimentum, justo eget ornare luctus, lorem ligula sagittis pede, a porta nunc nunc in neque. Quisque felis mauris, condimentum vitae, auctor vitae, tincidunt quis, pede. Nunc lacinia ante in leo. Pellentesque libero. Aenean a ligula et nunc vestibulum consectetuer. + +Fusce ornare. Praesent id urna. Integer venenatis, quam non sagittis accumsan, ante nibh sagittis augue, sollicitudin adipiscing dolor velit eu erat. Proin quis enim eu purus vehicula aliquam. Nulla vel enim vel elit sollicitudin fringilla. Aliquam erat volutpat. Sed suscipit felis ut turpis. Etiam rutrum risus imperdiet est. Aliquam a tellus at tellus commodo dapibus. Mauris rutrum magna et odio. In at dolor. Curabitur vehicula lectus in tortor. Fusce justo purus, luctus vitae, mollis in, pharetra ac, purus. Nullam posuere interdum justo. Curabitur vitae lacus vel leo congue pulvinar. + +Aenean eleifend nibh varius tortor. Suspendisse vel eros. Proin nec diam a tortor ultrices ornare. Aliquam scelerisque feugiat justo. Vivamus ante urna, adipiscing vitae, porttitor eu, sodales et, felis. Suspendisse potenti. Curabitur ac massa in nisl sagittis mollis. Nam quam ligula, consectetuer eget, iaculis at, varius eu, leo. Duis dolor ligula, tincidunt at, ullamcorper sed, accumsan aliquam, ligula. Phasellus vulputate, lorem at tincidunt pharetra, risus lectus lacinia magna, quis rutrum enim magna at sem. In hac habitasse platea dictumst. Duis id sem a mauris sollicitudin tincidunt. Etiam eu purus eu arcu fringilla adipiscing. Vivamus ornare tempus diam. Proin turpis quam, lacinia non, egestas at, commodo eget, pede. Praesent vulputate risus in est. Nulla facilisi. + +Ut elementum lacinia purus. Proin vitae arcu ac nulla convallis aliquam. Nulla congue, libero id pellentesque mattis, quam lectus porttitor diam, a scelerisque dui libero in sapien. Nullam felis diam, vehicula vel, molestie ut, vestibulum aliquam, sapien. Donec convallis, est ut elementum volutpat, mauris ipsum gravida sem, commodo facilisis sapien lectus semper lectus. Quisque porttitor eros ut nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam mattis risus sed odio. Vestibulum et odio. In hac habitasse platea dictumst. Nam tristique massa ut ligula. Quisque nibh tellus, vehicula sit amet, adipiscing at, convallis nec, ligula. Vestibulum pretium, mi nec fringilla bibendum, dui nunc sodales pede, a semper magna nibh non diam. Donec massa nunc, viverra vel, consectetuer porta, dapibus non, ipsum. Duis nisl mauris, cursus vel, semper non, sollicitudin bibendum, felis. Vestibulum eu neque. + +Cras nec dolor. Donec laoreet tempus lectus. Cras sed tortor interdum lacus eleifend dignissim. Maecenas sit amet elit. Nullam quis dolor vel dui pharetra luctus. In sit amet quam sit amet pede ultrices ultrices. Maecenas diam. Integer urna. Curabitur dictum, velit sed placerat suscipit, erat turpis fermentum justo, sed interdum neque sem et nibh. Vivamus consequat convallis magna. Nam aliquam, est ac bibendum commodo, magna est dictum mi, vitae malesuada elit magna vitae odio. Maecenas tempor vulputate tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus dui. Etiam accumsan pede congue tortor. + +Morbi tempor libero ac lorem. In aliquet varius magna. In arcu. Phasellus odio. Fusce tincidunt aliquet felis. Quisque velit. Sed luctus. Aliquam feugiat fringilla mi. Aliquam molestie viverra risus. Proin arcu. Vestibulum lobortis tempus nisi. Praesent a arcu in velit viverra rutrum. + +In sed lectus. Donec risus dolor, blandit sit amet, elementum convallis, pharetra quis, pede. Integer ornare. Aenean egestas dapibus justo. Sed quam leo, posuere at, elementum vitae, commodo eget, est. Aliquam molestie rhoncus enim. Curabitur iaculis ultrices pede. Morbi aliquet rutrum lacus. Aliquam quam. Sed commodo, turpis in pharetra posuere, mi risus imperdiet erat, a vestibulum massa tellus vehicula sem. Mauris fringilla ultrices nunc. Nam nisi enim, eleifend sit amet, ultrices sed, fermentum non, augue. Proin congue lobortis nisi. Maecenas hendrerit. Nam sed nisl. Nunc elementum odio eu risus. In metus. Phasellus gravida pretium ligula. Nulla vitae neque. Nam nisi tortor, ornare non, blandit at, cursus eu, tortor. + +Duis bibendum ipsum in nunc cursus molestie. Nunc orci. Nullam nec ante non est dignissim viverra. Mauris blandit, velit id feugiat pretium, elit magna pellentesque dolor, at sagittis lacus velit egestas magna. Pellentesque cursus, diam consectetuer sagittis fringilla, tortor nisi adipiscing nunc, eu varius lacus risus ac elit. Mauris id nisi quis leo euismod venenatis. Pellentesque ac ante. Mauris arcu sapien, tempor at, porttitor id, condimentum ut, dui. Etiam fermentum ultricies augue. Cras ut eros at justo ultricies iaculis. Duis dignissim, nisl et facilisis fermentum, erat purus molestie tellus, quis tempus ipsum lectus at elit. Nulla vitae lorem. + +Aenean vel sem et diam semper congue. In bibendum diam quis tellus. Nunc facilisis ultricies nibh. Cras nunc enim, feugiat sed, ultrices vitae, sagittis vitae, ipsum. Fusce vitae nulla. Donec pellentesque, velit in porttitor eleifend, est neque lobortis velit, sit amet rutrum ante tortor nec dolor. Donec vehicula. Nulla facilisi. Sed egestas ultrices nibh. Donec elit lectus, convallis porttitor, aliquet dapibus, feugiat eget, ligula. Sed consectetuer justo. Maecenas a sapien sit amet nisi dapibus lobortis. Vivamus luctus lorem non nulla. Sed eget erat vitae libero interdum posuere. Cras pulvinar. Nullam imperdiet, dolor tempor dignissim blandit, dui sapien rhoncus neque, id malesuada augue magna sit amet urna. Duis sed mauris. + +Morbi accumsan. Sed mauris augue, fringilla non, auctor ut, auctor et, orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus ut pede. Donec viverra enim vel lorem. Pellentesque neque mauris, interdum eu, venenatis id, condimentum eu, sapien. Donec ipsum arcu, lacinia adipiscing, laoreet et, cursus vel, velit. Ut sagittis mauris quis risus. Integer eu odio vitae lacus viverra accumsan. Morbi leo ante, dignissim sed, varius quis, volutpat vitae, nisi. Nulla placerat interdum elit. Donec neque dui, sagittis vitae, sollicitudin quis, commodo vitae, neque. Nulla quis ligula ornare ligula dictum ornare. Mauris rutrum rutrum neque. Aenean vehicula tempus est. Donec varius scelerisque pede. Donec placerat vulputate leo. Nullam nunc nisl, posuere non, feugiat vitae, pellentesque quis, mauris. In dui neque, cursus eget, sagittis eget, dapibus vitae, mi. Proin eget est. + +Fusce porta est. Mauris magna. Aliquam ipsum lacus, ultricies id, vestibulum luctus, accumsan ut, ante. Sed mauris. Sed adipiscing leo sit amet magna. Suspendisse potenti. Nunc massa elit, fringilla eget, egestas vitae, luctus vitae, dolor. Phasellus quis nulla eu nisi interdum sollicitudin. Nullam id tellus. Integer iaculis dolor ac purus. Sed vel mi. Curabitur non magna sit amet justo condimentum vulputate. Quisque tincidunt pede eu nisl. Vivamus lobortis. Nunc metus metus, congue sed, tincidunt sed, pretium at, odio. Donec a arcu. In sem justo, vehicula sed, varius id, volutpat at, risus. Praesent iaculis massa. In arcu elit, hendrerit eget, ullamcorper in, porta id, tellus. Donec sagittis hendrerit diam. + +Suspendisse potenti. Sed et diam et augue sagittis lobortis. Phasellus dolor. Ut et arcu eget ante tempor posuere. Aliquam fermentum scelerisque dui. Mauris at purus. Donec erat sem, vestibulum nec, faucibus ac, mattis a, leo. Suspendisse adipiscing lacinia sem. Nullam orci arcu, dictum et, faucibus viverra, dapibus et, neque. Cras nunc diam, adipiscing non, sollicitudin in, interdum vel, massa. Mauris sagittis, justo at tristique tempus, mauris mauris aliquam ante, sit amet posuere diam dui eget ligula. In dignissim, nisl ut lacinia condimentum, erat justo porttitor nulla, non gravida ligula magna eget massa. Vestibulum vitae ligula at mi vestibulum suscipit. Duis laoreet. Nulla commodo libero sit amet lorem. Ut elementum sem. Integer vel dolor. Nam facilisis mi quis sem ultrices sagittis. Sed quis quam at metus molestie bibendum. + +Proin dui enim, lacinia a, feugiat ac, placerat vitae, pede. Quisque egestas, leo eget aliquam pretium, libero justo tincidunt eros, ut egestas augue pede elementum nibh. Curabitur mollis sodales enim. Donec augue. Phasellus id ipsum posuere dui pretium faucibus. Mauris luctus ante semper nisi interdum adipiscing. Duis dapibus, odio quis viverra rhoncus, justo quam bibendum dolor, id dapibus velit erat vel erat. Fusce sit amet nisl venenatis quam ultrices condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec rhoncus scelerisque ligula. Vestibulum mi odio, accumsan et, adipiscing eget, ornare ut, quam. Nullam blandit molestie mauris. Curabitur dignissim mauris et lorem. Suspendisse a justo. Nam mattis faucibus arcu. Duis blandit enim non massa. + +Nullam lorem. In hac habitasse platea dictumst. Mauris consectetuer posuere mauris. Maecenas tincidunt mauris in eros. Nulla eu metus eu orci sollicitudin faucibus. Suspendisse aliquam mauris id est. Cras blandit dui et urna. Nulla arcu. Sed a urna. Nulla dapibus vehicula tortor. Donec risus. Sed quam metus, egestas eu, cursus ut, viverra non, odio. Ut justo justo, malesuada sit amet, blandit suscipit, molestie in, justo. Vestibulum consequat, quam ac feugiat tincidunt, ipsum libero eleifend odio, non eleifend pede ipsum non ante. Nullam a metus. + +Nam ac nisi at felis cursus mattis. Pellentesque consequat sem quis orci. Quisque tempus. Aenean imperdiet molestie pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eu tellus. Nulla diam eros, sodales ut, sodales nec, tincidunt ac, nunc. Nunc lacinia faucibus ipsum. Vivamus vel neque in erat fermentum luctus. Nulla eget metus nec augue bibendum placerat. Vivamus tempus. Praesent congue ornare ipsum. Etiam mattis feugiat justo. + +Aliquam dui. Aenean commodo tortor vitae nulla. Morbi et ipsum. Mauris ac ipsum. Nam vel risus ut lectus mollis viverra. Curabitur elementum mollis est. Nullam elit. Vestibulum suscipit pretium enim. Vestibulum ut massa. Proin nec felis. Maecenas gravida, arcu nec consequat sagittis, eros tellus scelerisque mauris, vitae accumsan quam quam ut nunc. Integer eget ante eu velit laoreet malesuada. Nunc sagittis, mauris vitae pharetra volutpat, tellus tellus eleifend eros, sit amet rutrum ipsum nisi a velit. Praesent varius leo eu erat. Vivamus consequat placerat purus. Donec pretium elementum nibh. Proin at elit non sem aliquet mattis. Sed ullamcorper ipsum sit amet elit. + +Mauris in metus. Suspendisse magna lorem, faucibus vel, tincidunt quis, scelerisque non, tellus. Fusce quis lorem. Proin a lacus sit amet mauris iaculis pulvinar. Suspendisse rhoncus eros nec mi. Praesent euismod, turpis vitae rutrum pretium, odio metus volutpat neque, eget tempus sapien neque sed erat. Donec fermentum purus at lectus. Nullam sem. Fusce vel mi quis erat lobortis posuere. Aenean eget urna. Suspendisse ligula. Duis in nisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Curabitur vulputate lectus id pede. Phasellus eu velit. Etiam venenatis adipiscing nibh. Aliquam cursus pulvinar tellus. Vestibulum neque. Mauris nec justo et erat semper pellentesque. Fusce mattis dictum dolor. Etiam eget purus eu massa varius elementum. Pellentesque massa. Ut ultricies diam sed ipsum. Nullam diam. Pellentesque id magna id libero tristique aliquam. + +Ut eleifend, purus id placerat venenatis, urna augue aliquet ligula, in ultricies leo risus et tellus. Mauris et nulla id urna tristique tempus. Ut facilisis, urna eu vestibulum rhoncus, lacus eros consectetuer metus, et rutrum dui lectus in purus. Nunc vel nisl non ipsum tincidunt mollis. Nam quam lacus, ornare vitae, rhoncus non, congue sed, odio. Proin nibh dui, porta vel, venenatis non, pellentesque ut, nisi. Sed tristique felis a magna. Suspendisse eget tellus. Cras gravida imperdiet velit. Integer hendrerit risus. Proin orci. Aliquam ullamcorper mauris quis mauris. Nunc lacinia vestibulum metus. Duis tellus. Nullam faucibus, leo ac vulputate sollicitudin, leo dolor faucibus erat, quis bibendum orci odio non arcu. + +Nullam accumsan mattis dolor. Donec et dui. Praesent a felis mollis lacus semper lacinia. Curabitur pellentesque luctus est. Proin nulla dui, condimentum vel, faucibus non, interdum ac, erat. Maecenas scelerisque, lectus id volutpat accumsan, sapien tortor pellentesque dui, sed semper magna sem ut leo. Proin nulla. Nullam dapibus ullamcorper sem. Suspendisse vehicula metus in nunc. Pellentesque non quam vel arcu ultrices ullamcorper. Phasellus quis felis sit amet tellus ullamcorper fermentum. Sed vehicula sollicitudin urna. Curabitur pharetra scelerisque risus. Pellentesque id massa quis metus aliquam imperdiet. In nunc lacus, feugiat in, gravida eget, venenatis ut, tellus. Suspendisse potenti. Nam consequat adipiscing dui. In nulla nisi, feugiat ut, fermentum vel, gravida nec, tortor. In sed augue. + +Etiam ullamcorper augue at enim. Integer dignissim. Aliquam pulvinar congue nulla. Morbi enim massa, fringilla a, accumsan eget, condimentum nec, erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean pharetra. Etiam porttitor purus a metus. Aliquam interdum sem eget justo. Quisque volutpat luctus est. Aenean augue. Phasellus dui lectus, ultrices nec, commodo vel, auctor vel, nisi. Ut ultrices pellentesque nisi. Integer ac velit et sem imperdiet luctus. Fusce vitae turpis id augue mollis consectetuer. + +Maecenas nec lacus. Maecenas condimentum odio eu felis. Mauris ut nisl viverra erat faucibus adipiscing. Etiam egestas. Nunc et dolor vitae risus dignissim commodo. Morbi lectus velit, tincidunt nec, aliquet vel, mattis vitae, ligula. Maecenas ultricies semper dolor. Suspendisse malesuada. Integer mattis elit. Donec accumsan, lacus facilisis varius tempus, nulla elit porta erat, et rutrum elit sem sit amet dui. + +Maecenas mollis mi non nulla. Vivamus turpis. Suspendisse a metus. In quis mi in turpis congue auctor. Maecenas lacus. Suspendisse sollicitudin. Phasellus porta nunc non nisl pulvinar egestas. Sed nulla. Vestibulum ac mi. Mauris ultricies condimentum neque. Nulla tempus justo vel massa. Nulla suscipit congue arcu. Praesent id turpis. Mauris nibh pede, euismod semper, molestie ac, rhoncus vitae, ante. Maecenas erat felis, viverra sollicitudin, sagittis eget, pellentesque nec, orci. Fusce ultrices consequat lacus. Aliquam erat magna, feugiat at, viverra a, mollis non, turpis. + +Donec mi. Nam dictum pellentesque sem. Donec mollis rhoncus elit. Phasellus rhoncus pede sit amet risus. Donec eget augue. Maecenas non lectus. Phasellus sollicitudin nisi nec felis. Aliquam pretium, est eget semper convallis, nibh nunc sollicitudin purus, id tempor pede dui vel magna. Vivamus ac lorem. Etiam nisl tortor, adipiscing dictum, elementum in, facilisis sed, nibh. Proin mauris. Proin rutrum massa eget sem. Curabitur tempor adipiscing elit. Curabitur purus tellus, fermentum eget, aliquet vitae, convallis ac, mauris. + +Integer consequat velit eu eros tincidunt vehicula. Nullam lorem sapien, rhoncus non, mattis quis, ultricies sit amet, enim. Curabitur commodo, libero in euismod suscipit, sem purus fringilla enim, ac molestie tortor orci et velit. Donec pede. Etiam placerat condimentum turpis. Phasellus egestas enim nec magna. Vivamus condimentum, nulla vel luctus tristique, eros risus vestibulum nulla, in vehicula arcu ipsum at felis. Donec aliquam elit at augue. Quisque a eros eu ligula accumsan dictum. Etiam vehicula turpis quis libero. Aliquam non mi. Donec et leo. Proin leo libero, aliquam tincidunt, congue nec, adipiscing porta, enim. Nulla lobortis, tortor sit amet imperdiet ullamcorper, dolor orci malesuada pede, sed gravida nibh urna vel lorem. Sed pharetra malesuada eros. Quisque euismod aliquet erat. Suspendisse aliquet mattis purus. + +Nunc id nulla quis justo congue sollicitudin. Praesent erat turpis, rhoncus eu, pretium eu, pellentesque a, nibh. Vivamus tempus. Cras nec risus at turpis imperdiet lobortis. Ut mattis. Maecenas est felis, pellentesque non, imperdiet sed, eleifend tincidunt, lorem. In tincidunt. Sed vel leo. Donec et urna in turpis hendrerit blandit. Donec condimentum accumsan est. Ut pharetra, metus vitae mattis consectetuer, leo quam vulputate odio, nec laoreet nisi velit eu erat. Integer lectus augue, egestas in, interdum eu, venenatis vel, sapien. Quisque et est vitae eros laoreet lobortis. Nullam ut risus non nulla placerat adipiscing. Praesent dapibus. Etiam a felis. Ut sodales consequat mauris. Duis lorem felis, luctus a, tristique in, molestie at, risus. Sed vehicula bibendum tellus. Nam consequat euismod lacus. + +Aenean tortor elit, gravida nec, fermentum eu, lobortis id, ipsum. Maecenas eu purus. Cras ac turpis ut nisi iaculis rhoncus. Nulla purus metus, dignissim nec, tincidunt vitae, dapibus eu, nibh. Fusce lobortis, nunc at viverra eleifend, justo turpis scelerisque eros, ac pellentesque metus nisl at purus. Sed elementum tellus sed enim interdum blandit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer ultricies aliquet odio. Mauris eget nunc a ipsum ultrices sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean accumsan. Donec sapien lectus, congue at, porta id, hendrerit vitae, nisl. Curabitur vel quam vel neque accumsan laoreet. Morbi sapien est, pretium in, consectetuer ac, mollis ut, libero. Donec tincidunt adipiscing metus. Nunc vestibulum egestas augue. Donec scelerisque dui ut sem. Suspendisse vel metus id est molestie iaculis. + +Vivamus pharetra, elit eu malesuada blandit, diam tortor mollis dui, sed pulvinar massa nunc et magna. Sed placerat elit auctor tortor. Nulla ac erat. Pellentesque consectetuer, dui convallis tincidunt condimentum, sem odio volutpat libero, non elementum felis neque nec odio. Maecenas hendrerit eros id diam. Mauris vel purus ac orci convallis convallis. Sed sit amet lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque dictum varius lacus. Mauris eget nisl. Suspendisse placerat, nulla non ornare dignissim, nisl diam sagittis tellus, in semper nisi dolor at nibh. Duis ullamcorper viverra felis. Integer a tellus. Suspendisse eget nunc. Aenean diam est, accumsan id, suscipit interdum, fringilla vitae, justo. Proin pede. Maecenas at neque in neque vestibulum eleifend. + +Vestibulum nulla lorem, porttitor eget, euismod ac, aliquam at, nisl. Maecenas et est eget massa varius lobortis. In mi. Duis porttitor fermentum purus. Donec cursus imperdiet ligula. Morbi et ligula et ante molestie vehicula. Mauris sed dolor. Sed imperdiet felis ut sem. Sed vitae neque elementum leo auctor fermentum. Duis feugiat ullamcorper erat. Aenean purus. Morbi fermentum vestibulum est. Pellentesque venenatis mauris. Phasellus pulvinar. Integer ipsum lectus, iaculis a, lacinia id, accumsan id, arcu. Phasellus at est. Fusce neque quam, ultricies id, iaculis vel, dapibus vitae, lacus. In lobortis convallis ante. Nulla nunc purus, vulputate in, hendrerit et, blandit et, ligula. + +Pellentesque leo metus, sagittis in, molestie vitae, dictum in, pede. Morbi pretium felis nec quam. Pellentesque mattis ante sed quam sagittis dapibus. Suspendisse sapien. Praesent bibendum iaculis tortor. Duis a nisl. Aenean mi. Donec dictum arcu in est. Morbi interdum vulputate ipsum. Aenean sit amet magna non nisl tristique posuere. Phasellus velit metus, tempor ac, fermentum eget, condimentum non, velit. Vestibulum sit posuere. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras aliquet massa nec dui. Cras arcu nunc, hendrerit ac, eleifend eu, ullamcorper nec, tellus. Sed pharetra purus sit amet quam. Curabitur mollis. Nam vitae pede. Etiam risus massa, vehicula sit amet, pharetra nec, sollicitudin ut, dui. Donec egestas justo at quam. Proin nisl risus, vestibulum nec, pretium vitae, tristique ac, lorem. Aliquam erat volutpat. Cras sed nibh. Pellentesque sollicitudin euismod augue. + +Etiam fringilla sollicitudin orci. Mauris cursus elit quis lacus. Cras tortor. In adipiscing, lectus id auctor vestibulum, neque pede accumsan dolor, non imperdiet magna diam accumsan velit. Suspendisse at libero ut nisi blandit sagittis. Phasellus non mauris. Fusce elementum sagittis sem. Suspendisse aliquam eleifend tellus. Proin ligula lorem, imperdiet quis, venenatis id, iaculis mollis, nisl. Etiam convallis pede at massa. Morbi accumsan dui et mauris. + +Sed sed orci. Nunc purus. Suspendisse potenti. Ut luctus fringilla mauris. Donec nibh. Phasellus porta. Phasellus sit amet odio sed magna sodales pharetra. Cras lectus. Suspendisse libero ipsum, commodo nec, facilisis in, suscipit lobortis, ligula. Duis massa nulla, semper et, consequat nec, pharetra eu, elit. Vivamus ultricies aliquam odio. Vestibulum sit amet massa. Sed consequat lacus sed urna. Etiam faucibus felis vel orci. Phasellus ullamcorper. Aenean consectetuer lacus at libero. + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis facilisis, ligula vitae condimentum scelerisque, velit orci gravida felis, vel ultricies quam mi non diam. Vivamus auctor metus non libero. Praesent ligula nisi, commodo condimentum, molestie et, viverra et, justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus sollicitudin. Nunc blandit cursus ipsum. Aenean nec ligula ut tellus sodales mattis. Integer sem. Aliquam id ligula. Sed tortor mauris, blandit vitae, cursus vel, elementum et, nulla. Aliquam scelerisque metus et nisl. Duis adipiscing magna at neque. Quisque vulputate eleifend nunc. Aliquam eget elit. Phasellus dui odio, bibendum sagittis, vestibulum id, dignissim imperdiet, orci. Nullam eu felis non nunc lacinia sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Suspendisse pellentesque, libero mattis ultricies accumsan, tortor tortor malesuada sem, et sodales libero odio ac ipsum. Vivamus quis magna nec est suscipit lobortis. Cras tempus posuere nunc. Quisque ut enim a felis egestas semper. Sed pharetra mattis neque. Fusce turpis nunc, congue sed, consequat non, congue sed, nulla. Suspendisse varius lorem id risus porta vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce sed purus. In a felis. Integer egestas auctor orci. Mauris ultrices suscipit nisl. Nullam purus. + +Cras tempor adipiscing ipsum. Ut quis mi. Maecenas in justo ut nulla congue pharetra. Pellentesque ut libero eu dolor venenatis suscipit. Praesent feugiat consectetuer nibh. Morbi faucibus sem non felis. In hendrerit arcu ac massa. In accumsan ultrices mi. Proin malesuada auctor felis. Curabitur interdum. Sed diam ipsum, ultricies in, tempor sit amet, viverra imperdiet, elit. Morbi molestie nisi. Mauris ipsum. Fusce dictum mollis magna. Duis commodo dignissim nulla. Vestibulum augue enim, ultricies quis, iaculis nec, tincidunt vitae, diam. Mauris lacinia tempus ipsum. Sed at mauris. Ut lorem. Donec libero. + +Duis iaculis lacinia lectus. Aenean convallis eros ac ante. Sed quis orci nec risus auctor fringilla. Phasellus facilisis elementum nisi. In hac habitasse platea dictumst. Nunc porta lacus nec ante. Morbi mauris erat, adipiscing in, pulvinar nec, lobortis nec, odio. Ut eleifend lectus sed quam. Nullam mollis. In non turpis et nisl hendrerit blandit. Duis elementum. Nunc nec libero. Suspendisse vestibulum risus non pede. Morbi imperdiet odio sit amet libero. Sed sed massa vitae ipsum mattis tincidunt. Nulla nec tortor vitae libero volutpat tempus. Donec aliquam. + +Duis sed nunc. Curabitur turpis nulla, vehicula sed, luctus quis, elementum eget, felis. Maecenas et purus. Maecenas leo tellus, tincidunt a, facilisis vitae, lobortis sit amet, velit. Donec convallis sapien. Maecenas mollis odio eu nibh. Etiam gravida. Integer molestie, sapien eu molestie lacinia, nunc nibh aliquam ligula, eu sagittis tellus erat sollicitudin odio. Duis et risus. Phasellus nisi neque, placerat nec, condimentum non, ultrices eu, sem. Ut pede. Etiam nulla metus, volutpat id, convallis sed, suscipit vel, urna. Donec vel elit. Ut leo neque, venenatis faucibus, lacinia nec, tincidunt eu, enim. Cras id dui a libero pharetra dignissim. Donec eros leo, porta quis, laoreet ut, pellentesque volutpat, lectus. + +Nullam blandit. Aliquam erat volutpat. Fusce adipiscing enim. Suspendisse non dui quis ligula porta vestibulum. Donec eu tellus vel lorem pretium porttitor. Praesent luctus. Aliquam ac eros in massa dapibus tincidunt. Donec ut magna. Etiam auctor lacus sit amet lacus. Sed ultricies ipsum nec elit. Quisque a est in purus suscipit tristique. + +Aenean sed dui vel dolor pulvinar laoreet. Vivamus vehicula lorem in pede. Vivamus et diam. Integer ac odio vel diam hendrerit bibendum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a nisi. Phasellus tincidunt dui vitae augue. Duis faucibus, dui interdum fringilla tincidunt, odio elit vestibulum libero, ac molestie magna lectus id lacus. Aenean ligula. Nulla facilisi. + +Fusce vel sem eu velit fringilla ornare. Sed feugiat tincidunt felis. Nullam felis mi, euismod sit amet, mollis at, sodales eget, augue. Nam imperdiet nibh at velit. Sed ut erat. In dui. Nulla facilisi. Nullam augue libero, tincidunt nec, pretium eu, pulvinar in, dui. Morbi vitae felis. Pellentesque vel justo vel velit sagittis malesuada. Proin vehicula blandit massa. Etiam tincidunt pharetra urna. In metus est, auctor nec, blandit a, cursus nec, quam. Mauris ac metus a libero congue faucibus. Mauris mauris dolor, sodales in, cursus ut, sodales rutrum, eros. Quisque mauris eros, sagittis vitae, lobortis ut, eleifend id, nisi. + +Aenean neque. Vestibulum egestas pellentesque ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus sagittis justo vel risus. Sed pretium neque vitae urna. Pellentesque congue libero id lorem. Mauris leo lorem, blandit sit amet, convallis quis, consectetuer sed, eros. Mauris tincidunt, enim a gravida euismod, magna nulla fermentum libero, viverra egestas velit quam et tortor. Vivamus aliquet massa vitae justo. Nulla congue lacus ac elit. + +Phasellus commodo quam vel ligula. Proin non metus at eros pulvinar luctus. Mauris diam lorem, posuere quis, gravida et, tincidunt nec, ligula. Sed diam. Aliquam elit lectus, hendrerit ut, imperdiet sit amet, pretium sit amet, ipsum. Mauris vehicula nisl in dui. Curabitur eget quam ut magna elementum fermentum. Mauris scelerisque. Quisque laoreet. Etiam tempus turpis. Pellentesque augue quam, hendrerit sed, tincidunt at, pharetra at, nisl. Aliquam lacus. Suspendisse potenti. Aenean velit libero, ultrices in, lacinia eu, luctus vel, ante. Etiam dictum mi in felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce gravida dapibus nisl. Cras vitae nisl. + +Maecenas dignissim, ligula non porta cursus, enim nunc malesuada sem, eu porttitor nulla urna eu quam. Fusce eros. Aliquam eros. Nam auctor. Nulla molestie porta est. Suspendisse potenti. Vivamus molestie lorem sed erat. Sed eget ipsum. Integer aliquam pulvinar nulla. Cras aliquet sem ut nunc. Fusce faucibus tempus lectus. Cras sodales, nisi ac facilisis ultrices, eros arcu dapibus sapien, et ultrices mauris tellus non dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras cursus varius metus. Ut turpis. Vivamus eget tortor. + +Sed laoreet, velit non accumsan cursus, nunc urna posuere justo, in dictum lectus pede id ante. Cras vulputate. Cras congue dui sed elit. Proin lacus sem, ultrices at, consequat in, tempor quis, metus. Proin vel arcu. Nam euismod hendrerit elit. Ut erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed posuere. Morbi eros urna, semper at, semper non, convallis quis, velit. Maecenas orci. Vestibulum lobortis tristique metus. Vestibulum lorem nulla, sollicitudin vitae, condimentum quis, auctor ut, dui. Vivamus vestibulum magna ut nisi. Curabitur eleifend dui vel nunc. Curabitur mauris lacus, malesuada sit amet, suscipit sed, rutrum luctus, tellus. Integer facilisis urna vitae lectus. + +Aenean quam leo, lobortis quis, malesuada eu, vulputate vitae, nisl. Praesent eget eros. Ut fermentum turpis id quam. Nam tortor. Praesent nec orci. Nulla bibendum adipiscing augue. Ut commodo, magna id malesuada gravida, augue odio malesuada mi, porta malesuada elit est vitae diam. Mauris non nulla. Suspendisse tincidunt, nunc ultricies porta venenatis, mi pede tincidunt libero, eget varius ante libero ut ligula. Curabitur pretium porttitor tortor. + +Maecenas vitae elit eget nisi dapibus dictum. Nunc in libero. Nulla dictum orci eu erat auctor lobortis. Phasellus risus. Suspendisse potenti. Suspendisse potenti. Praesent adipiscing consequat elit. Integer id augue. Praesent in justo nec magna dapibus pulvinar. Duis nisl. Suspendisse ac odio. Vivamus imperdiet. Donec non velit sit amet risus dignissim congue. Nam aliquet posuere velit. Cras turpis. Morbi malesuada dignissim mi. + +Sed leo neque, varius quis, venenatis sed, pharetra sed, est. Morbi blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam semper pellentesque mi. Ut vel lorem. Nunc mi tortor, laoreet at, faucibus eu, tincidunt sit amet, erat. Duis tempor malesuada ipsum. Phasellus aliquet. Donec et elit. Pellentesque purus. Vestibulum rutrum semper nibh. Nulla facilisi. Phasellus et enim sit amet ante vestibulum vehicula. Phasellus id nisl. Donec mollis leo at eros. Mauris pellentesque neque at purus. Morbi quis dolor at ipsum scelerisque sodales. Etiam volutpat turpis a metus. In hac habitasse platea dictumst. Nunc lorem lorem, vestibulum ac, euismod eget, ullamcorper dignissim, velit. + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ultrices, nibh vel aliquam vestibulum, eros enim venenatis dui, id iaculis enim nunc vel massa. Morbi eleifend orci et massa. Aliquam erat volutpat. Nulla mollis egestas turpis. In sodales nunc eget tortor. Sed ipsum eros, tempor quis, aliquet vitae, imperdiet non, lorem. Pellentesque quis elit id mi luctus dapibus. Sed nunc arcu, rhoncus nec, convallis quis, cursus at, neque. Mauris convallis purus at erat. Pellentesque vestibulum. Vivamus fringilla elit at arcu. Nullam aliquet enim nec arcu. Nam id tortor. Nulla quis nunc. Ut arcu. Suspendisse potenti. Pellentesque ullamcorper ligula id arcu. + +Nam non libero vitae nisl scelerisque fringilla. Quisque varius ante id metus rhoncus fringilla. Nulla facilisi. Praesent eleifend porttitor ligula. Etiam quis dolor non augue commodo auctor. Donec a mi. Vestibulum tempor. Donec felis urna, auctor at, cursus dictum, gravida id, arcu. Aenean dictum malesuada dolor. Vivamus mattis. Phasellus eu pede. Fusce adipiscing justo fringilla metus. Etiam ante. Integer mollis massa quis nunc. Integer dictum neque luctus enim. + +Sed eu libero. Integer tempor ligula in velit. Ut tincidunt lacinia sem. Nullam vel risus. Sed sodales ante a dolor. Curabitur eros. Sed sodales. Sed non metus. Vestibulum elementum faucibus ante. Nulla vel nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In hac habitasse platea dictumst. Nunc nec lorem ut ipsum lacinia iaculis. Duis erat. Aliquam erat. Cras iaculis. In hac habitasse platea dictumst. + +Nullam ante. Cras vitae est. Pellentesque vel metus a ligula dapibus mattis. Duis feugiat aliquet felis. Etiam id nisl quis est dignissim condimentum. Suspendisse potenti. Morbi velit lorem, ornare quis, pellentesque vel, placerat eget, tortor. Vestibulum tincidunt molestie libero. Nulla nulla enim, malesuada id, ullamcorper vitae, dictum at, purus. Donec dignissim odio ut enim. Suspendisse at lectus. + +Praesent lobortis augue vel lectus. Ut in ligula ut felis congue suscipit. Quisque dignissim tortor ut mi. Fusce magna nisi, eleifend ac, ornare vel, porttitor vitae, quam. Vestibulum sodales justo quis turpis. Fusce urna nisi, rhoncus quis, condimentum vel, dictum eu, nunc. Fusce sed nibh vitae odio posuere adipiscing. Sed porta elit quis dolor. Nam libero nulla, auctor sed, tincidunt quis, faucibus sit amet, mi. Quisque orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam id sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vel eros. + +Vivamus luctus lobortis leo. Suspendisse vel elit a enim ullamcorper posuere. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec quis pede mattis lectus mollis adipiscing. Sed accumsan posuere erat. Praesent euismod tincidunt felis. Donec mi. Ut commodo arcu lacinia tellus. Aliquam a libero quis lectus semper viverra. Curabitur lacinia mauris at tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sit amet magna molestie orci suscipit fringilla. Fusce pretium metus non sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed hendrerit. Nulla felis. Suspendisse potenti. Aliquam blandit tristique neque. Curabitur quis erat vel nunc accumsan mollis. + +Duis sagittis, tellus ut aliquam fringilla, dolor mi ullamcorper nisl, ut tristique pede elit sed mauris. Curabitur id felis. Donec pulvinar lacus et lectus. Aliquam vulputate vulputate metus. Curabitur magna felis, adipiscing ac, accumsan vel, molestie quis, quam. Mauris elit arcu, pretium vitae, mollis sit amet, sollicitudin ut, mi. Donec imperdiet dignissim mi. Nullam sit amet tortor. Aliquam neque nulla, venenatis a, porta in, placerat tempus, lacus. Quisque vestibulum dui et lacus. Proin dignissim consectetuer purus. Etiam gravida tortor in nunc. Ut tempor tristique tortor. Sed laoreet tincidunt quam. Vestibulum porta turpis ut elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nibh dui, feugiat nec, laoreet id, malesuada eget, nisi. Ut neque massa, vehicula eu, commodo non, ultricies vitae, purus. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris euismod, felis vel tempor aliquet, tortor mauris malesuada nunc, vel fermentum sem diam id dui. Nam rutrum sapien eget odio. Aliquam sed libero non mi faucibus tempus. Fusce hendrerit, diam non volutpat rutrum, erat metus venenatis ligula, non scelerisque pede ligula vel quam. Morbi rhoncus eros ac dui feugiat elementum. Duis eu libero et tellus congue viverra. Morbi quam quam, elementum sed, ullamcorper imperdiet, commodo non, odio. Nam aliquet egestas urna. Mauris odio felis, varius eu, lacinia eu, condimentum a, lectus. Sed justo massa, pulvinar id, varius a, porttitor nec, libero. Etiam varius. Curabitur sodales, odio at posuere semper, eros nibh tincidunt lectus, vel rutrum sapien nisi in ligula. Suspendisse eget arcu. Phasellus imperdiet est ac sapien. Donec nulla tortor, placerat vel, tempus a, lobortis vel, nibh. Aliquam varius nisi. Nulla et enim. Fusce convallis laoreet lacus. + +Phasellus ipsum dolor, molestie quis, condimentum in, commodo eu, diam. Quisque bibendum lacinia dui. Nullam blandit vulputate orci. Ut lacinia massa vel augue. Aliquam gravida, quam quis imperdiet imperdiet, tellus diam pharetra erat, at pharetra lacus nibh egestas magna. Nulla sagittis lorem ut lorem. Duis condimentum, dui vitae aliquam posuere, diam quam convallis velit, ut gravida leo ipsum non risus. Ut fermentum sollicitudin erat. Donec sagittis scelerisque felis. Nunc arcu. Etiam tempus, magna sit amet suscipit euismod, eros sem rutrum dui, vitae sagittis nibh purus non lacus. Sed mollis arcu eget dolor. Donec ornare, arcu sit amet fermentum vulputate, risus enim fermentum libero, a lacinia dolor mi non velit. Etiam lobortis purus a elit. Nunc nulla dui, mattis quis, bibendum a, ultrices ac, augue. In aliquam vehicula turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Integer id nisl. Quisque dictum elementum odio. Aenean luctus. Sed eu sem a pede vulputate condimentum. Quisque magna. Donec aliquam mattis ipsum. Curabitur dictum sollicitudin sem. Aliquam pulvinar. Nunc sollicitudin risus a erat. Vivamus quis tellus sit amet nibh vestibulum consequat. Nulla pretium sollicitudin dolor. Aliquam iaculis tincidunt turpis. Phasellus ipsum leo, venenatis in, sagittis in, ornare at, nunc. + +Pellentesque ultrices, dui eu iaculis luctus, tellus augue volutpat sapien, in dignissim urna felis ut mi. Sed arcu dui, dignissim id, porttitor ut, imperdiet vitae, ante. Nulla dui sem, commodo nec, sagittis et, lacinia et, pede. Etiam eleifend dui ut nisl. Donec ante mauris, tempus sit amet, varius vitae, gravida quis, mi. In scelerisque, felis vitae viverra sagittis, velit metus ultricies neque, quis imperdiet velit elit et magna. Suspendisse potenti. Sed velit eros, euismod sed, condimentum nec, faucibus sed, sapien. Nam accumsan ligula sit amet neque. Aliquam erat volutpat. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam eu pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed eu felis sed tortor tempor fermentum. Phasellus commodo sem vel nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lectus elit, pharetra sit amet, accumsan sed, tincidunt et, mauris. Duis dapibus pharetra sem. Integer in justo. Praesent eros. Vestibulum ac ante. Aliquam scelerisque sem pellentesque nibh consectetuer sodales. Aliquam consectetuer odio. Duis lectus odio, luctus eu, commodo quis, mollis vitae, velit. Cras nec nunc non elit iaculis mattis. Aenean justo neque, sollicitudin eget, ullamcorper eget, egestas id, sem. In eu risus. Sed egestas. + +Integer at neque. Sed pretium scelerisque nulla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce ut pede. Etiam vitae quam a urna varius imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vehicula. Fusce ullamcorper nibh non erat. Quisque in neque. Praesent est. Pellentesque arcu. + +Proin posuere. Suspendisse potenti. Integer felis lacus, aliquam sed, vulputate in, mollis vel, tellus. Integer vehicula bibendum est. Nunc non dolor in tellus mattis facilisis. Integer vestibulum, augue at commodo aliquam, dui est mattis ligula, sit amet adipiscing orci sem vitae magna. Praesent enim velit, malesuada at, congue nec, luctus in, justo. Sed varius. Morbi pharetra. Donec eu massa nec tellus vulputate pulvinar. Ut commodo turpis non sem. Ut convallis ullamcorper risus. Etiam interdum pede id nisi. Cras magna sapien, suscipit a, laoreet non, rhoncus et, felis. Integer orci lorem, vestibulum dictum, ullamcorper a, porttitor et, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc et magna. Sed bibendum tellus in diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vitae tortor. Integer magna. Duis venenatis, leo ac tempor laoreet, elit nulla pharetra pede, non fermentum nunc odio a odio. Proin non velit. Sed imperdiet augue quis nisl. Integer condimentum nisl nec libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus placerat libero. Duis congue dictum magna. Aliquam dapibus bibendum enim. Nunc eleifend pede vel ipsum. + +Etiam vitae velit. Mauris erat nunc, malesuada ut, feugiat ac, placerat condimentum, augue. Nam volutpat. Aliquam vehicula ipsum id odio. Vivamus sollicitudin turpis id sapien. Fusce a felis vitae odio convallis blandit. Curabitur vitae eros id eros porta pretium. Nulla in magna eget urna lacinia convallis. Aliquam mattis venenatis purus. Sed sed mi eget erat tristique porta. Donec auctor dolor a erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In nec ligula. Nunc eleifend. Vestibulum quis nisi eget elit porttitor congue. Maecenas faucibus, magna eget adipiscing tincidunt, dolor ante malesuada elit, non elementum lacus turpis in pede. + +Ut malesuada mi nec metus. Praesent auctor augue ac nisl ultricies facilisis. Nam purus sapien, pellentesque dignissim, posuere eu, cursus id, diam. Quisque sollicitudin, elit a pellentesque scelerisque, lorem risus auctor quam, quis consequat tellus neque id urna. Suspendisse diam tortor, eleifend dignissim, egestas ut, luctus in, ante. Duis ante. Maecenas luctus. Curabitur cursus pharetra urna. Maecenas imperdiet, erat non elementum euismod, tortor odio euismod lectus, ac facilisis sem nibh vitae nulla. Nunc gravida. Morbi sollicitudin odio quis lacus. Aliquam a nibh non urna porta imperdiet. Aliquam erat volutpat. In iaculis lacinia velit. Sed libero lacus, tristique eu, lacinia ac, aliquet eget, urna. + +Etiam at nisl. Phasellus faucibus luctus lectus. Ut placerat vulputate dolor. Phasellus vel velit. Morbi viverra. Phasellus orci. Integer dignissim mattis mauris. Pellentesque posuere leo posuere quam. Quisque nec magna at diam viverra pellentesque. Suspendisse velit arcu, ultricies quis, congue a, venenatis eget, lacus. Integer sagittis hendrerit dolor. Fusce tincidunt ante a sem. + +Maecenas consectetuer, justo sed rhoncus venenatis, nibh arcu rutrum dolor, sed condimentum libero libero et ipsum. Vivamus mattis justo ut lorem tincidunt lobortis. Ut non velit id neque aliquet accumsan. Sed tempus viverra nulla. Curabitur ullamcorper, neque quis dapibus scelerisque, felis diam gravida orci, non cursus quam neque vitae elit. Etiam pharetra tincidunt lacus. Duis euismod fringilla est. Etiam ornare tincidunt lectus. Proin in turpis. Nunc blandit blandit turpis. Aenean ut augue. Duis orci justo, tincidunt eu, rutrum sed, rutrum et, turpis. Curabitur facilisis odio in ante. In hac habitasse platea dictumst. Sed eros est, pellentesque at, tincidunt eu, ultrices quis, metus. Morbi sit amet justo. Maecenas ac arcu. Mauris dignissim. + +Pellentesque ultricies rutrum orci. Aenean ornare. Vivamus eu risus vel mauris lobortis dictum. Sed et turpis auctor mi rhoncus pulvinar. Sed nec nunc a purus tempor viverra. Pellentesque suscipit. Donec tristique risus non nibh. Etiam nisl magna, sollicitudin ut, ultrices sit amet, egestas eu, nulla. Aliquam erat volutpat. Vestibulum pharetra. Sed egestas, metus sit amet lobortis consequat, erat elit imperdiet libero, eu interdum quam massa eget dolor. Suspendisse vitae odio. Proin blandit mauris iaculis metus. + +Vivamus vestibulum. Etiam et nisl. Aliquam in diam vel elit placerat suscipit. Duis sodales purus ac nibh. Nulla in odio eget enim luctus blandit. Curabitur ultrices ipsum non neque egestas eleifend. Sed turpis. Proin consectetuer. Vivamus mattis. In aliquet. + +Nunc id eros. Donec venenatis, nulla et mattis luctus, ante leo semper justo, non adipiscing odio risus sed lacus. Praesent vitae risus congue libero congue tempus. Phasellus ac eros. Nulla vehicula, lorem in aliquet suscipit, arcu erat egestas sem, quis lobortis quam ante eu massa. Curabitur non massa. Sed bibendum lacinia odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus volutpat blandit lacus. Proin porta, tellus ut auctor laoreet, lectus eros fermentum lectus, id sagittis arcu justo in turpis. Phasellus consequat. Nam pellentesque, mi id viverra convallis, nunc libero placerat leo, eleifend porta sem nisl vitae sapien. Pellentesque ligula libero, tristique non, porttitor rutrum, porttitor non, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer dictum tellus a tortor. Vivamus felis nunc, molestie non, rhoncus quis, pharetra id, dui. Donec risus metus, fringilla vel, aliquet eu, placerat id, neque. + +Suspendisse ipsum. Vivamus lectus. Sed viverra, massa eget convallis mattis, quam turpis consectetuer nunc, eget posuere magna sem id velit. In nec mauris. Aenean a purus sed quam lobortis fringilla. Proin ultricies lacinia ante. Sed adipiscing erat quis velit. Nullam vitae nisl id justo sollicitudin molestie. Nulla facilisi. Sed nec urna sed nisl fringilla dapibus. Nulla at diam. Aliquam eget nibh. Nunc ac nisi sit amet tellus egestas tempus. Nam scelerisque urna et neque. Donec est orci, sagittis non, vulputate a, commodo et, augue. Ut dapibus tortor. Ut nunc. Donec dictum dapibus odio. Nam ultricies ullamcorper ligula. Pellentesque accumsan varius leo. + +Morbi euismod laoreet erat. Vivamus quis ipsum. Morbi euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel purus. Nullam at magna. Curabitur lacus lorem, iaculis quis, dapibus non, volutpat vel, nulla. Donec ut arcu rhoncus dolor pretium dictum. Nullam vel metus. Ut arcu. Pellentesque nisi nunc, placerat eget, tincidunt vel, pharetra non, nunc. Integer tincidunt ultricies lectus. Integer semper, purus sed ultrices feugiat, nulla pede sollicitudin erat, vel auctor nulla ipsum vel lectus. Aenean mi. + +Nullam sed nisi et arcu imperdiet fermentum. Mauris nec metus. In ac dolor. In mi arcu, congue ac, pharetra nec, scelerisque sit amet, magna. Curabitur lacus. Curabitur et elit. Aliquam ullamcorper nunc eu elit. Sed convallis dolor at velit. Vestibulum dapibus, augue id consectetuer placerat, nunc massa blandit sapien, id aliquam elit nisi id mi. Phasellus sapien est, gravida eu, bibendum ut, adipiscing quis, est. Ut molestie quam vitae odio. Donec quis risus id erat faucibus sollicitudin. Nam id felis. Mauris sed enim vitae leo accumsan pretium. + +Nam justo. Donec turpis nisl, commodo et, interdum ac, consectetuer non, massa. Fusce sem metus, laoreet nec, posuere id, imperdiet in, velit. Donec vulputate justo eget turpis. Nulla pede. Morbi tincidunt. Fusce aliquet, quam et aliquam fringilla, ante ante iaculis dui, nec aliquam arcu purus sed erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus suscipit quam et est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; + +Integer sed tellus. Sed sed velit ultricies leo rutrum laoreet. Sed non eros ac purus sagittis feugiat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed hendrerit ligula sit amet nibh. Maecenas turpis. Morbi consectetuer, dolor et adipiscing imperdiet, ante neque feugiat dolor, at porta quam neque quis ligula. Mauris semper velit sit amet ipsum. Pellentesque tempus, purus in rutrum consequat, enim erat vehicula massa, id accumsan leo sapien nec purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In dolor. Integer facilisis libero sit amet pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut varius aliquet enim. Nulla facilisi. Curabitur consectetuer, odio eu pretium tincidunt, nunc nisi aliquet neque, vel imperdiet elit massa sit amet turpis. Pellentesque tempus, orci volutpat blandit fringilla, odio sem posuere ante, vitae bibendum urna lorem vitae eros. Praesent viverra rhoncus arcu. Sed auctor, est sit amet mollis mollis, quam quam gravida sapien, in commodo metus nulla auctor enim. Donec facilisis. + +Proin tincidunt, sapien eget ultricies adipiscing, est odio dictum arcu, ut mollis erat dui sit amet velit. Morbi est sem, interdum at, congue a, elementum vitae, metus. Suspendisse id augue. Mauris enim sem, pulvinar eget, tempus a, tempus sit amet, sapien. Fusce vestibulum consectetuer dui. Pellentesque erat. Sed dignissim placerat odio. Maecenas semper rhoncus lectus. Phasellus pretium. Duis libero elit, eleifend nec, egestas ut, cursus sed, felis. Nam nisl arcu, aliquet et, facilisis eu, luctus ut, risus. Etiam ultrices, dolor sed volutpat malesuada, turpis arcu imperdiet tortor, euismod commodo libero massa ut quam. Integer molestie purus non elit. Ut venenatis semper tortor. Etiam bibendum egestas ipsum. Mauris sollicitudin sem nec nibh. Nulla pretium metus eu metus. Pellentesque sit amet sem. + +Suspendisse ac nisi. Ut leo. Vestibulum hendrerit pretium dolor. Nunc feugiat malesuada purus. Cras et nibh. Curabitur nunc erat, malesuada vitae, laoreet ac, ultricies in, purus. Vivamus tellus arcu, sodales eu, facilisis a, lacinia nec, nunc. Pellentesque id velit. In eu nibh. Nunc nec erat. Sed dictum neque ut nisl. + +Morbi lectus tellus, tincidunt ac, porttitor ac, tristique in, eros. Donec luctus luctus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ut est et enim scelerisque accumsan. Donec ligula felis, lacinia quis, pellentesque in, semper vestibulum, elit. Mauris eget orci a felis congue vehicula. Ut sollicitudin. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam id dolor ut lorem dignissim venenatis. Suspendisse vitae sapien. Proin non magna ut eros viverra pulvinar. Donec quis odio. Nullam non arcu vel lorem suscipit aliquam. Aliquam rutrum turpis in leo. + +Ut luctus nibh tristique erat. Suspendisse bibendum odio vitae tortor. Donec lacinia. Cras sodales felis luctus nulla. Nam eleifend sagittis ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse vel neque. Morbi aliquet vehicula magna. Aenean at odio. Duis pellentesque magna. Nulla at tortor ut diam dictum faucibus. Mauris quis velit. Donec non tellus vitae lorem fringilla porttitor. Fusce ut sapien quis tortor feugiat sagittis. Donec viverra sem vitae sapien. Praesent sodales, lacus in fringilla viverra, odio augue adipiscing urna, vitae interdum ante sem non nisi. Nullam tortor lorem, eleifend ac, mollis non, laoreet ac, risus. Integer ornare leo sed justo. Quisque cursus, sem non facilisis bibendum, nisi mi varius felis, fermentum feugiat lorem eros laoreet risus. + +Quisque sit amet est et lorem vehicula lacinia. Donec nec tortor. Cras odio. Nam scelerisque vulputate urna. Praesent dui. Etiam nec nisl lobortis ipsum aliquet tempus. Maecenas pretium sollicitudin mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus augue massa, congue eget, convallis eget, tristique sit amet, eros. Sed consequat nisi eu felis. Pellentesque justo. Suspendisse non augue. In dignissim lobortis mauris. Mauris sagittis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + +Sed adipiscing. Donec a tellus vitae est cursus vehicula. Nam ante sem, sodales id, fringilla vel, condimentum vel, nulla. Quisque sodales. Etiam imperdiet elit id odio. Aliquam erat volutpat. Maecenas porta tempor arcu. Nulla sem augue, pellentesque ac, consequat ut, condimentum euismod, risus. Sed aliquam tincidunt mi. In interdum lobortis orci. + +Sed vehicula hendrerit purus. Etiam a diam. Curabitur convallis. Suspendisse a nisi. Donec id magna in quam sollicitudin ultricies. Donec viverra. Quisque volutpat est sed sem. Aliquam justo. Vestibulum tortor massa, porttitor sed, varius quis, iaculis quis, odio. Aliquam eget neque. + +Mauris nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum eu quam in neque ultrices pellentesque. Cras in dolor quis quam varius hendrerit. Aliquam nisi lacus, lobortis eu, convallis sit amet, facilisis ut, mi. Aliquam at neque. Cras sagittis elementum justo. Vestibulum ut lectus aliquet purus malesuada volutpat. Duis at lacus adipiscing libero tincidunt vestibulum. Morbi a libero. Cras purus. Morbi ut augue et purus interdum scelerisque. Integer a dui. In hac habitasse platea dictumst. Duis pharetra metus eget mauris. Aliquam interdum ullamcorper massa. + +Etiam ornare. Nullam euismod. Aenean consequat gravida ligula. Aliquam est. Proin vitae lacus. Praesent a eros sit amet dui luctus commodo. Phasellus vehicula arcu eget dolor. Praesent fermentum congue leo. Aliquam volutpat purus ut lorem. Fusce hendrerit enim at leo. Aliquam rhoncus nisl. Vivamus dictum egestas mi. Suspendisse pellentesque bibendum dolor. Pellentesque tincidunt, turpis semper pellentesque condimentum, ipsum metus sodales ligula, id volutpat diam turpis ut elit. + +Praesent sed lacus. Nam eleifend molestie mauris. Donec dapibus fermentum massa. Donec viverra faucibus purus. Curabitur congue, libero vitae viverra pellentesque, diam velit sodales enim, sed suscipit lectus nisi nec neque. Vestibulum malesuada, lacus at cursus congue, velit lectus tristique dolor, sit amet sodales neque ipsum a libero. Vestibulum et quam. Curabitur placerat. Curabitur nunc arcu, euismod nec, vulputate hendrerit, aliquet eget, quam. Curabitur vel enim. Suspendisse potenti. + +Nunc consequat orci ut lacus. Fusce velit dolor, dapibus sed, blandit sit amet, rhoncus id, risus. Duis urna nibh, scelerisque quis, dapibus a, scelerisque sed, nibh. Donec luctus. Ut eu mauris cursus diam lacinia rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam vehicula molestie justo. Maecenas imperdiet pede sed mi. Suspendisse nulla dolor, hendrerit eget, hendrerit id, dictum vel, leo. Duis accumsan. Curabitur in felis. Nunc lorem. Ut leo dolor, laoreet nec, vulputate at, eleifend in, nulla. Quisque nunc purus, varius eget, accumsan nec, aliquet et, nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras adipiscing viverra dolor. Mauris porttitor ultrices purus. Nulla facilisi. Praesent faucibus ante vitae mauris. + +Praesent lacinia lectus sed nisl. In tempus congue mauris. Integer facilisis ornare enim. Nulla id massa. Donec commodo diam at tellus. Nam dapibus viverra est. Nam tellus. Praesent a libero. In faucibus est eget nibh. Nulla eros orci, imperdiet non, blandit non, tempor eget, mi. Pellentesque convallis. + +Quisque eget mi ac leo euismod faucibus. Phasellus rhoncus purus id dui. Vestibulum malesuada eleifend ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque blandit mattis odio. Suspendisse consequat, lectus ac semper sollicitudin, mi velit dictum augue, ac tempus dolor erat sit amet dui. Proin hendrerit, felis quis volutpat posuere, diam odio malesuada odio, a interdum orci diam quis sapien. Pellentesque odio odio, viverra vel, gravida eu, molestie sed, nulla. Phasellus mauris pede, commodo ut, euismod eu, hendrerit eu, est. In hac habitasse platea dictumst. Nulla elementum lacus eu augue. Sed erat. Proin porta. Maecenas quis mi. Phasellus at enim ac justo gravida ultrices. Cras leo. + +Integer ut arcu. Donec sed magna. Proin felis. In iaculis, ligula id fringilla pretium, nibh diam accumsan tellus, eget accumsan metus dui varius turpis. Phasellus orci metus, eleifend sed, tempor ac, scelerisque ac, urna. Integer viverra neque a mauris. Mauris porttitor dolor eu velit. Integer odio elit, vestibulum ut, volutpat id, rhoncus commodo, urna. Etiam placerat pharetra erat. Ut tempor est. Integer dignissim blandit tellus. Morbi nibh dolor, scelerisque id, commodo malesuada, mattis at, mi. Cras tincidunt commodo purus. In tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ullamcorper. Ut hendrerit. Morbi ultrices. + +Praesent iaculis, eros ac egestas sodales, urna leo fermentum ligula, sit amet aliquam velit sem non purus. Donec rutrum arcu quis purus. Nam posuere, lacus at consequat placerat, nulla pede posuere orci, non euismod turpis dui quis nisl. Proin porta adipiscing nibh. Donec tristique dolor at tellus. Donec neque massa, auctor id, faucibus vitae, ullamcorper vel, nisi. Proin molestie neque sed massa. Nam tempor. Morbi aliquam sapien at tellus. Fusce quis risus et mi pretium pulvinar. Fusce sit amet ligula. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse eu enim et felis scelerisque lobortis. Praesent bibendum. Vivamus vehicula. Integer at nibh sed velit rhoncus molestie. Cras lacus. Sed ullamcorper eros vel erat. Fusce eu tortor sit amet diam euismod sagittis. Nunc quis lacus id nibh convallis varius. Suspendisse vitae mi. Vestibulum tristique. Donec malesuada ipsum id neque. Nullam sed lacus. Duis egestas, justo ut congue ornare, augue sapien luctus diam, at accumsan erat sapien ut libero. Phasellus vel nulla. Suspendisse arcu tellus, porttitor a, pharetra faucibus, aliquam sit amet, massa. Nulla porttitor tincidunt lorem. Nunc dolor odio, sagittis in, lobortis vel, volutpat sed, nibh. + +Quisque blandit leo ut sapien tempus facilisis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean ultricies porttitor justo. Fusce rutrum eros ut urna. Proin quis quam eget dui aliquam accumsan. Donec suscipit eleifend elit. Pellentesque mattis, felis sodales iaculis imperdiet, lacus sem convallis augue, sit amet aliquet arcu purus fringilla risus. In eu odio id magna pharetra ornare. Aliquam interdum pulvinar ipsum. Sed neque. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam sit amet nisi. Ut at augue. Mauris volutpat blandit ligula. Nulla eu metus. Vestibulum eget elit. Praesent posuere. Vestibulum id sem non lectus mollis tincidunt. Aliquam id felis at ante ornare tempor. Nulla lacus turpis, feugiat vitae, cursus quis, consectetuer non, mauris. Fusce lacus massa, porttitor ut, molestie ut, venenatis a, lorem. Praesent sit amet orci. Mauris rhoncus felis vitae felis adipiscing imperdiet. Maecenas mollis diam nec leo. + +Fusce enim ipsum, ultrices eu, molestie id, elementum id, sapien. Integer a urna. Nam velit libero, venenatis eget, tempor sit amet, feugiat vitae, ante. Fusce nunc. Sed semper nisl nec risus. In sed libero. Proin tortor neque, tincidunt ac, tempor ac, pharetra quis, velit. Duis lectus augue, ultricies vel, consequat id, iaculis id, ante. Vivamus auctor metus a ante. Curabitur arcu nisi, facilisis at, laoreet in, consectetuer sed, mauris. Quisque placerat diam sed dui. Vivamus pretium condimentum lorem. Curabitur laoreet. Aenean orci ligula, cursus eget, lacinia non, faucibus vel, lorem. + +Aliquam erat volutpat. Curabitur eros dolor, congue a, condimentum sed, luctus ut, nibh. Maecenas non tortor nec turpis commodo pellentesque. Praesent euismod placerat mi. Suspendisse potenti. Phasellus ut neque vitae orci mattis iaculis. Integer eget tellus. Donec at ante. Nam lacinia leo eget erat. Maecenas euismod magna congue tortor. Morbi nec massa eu enim malesuada sollicitudin. Sed accumsan. Nullam ipsum. Ut odio. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque id velit. Nam odio sem, aliquet ut, tempus sit amet, euismod et, nunc. + +Pellentesque libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent mauris nunc, varius ut, convallis molestie, luctus sit amet, leo. Sed dictum lorem et arcu. Nunc venenatis pellentesque massa. Nulla facilisi. Phasellus in tortor eget risus scelerisque vulputate. Sed nibh elit, sagittis ac, condimentum nec, convallis et, justo. Fusce volutpat metus. Nunc auctor. Vestibulum leo eros, pellentesque ac, mollis ultrices, rhoncus non, dolor. Mauris vehicula placerat nisl. Vestibulum bibendum, arcu quis congue elementum, velit nunc eleifend turpis, id luctus risus nisl sit amet tellus. Phasellus pede neque, blandit non, commodo vitae, ultricies eget, magna. Aliquam erat volutpat. + +Nulla facilisi. Aliquam ac ante. Cras risus. Morbi mauris lacus, posuere eu, blandit et, pharetra at, mi. Proin ac purus. Duis cursus nisl rutrum quam. Aliquam a odio non magna pellentesque ultricies. Maecenas ac massa quis sapien ullamcorper tempus. Cras cursus velit sed sapien. Proin nulla. Vivamus sodales aliquam nibh. Etiam et erat ut ante lacinia euismod. Fusce nisi. Proin quis nulla. + +Quisque venenatis, eros sed laoreet sollicitudin, orci ante pellentesque nisl, sit amet viverra quam erat non risus. Cras eget libero. Sed elit magna, semper eu, fringilla in, dignissim sodales, erat. Vivamus feugiat sem vel dui. Donec convallis sollicitudin diam. Cras sed purus. Donec felis eros, semper eget, tempor consectetuer, sagittis quis, nisl. Duis in ante. Cras non turpis. Nulla tempor velit aliquet turpis molestie placerat. Proin elementum fermentum mauris. Vivamus sed orci lacinia dui placerat venenatis. Vestibulum feugiat, tellus in volutpat rutrum, magna nisi ullamcorper eros, id pulvinar neque erat ut lacus. Vivamus sed augue. Nulla facilisi. Maecenas ante augue, elementum ut, sodales vitae, condimentum nec, lorem. Duis pede orci, fringilla at, eleifend nec, pretium in, erat. Nam sagittis, turpis vitae convallis pharetra, odio sem scelerisque lacus, nec lobortis dui diam vel eros. In semper gravida neque. + +Integer nunc. Ut pretium ipsum sit amet elit. In nec arcu. Sed vestibulum vulputate ipsum. Pellentesque tincidunt. Nulla gravida dolor in tellus. Cras vehicula, dolor ut pellentesque aliquam, erat enim auctor massa, vehicula lobortis odio eros quis quam. Proin dapibus neque in enim. Proin elit. Integer rhoncus tincidunt elit. Fusce lorem metus, semper ac, volutpat vitae, facilisis ut, tellus. Donec vel turpis vitae nisi pharetra porttitor. Maecenas tortor. Fusce mi. Nullam nec turpis. Sed sodales vestibulum nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Pellentesque dolor dolor, laoreet eu, aliquet quis, scelerisque sit amet, arcu. In hac habitasse platea dictumst. Nullam cursus urna eget elit. Quisque blandit sapien ac ante. Proin nulla eros, gravida volutpat, sodales vel, mollis eu, massa. Nulla tristique sollicitudin nisl. Curabitur vitae lorem vitae velit egestas ornare. Aenean eget eros. Aliquam erat volutpat. Fusce a urna id odio aliquet convallis. Curabitur sit amet nisl posuere leo posuere dapibus. Duis metus erat, luctus vel, rhoncus at, convallis sit amet, enim. Vivamus hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam eget elit. + +Nullam a nunc. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In metus urna, tincidunt et, lacinia sit amet, lobortis vitae, ligula. Proin et mauris vitae mi accumsan pellentesque. Etiam quam purus, hendrerit sed, feugiat vitae, euismod eget, tortor. Ut aliquam magna vitae justo. Suspendisse non justo vel velit condimentum tempus. Duis tempus ipsum vitae tellus. Proin in massa. Etiam ullamcorper dictum tellus. Proin aliquet felis at leo laoreet pulvinar. Vestibulum arcu purus, malesuada sit amet, cursus eu, placerat sit amet, nunc. Nam massa odio, sollicitudin in, adipiscing a, aliquam nec, risus. Aliquam blandit hendrerit libero. Mauris gravida. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur a nibh. Ut interdum fermentum neque. Pellentesque sed nunc. Mauris vehicula nisi et nunc. Praesent lorem. Donec semper. Integer eu lacus in est aliquam hendrerit. Vestibulum eget neque. Sed semper luctus velit. Curabitur nibh augue, congue eu, hendrerit id, congue et, enim. Integer placerat aliquam lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae eros. Donec vel nisl. + +In vestibulum facilisis urna. Ut risus. Mauris pharetra. Pellentesque mattis. Integer suscipit aliquam ipsum. Duis blandit, sapien et ultricies condimentum, felis mi elementum pede, nec sagittis metus mauris quis quam. Quisque accumsan arcu vel nulla. Cras sem sapien, porttitor id, ultricies sagittis, luctus eu, nulla. Integer quis eros. Morbi sed urna a tellus vehicula vulputate. Etiam nec augue eget felis semper tristique. Quisque ut dolor vel risus dictum consequat. Sed eget dolor sed nunc lacinia aliquet. Suspendisse ac tortor in ipsum posuere venenatis. Sed eget erat. Nulla faucibus. Duis laoreet, massa porttitor aliquet egestas, ipsum lectus rhoncus quam, in adipiscing eros sem ut tellus. Pellentesque feugiat tempus quam. Vivamus id dolor eget sapien consectetuer tempor. Aliquam erat volutpat. + +Nulla iaculis fermentum libero. Curabitur faucibus, massa malesuada cursus tincidunt, erat sem eleifend mauris, sed fringilla mi ante ac purus. Duis elementum lectus. Nunc ornare arcu eu tortor. Vestibulum vel dolor at purus lacinia fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas tincidunt, eros a egestas pellentesque, risus risus dictum libero, id aliquet metus justo in massa. Proin a tellus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed purus. Sed non pede. Aenean massa sapien, sodales sit amet, consequat dictum, eleifend vitae, tortor. Donec ultrices lacinia elit. + +Morbi adipiscing sodales dolor. Ut ullamcorper ultricies est. In venenatis tempus augue. Suspendisse tortor dolor, accumsan et, suscipit a, tincidunt ut, libero. Aliquam scelerisque magna sed felis. Quisque ut nunc a magna vulputate placerat. Aliquam rhoncus vehicula dui. Sed tortor. Nullam sit amet diam. Nunc sed eros. Sed et odio tincidunt elit gravida convallis. Curabitur quis tortor a lacus semper varius. Mauris at augue non mi sollicitudin aliquam. Integer ullamcorper. Pellentesque suscipit quam non purus. Aliquam ac eros at arcu ullamcorper consectetuer. Suspendisse pretium mattis leo. + +Duis at nunc. Sed dolor est, varius ac, porta et, tincidunt hendrerit, risus. Vivamus ut magna. Praesent ut mauris. In purus lacus, mattis sed, vestibulum nec, tempor at, nisl. Cras ullamcorper venenatis tellus. Ut dolor. Maecenas malesuada, pede a pulvinar mattis, arcu diam vehicula risus, quis porttitor augue massa in velit. Nunc congue. Morbi velit metus, rhoncus et, aliquam consectetuer, ultricies malesuada, ligula. Sed velit nisl, sagittis vitae, pharetra a, posuere sed, massa. Nulla facilisi. In varius, ligula id lobortis sodales, augue orci fermentum tellus, eu pulvinar risus ligula a sapien. Morbi laoreet ipsum non mi. Nam cursus lorem ut mi. Vivamus magna enim, posuere non, semper quis, sodales eu, arcu. Etiam mi purus, pretium feugiat, varius sed, pellentesque eget, ligula. In leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vitae orci eu orci sollicitudin feugiat. + +Praesent purus massa, euismod vitae, tempus nec, consequat hendrerit, metus. Aenean felis est, egestas vitae, accumsan eget, pellentesque in, sapien. Duis dapibus pede non sapien. Nunc urna. Integer vel libero. Duis augue arcu, dapibus non, facilisis vitae, posuere ut, eros. Donec vitae nunc sit amet arcu imperdiet dictum. Morbi eleifend, lorem eu consectetuer vestibulum, diam nunc ornare arcu, ac tempor felis dolor eget eros. Phasellus massa sem, sollicitudin ac, sodales gravida, luctus a, quam. Nam neque quam, viverra at, venenatis quis, sagittis non, enim. + +Nulla facilisi. Pellentesque egestas lacinia est. Sed tincidunt, pede sed tincidunt vestibulum, urna dolor adipiscing purus, vitae fringilla felis elit in nibh. Nulla sed nisi. Mauris suscipit scelerisque arcu. Etiam non enim vel eros accumsan malesuada. Nunc tincidunt commodo mauris. In tincidunt risus quis urna. Nulla diam tortor, aliquet et, tincidunt quis, sollicitudin ac, tortor. Cras nisl neque, vulputate suscipit, molestie quis, pulvinar at, nulla. Nullam ac metus nec odio posuere varius. Cras sed pede nec dui posuere bibendum. Duis euismod ullamcorper libero. Aliquam faucibus pulvinar turpis. + +In ut neque id nunc feugiat commodo. Curabitur dignissim, felis at sollicitudin lacinia, enim elit suscipit neque, sed luctus lorem ipsum in leo. Duis dapibus, odio quis auctor commodo, nisl odio mattis tellus, nec tincidunt turpis diam in arcu. Curabitur a sem. Nullam volutpat magna. Pellentesque sagittis, neque consequat pretium cursus, dolor lacus consectetuer arcu, sed laoreet est urna et metus. Suspendisse placerat, dui a porta tempor, lorem dui lobortis neque, sed venenatis diam enim id eros. Etiam et nisl non lectus faucibus consectetuer. Morbi scelerisque, sem nec tempus ullamcorper, ipsum diam feugiat lorem, a fringilla sapien elit quis nibh. Nullam diam urna, viverra sed, pharetra rhoncus, tincidunt vel, orci. Integer accumsan mattis erat. Nam dictum. Mauris nec leo. Nulla iaculis. Nulla nisl mi, dapibus quis, vehicula a, cursus eget, odio. + +Phasellus dapibus euismod nibh. Vivamus imperdiet ante in ligula. Pellentesque accumsan. In imperdiet, dui a auctor fringilla, metus nisi cursus dolor, vel luctus ligula lorem vitae mauris. Praesent mattis vestibulum elit. Aliquam enim lacus, pulvinar non, lacinia sit amet, eleifend non, velit. Vestibulum ac leo. Mauris imperdiet justo ac lectus. Sed molestie lectus sed dui. Sed fermentum tempus mauris. Nam ornare orci ac tellus. Ut malesuada, lacus id lacinia accumsan, diam elit adipiscing metus, et bibendum sapien nibh blandit orci. Suspendisse ipsum tellus, sagittis quis, vestibulum non, vulputate eu, eros. Praesent at nulla id pede scelerisque ultricies. Cras blandit pretium tellus. Maecenas dapibus condimentum augue. Phasellus tincidunt pharetra lorem. Morbi non eros. Sed tempor, nisl a tincidunt tincidunt, eros diam dictum sem, vel dignissim ante diam sed magna. Praesent non ligula id metus molestie consectetuer. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse vel mi. Curabitur ante nulla, rutrum a, convallis vel, vehicula ac, nunc. Nunc sagittis, enim sit amet auctor rutrum, mauris arcu vulputate neque, et euismod est felis quis ante. Vestibulum turpis tellus, hendrerit in, lacinia commodo, ullamcorper gravida, risus. Mauris rhoncus lacinia risus. Maecenas sollicitudin erat vitae nunc. Praesent pretium pellentesque augue. Donec interdum. Praesent ac eros vitae erat lobortis fringilla. Aenean consequat tellus. Nulla accumsan bibendum felis. Maecenas pretium ante id nisi. Aenean mi arcu, semper sed, mattis eu, venenatis sit amet, arcu. Donec aliquet euismod leo. Proin magna justo, tristique a, semper ac, sollicitudin a, ligula. Morbi velit. Aliquam vel nisi. + +In a lorem ut nunc feugiat congue. Donec fermentum bibendum dui. Proin varius est quis velit. Donec aliquet sem accumsan mi. Sed placerat. Nullam ac nisi a massa lobortis suscipit. Nunc id leo. Aliquam et massa. Nullam vestibulum elementum metus. In consectetuer nisi vel justo. Maecenas eget purus sed massa varius pellentesque. Phasellus faucibus felis quis felis. Aenean odio arcu, blandit quis, facilisis in, imperdiet eu, lorem. Nam posuere pulvinar mi. Fusce tristique, mauris et consectetuer ultricies, mauris lectus tempor justo, at fringilla est est sed nisi. Quisque faucibus. Sed in tortor tincidunt est lacinia iaculis. Maecenas a massa. Pellentesque a nibh at purus porta hendrerit. + +Nullam turpis. Fusce ac sem sed odio pellentesque imperdiet. Curabitur in arcu. Praesent lacus lacus, feugiat id, pulvinar in, tincidunt sed, neque. Maecenas viverra odio eget tortor. Integer aliquam, lorem rutrum venenatis dignissim, ligula magna malesuada arcu, vel feugiat lorem ipsum quis massa. Morbi ante. Vestibulum mauris libero, ullamcorper quis, ultrices quis, facilisis non, massa. Maecenas imperdiet. Aliquam erat volutpat. Pellentesque dignissim gravida lectus. In nibh odio, auctor eget, dapibus quis, dignissim venenatis, arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis pellentesque ligula quis massa. Curabitur condimentum, justo eget ornare luctus, lorem ligula sagittis pede, a porta nunc nunc in neque. Quisque felis mauris, condimentum vitae, auctor vitae, tincidunt quis, pede. Nunc lacinia ante in leo. Pellentesque libero. Aenean a ligula et nunc vestibulum consectetuer. + +Fusce ornare. Praesent id urna. Integer venenatis, quam non sagittis accumsan, ante nibh sagittis augue, sollicitudin adipiscing dolor velit eu erat. Proin quis enim eu purus vehicula aliquam. Nulla vel enim vel elit sollicitudin fringilla. Aliquam erat volutpat. Sed suscipit felis ut turpis. Etiam rutrum risus imperdiet est. Aliquam a tellus at tellus commodo dapibus. Mauris rutrum magna et odio. In at dolor. Curabitur vehicula lectus in tortor. Fusce justo purus, luctus vitae, mollis in, pharetra ac, purus. Nullam posuere interdum justo. Curabitur vitae lacus vel leo congue pulvinar. + +Aenean eleifend nibh varius tortor. Suspendisse vel eros. Proin nec diam a tortor ultrices ornare. Aliquam scelerisque feugiat justo. Vivamus ante urna, adipiscing vitae, porttitor eu, sodales et, felis. Suspendisse potenti. Curabitur ac massa in nisl sagittis mollis. Nam quam ligula, consectetuer eget, iaculis at, varius eu, leo. Duis dolor ligula, tincidunt at, ullamcorper sed, accumsan aliquam, ligula. Phasellus vulputate, lorem at tincidunt pharetra, risus lectus lacinia magna, quis rutrum enim magna at sem. In hac habitasse platea dictumst. Duis id sem a mauris sollicitudin tincidunt. Etiam eu purus eu arcu fringilla adipiscing. Vivamus ornare tempus diam. Proin turpis quam, lacinia non, egestas at, commodo eget, pede. Praesent vulputate risus in est. Nulla facilisi. + +Ut elementum lacinia purus. Proin vitae arcu ac nulla convallis aliquam. Nulla congue, libero id pellentesque mattis, quam lectus porttitor diam, a scelerisque dui libero in sapien. Nullam felis diam, vehicula vel, molestie ut, vestibulum aliquam, sapien. Donec convallis, est ut elementum volutpat, mauris ipsum gravida sem, commodo facilisis sapien lectus semper lectus. Quisque porttitor eros ut nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam mattis risus sed odio. Vestibulum et odio. In hac habitasse platea dictumst. Nam tristique massa ut ligula. Quisque nibh tellus, vehicula sit amet, adipiscing at, convallis nec, ligula. Vestibulum pretium, mi nec fringilla bibendum, dui nunc sodales pede, a semper magna nibh non diam. Donec massa nunc, viverra vel, consectetuer porta, dapibus non, ipsum. Duis nisl mauris, cursus vel, semper non, sollicitudin bibendum, felis. Vestibulum eu neque. + +Cras nec dolor. Donec laoreet tempus lectus. Cras sed tortor interdum lacus eleifend dignissim. Maecenas sit amet elit. Nullam quis dolor vel dui pharetra luctus. In sit amet quam sit amet pede ultrices ultrices. Maecenas diam. Integer urna. Curabitur dictum, velit sed placerat suscipit, erat turpis fermentum justo, sed interdum neque sem et nibh. Vivamus consequat convallis magna. Nam aliquam, est ac bibendum commodo, magna est dictum mi, vitae malesuada elit magna vitae odio. Maecenas tempor vulputate tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus dui. Etiam accumsan pede congue tortor. + +Morbi tempor libero ac lorem. In aliquet varius magna. In arcu. Phasellus odio. Fusce tincidunt aliquet felis. Quisque velit. Sed luctus. Aliquam feugiat fringilla mi. Aliquam molestie viverra risus. Proin arcu. Vestibulum lobortis tempus nisi. Praesent a arcu in velit viverra rutrum. + +In sed lectus. Donec risus dolor, blandit sit amet, elementum convallis, pharetra quis, pede. Integer ornare. Aenean egestas dapibus justo. Sed quam leo, posuere at, elementum vitae, commodo eget, est. Aliquam molestie rhoncus enim. Curabitur iaculis ultrices pede. Morbi aliquet rutrum lacus. Aliquam quam. Sed commodo, turpis in pharetra posuere, mi risus imperdiet erat, a vestibulum massa tellus vehicula sem. Mauris fringilla ultrices nunc. Nam nisi enim, eleifend sit amet, ultrices sed, fermentum non, augue. Proin congue lobortis nisi. Maecenas hendrerit. Nam sed nisl. Nunc elementum odio eu risus. In metus. Phasellus gravida pretium ligula. Nulla vitae neque. Nam nisi tortor, ornare non, blandit at, cursus eu, tortor. + +Duis bibendum ipsum in nunc cursus molestie. Nunc orci. Nullam nec ante non est dignissim viverra. Mauris blandit, velit id feugiat pretium, elit magna pellentesque dolor, at sagittis lacus velit egestas magna. Pellentesque cursus, diam consectetuer sagittis fringilla, tortor nisi adipiscing nunc, eu varius lacus risus ac elit. Mauris id nisi quis leo euismod venenatis. Pellentesque ac ante. Mauris arcu sapien, tempor at, porttitor id, condimentum ut, dui. Etiam fermentum ultricies augue. Cras ut eros at justo ultricies iaculis. Duis dignissim, nisl et facilisis fermentum, erat purus molestie tellus, quis tempus ipsum lectus at elit. Nulla vitae lorem. + +Aenean vel sem et diam semper congue. In bibendum diam quis tellus. Nunc facilisis ultricies nibh. Cras nunc enim, feugiat sed, ultrices vitae, sagittis vitae, ipsum. Fusce vitae nulla. Donec pellentesque, velit in porttitor eleifend, est neque lobortis velit, sit amet rutrum ante tortor nec dolor. Donec vehicula. Nulla facilisi. Sed egestas ultrices nibh. Donec elit lectus, convallis porttitor, aliquet dapibus, feugiat eget, ligula. Sed consectetuer justo. Maecenas a sapien sit amet nisi dapibus lobortis. Vivamus luctus lorem non nulla. Sed eget erat vitae libero interdum posuere. Cras pulvinar. Nullam imperdiet, dolor tempor dignissim blandit, dui sapien rhoncus neque, id malesuada augue magna sit amet urna. Duis sed mauris. + +Morbi accumsan. Sed mauris augue, fringilla non, auctor ut, auctor et, orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus ut pede. Donec viverra enim vel lorem. Pellentesque neque mauris, interdum eu, venenatis id, condimentum eu, sapien. Donec ipsum arcu, lacinia adipiscing, laoreet et, cursus vel, velit. Ut sagittis mauris quis risus. Integer eu odio vitae lacus viverra accumsan. Morbi leo ante, dignissim sed, varius quis, volutpat vitae, nisi. Nulla placerat interdum elit. Donec neque dui, sagittis vitae, sollicitudin quis, commodo vitae, neque. Nulla quis ligula ornare ligula dictum ornare. Mauris rutrum rutrum neque. Aenean vehicula tempus est. Donec varius scelerisque pede. Donec placerat vulputate leo. Nullam nunc nisl, posuere non, feugiat vitae, pellentesque quis, mauris. In dui neque, cursus eget, sagittis eget, dapibus vitae, mi. Proin eget est. + +Fusce porta est. Mauris magna. Aliquam ipsum lacus, ultricies id, vestibulum luctus, accumsan ut, ante. Sed mauris. Sed adipiscing leo sit amet magna. Suspendisse potenti. Nunc massa elit, fringilla eget, egestas vitae, luctus vitae, dolor. Phasellus quis nulla eu nisi interdum sollicitudin. Nullam id tellus. Integer iaculis dolor ac purus. Sed vel mi. Curabitur non magna sit amet justo condimentum vulputate. Quisque tincidunt pede eu nisl. Vivamus lobortis. Nunc metus metus, congue sed, tincidunt sed, pretium at, odio. Donec a arcu. In sem justo, vehicula sed, varius id, volutpat at, risus. Praesent iaculis massa. In arcu elit, hendrerit eget, ullamcorper in, porta id, tellus. Donec sagittis hendrerit diam. + +Suspendisse potenti. Sed et diam et augue sagittis lobortis. Phasellus dolor. Ut et arcu eget ante tempor posuere. Aliquam fermentum scelerisque dui. Mauris at purus. Donec erat sem, vestibulum nec, faucibus ac, mattis a, leo. Suspendisse adipiscing lacinia sem. Nullam orci arcu, dictum et, faucibus viverra, dapibus et, neque. Cras nunc diam, adipiscing non, sollicitudin in, interdum vel, massa. Mauris sagittis, justo at tristique tempus, mauris mauris aliquam ante, sit amet posuere diam dui eget ligula. In dignissim, nisl ut lacinia condimentum, erat justo porttitor nulla, non gravida ligula magna eget massa. Vestibulum vitae ligula at mi vestibulum suscipit. Duis laoreet. Nulla commodo libero sit amet lorem. Ut elementum sem. Integer vel dolor. Nam facilisis mi quis sem ultrices sagittis. Sed quis quam at metus molestie bibendum. + +Proin dui enim, lacinia a, feugiat ac, placerat vitae, pede. Quisque egestas, leo eget aliquam pretium, libero justo tincidunt eros, ut egestas augue pede elementum nibh. Curabitur mollis sodales enim. Donec augue. Phasellus id ipsum posuere dui pretium faucibus. Mauris luctus ante semper nisi interdum adipiscing. Duis dapibus, odio quis viverra rhoncus, justo quam bibendum dolor, id dapibus velit erat vel erat. Fusce sit amet nisl venenatis quam ultrices condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec rhoncus scelerisque ligula. Vestibulum mi odio, accumsan et, adipiscing eget, ornare ut, quam. Nullam blandit molestie mauris. Curabitur dignissim mauris et lorem. Suspendisse a justo. Nam mattis faucibus arcu. Duis blandit enim non massa. + +Nullam lorem. In hac habitasse platea dictumst. Mauris consectetuer posuere mauris. Maecenas tincidunt mauris in eros. Nulla eu metus eu orci sollicitudin faucibus. Suspendisse aliquam mauris id est. Cras blandit dui et urna. Nulla arcu. Sed a urna. Nulla dapibus vehicula tortor. Donec risus. Sed quam metus, egestas eu, cursus ut, viverra non, odio. Ut justo justo, malesuada sit amet, blandit suscipit, molestie in, justo. Vestibulum consequat, quam ac feugiat tincidunt, ipsum libero eleifend odio, non eleifend pede ipsum non ante. Nullam a metus. + +Nam ac nisi at felis cursus mattis. Pellentesque consequat sem quis orci. Quisque tempus. Aenean imperdiet molestie pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eu tellus. Nulla diam eros, sodales ut, sodales nec, tincidunt ac, nunc. Nunc lacinia faucibus ipsum. Vivamus vel neque in erat fermentum luctus. Nulla eget metus nec augue bibendum placerat. Vivamus tempus. Praesent congue ornare ipsum. Etiam mattis feugiat justo. + +Aliquam dui. Aenean commodo tortor vitae nulla. Morbi et ipsum. Mauris ac ipsum. Nam vel risus ut lectus mollis viverra. Curabitur elementum mollis est. Nullam elit. Vestibulum suscipit pretium enim. Vestibulum ut massa. Proin nec felis. Maecenas gravida, arcu nec consequat sagittis, eros tellus scelerisque mauris, vitae accumsan quam quam ut nunc. Integer eget ante eu velit laoreet malesuada. Nunc sagittis, mauris vitae pharetra volutpat, tellus tellus eleifend eros, sit amet rutrum ipsum nisi a velit. Praesent varius leo eu erat. Vivamus consequat placerat purus. Donec pretium elementum nibh. Proin at elit non sem aliquet mattis. Sed ullamcorper ipsum sit amet elit. + +Mauris in metus. Suspendisse magna lorem, faucibus vel, tincidunt quis, scelerisque non, tellus. Fusce quis lorem. Proin a lacus sit amet mauris iaculis pulvinar. Suspendisse rhoncus eros nec mi. Praesent euismod, turpis vitae rutrum pretium, odio metus volutpat neque, eget tempus sapien neque sed erat. Donec fermentum purus at lectus. Nullam sem. Fusce vel mi quis erat lobortis posuere. Aenean eget urna. Suspendisse ligula. Duis in nisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Curabitur vulputate lectus id pede. Phasellus eu velit. Etiam venenatis adipiscing nibh. Aliquam cursus pulvinar tellus. Vestibulum neque. Mauris nec justo et erat semper pellentesque. Fusce mattis dictum dolor. Etiam eget purus eu massa varius elementum. Pellentesque massa. Ut ultricies diam sed ipsum. Nullam diam. Pellentesque id magna id libero tristique aliquam. + +Ut eleifend, purus id placerat venenatis, urna augue aliquet ligula, in ultricies leo risus et tellus. Mauris et nulla id urna tristique tempus. Ut facilisis, urna eu vestibulum rhoncus, lacus eros consectetuer metus, et rutrum dui lectus in purus. Nunc vel nisl non ipsum tincidunt mollis. Nam quam lacus, ornare vitae, rhoncus non, congue sed, odio. Proin nibh dui, porta vel, venenatis non, pellentesque ut, nisi. Sed tristique felis a magna. Suspendisse eget tellus. Cras gravida imperdiet velit. Integer hendrerit risus. Proin orci. Aliquam ullamcorper mauris quis mauris. Nunc lacinia vestibulum metus. Duis tellus. Nullam faucibus, leo ac vulputate sollicitudin, leo dolor faucibus erat, quis bibendum orci odio non arcu. + +Nullam accumsan mattis dolor. Donec et dui. Praesent a felis mollis lacus semper lacinia. Curabitur pellentesque luctus est. Proin nulla dui, condimentum vel, faucibus non, interdum ac, erat. Maecenas scelerisque, lectus id volutpat accumsan, sapien tortor pellentesque dui, sed semper magna sem ut leo. Proin nulla. Nullam dapibus ullamcorper sem. Suspendisse vehicula metus in nunc. Pellentesque non quam vel arcu ultrices ullamcorper. Phasellus quis felis sit amet tellus ullamcorper fermentum. Sed vehicula sollicitudin urna. Curabitur pharetra scelerisque risus. Pellentesque id massa quis metus aliquam imperdiet. In nunc lacus, feugiat in, gravida eget, venenatis ut, tellus. Suspendisse potenti. Nam consequat adipiscing dui. In nulla nisi, feugiat ut, fermentum vel, gravida nec, tortor. In sed augue. + +Etiam ullamcorper augue at enim. Integer dignissim. Aliquam pulvinar congue nulla. Morbi enim massa, fringilla a, accumsan eget, condimentum nec, erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean pharetra. Etiam porttitor purus a metus. Aliquam interdum sem eget justo. Quisque volutpat luctus est. Aenean augue. Phasellus dui lectus, ultrices nec, commodo vel, auctor vel, nisi. Ut ultrices pellentesque nisi. Integer ac velit et sem imperdiet luctus. Fusce vitae turpis id augue mollis consectetuer. + +Maecenas nec lacus. Maecenas condimentum odio eu felis. Mauris ut nisl viverra erat faucibus adipiscing. Etiam egestas. Nunc et dolor vitae risus dignissim commodo. Morbi lectus velit, tincidunt nec, aliquet vel, mattis vitae, ligula. Maecenas ultricies semper dolor. Suspendisse malesuada. Integer mattis elit. Donec accumsan, lacus facilisis varius tempus, nulla elit porta erat, et rutrum elit sem sit amet dui. + +Maecenas mollis mi non nulla. Vivamus turpis. Suspendisse a metus. In quis mi in turpis congue auctor. Maecenas lacus. Suspendisse sollicitudin. Phasellus porta nunc non nisl pulvinar egestas. Sed nulla. Vestibulum ac mi. Mauris ultricies condimentum neque. Nulla tempus justo vel massa. Nulla suscipit congue arcu. Praesent id turpis. Mauris nibh pede, euismod semper, molestie ac, rhoncus vitae, ante. Maecenas erat felis, viverra sollicitudin, sagittis eget, pellentesque nec, orci. Fusce ultrices consequat lacus. Aliquam erat magna, feugiat at, viverra a, mollis non, turpis. + +Donec mi. Nam dictum pellentesque sem. Donec mollis rhoncus elit. Phasellus rhoncus pede sit amet risus. Donec eget augue. Maecenas non lectus. Phasellus sollicitudin nisi nec felis. Aliquam pretium, est eget semper convallis, nibh nunc sollicitudin purus, id tempor pede dui vel magna. Vivamus ac lorem. Etiam nisl tortor, adipiscing dictum, elementum in, facilisis sed, nibh. Proin mauris. Proin rutrum massa eget sem. Curabitur tempor adipiscing elit. Curabitur purus tellus, fermentum eget, aliquet vitae, convallis ac, mauris. + +Integer consequat velit eu eros tincidunt vehicula. Nullam lorem sapien, rhoncus non, mattis quis, ultricies sit amet, enim. Curabitur commodo, libero in euismod suscipit, sem purus fringilla enim, ac molestie tortor orci et velit. Donec pede. Etiam placerat condimentum turpis. Phasellus egestas enim nec magna. Vivamus condimentum, nulla vel luctus tristique, eros risus vestibulum nulla, in vehicula arcu ipsum at felis. Donec aliquam elit at augue. Quisque a eros eu ligula accumsan dictum. Etiam vehicula turpis quis libero. Aliquam non mi. Donec et leo. Proin leo libero, aliquam tincidunt, congue nec, adipiscing porta, enim. Nulla lobortis, tortor sit amet imperdiet ullamcorper, dolor orci malesuada pede, sed gravida nibh urna vel lorem. Sed pharetra malesuada eros. Quisque euismod aliquet erat. Suspendisse aliquet mattis purus. + +Nunc id nulla quis justo congue sollicitudin. Praesent erat turpis, rhoncus eu, pretium eu, pellentesque a, nibh. Vivamus tempus. Cras nec risus at turpis imperdiet lobortis. Ut mattis. Maecenas est felis, pellentesque non, imperdiet sed, eleifend tincidunt, lorem. In tincidunt. Sed vel leo. Donec et urna in turpis hendrerit blandit. Donec condimentum accumsan est. Ut pharetra, metus vitae mattis consectetuer, leo quam vulputate odio, nec laoreet nisi velit eu erat. Integer lectus augue, egestas in, interdum eu, venenatis vel, sapien. Quisque et est vitae eros laoreet lobortis. Nullam ut risus non nulla placerat adipiscing. Praesent dapibus. Etiam a felis. Ut sodales consequat mauris. Duis lorem felis, luctus a, tristique in, molestie at, risus. Sed vehicula bibendum tellus. Nam consequat euismod lacus. + +Aenean tortor elit, gravida nec, fermentum eu, lobortis id, ipsum. Maecenas eu purus. Cras ac turpis ut nisi iaculis rhoncus. Nulla purus metus, dignissim nec, tincidunt vitae, dapibus eu, nibh. Fusce lobortis, nunc at viverra eleifend, justo turpis scelerisque eros, ac pellentesque metus nisl at purus. Sed elementum tellus sed enim interdum blandit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer ultricies aliquet odio. Mauris eget nunc a ipsum ultrices sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean accumsan. Donec sapien lectus, congue at, porta id, hendrerit vitae, nisl. Curabitur vel quam vel neque accumsan laoreet. Morbi sapien est, pretium in, consectetuer ac, mollis ut, libero. Donec tincidunt adipiscing metus. Nunc vestibulum egestas augue. Donec scelerisque dui ut sem. Suspendisse vel metus id est molestie iaculis. + +Vivamus pharetra, elit eu malesuada blandit, diam tortor mollis dui, sed pulvinar massa nunc et magna. Sed placerat elit auctor tortor. Nulla ac erat. Pellentesque consectetuer, dui convallis tincidunt condimentum, sem odio volutpat libero, non elementum felis neque nec odio. Maecenas hendrerit eros id diam. Mauris vel purus ac orci convallis convallis. Sed sit amet lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque dictum varius lacus. Mauris eget nisl. Suspendisse placerat, nulla non ornare dignissim, nisl diam sagittis tellus, in semper nisi dolor at nibh. Duis ullamcorper viverra felis. Integer a tellus. Suspendisse eget nunc. Aenean diam est, accumsan id, suscipit interdum, fringilla vitae, justo. Proin pede. Maecenas at neque in neque vestibulum eleifend. + +Vestibulum nulla lorem, porttitor eget, euismod ac, aliquam at, nisl. Maecenas et est eget massa varius lobortis. In mi. Duis porttitor fermentum purus. Donec cursus imperdiet ligula. Morbi et ligula et ante molestie vehicula. Mauris sed dolor. Sed imperdiet felis ut sem. Sed vitae neque elementum leo auctor fermentum. Duis feugiat ullamcorper erat. Aenean purus. Morbi fermentum vestibulum est. Pellentesque venenatis mauris. Phasellus pulvinar. Integer ipsum lectus, iaculis a, lacinia id, accumsan id, arcu. Phasellus at est. Fusce neque quam, ultricies id, iaculis vel, dapibus vitae, lacus. In lobortis convallis ante. Nulla nunc purus, vulputate in, hendrerit et, blandit et, ligula. + +Pellentesque leo metus, sagittis in, molestie vitae, dictum in, pede. Morbi pretium felis nec quam. Pellentesque mattis ante sed quam sagittis dapibus. Suspendisse sapien. Praesent bibendum iaculis tortor. Duis a nisl. Aenean mi. Donec dictum arcu in est. Morbi interdum vulputate ipsum. Aenean sit amet magna non nisl tristique posuere. Phasellus velit metus, tempor ac, fermentum eget, condimentum non, velit. Vestibulum sit posuere. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras aliquet massa nec dui. Cras arcu nunc, hendrerit ac, eleifend eu, ullamcorper nec, tellus. Sed pharetra purus sit amet quam. Curabitur mollis. Nam vitae pede. Etiam risus massa, vehicula sit amet, pharetra nec, sollicitudin ut, dui. Donec egestas justo at quam. Proin nisl risus, vestibulum nec, pretium vitae, tristique ac, lorem. Aliquam erat volutpat. Cras sed nibh. Pellentesque sollicitudin euismod augue. + +Etiam fringilla sollicitudin orci. Mauris cursus elit quis lacus. Cras tortor. In adipiscing, lectus id auctor vestibulum, neque pede accumsan dolor, non imperdiet magna diam accumsan velit. Suspendisse at libero ut nisi blandit sagittis. Phasellus non mauris. Fusce elementum sagittis sem. Suspendisse aliquam eleifend tellus. Proin ligula lorem, imperdiet quis, venenatis id, iaculis mollis, nisl. Etiam convallis pede at massa. Morbi accumsan dui et mauris. + +Sed sed orci. Nunc purus. Suspendisse potenti. Ut luctus fringilla mauris. Donec nibh. Phasellus porta. Phasellus sit amet odio sed magna sodales pharetra. Cras lectus. Suspendisse libero ipsum, commodo nec, facilisis in, suscipit lobortis, ligula. Duis massa nulla, semper et, consequat nec, pharetra eu, elit. Vivamus ultricies aliquam odio. Vestibulum sit amet massa. Sed consequat lacus sed urna. Etiam faucibus felis vel orci. Phasellus ullamcorper. Aenean consectetuer lacus at libero. + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis facilisis, ligula vitae condimentum scelerisque, velit orci gravida felis, vel ultricies quam mi non diam. Vivamus auctor metus non libero. Praesent ligula nisi, commodo condimentum, molestie et, viverra et, justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus sollicitudin. Nunc blandit cursus ipsum. Aenean nec ligula ut tellus sodales mattis. Integer sem. Aliquam id ligula. Sed tortor mauris, blandit vitae, cursus vel, elementum et, nulla. Aliquam scelerisque metus et nisl. Duis adipiscing magna at neque. Quisque vulputate eleifend nunc. Aliquam eget elit. Phasellus dui odio, bibendum sagittis, vestibulum id, dignissim imperdiet, orci. Nullam eu felis non nunc lacinia sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Suspendisse pellentesque, libero mattis ultricies accumsan, tortor tortor malesuada sem, et sodales libero odio ac ipsum. Vivamus quis magna nec est suscipit lobortis. Cras tempus posuere nunc. Quisque ut enim a felis egestas semper. Sed pharetra mattis neque. Fusce turpis nunc, congue sed, consequat non, congue sed, nulla. Suspendisse varius lorem id risus porta vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce sed purus. In a felis. Integer egestas auctor orci. Mauris ultrices suscipit nisl. Nullam purus. + +Cras tempor adipiscing ipsum. Ut quis mi. Maecenas in justo ut nulla congue pharetra. Pellentesque ut libero eu dolor venenatis suscipit. Praesent feugiat consectetuer nibh. Morbi faucibus sem non felis. In hendrerit arcu ac massa. In accumsan ultrices mi. Proin malesuada auctor felis. Curabitur interdum. Sed diam ipsum, ultricies in, tempor sit amet, viverra imperdiet, elit. Morbi molestie nisi. Mauris ipsum. Fusce dictum mollis magna. Duis commodo dignissim nulla. Vestibulum augue enim, ultricies quis, iaculis nec, tincidunt vitae, diam. Mauris lacinia tempus ipsum. Sed at mauris. Ut lorem. Donec libero. + +Duis iaculis lacinia lectus. Aenean convallis eros ac ante. Sed quis orci nec risus auctor fringilla. Phasellus facilisis elementum nisi. In hac habitasse platea dictumst. Nunc porta lacus nec ante. Morbi mauris erat, adipiscing in, pulvinar nec, lobortis nec, odio. Ut eleifend lectus sed quam. Nullam mollis. In non turpis et nisl hendrerit blandit. Duis elementum. Nunc nec libero. Suspendisse vestibulum risus non pede. Morbi imperdiet odio sit amet libero. Sed sed massa vitae ipsum mattis tincidunt. Nulla nec tortor vitae libero volutpat tempus. Donec aliquam. + +Duis sed nunc. Curabitur turpis nulla, vehicula sed, luctus quis, elementum eget, felis. Maecenas et purus. Maecenas leo tellus, tincidunt a, facilisis vitae, lobortis sit amet, velit. Donec convallis sapien. Maecenas mollis odio eu nibh. Etiam gravida. Integer molestie, sapien eu molestie lacinia, nunc nibh aliquam ligula, eu sagittis tellus erat sollicitudin odio. Duis et risus. Phasellus nisi neque, placerat nec, condimentum non, ultrices eu, sem. Ut pede. Etiam nulla metus, volutpat id, convallis sed, suscipit vel, urna. Donec vel elit. Ut leo neque, venenatis faucibus, lacinia nec, tincidunt eu, enim. Cras id dui a libero pharetra dignissim. Donec eros leo, porta quis, laoreet ut, pellentesque volutpat, lectus. + +Nullam blandit. Aliquam erat volutpat. Fusce adipiscing enim. Suspendisse non dui quis ligula porta vestibulum. Donec eu tellus vel lorem pretium porttitor. Praesent luctus. Aliquam ac eros in massa dapibus tincidunt. Donec ut magna. Etiam auctor lacus sit amet lacus. Sed ultricies ipsum nec elit. Quisque a est in purus suscipit tristique. + +Aenean sed dui vel dolor pulvinar laoreet. Vivamus vehicula lorem in pede. Vivamus et diam. Integer ac odio vel diam hendrerit bibendum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a nisi. Phasellus tincidunt dui vitae augue. Duis faucibus, dui interdum fringilla tincidunt, odio elit vestibulum libero, ac molestie magna lectus id lacus. Aenean ligula. Nulla facilisi. + +Fusce vel sem eu velit fringilla ornare. Sed feugiat tincidunt felis. Nullam felis mi, euismod sit amet, mollis at, sodales eget, augue. Nam imperdiet nibh at velit. Sed ut erat. In dui. Nulla facilisi. Nullam augue libero, tincidunt nec, pretium eu, pulvinar in, dui. Morbi vitae felis. Pellentesque vel justo vel velit sagittis malesuada. Proin vehicula blandit massa. Etiam tincidunt pharetra urna. In metus est, auctor nec, blandit a, cursus nec, quam. Mauris ac metus a libero congue faucibus. Mauris mauris dolor, sodales in, cursus ut, sodales rutrum, eros. Quisque mauris eros, sagittis vitae, lobortis ut, eleifend id, nisi. + +Aenean neque. Vestibulum egestas pellentesque ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus sagittis justo vel risus. Sed pretium neque vitae urna. Pellentesque congue libero id lorem. Mauris leo lorem, blandit sit amet, convallis quis, consectetuer sed, eros. Mauris tincidunt, enim a gravida euismod, magna nulla fermentum libero, viverra egestas velit quam et tortor. Vivamus aliquet massa vitae justo. Nulla congue lacus ac elit. + +Phasellus commodo quam vel ligula. Proin non metus at eros pulvinar luctus. Mauris diam lorem, posuere quis, gravida et, tincidunt nec, ligula. Sed diam. Aliquam elit lectus, hendrerit ut, imperdiet sit amet, pretium sit amet, ipsum. Mauris vehicula nisl in dui. Curabitur eget quam ut magna elementum fermentum. Mauris scelerisque. Quisque laoreet. Etiam tempus turpis. Pellentesque augue quam, hendrerit sed, tincidunt at, pharetra at, nisl. Aliquam lacus. Suspendisse potenti. Aenean velit libero, ultrices in, lacinia eu, luctus vel, ante. Etiam dictum mi in felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce gravida dapibus nisl. Cras vitae nisl. + +Maecenas dignissim, ligula non porta cursus, enim nunc malesuada sem, eu porttitor nulla urna eu quam. Fusce eros. Aliquam eros. Nam auctor. Nulla molestie porta est. Suspendisse potenti. Vivamus molestie lorem sed erat. Sed eget ipsum. Integer aliquam pulvinar nulla. Cras aliquet sem ut nunc. Fusce faucibus tempus lectus. Cras sodales, nisi ac facilisis ultrices, eros arcu dapibus sapien, et ultrices mauris tellus non dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras cursus varius metus. Ut turpis. Vivamus eget tortor. + +Sed laoreet, velit non accumsan cursus, nunc urna posuere justo, in dictum lectus pede id ante. Cras vulputate. Cras congue dui sed elit. Proin lacus sem, ultrices at, consequat in, tempor quis, metus. Proin vel arcu. Nam euismod hendrerit elit. Ut erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed posuere. Morbi eros urna, semper at, semper non, convallis quis, velit. Maecenas orci. Vestibulum lobortis tristique metus. Vestibulum lorem nulla, sollicitudin vitae, condimentum quis, auctor ut, dui. Vivamus vestibulum magna ut nisi. Curabitur eleifend dui vel nunc. Curabitur mauris lacus, malesuada sit amet, suscipit sed, rutrum luctus, tellus. Integer facilisis urna vitae lectus. + +Aenean quam leo, lobortis quis, malesuada eu, vulputate vitae, nisl. Praesent eget eros. Ut fermentum turpis id quam. Nam tortor. Praesent nec orci. Nulla bibendum adipiscing augue. Ut commodo, magna id malesuada gravida, augue odio malesuada mi, porta malesuada elit est vitae diam. Mauris non nulla. Suspendisse tincidunt, nunc ultricies porta venenatis, mi pede tincidunt libero, eget varius ante libero ut ligula. Curabitur pretium porttitor tortor. + +Maecenas vitae elit eget nisi dapibus dictum. Nunc in libero. Nulla dictum orci eu erat auctor lobortis. Phasellus risus. Suspendisse potenti. Suspendisse potenti. Praesent adipiscing consequat elit. Integer id augue. Praesent in justo nec magna dapibus pulvinar. Duis nisl. Suspendisse ac odio. Vivamus imperdiet. Donec non velit sit amet risus dignissim congue. Nam aliquet posuere velit. Cras turpis. Morbi malesuada dignissim mi. + +Sed leo neque, varius quis, venenatis sed, pharetra sed, est. Morbi blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam semper pellentesque mi. Ut vel lorem. Nunc mi tortor, laoreet at, faucibus eu, tincidunt sit amet, erat. Duis tempor malesuada ipsum. Phasellus aliquet. Donec et elit. Pellentesque purus. Vestibulum rutrum semper nibh. Nulla facilisi. Phasellus et enim sit amet ante vestibulum vehicula. Phasellus id nisl. Donec mollis leo at eros. Mauris pellentesque neque at purus. Morbi quis dolor at ipsum scelerisque sodales. Etiam volutpat turpis a metus. In hac habitasse platea dictumst. Nunc lorem lorem, vestibulum ac, euismod eget, ullamcorper dignissim, velit. + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ultrices, nibh vel aliquam vestibulum, eros enim venenatis dui, id iaculis enim nunc vel massa. Morbi eleifend orci et massa. Aliquam erat volutpat. Nulla mollis egestas turpis. In sodales nunc eget tortor. Sed ipsum eros, tempor quis, aliquet vitae, imperdiet non, lorem. Pellentesque quis elit id mi luctus dapibus. Sed nunc arcu, rhoncus nec, convallis quis, cursus at, neque. Mauris convallis purus at erat. Pellentesque vestibulum. Vivamus fringilla elit at arcu. Nullam aliquet enim nec arcu. Nam id tortor. Nulla quis nunc. Ut arcu. Suspendisse potenti. Pellentesque ullamcorper ligula id arcu. + +Nam non libero vitae nisl scelerisque fringilla. Quisque varius ante id metus rhoncus fringilla. Nulla facilisi. Praesent eleifend porttitor ligula. Etiam quis dolor non augue commodo auctor. Donec a mi. Vestibulum tempor. Donec felis urna, auctor at, cursus dictum, gravida id, arcu. Aenean dictum malesuada dolor. Vivamus mattis. Phasellus eu pede. Fusce adipiscing justo fringilla metus. Etiam ante. Integer mollis massa quis nunc. Integer dictum neque luctus enim. + +Sed eu libero. Integer tempor ligula in velit. Ut tincidunt lacinia sem. Nullam vel risus. Sed sodales ante a dolor. Curabitur eros. Sed sodales. Sed non metus. Vestibulum elementum faucibus ante. Nulla vel nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In hac habitasse platea dictumst. Nunc nec lorem ut ipsum lacinia iaculis. Duis erat. Aliquam erat. Cras iaculis. In hac habitasse platea dictumst. + +Nullam ante. Cras vitae est. Pellentesque vel metus a ligula dapibus mattis. Duis feugiat aliquet felis. Etiam id nisl quis est dignissim condimentum. Suspendisse potenti. Morbi velit lorem, ornare quis, pellentesque vel, placerat eget, tortor. Vestibulum tincidunt molestie libero. Nulla nulla enim, malesuada id, ullamcorper vitae, dictum at, purus. Donec dignissim odio ut enim. Suspendisse at lectus. + +Praesent lobortis augue vel lectus. Ut in ligula ut felis congue suscipit. Quisque dignissim tortor ut mi. Fusce magna nisi, eleifend ac, ornare vel, porttitor vitae, quam. Vestibulum sodales justo quis turpis. Fusce urna nisi, rhoncus quis, condimentum vel, dictum eu, nunc. Fusce sed nibh vitae odio posuere adipiscing. Sed porta elit quis dolor. Nam libero nulla, auctor sed, tincidunt quis, faucibus sit amet, mi. Quisque orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam id sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec vel eros. + +Vivamus luctus lobortis leo. Suspendisse vel elit a enim ullamcorper posuere. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec quis pede mattis lectus mollis adipiscing. Sed accumsan posuere erat. Praesent euismod tincidunt felis. Donec mi. Ut commodo arcu lacinia tellus. Aliquam a libero quis lectus semper viverra. Curabitur lacinia mauris at tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sit amet magna molestie orci suscipit fringilla. Fusce pretium metus non sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed hendrerit. Nulla felis. Suspendisse potenti. Aliquam blandit tristique neque. Curabitur quis erat vel nunc accumsan mollis. + +Duis sagittis, tellus ut aliquam fringilla, dolor mi ullamcorper nisl, ut tristique pede elit sed mauris. Curabitur id felis. Donec pulvinar lacus et lectus. Aliquam vulputate vulputate metus. Curabitur magna felis, adipiscing ac, accumsan vel, molestie quis, quam. Mauris elit arcu, pretium vitae, mollis sit amet, sollicitudin ut, mi. Donec imperdiet dignissim mi. Nullam sit amet tortor. Aliquam neque nulla, venenatis a, porta in, placerat tempus, lacus. Quisque vestibulum dui et lacus. Proin dignissim consectetuer purus. Etiam gravida tortor in nunc. Ut tempor tristique tortor. Sed laoreet tincidunt quam. Vestibulum porta turpis ut elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nibh dui, feugiat nec, laoreet id, malesuada eget, nisi. Ut neque massa, vehicula eu, commodo non, ultricies vitae, purus. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris euismod, felis vel tempor aliquet, tortor mauris malesuada nunc, vel fermentum sem diam id dui. Nam rutrum sapien eget odio. Aliquam sed libero non mi faucibus tempus. Fusce hendrerit, diam non volutpat rutrum, erat metus venenatis ligula, non scelerisque pede ligula vel quam. Morbi rhoncus eros ac dui feugiat elementum. Duis eu libero et tellus congue viverra. Morbi quam quam, elementum sed, ullamcorper imperdiet, commodo non, odio. Nam aliquet egestas urna. Mauris odio felis, varius eu, lacinia eu, condimentum a, lectus. Sed justo massa, pulvinar id, varius a, porttitor nec, libero. Etiam varius. Curabitur sodales, odio at posuere semper, eros nibh tincidunt lectus, vel rutrum sapien nisi in ligula. Suspendisse eget arcu. Phasellus imperdiet est ac sapien. Donec nulla tortor, placerat vel, tempus a, lobortis vel, nibh. Aliquam varius nisi. Nulla et enim. Fusce convallis laoreet lacus. + +Phasellus ipsum dolor, molestie quis, condimentum in, commodo eu, diam. Quisque bibendum lacinia dui. Nullam blandit vulputate orci. Ut lacinia massa vel augue. Aliquam gravida, quam quis imperdiet imperdiet, tellus diam pharetra erat, at pharetra lacus nibh egestas magna. Nulla sagittis lorem ut lorem. Duis condimentum, dui vitae aliquam posuere, diam quam convallis velit, ut gravida leo ipsum non risus. Ut fermentum sollicitudin erat. Donec sagittis scelerisque felis. Nunc arcu. Etiam tempus, magna sit amet suscipit euismod, eros sem rutrum dui, vitae sagittis nibh purus non lacus. Sed mollis arcu eget dolor. Donec ornare, arcu sit amet fermentum vulputate, risus enim fermentum libero, a lacinia dolor mi non velit. Etiam lobortis purus a elit. Nunc nulla dui, mattis quis, bibendum a, ultrices ac, augue. In aliquam vehicula turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +Integer id nisl. Quisque dictum elementum odio. Aenean luctus. Sed eu sem a pede vulputate condimentum. Quisque magna. Donec aliquam mattis ipsum. Curabitur dictum sollicitudin sem. Aliquam pulvinar. Nunc sollicitudin risus a erat. Vivamus quis tellus sit amet nibh vestibulum consequat. Nulla pretium sollicitudin dolor. Aliquam iaculis tincidunt turpis. Phasellus ipsum leo, venenatis in, sagittis in, ornare at, nunc. + +Pellentesque ultrices, dui eu iaculis luctus, tellus augue volutpat sapien, in dignissim urna felis ut mi. Sed arcu dui, dignissim id, porttitor ut, imperdiet vitae, ante. Nulla dui sem, commodo nec, sagittis et, lacinia et, pede. Etiam eleifend dui ut nisl. Donec ante mauris, tempus sit amet, varius vitae, gravida quis, mi. In scelerisque, felis vitae viverra sagittis, velit metus ultricies neque, quis imperdiet velit elit et magna. Suspendisse potenti. Sed velit eros, euismod sed, condimentum nec, faucibus sed, sapien. Nam accumsan ligula sit amet neque. Aliquam erat volutpat. + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam eu pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed eu felis sed tortor tempor fermentum. Phasellus commodo sem vel nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lectus elit, pharetra sit amet, accumsan sed, tincidunt et, mauris. Duis dapibus pharetra sem. Integer in justo. Praesent eros. Vestibulum ac ante. Aliquam scelerisque sem pellentesque nibh consectetuer sodales. Aliquam consectetuer odio. Duis lectus odio, luctus eu, commodo quis, mollis vitae, velit. Cras nec nunc non elit iaculis mattis. Aenean justo neque, sollicitudin eget, ullamcorper eget, egestas id, sem. In eu risus. Sed egestas. + +Integer at neque. Sed pretium scelerisque nulla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce ut pede. Etiam vitae quam a urna varius imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vehicula. Fusce ullamcorper nibh non erat. Quisque in neque. Praesent est. Pellentesque arcu. + +Proin posuere. Suspendisse potenti. Integer felis lacus, aliquam sed, vulputate in, mollis vel, tellus. Integer vehicula bibendum est. Nunc non dolor in tellus mattis facilisis. Integer vestibulum, augue at commodo aliquam, dui est mattis ligula, sit amet adipiscing orci sem vitae magna. Praesent enim velit, malesuada at, congue nec, luctus in, justo. Sed varius. Morbi pharetra. Donec eu massa nec tellus vulputate pulvinar. Ut commodo turpis non sem. Ut convallis ullamcorper risus. Etiam interdum pede id nisi. Cras magna sapien, suscipit a, laoreet non, rhoncus et, felis. Integer orci lorem, vestibulum dictum, ullamcorper a, porttitor et, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc et magna. Sed bibendum tellus in diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vitae tortor. Integer magna. Duis venenatis, leo ac tempor laoreet, elit nulla pharetra pede, non fermentum nunc odio a odio. Proin non velit. Sed imperdiet augue quis nisl. Integer condimentum nisl nec libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus placerat libero. Duis congue dictum magna. Aliquam dapibus bibendum enim. Nunc eleifend pede vel ipsum. + +Etiam vitae velit. Mauris erat nunc, malesuada ut, feugiat ac, placerat condimentum, augue. Nam volutpat. Aliquam vehicula ipsum id odio. Vivamus sollicitudin turpis id sapien. Fusce a felis vitae odio convallis blandit. Curabitur vitae eros id eros porta pretium. Nulla in magna eget urna lacinia convallis. Aliquam mattis venenatis purus. Sed sed mi eget erat tristique porta. Donec auctor dolor a erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In nec ligula. Nunc eleifend. Vestibulum quis nisi eget elit porttitor congue. Maecenas faucibus, magna eget adipiscing tincidunt, dolor ante malesuada elit, non elementum lacus turpis in pede. + +Ut malesuada mi nec metus. Praesent auctor augue ac nisl ultricies facilisis. Nam purus sapien, pellentesque dignissim, posuere eu, cursus id, diam. Quisque sollicitudin, elit a pellentesque scelerisque, lorem risus auctor quam, quis consequat tellus neque id urna. Suspendisse diam tortor, eleifend dignissim, egestas ut, luctus in, ante. Duis ante. Maecenas luctus. Curabitur cursus pharetra urna. Maecenas imperdiet, erat non elementum euismod, tortor odio euismod lectus, ac facilisis sem nibh vitae nulla. Nunc gravida. Morbi sollicitudin odio quis lacus. Aliquam a nibh non urna porta imperdiet. Aliquam erat volutpat. In iaculis lacinia velit. Sed libero lacus, tristique eu, lacinia ac, aliquet eget, urna. + +Etiam at nisl. Phasellus faucibus luctus lectus. Ut placerat vulputate dolor. Phasellus vel velit. Morbi viverra. Phasellus orci. Integer dignissim mattis mauris. Pellentesque posuere leo posuere quam. Quisque nec magna at diam viverra pellentesque. Suspendisse velit arcu, ultricies quis, congue a, venenatis eget, lacus. Integer sagittis hendrerit dolor. Fusce tincidunt ante a sem. + +Maecenas consectetuer, justo sed rhoncus venenatis, nibh arcu rutrum dolor, sed condimentum libero libero et ipsum. Vivamus mattis justo ut lorem tincidunt lobortis. Ut non velit id neque aliquet accumsan. Sed tempus viverra nulla. Curabitur ullamcorper, neque quis dapibus scelerisque, felis diam gravida orci, non cursus quam neque vitae elit. Etiam pharetra tincidunt lacus. Duis euismod fringilla est. Etiam ornare tincidunt lectus. Proin in turpis. Nunc blandit blandit turpis. Aenean ut augue. Duis orci justo, tincidunt eu, rutrum sed, rutrum et, turpis. Curabitur facilisis odio in ante. In hac habitasse platea dictumst. Sed eros est, pellentesque at, tincidunt eu, ultrices quis, metus. Morbi sit amet justo. Maecenas ac arcu. Mauris dignissim. + +Pellentesque ultricies rutrum orci. Aenean ornare. Vivamus eu risus vel mauris lobortis dictum. Sed et turpis auctor mi rhoncus pulvinar. Sed nec nunc a purus tempor viverra. Pellentesque suscipit. Donec tristique risus non nibh. Etiam nisl magna, sollicitudin ut, ultrices sit amet, egestas eu, nulla. Aliquam erat volutpat. Vestibulum pharetra. Sed egestas, metus sit amet lobortis consequat, erat elit imperdiet libero, eu interdum quam massa eget dolor. Suspendisse vitae odio. Proin blandit mauris iaculis metus. + +Vivamus vestibulum. Etiam et nisl. Aliquam in diam vel elit placerat suscipit. Duis sodales purus ac nibh. Nulla in odio eget enim luctus blandit. Curabitur ultrices ipsum non neque egestas eleifend. Sed turpis. Proin consectetuer. Vivamus mattis. In aliquet. + +Nunc id eros. Donec venenatis, nulla et mattis luctus, ante leo semper justo, non adipiscing odio risus sed lacus. Praesent vitae risus congue libero congue tempus. Phasellus ac eros. Nulla vehicula, lorem in aliquet suscipit, arcu erat egestas sem, quis lobortis quam ante eu massa. Curabitur non massa. Sed bibendum lacinia odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus volutpat blandit lacus. Proin porta, tellus ut auctor laoreet, lectus eros fermentum lectus, id sagittis arcu justo in turpis. Phasellus consequat. Nam pellentesque, mi id viverra convallis, nunc libero placerat leo, eleifend porta sem nisl vitae sapien. Pellentesque ligula libero, tristique non, porttitor rutrum, porttitor non, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer dictum tellus a tortor. Vivamus felis nunc, molestie non, rhoncus quis, pharetra id, dui. Donec risus metus, fringilla vel, aliquet eu, placerat id, neque. + +Suspendisse ipsum. Vivamus lectus. Sed viverra, massa eget convallis mattis, quam turpis consectetuer nunc, eget posuere magna sem id velit. In nec mauris. Aenean a purus sed quam lobortis fringilla. Proin ultricies lacinia ante. Sed adipiscing erat quis velit. Nullam vitae nisl id justo sollicitudin molestie. Nulla facilisi. Sed nec urna sed nisl fringilla dapibus. Nulla at diam. Aliquam eget nibh. Nunc ac nisi sit amet tellus egestas tempus. Nam scelerisque urna et neque. Donec est orci, sagittis non, vulputate a, commodo et, augue. Ut dapibus tortor. Ut nunc. Donec dictum dapibus odio. Nam ultricies ullamcorper ligula. Pellentesque accumsan varius leo. + +Morbi euismod laoreet erat. Vivamus quis ipsum. Morbi euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel purus. Nullam at magna. Curabitur lacus lorem, iaculis quis, dapibus non, volutpat vel, nulla. Donec ut arcu rhoncus dolor pretium dictum. Nullam vel metus. Ut arcu. Pellentesque nisi nunc, placerat eget, tincidunt vel, pharetra non, nunc. Integer tincidunt ultricies lectus. Integer semper, purus sed ultrices feugiat, nulla pede sollicitudin erat, vel auctor nulla ipsum vel lectus. Aenean mi. + +Nullam sed nisi et arcu imperdiet fermentum. Mauris nec metus. In ac dolor. In mi arcu, congue ac, pharetra nec, scelerisque sit amet, magna. Curabitur lacus. Curabitur et elit. Aliquam ullamcorper nunc eu elit. Sed convallis dolor at velit. Vestibulum dapibus, augue id consectetuer placerat, nunc massa blandit sapien, id aliquam elit nisi id mi. Phasellus sapien est, gravida eu, bibendum ut, adipiscing quis, est. Ut molestie quam vitae odio. Donec quis risus id erat faucibus sollicitudin. Nam id felis. Mauris sed enim vitae leo accumsan pretium. + +Nam justo. Donec turpis nisl, commodo et, interdum ac, consectetuer non, massa. Fusce sem metus, laoreet nec, posuere id, imperdiet in, velit. Donec vulputate justo eget turpis. Nulla pede. Morbi tincidunt. Fusce aliquet, quam et aliquam fringilla, ante ante iaculis dui, nec aliquam arcu purus sed erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus suscipit quam et est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; + +Integer sed tellus. Sed sed velit ultricies leo rutrum laoreet. Sed non eros ac purus sagittis feugiat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed hendrerit ligula sit amet nibh. Maecenas turpis. Morbi consectetuer, dolor et adipiscing imperdiet, ante neque feugiat dolor, at porta quam neque quis ligula. Mauris semper velit sit amet ipsum. Pellentesque tempus, purus in rutrum consequat, enim erat vehicula massa, id accumsan leo sapien nec purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In dolor. Integer facilisis libero sit amet pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut varius aliquet enim. Nulla facilisi. Curabitur consectetuer, odio eu pretium tincidunt, nunc nisi aliquet neque, vel imperdiet elit massa sit amet turpis. Pellentesque tempus, orci volutpat blandit fringilla, odio sem posuere ante, vitae bibendum urna lorem vitae eros. Praesent viverra rhoncus arcu. Sed auctor, est sit amet mollis mollis, quam quam gravida sapien, in commodo metus nulla auctor enim. Donec facilisis. + +Proin tincidunt, sapien eget ultricies adipiscing, est odio dictum arcu, ut mollis erat dui sit amet velit. Morbi est sem, interdum at, congue a, elementum vitae, metus. Suspendisse id augue. Mauris enim sem, pulvinar eget, tempus a, tempus sit amet, sapien. Fusce vestibulum consectetuer dui. Pellentesque erat. Sed dignissim placerat odio. Maecenas semper rhoncus lectus. Phasellus pretium. Duis libero elit, eleifend nec, egestas ut, cursus sed, felis. Nam nisl arcu, aliquet et, facilisis eu, luctus ut, risus. Etiam ultrices, dolor sed volutpat malesuada, turpis arcu imperdiet tortor, euismod commodo libero massa ut quam. Integer molestie purus non elit. Ut venenatis semper tortor. Etiam bibendum egestas ipsum. Mauris sollicitudin sem nec nibh. Nulla pretium metus eu metus. Pellentesque sit amet sem. + +Suspendisse ac nisi. Ut leo. Vestibulum hendrerit pretium dolor. Nunc feugiat malesuada purus. Cras et nibh. Curabitur nunc erat, malesuada vitae, laoreet ac, ultricies in, purus. Vivamus tellus arcu, sodales eu, facilisis a, lacinia nec, nunc. Pellentesque id velit. In eu nibh. Nunc nec erat. Sed dictum neque ut nisl. + +Morbi lectus tellus, tincidunt ac, porttitor ac, tristique in, eros. Donec luctus luctus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ut est et enim scelerisque accumsan. Donec ligula felis, lacinia quis, pellentesque in, semper vestibulum, elit. Mauris eget orci a felis congue vehicula. Ut sollicitudin. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam id dolor ut lorem dignissim venenatis. Suspendisse vitae sapien. Proin non magna ut eros viverra pulvinar. Donec quis odio. Nullam non arcu vel lorem suscipit aliquam. Aliquam rutrum turpis in leo. + +Ut luctus nibh tristique erat. Suspendisse bibendum odio vitae tortor. Donec lacinia. Cras sodales felis luctus nulla. Nam eleifend sagittis ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse vel neque. Morbi aliquet vehicula magna. Aenean at odio. Duis pellentesque magna. Nulla at tortor ut diam dictum faucibus. Mauris quis velit. Donec non tellus vitae lorem fringilla porttitor. Fusce ut sapien quis tortor feugiat sagittis. Donec viverra sem vitae sapien. Praesent sodales, lacus in fringilla viverra, odio augue adipiscing urna, vitae interdum ante sem non nisi. Nullam tortor lorem, eleifend ac, mollis non, laoreet ac, risus. Integer ornare leo sed justo. Quisque cursus, sem non facilisis bibendum, nisi mi varius felis, fermentum feugiat lorem eros laoreet risus. + +Quisque sit amet est et lorem vehicula lacinia. Donec nec tortor. Cras odio. Nam scelerisque vulputate urna. Praesent dui. Etiam nec nisl lobortis ipsum aliquet tempus. Maecenas pretium sollicitudin mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus augue massa, congue eget, convallis eget, tristique sit amet, eros. Sed consequat nisi eu felis. Pellentesque justo. Suspendisse non augue. In dignissim lobortis mauris. Mauris sagittis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + +Sed adipiscing. Donec a tellus vitae est cursus vehicula. Nam ante sem, sodales id, fringilla vel, condimentum vel, nulla. Quisque sodales. Etiam imperdiet elit id odio. Aliquam erat volutpat. Maecenas porta tempor arcu. Nulla sem augue, pellentesque ac, consequat ut, condimentum euismod, risus. Sed aliquam tincidunt mi. In interdum lobortis orci. + +Sed vehicula hendrerit purus. Etiam a diam. Curabitur convallis. Suspendisse a nisi. Donec id magna in quam sollicitudin ultricies. Donec viverra. Quisque volutpat est sed sem. Aliquam justo. Vestibulum tortor massa, porttitor sed, varius quis, iaculis quis, odio. Aliquam eget neque. + +Mauris nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum eu quam in neque ultrices pellentesque. Cras in dolor quis quam varius hendrerit. Aliquam nisi lacus, lobortis eu, convallis sit amet, facilisis ut, mi. Aliquam at neque. Cras sagittis elementum justo. Vestibulum ut lectus aliquet purus malesuada volutpat. Duis at lacus adipiscing libero tincidunt vestibulum. Morbi a libero. Cras purus. Morbi ut augue et purus interdum scelerisque. Integer a dui. In hac habitasse platea dictumst. Duis pharetra metus eget mauris. Aliquam interdum ullamcorper massa. + +Etiam ornare. Nullam euismod. Aenean consequat gravida ligula. Aliquam est. Proin vitae lacus. Praesent a eros sit amet dui luctus commodo. Phasellus vehicula arcu eget dolor. Praesent fermentum congue leo. Aliquam volutpat purus ut lorem. Fusce hendrerit enim at leo. Aliquam rhoncus nisl. Vivamus dictum egestas mi. Suspendisse pellentesque bibendum dolor. Pellentesque tincidunt, turpis semper pellentesque condimentum, ipsum metus sodales ligula, id volutpat diam turpis ut elit. + +Praesent sed lacus. Nam eleifend molestie mauris. Donec dapibus fermentum massa. Donec viverra faucibus purus. Curabitur congue, libero vitae viverra pellentesque, diam velit sodales enim, sed suscipit lectus nisi nec neque. Vestibulum malesuada, lacus at cursus congue, velit lectus tristique dolor, sit amet sodales neque ipsum a libero. Vestibulum et quam. Curabitur placerat. Curabitur nunc arcu, euismod nec, vulputate hendrerit, aliquet eget, quam. Curabitur vel enim. Suspendisse potenti. + +Nunc consequat orci ut lacus. Fusce velit dolor, dapibus sed, blandit sit amet, rhoncus id, risus. Duis urna nibh, scelerisque quis, dapibus a, scelerisque sed, nibh. Donec luctus. Ut eu mauris cursus diam lacinia rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam vehicula molestie justo. Maecenas imperdiet pede sed mi. Suspendisse nulla dolor, hendrerit eget, hendrerit id, dictum vel, leo. Duis accumsan. Curabitur in felis. Nunc lorem. Ut leo dolor, laoreet nec, vulputate at, eleifend in, nulla. Quisque nunc purus, varius eget, accumsan nec, aliquet et, nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras adipiscing viverra dolor. Mauris porttitor ultrices purus. Nulla facilisi. Praesent faucibus ante vitae mauris. + +Praesent lacinia lectus sed nisl. In tempus congue mauris. Integer facilisis ornare enim. Nulla id massa. Donec commodo diam at tellus. Nam dapibus viverra est. Nam tellus. Praesent a libero. In faucibus est eget nibh. Nulla eros orci, imperdiet non, blandit non, tempor eget, mi. Pellentesque convallis. + +Quisque eget mi ac leo euismod faucibus. Phasellus rhoncus purus id dui. Vestibulum malesuada eleifend ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque blandit mattis odio. Suspendisse consequat, lectus ac semper sollicitudin, mi velit dictum augue, ac tempus dolor erat sit amet dui. Proin hendrerit, felis quis volutpat posuere, diam odio malesuada odio, a interdum orci diam quis sapien. Pellentesque odio odio, viverra vel, gravida eu, molestie sed, nulla. Phasellus mauris pede, commodo ut, euismod eu, hendrerit eu, est. In hac habitasse platea dictumst. Nulla elementum lacus eu augue. Sed erat. Proin porta. Maecenas quis mi. Phasellus at enim ac justo gravida ultrices. Cras leo. + +Integer ut arcu. Donec sed magna. Proin felis. In iaculis, ligula id fringilla pretium, nibh diam accumsan tellus, eget accumsan metus dui varius turpis. Phasellus orci metus, eleifend sed, tempor ac, scelerisque ac, urna. Integer viverra neque a mauris. Mauris porttitor dolor eu velit. Integer odio elit, vestibulum ut, volutpat id, rhoncus commodo, urna. Etiam placerat pharetra erat. Ut tempor est. Integer dignissim blandit tellus. Morbi nibh dolor, scelerisque id, commodo malesuada, mattis at, mi. Cras tincidunt commodo purus. In tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ullamcorper. Ut hendrerit. Morbi ultrices. + +Praesent iaculis, eros ac egestas sodales, urna leo fermentum ligula, sit amet aliquam velit sem non purus. Donec rutrum arcu quis purus. Nam posuere, lacus at consequat placerat, nulla pede posuere orci, non euismod turpis dui quis nisl. Proin porta adipiscing nibh. Donec tristique dolor at tellus. Donec neque massa, auctor id, faucibus vitae, ullamcorper vel, nisi. Proin molestie neque sed massa. Nam tempor. Morbi aliquam sapien at tellus. Fusce quis risus et mi pretium pulvinar. Fusce sit amet ligula. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse eu enim et felis scelerisque lobortis. Praesent bibendum. Vivamus vehicula. Integer at nibh sed velit rhoncus molestie. Cras lacus. Sed ullamcorper eros vel erat. Fusce eu tortor sit amet diam euismod sagittis. Nunc quis lacus id nibh convallis varius. Suspendisse vitae mi. Vestibulum tristique. Donec malesuada ipsum id neque. Nullam sed lacus. Duis egestas, justo ut congue ornare, augue sapien luctus diam, at accumsan erat sapien ut libero. Phasellus vel nulla. Suspendisse arcu tellus, porttitor a, pharetra faucibus, aliquam sit amet, massa. Nulla porttitor tincidunt lorem. Nunc dolor odio, sagittis in, lobortis vel, volutpat sed, nibh. + +Quisque blandit leo ut sapien tempus facilisis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean ultricies porttitor justo. Fusce rutrum eros ut urna. Proin quis quam eget dui aliquam accumsan. Donec suscipit eleifend elit. Pellentesque mattis, felis sodales iaculis imperdiet, lacus sem convallis augue, sit amet aliquet arcu purus fringilla risus. In eu odio id magna pharetra ornare. Aliquam interdum pulvinar ipsum. Sed neque. + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam sit amet nisi. Ut at augue. Mauris volutpat blandit ligula. Nulla eu metus. Vestibulum eget elit. Praesent posuere. Vestibulum id sem non lectus mollis tincidunt. Aliquam id felis at ante ornare tempor. Nulla lacus turpis, feugiat vitae, cursus quis, consectetuer non, mauris. Fusce lacus massa, porttitor ut, molestie ut, venenatis a, lorem. Praesent sit amet orci. Mauris rhoncus felis vitae felis adipiscing imperdiet. Maecenas mollis diam nec leo. + +Fusce enim ipsum, ultrices eu, molestie id, elementum id, sapien. Integer a urna. Nam velit libero, venenatis eget, tempor sit amet, feugiat vitae, ante. Fusce nunc. Sed semper nisl nec risus. In sed libero. Proin tortor neque, tincidunt ac, tempor ac, pharetra quis, velit. Duis lectus augue, ultricies vel, consequat id, iaculis id, ante. Vivamus auctor metus a ante. Curabitur arcu nisi, facilisis at, laoreet in, consectetuer sed, mauris. Quisque placerat diam sed dui. Vivamus pretium condimentum lorem. Curabitur laoreet. Aenean orci ligula, cursus eget, lacinia non, faucibus vel, lorem. + +Aliquam erat volutpat. Curabitur eros dolor, congue a, condimentum sed, luctus ut, nibh. Maecenas non tortor nec turpis commodo pellentesque. Praesent euismod placerat mi. Suspendisse potenti. Phasellus ut neque vitae orci mattis iaculis. Integer eget tellus. Donec at ante. Nam lacinia leo eget erat. Maecenas euismod magna congue tortor. Morbi nec massa eu enim malesuada sollicitudin. Sed accumsan. Nullam ipsum. Ut odio. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque id velit. Nam odio sem, aliquet ut, tempus sit amet, euismod et, nunc. + +Pellentesque libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent mauris nunc, varius ut, convallis molestie, luctus sit amet, leo. Sed dictum lorem et arcu. Nunc venenatis pellentesque massa. Nulla facilisi. Phasellus in tortor eget risus scelerisque vulputate. Sed nibh elit, sagittis ac, condimentum nec, convallis et, justo. Fusce volutpat metus. Nunc auctor. Vestibulum leo eros, pellentesque ac, mollis ultrices, rhoncus non, dolor. Mauris vehicula placerat nisl. Vestibulum bibendum, arcu quis congue elementum, velit nunc eleifend turpis, id luctus risus nisl sit amet tellus. Phasellus pede neque, blandit non, commodo vitae, ultricies eget, magna. Aliquam erat volutpat. + +Nulla facilisi. Aliquam ac ante. Cras risus. Morbi mauris lacus, posuere eu, blandit et, pharetra at, mi. Proin ac purus. Duis cursus nisl rutrum quam. Aliquam a odio non magna pellentesque ultricies. Maecenas ac massa quis sapien ullamcorper tempus. Cras cursus velit sed sapien. Proin nulla. Vivamus sodales aliquam nibh. Etiam et erat ut ante lacinia euismod. Fusce nisi. Proin quis nulla. + +Quisque venenatis, eros sed laoreet sollicitudin, orci ante pellentesque nisl, sit amet viverra quam erat non risus. Cras eget libero. Sed elit magna, semper eu, fringilla in, dignissim sodales, erat. Vivamus feugiat sem vel dui. Donec convallis sollicitudin diam. Cras sed purus. Donec felis eros, semper eget, tempor consectetuer, sagittis quis, nisl. Duis in ante. Cras non turpis. Nulla tempor velit aliquet turpis molestie placerat. Proin elementum fermentum mauris. Vivamus sed orci lacinia dui placerat venenatis. Vestibulum feugiat, tellus in volutpat rutrum, magna nisi ullamcorper eros, id pulvinar neque erat ut lacus. Vivamus sed augue. Nulla facilisi. Maecenas ante augue, elementum ut, sodales vitae, condimentum nec, lorem. Duis pede orci, fringilla at, eleifend nec, pretium in, erat. Nam sagittis, turpis vitae convallis pharetra, odio sem scelerisque lacus, nec lobortis dui diam vel eros. In semper gravida neque. + +Integer nunc. Ut pretium ipsum sit amet elit. In nec arcu. Sed vestibulum vulputate ipsum. Pellentesque tincidunt. Nulla gravida dolor in tellus. Cras vehicula, dolor ut pellentesque aliquam, erat enim auctor massa, vehicula lobortis odio eros quis quam. Proin dapibus neque in enim. Proin elit. Integer rhoncus tincidunt elit. Fusce lorem metus, semper ac, volutpat vitae, facilisis ut, tellus. Donec vel turpis vitae nisi pharetra porttitor. Maecenas tortor. Fusce mi. Nullam nec \ No newline at end of file
diff --git a/distribution/LICENSE b/distribution/LICENSE new file mode 100644 index 0000000..4903a01 --- /dev/null +++ b/distribution/LICENSE
@@ -0,0 +1,2 @@ +This product is dual licensed under both the Apache2 and LGPL licenses. +See LICENSE-apache2 and LICENSE-lgpl.
diff --git a/distribution/LICENSE-apache2 b/distribution/LICENSE-apache2 new file mode 100644 index 0000000..6b0b127 --- /dev/null +++ b/distribution/LICENSE-apache2
@@ -0,0 +1,203 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +
diff --git a/distribution/LICENSE-lgpl b/distribution/LICENSE-lgpl new file mode 100644 index 0000000..cca7fc2 --- /dev/null +++ b/distribution/LICENSE-lgpl
@@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library.
diff --git a/distribution/NOTICE b/distribution/NOTICE new file mode 100644 index 0000000..a61cbf5 --- /dev/null +++ b/distribution/NOTICE
@@ -0,0 +1,6 @@ +Ldaptive Java Library +Copyright (C) 2003-2017 Virginia Tech. +All rights reserved. + +This product includes software developed at +Virginia Tech (http://www.vt.edu).
diff --git a/distribution/bin/krb5_jaas.config b/distribution/bin/krb5_jaas.config new file mode 100644 index 0000000..08b3557 --- /dev/null +++ b/distribution/bin/krb5_jaas.config
@@ -0,0 +1,11 @@ +com.sun.security.jgss.initiate { + com.sun.security.auth.module.Krb5LoginModule required + doNotPrompt="true" + debug="true" + renewTGT="true" + principal="dfisher" + useTicketCache="true" + ticketCache="/tmp/krb5cc_dfisher" + useKeyTab="true" + keyTab="/home/dfisher/krb5.keytab"; +};
diff --git a/distribution/bin/ldap_jaas.config b/distribution/bin/ldap_jaas.config new file mode 100644 index 0000000..106304b --- /dev/null +++ b/distribution/bin/ldap_jaas.config
@@ -0,0 +1,8 @@ +ldaptive { + org.ldaptive.jaas.LdapLoginModule required + ldapUrl="ldap://directory.ldaptive.org" + baseDn="dc=ldaptive,dc=org" + useStartTLS="true" + userFilter="(uupid={user})" + userRoleAttribute="eduPersonAffiliation,groupMembership"; +};
diff --git a/distribution/bin/ldapadd b/distribution/bin/ldapadd new file mode 100755 index 0000000..bf7b83f --- /dev/null +++ b/distribution/bin/ldapadd
@@ -0,0 +1,27 @@ +#!/bin/sh + +JAVA=java + +# sample options for kerberos +#KRB5_OPTS="-Djava.security.auth.login.config=krb5_jaas.config -Djavax.security.auth.useSubjectCredsOnly=false -Djava.security.krb5.realm=VT.EDU -Djava.security.krb5.kdc=directory.ldaptive.org" + +#KEYSTORE_OPTS="-Djavax.net.ssl.keyStore= -Djavax.net.ssl.keyStorePassword=changeit -Djavax.net.ssl.keyStoreType=BKS" + +#TRUSTSTORE_OPTS="-Djavax.net.ssl.trustStore= -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStoreType=BKS" + +JAVA_OPTS="${JAVA_OPTS} ${KRB5_OPTS} ${KEYSTORE_OPTS} ${TRUSTSTORE_OPTS}" + +if [ "x$LDAPTIVE_HOME" = "x" ]; then + PREFIX=`dirname $0`/.. +else + PREFIX="$LDAPTIVE_HOME" +fi + +CLASSPATH="${PREFIX}/jars/ldaptive-${project.version}.jar" +for JAR in `ls ${PREFIX}/lib/*.jar` ; do + CLASSPATH=${CLASSPATH}:$JAR +done + +${JAVA} ${JAVA_OPTS} -cp ${CLASSPATH} \ + org.ldaptive.cli.AddOperationCli "$@" +
diff --git a/distribution/bin/ldapadd.bat b/distribution/bin/ldapadd.bat new file mode 100644 index 0000000..92309d2 --- /dev/null +++ b/distribution/bin/ldapadd.bat
@@ -0,0 +1,24 @@ +@echo off +if "%OS%" == "Windows_NT" setlocal + +if not defined JAVA_HOME goto no_java_home +if not defined LDAPTIVE_HOME goto no_ldaptive_home + +set JAVA=%JAVA_HOME%\bin\java + +set LDAP_JAR=%LDAPTIVE_HOME%\jars\ldaptive-${project.version}.jar +set LIBDIR=%LDAPTIVE_HOME%\lib + +set CLASSPATH=%LIBDIR%\commons-cli-${commons-cli.version}.jar;%LIBDIR%\slf4j-api-${org.slf4j.version}.jar;%LDAP_JAR% + +call "%JAVA%" -cp "%CLASSPATH%" org.ldaptive.cli.AddOperationCli %* +goto end + +:no_ldaptive_home +echo ERROR: LDAPTIVE_HOME environment variable must be set to Ldaptive install path. +goto end + +:no_java_home +echo ERROR: JAVA_HOME environment variable must be set to JRE/JDK install path. + +:end
diff --git a/distribution/bin/ldapauth b/distribution/bin/ldapauth new file mode 100755 index 0000000..7820f95 --- /dev/null +++ b/distribution/bin/ldapauth
@@ -0,0 +1,24 @@ +#!/bin/sh + +JAVA=java + +#KEYSTORE_OPTS="-Djavax.net.ssl.keyStore= -Djavax.net.ssl.keyStorePassword=changeit -Djavax.net.ssl.keyStoreType=BKS" + +#TRUSTSTORE_OPTS="-Djavax.net.ssl.trustStore= -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStoreType=BKS" + +JAVA_OPTS="${JAVA_OPTS} ${KEYSTORE_OPTS} ${TRUSTSTORE_OPTS}" + +if [ "x$LDAPTIVE_HOME" = "x" ]; then + PREFIX=`dirname $0`/.. +else + PREFIX="$LDAPTIVE_HOME" +fi + +CLASSPATH="${PREFIX}/jars/ldaptive-${project.version}.jar" +for JAR in `ls ${PREFIX}/lib/*.jar` ; do + CLASSPATH=${CLASSPATH}:$JAR +done + +${JAVA} ${JAVA_OPTS} -cp ${CLASSPATH} \ + org.ldaptive.cli.AuthenticatorCli "$@" +
diff --git a/distribution/bin/ldapauth.bat b/distribution/bin/ldapauth.bat new file mode 100644 index 0000000..c0f7a0e --- /dev/null +++ b/distribution/bin/ldapauth.bat
@@ -0,0 +1,24 @@ +@echo off +if "%OS%" == "Windows_NT" setlocal + +if not defined JAVA_HOME goto no_java_home +if not defined LDAPTIVE_HOME goto no_ldaptive_home + +set JAVA=%JAVA_HOME%\bin\java + +set LDAP_JAR=%LDAPTIVE_HOME%\jars\ldaptive-${project.version}.jar +set LIBDIR=%LDAPTIVE_HOME%\lib + +set CLASSPATH=%LIBDIR%\commons-cli-${commons-cli.version}.jar;%LIBDIR%\slf4j-api-${org.slf4j.version}.jar;%LDAP_JAR% + +call "%JAVA%" -cp "%CLASSPATH%" org.ldaptive.cli.AuthenticatorCli %* +goto end + +:no_ldaptive_home +echo ERROR: LDAPTIVE_HOME environment variable must be set to Ldaptive install path. +goto end + +:no_java_home +echo ERROR: JAVA_HOME environment variable must be set to JRE/JDK install path. + +:end
diff --git a/distribution/bin/ldapcompare b/distribution/bin/ldapcompare new file mode 100755 index 0000000..a03ec30 --- /dev/null +++ b/distribution/bin/ldapcompare
@@ -0,0 +1,27 @@ +#!/bin/sh + +JAVA=java + +# sample options for kerberos +#KRB5_OPTS="-Djava.security.auth.login.config=krb5_jaas.config -Djavax.security.auth.useSubjectCredsOnly=false -Djava.security.krb5.realm=VT.EDU -Djava.security.krb5.kdc=directory.ldaptive.org" + +#KEYSTORE_OPTS="-Djavax.net.ssl.keyStore= -Djavax.net.ssl.keyStorePassword=changeit -Djavax.net.ssl.keyStoreType=BKS" + +#TRUSTSTORE_OPTS="-Djavax.net.ssl.trustStore= -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStoreType=BKS" + +JAVA_OPTS="${JAVA_OPTS} ${KRB5_OPTS} ${KEYSTORE_OPTS} ${TRUSTSTORE_OPTS}" + +if [ "x$LDAPTIVE_HOME" = "x" ]; then + PREFIX=`dirname $0`/.. +else + PREFIX="$LDAPTIVE_HOME" +fi + +CLASSPATH="${PREFIX}/jars/ldaptive-${project.version}.jar" +for JAR in `ls ${PREFIX}/lib/*.jar` ; do + CLASSPATH=${CLASSPATH}:$JAR +done + +${JAVA} ${JAVA_OPTS} -cp ${CLASSPATH} \ + org.ldaptive.cli.CompareOperationCli "$@" +
diff --git a/distribution/bin/ldapcompare.bat b/distribution/bin/ldapcompare.bat new file mode 100644 index 0000000..b209986 --- /dev/null +++ b/distribution/bin/ldapcompare.bat
@@ -0,0 +1,24 @@ +@echo off +if "%OS%" == "Windows_NT" setlocal + +if not defined JAVA_HOME goto no_java_home +if not defined LDAPTIVE_HOME goto no_ldaptive_home + +set JAVA=%JAVA_HOME%\bin\java + +set LDAP_JAR=%LDAPTIVE_HOME%\jars\ldaptive-${project.version}.jar +set LIBDIR=%LDAPTIVE_HOME%\lib + +set CLASSPATH=%LIBDIR%\commons-cli-${commons-cli.version}.jar;%LIBDIR%\slf4j-api-${org.slf4j.version}.jar;%LDAP_JAR% + +call "%JAVA%" -cp "%CLASSPATH%" org.ldaptive.cli.CompareOperationCli %* +goto end + +:no_ldaptive_home +echo ERROR: LDAPTIVE_HOME environment variable must be set to Ldaptive install path. +goto end + +:no_java_home +echo ERROR: JAVA_HOME environment variable must be set to JRE/JDK install path. + +:end
diff --git a/distribution/bin/ldapdelete b/distribution/bin/ldapdelete new file mode 100755 index 0000000..fb67652 --- /dev/null +++ b/distribution/bin/ldapdelete
@@ -0,0 +1,27 @@ +#!/bin/sh + +JAVA=java + +# sample options for kerberos +#KRB5_OPTS="-Djava.security.auth.login.config=krb5_jaas.config -Djavax.security.auth.useSubjectCredsOnly=false -Djava.security.krb5.realm=VT.EDU -Djava.security.krb5.kdc=directory.ldaptive.org" + +#KEYSTORE_OPTS="-Djavax.net.ssl.keyStore= -Djavax.net.ssl.keyStorePassword=changeit -Djavax.net.ssl.keyStoreType=BKS" + +#TRUSTSTORE_OPTS="-Djavax.net.ssl.trustStore= -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStoreType=BKS" + +JAVA_OPTS="${JAVA_OPTS} ${KRB5_OPTS} ${KEYSTORE_OPTS} ${TRUSTSTORE_OPTS}" + +if [ "x$LDAPTIVE_HOME" = "x" ]; then + PREFIX=`dirname $0`/.. +else + PREFIX="$LDAPTIVE_HOME" +fi + +CLASSPATH="${PREFIX}/jars/ldaptive-${project.version}.jar" +for JAR in `ls ${PREFIX}/lib/*.jar` ; do + CLASSPATH=${CLASSPATH}:$JAR +done + +${JAVA} ${JAVA_OPTS} -cp ${CLASSPATH} \ + org.ldaptive.cli.DeleteOperationCli "$@" +
diff --git a/distribution/bin/ldapdelete.bat b/distribution/bin/ldapdelete.bat new file mode 100644 index 0000000..4a9cdbc --- /dev/null +++ b/distribution/bin/ldapdelete.bat
@@ -0,0 +1,24 @@ +@echo off +if "%OS%" == "Windows_NT" setlocal + +if not defined JAVA_HOME goto no_java_home +if not defined LDAPTIVE_HOME goto no_ldaptive_home + +set JAVA=%JAVA_HOME%\bin\java + +set LDAP_JAR=%LDAPTIVE_HOME%\jars\ldaptive-${project.version}.jar +set LIBDIR=%LDAPTIVE_HOME%\lib + +set CLASSPATH=%LIBDIR%\commons-cli-${commons-cli.version}.jar;%LIBDIR%\slf4j-api-${org.slf4j.version}.jar;%LDAP_JAR% + +call "%JAVA%" -cp "%CLASSPATH%" org.ldaptive.cli.DeleteOperationCli %* +goto end + +:no_ldaptive_home +echo ERROR: LDAPTIVE_HOME environment variable must be set to Ldaptive install path. +goto end + +:no_java_home +echo ERROR: JAVA_HOME environment variable must be set to JRE/JDK install path. + +:end
diff --git a/distribution/bin/ldapjaas b/distribution/bin/ldapjaas new file mode 100755 index 0000000..f0c0010 --- /dev/null +++ b/distribution/bin/ldapjaas
@@ -0,0 +1,27 @@ +#!/bin/sh + +JAVA=java + +# sample options for jaas +JAAS_OPTS="-Djava.security.auth.login.config=bin/ldap_jaas.config" + +#KEYSTORE_OPTS="-Djavax.net.ssl.keyStore= -Djavax.net.ssl.keyStorePassword=changeit -Djavax.net.ssl.keyStoreType=BKS" + +#TRUSTSTORE_OPTS="-Djavax.net.ssl.trustStore= -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStoreType=BKS" + +JAVA_OPTS="${JAVA_OPTS} ${JAAS_OPTS} ${KEYSTORE_OPTS} ${TRUSTSTORE_OPTS}" + +if [ "x$LDAPTIVE_HOME" = "x" ]; then + PREFIX=`dirname $0`/.. +else + PREFIX="$LDAPTIVE_HOME" +fi + +CLASSPATH="${PREFIX}/jars/ldaptive-${project.version}.jar" +for JAR in `ls ${PREFIX}/lib/*.jar` ; do + CLASSPATH=${CLASSPATH}:$JAR +done + +${JAVA} ${JAVA_OPTS} -cp ${CLASSPATH} \ + org.ldaptive.jaas.LdapLoginModule "$@" +
diff --git a/distribution/bin/ldapjaas.bat b/distribution/bin/ldapjaas.bat new file mode 100644 index 0000000..63ce916 --- /dev/null +++ b/distribution/bin/ldapjaas.bat
@@ -0,0 +1,26 @@ +@echo off +if "%OS%" == "Windows_NT" setlocal + +if not defined JAVA_HOME goto no_java_home +if not defined LDAPTIVE_HOME goto no_ldaptive_home + +set JAVA=%JAVA_HOME%\bin\java + +set LDAP_JAR=%LDAPTIVE_HOME%\jars\ldaptive-${project.version}.jar +set LIBDIR=%LDAPTIVE_HOME%\lib + +set JAAS_OPTS=-Djava.security.auth.login.config=%LDAPTIVE_HOME%\bin\ldap_jaas.config + +set CLASSPATH=%LIBDIR%\commons-cli-${commons-cli.version}.jar;%LIBDIR%\slf4j-api-${org.slf4j.version}.jar;%LDAP_JAR% + +call "%JAVA%" "%JAAS_OPTS%" -cp "%CLASSPATH%" org.ldaptive.jaas.LdapLoginModule %* +goto end + +:no_ldaptive_home +echo ERROR: LDAPTIVE_HOME environment variable must be set to Ldaptive install path. +goto end + +:no_java_home +echo ERROR: JAVA_HOME environment variable must be set to JRE/JDK install path. + +:end
diff --git a/distribution/bin/ldapsearch b/distribution/bin/ldapsearch new file mode 100755 index 0000000..513d48a --- /dev/null +++ b/distribution/bin/ldapsearch
@@ -0,0 +1,27 @@ +#!/bin/sh + +JAVA=java + +# sample options for kerberos +#KRB5_OPTS="-Djava.security.auth.login.config=krb5_jaas.config -Djavax.security.auth.useSubjectCredsOnly=false -Djava.security.krb5.realm=VT.EDU -Djava.security.krb5.kdc=directory.ldaptive.org" + +#KEYSTORE_OPTS="-Djavax.net.ssl.keyStore= -Djavax.net.ssl.keyStorePassword=changeit -Djavax.net.ssl.keyStoreType=BKS" + +#TRUSTSTORE_OPTS="-Djavax.net.ssl.trustStore= -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStoreType=BKS" + +JAVA_OPTS="${JAVA_OPTS} ${KRB5_OPTS} ${KEYSTORE_OPTS} ${TRUSTSTORE_OPTS}" + +if [ "x$LDAPTIVE_HOME" = "x" ]; then + PREFIX=`dirname $0`/.. +else + PREFIX="$LDAPTIVE_HOME" +fi + +CLASSPATH="${PREFIX}/jars/ldaptive-${project.version}.jar" +for JAR in `ls ${PREFIX}/lib/*.jar` ; do + CLASSPATH=${CLASSPATH}:$JAR +done + +${JAVA} ${JAVA_OPTS} -cp ${CLASSPATH} \ + org.ldaptive.cli.SearchOperationCli "$@" +
diff --git a/distribution/bin/ldapsearch.bat b/distribution/bin/ldapsearch.bat new file mode 100644 index 0000000..c54b604 --- /dev/null +++ b/distribution/bin/ldapsearch.bat
@@ -0,0 +1,24 @@ +@echo off +if "%OS%" == "Windows_NT" setlocal + +if not defined JAVA_HOME goto no_java_home +if not defined LDAPTIVE_HOME goto no_ldaptive_home + +set JAVA=%JAVA_HOME%\bin\java + +set LDAP_JAR=%LDAPTIVE_HOME%\jars\ldaptive-${project.version}.jar +set LIBDIR=%LDAPTIVE_HOME%\lib + +set CLASSPATH=%LIBDIR%\commons-cli-${commons-cli.version}.jar;%LIBDIR%\slf4j-api-${org.slf4j.version}.jar;%LDAP_JAR% + +call "%JAVA%" -cp "%CLASSPATH%" org.ldaptive.cli.SearchOperationCli %* +goto end + +:no_ldaptive_home +echo ERROR: LDAPTIVE_HOME environment variable must be set to Ldaptive install path. +goto end + +:no_java_home +echo ERROR: JAVA_HOME environment variable must be set to JRE/JDK install path. + +:end
diff --git a/distribution/pom.xml b/distribution/pom.xml new file mode 100644 index 0000000..34c004d --- /dev/null +++ b/distribution/pom.xml
@@ -0,0 +1,242 @@ +<?xml version='1.0' encoding='UTF-8'?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>ldaptive-distribution</artifactId> + <packaging>jar</packaging> + <name>LDAPTIVE DISTRIBUTION</name> + <description>Ldaptive distribution</description> + <parent> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-parent</artifactId> + <version>1.2.3</version> + </parent> + + <dependencies> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive</artifactId> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-apache</artifactId> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-apache</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-jldap</artifactId> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-jldap</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-opendj</artifactId> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-opendj</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-unboundid</artifactId> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-unboundid</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-json</artifactId> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-json</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-templates</artifactId> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-templates</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-webapp</artifactId> + <type>war</type> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-beans</artifactId> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-beans</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-ldapi</artifactId> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-ldapi</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <scope>runtime</scope> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.sun.codemodel</groupId> + <artifactId>codemodel</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>findbugs</groupId> + <artifactId>annotations</artifactId> + <version>1.0.0</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-info</id> + <phase>validate</phase> + <goals> + <goal>copy-resources</goal> + </goals> + <configuration> + <outputDirectory>${basedir}/target/package-info</outputDirectory> + <resources> + <resource> + <directory>${basedir}</directory> + <filtering>false</filtering> + <includes> + <include>README*</include> + <include>LICENSE*</include> + <include>NOTICE*</include> + </includes> + </resource> + </resources> + </configuration> + </execution> + <execution> + <id>copy-scripts</id> + <phase>validate</phase> + <goals> + <goal>copy-resources</goal> + </goals> + <configuration> + <outputDirectory>${basedir}/target/bin</outputDirectory> + <resources> + <resource> + <directory>${basedir}/bin</directory> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-src</id> + <phase>process-resources</phase> + <goals> + <goal>unpack-dependencies</goal> + </goals> + <configuration> + <includeGroupIds>org.ldaptive</includeGroupIds> + <includeClassifiers>sources</includeClassifiers> + <outputDirectory>${project.build.directory}/sources</outputDirectory> + </configuration> + </execution> + <execution> + <id>copy-depends</id> + <phase>package</phase> + <goals> + <goal>copy-dependencies</goal> + </goals> + <configuration> + <includeScope>runtime</includeScope> + <excludeArtifactIds>${project.artifactId}</excludeArtifactIds> + <outputDirectory>${basedir}/target/lib</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <attach>false</attach> + <descriptors> + <descriptor>src/main/assembly/ldaptive.xml</descriptor> + </descriptors> + <finalName>ldaptive-${project.version}</finalName> + <archiverConfig> + <defaultDirectoryMode>0755</defaultDirectoryMode> + </archiverConfig> + </configuration> + <executions> + <execution> + <id>assembly</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>com.github.siom79.japicmp</groupId> + <artifactId>japicmp-maven-plugin</artifactId> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + </plugins> + </build> +</project>
diff --git a/distribution/release b/distribution/release new file mode 100755 index 0000000..1c27a29 --- /dev/null +++ b/distribution/release
@@ -0,0 +1,135 @@ +#!/bin/sh + +function extract_from_pom { + cat pom.xml | xpath $1 2>/dev/null +} + +function read_pom() { + GROUP=$(extract_from_pom '/project/groupId/text()') + PROJECT=$(extract_from_pom '/project/artifactId/text()') + VERSION=$(extract_from_pom '/project/version/text()') +} + +function user_continue() { + read -p "Do you want to continue? [y/n]" -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi +} + +function update_pom() { + OLD_V="${1}" + NEW_V="${2}" + POMS=$(find ./ -type f -name "pom.xml") + for POM in ${POMS} + do + # this works on OSX to replace the first occurance + # may or may not work on linux + sed -i '' -e "1,/<version>${OLD_V}<\/version>/s/<version>${OLD_V}<\/version>/<version>${NEW_V}<\/version>/g" ${POM} + echo "Set version in ${POM} from ${OLD_V} to ${NEW_V}" + done +} + +if [ "$#" -ne 3 ]; then + echo "USAGE: `basename $0` <branch> <release-version> <next-version>" + exit +fi + +BRANCH="${1}" +RELEASE_VERSION="${2}" +NEXT_VERSION="${3}" +read_pom +echo "=================================================================" +echo "BEGIN RELEASE for artifact ${PROJECT} in group ${GROUP}" +echo "BRANCH TO TAG: ${BRANCH}" +echo "CURRENT VERSION: ${VERSION}" +echo "RELEASE VERSION: ${RELEASE_VERSION}" +echo "NEXT VERSION: ${NEXT_VERSION}" +echo "=================================================================" +user_continue + +# update pom to release version +./mvn_cmd clean +update_pom ${VERSION} ${RELEASE_VERSION} +echo "Updated pom to release version ${RELEASE_VERSION}" +user_continue + +# commit pom changes +git commit -a -m "Update version for ${RELEASE_VERSION} release." +git push origin ${BRANCH} + +# tag the release version +git tag -a v${RELEASE_VERSION} -m "Tagging ${RELEASE_VERSION} release." +git push origin v${RELEASE_VERSION} +echo "Tagged release ${RELEASE_VERSION}" + +# update pom to the next version +update_pom ${RELEASE_VERSION} ${NEXT_VERSION} +echo "Updated pom to next version ${NEXT_VERSION}" +user_continue + +# commit pom changes +git commit -a -m "Bump version to ${NEXT_VERSION}." +git push origin ${BRANCH} + +# checkout the release tag +git checkout v${RELEASE_VERSION} +echo "Switched to the tag version ${RELEASE_VERSION}" + +# build the release distribution +./mvn_cmd install +./mvn_cmd bundle-create +gpg --armor --detach-sign distribution/target/ldaptive-${RELEASE_VERSION}-dist.tar.gz +gpg --armor --detach-sign distribution/target/ldaptive-${RELEASE_VERSION}-dist.zip + +# update the javadocs +echo "Updating javadocs" +user_continue + +git checkout gh-pages +git pull origin gh-pages +# remove root directory javadocs +git rm -r javadocs/org javadocs/*.html javadocs/*.css javadocs/*.js javadocs/package-list +# add new javadocs to root directory +cp distribution/target/ldaptive-distribution-${RELEASE_VERSION}-javadoc.jar javadocs +pushd javadocs +jar xf ldaptive-distribution-${RELEASE_VERSION}-javadoc.jar +rm -rf META-INF ldaptive-distribution-${RELEASE_VERSION}-javadoc.jar +popd +# add new javadocs to release version directory +mkdir javadocs/${RELEASE_VERSION} +cp distribution/target/ldaptive-distribution-${RELEASE_VERSION}-javadoc.jar javadocs/${RELEASE_VERSION} +pushd javadocs/${RELEASE_VERSION} +jar xf ldaptive-distribution-${RELEASE_VERSION}-javadoc.jar +rm -rf META-INF ldaptive-distribution-${RELEASE_VERSION}-javadoc.jar +popd +git add javadocs +git commit -a -m "Updated javadocs for ${RELEASE_VERSION} release." +echo "Committed new javadocs" + +# update the spring ext schema +echo "Updating schema" +user_continue + +cp beans/target/classes/org/ldaptive/beans/spring/spring-ext.xsd schema/spring-ext.xsd +cp beans/target/classes/org/ldaptive/beans/spring/spring-ext.xsd schema/spring-ext-${RELEASE_VERSION}.xsd +git add schema +git commit -a -m "Updated schema for ${RELEASE_VERSION} release." +echo "Committed new schema" + +# add new binaries +echo "Adding release binaries" +user_continue + +mkdir downloads/${RELEASE_VERSION} +cp distribution/target/ldaptive-${RELEASE_VERSION}-dist* downloads/${RELEASE_VERSION} +git add downloads/${RELEASE_VERSION} +git commit -a -m "Added binaries for ${RELEASE_VERSION} release." +echo "Committed new release binaries" + +# push changes to the server +git push origin gh-pages + +echo "Finished release ${RELEASE_VERSION} for ${PROJECT}" +
diff --git a/distribution/src/main/assembly/ldaptive.xml b/distribution/src/main/assembly/ldaptive.xml new file mode 100644 index 0000000..92a884d --- /dev/null +++ b/distribution/src/main/assembly/ldaptive.xml
@@ -0,0 +1,75 @@ +<?xml version='1.0' encoding='UTF-8'?> +<assembly> + <id>dist</id> + <formats> + <format>tar.gz</format> + <format>zip</format> + </formats> + <dependencySets> + <dependencySet> + <useProjectArtifact>false</useProjectArtifact> + <outputDirectory>jars</outputDirectory> + <useTransitiveDependencies>false</useTransitiveDependencies> + <includes> + <include>org.ldaptive:*:jar</include> + </includes> + <excludes> + <exclude>org.ldaptive:*:jar:sources</exclude> + </excludes> + </dependencySet> + <dependencySet> + <useProjectArtifact>false</useProjectArtifact> + <outputDirectory>wars</outputDirectory> + <useTransitiveDependencies>false</useTransitiveDependencies> + <includes> + <include>org.ldaptive:*:war</include> + </includes> + </dependencySet> + <dependencySet> + <useProjectArtifact>false</useProjectArtifact> + <outputDirectory>sources</outputDirectory> + <useTransitiveDependencies>false</useTransitiveDependencies> + <includes> + <include>org.ldaptive:*:jar:sources</include> + </includes> + </dependencySet> + </dependencySets> + <fileSets> + <fileSet> + <directory>target/package-info</directory> + <outputDirectory>/</outputDirectory> + <includes> + <include>**</include> + </includes> + <useDefaultExcludes>true</useDefaultExcludes> + </fileSet> + <fileSet> + <directory>target/bin</directory> + <outputDirectory>bin</outputDirectory> + <useDefaultExcludes>true</useDefaultExcludes> + <includes> + <include>*.bat</include> + <include>*.config</include> + </includes> + </fileSet> + <fileSet> + <directory>target/bin</directory> + <outputDirectory>bin</outputDirectory> + <fileMode>0755</fileMode> + <useDefaultExcludes>true</useDefaultExcludes> + <excludes> + <exclude>*.bat</exclude> + <exclude>*.config</exclude> + </excludes> + </fileSet> + <fileSet> + <directory>target/lib</directory> + <outputDirectory>lib</outputDirectory> + <useDefaultExcludes>true</useDefaultExcludes> + <includes> + <include>commons-cli-*</include> + <include>slf4j-api-*</include> + </includes> + </fileSet> + </fileSets> +</assembly>
diff --git a/integration/pom.xml b/integration/pom.xml new file mode 100644 index 0000000..e00555b --- /dev/null +++ b/integration/pom.xml
@@ -0,0 +1,314 @@ +<?xml version='1.0' encoding='UTF-8'?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>ldaptive-integration</artifactId> + <packaging>jar</packaging> + <name>LDAPTIVE INTEGRATION TESTS</name> + <description>Ldaptive server integration tests</description> + <parent> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-parent</artifactId> + <version>1.2.3</version> + </parent> + + <properties> + <ldapTestProvider>org.ldaptive.provider.jndi.JndiProvider</ldapTestProvider> + </properties> + + <dependencies> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-templates</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-beans</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.sun.codemodel</groupId> + <artifactId>codemodel</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.bouncycastle</groupId> + <artifactId>bcprov-jdk15on</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>httpunit</groupId> + <artifactId>httpunit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.velocity</groupId> + <artifactId>velocity</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-expression</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <testResources> + <testResource> + <directory>src/test/resources</directory> + <filtering>true</filtering> + <includes> + <include>**/*.config</include> + <include>**/*.ldif</include> + <include>**/*.dsmlv1</include> + <include>**/*.xml</include> + <include>**/*.properties</include> + <include>**/*.credential</include> + </includes> + </testResource> + <testResource> + <directory>src/test/resources</directory> + <filtering>false</filtering> + <includes> + <include>**/*.keytab</include> + <include>**/*.keystore</include> + <include>**/*.truststore</include> + <include>**/*.crt</include> + <include>**/*.jpg</include> + </includes> + </testResource> + </testResources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-enforcer-plugin</artifactId> + <executions> + <execution> + <id>enforce-has-env</id> + <goals> + <goal>enforce</goal> + </goals> + <configuration> + <rules> + <requireProperty> + <property>ldapTestHost</property> + </requireProperty> + <requireProperty> + <property>ldapSslTestHost</property> + </requireProperty> + <requireProperty> + <property>ldapBaseDn</property> + </requireProperty> + <requireProperty> + <property>ldapBindDn</property> + </requireProperty> + <requireProperty> + <property>ldapBindCredential</property> + </requireProperty> + <requireProperty> + <property>ldapTestGroup</property> + </requireProperty> + </rules> + <fail>true</fail> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-testng</id> + <phase>validate</phase> + <goals> + <goal>copy-resources</goal> + </goals> + <configuration> + <outputDirectory>${project.build.directory}/test-classes</outputDirectory> + <resources> + <resource> + <directory>${basedir}/src/test/testng</directory> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <argLine>-Dorg.ldaptive.provider=${ldapTestProvider} -Xms1g -Xmx2g</argLine> + <suiteXmlFiles> + <suiteXmlFile>${project.build.directory}/test-classes/testng.xml</suiteXmlFile> + </suiteXmlFiles> + <!-- sometimes useful if testng runs out of memory + <disableXmlReport>true</disableXmlReport> + --> + <systemProperties> + <property> + <name>log4j.configuration</name> + <value>log4j.xml</value> + </property> + </systemProperties> + </configuration> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <executions> + <execution> + <phase>test</phase> + <goals> + <goal>java</goal> + </goals> + <configuration> + <classpathScope>test</classpathScope> + <mainClass>org.ldaptive.doc.ClassGenerator</mainClass> + <arguments> + <argument>https://github.com/vt-middleware/ldaptive/blob/gh-pages/_includes/source/source.zip?raw=true</argument> + <argument>${project.build.directory}</argument> + </arguments> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>add-test-source</id> + <goals> + <goal>add-test-source</goal> + </goals> + <phase>pre-integration-test</phase> + <configuration> + <sources> + <source>${project.build.directory}/generated-test-sources/ldaptive</source> + <source>${project.build.directory}/generated-test-sources/ldaptive-docs</source> + </sources> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <fork>true</fork> + <debug>true</debug> + <showDeprecation>true</showDeprecation> + <showWarnings>true</showWarnings> + <compilerArgument>-Xlint:unchecked</compilerArgument> + <source>1.8</source> + <target>1.8</target> + </configuration> + <executions> + <execution> + <phase>integration-test</phase> + <goals> + <goal>testCompile</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>com.github.siom79.japicmp</groupId> + <artifactId>japicmp-maven-plugin</artifactId> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + </plugins> + </build> + <profiles> + <profile> + <id>apache</id> + <dependencies> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-apache</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + <properties> + <ldapTestProvider>org.ldaptive.provider.apache.ApacheLdapProvider</ldapTestProvider> + </properties> + </profile> + <profile> + <id>jldap</id> + <dependencies> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-jldap</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + <properties> + <ldapTestProvider>org.ldaptive.provider.jldap.JLdapProvider</ldapTestProvider> + </properties> + </profile> + <profile> + <id>opendj</id> + <dependencies> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-opendj</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + <properties> + <ldapTestProvider>org.ldaptive.provider.opendj.OpenDJProvider</ldapTestProvider> + </properties> + </profile> + <profile> + <id>unboundid</id> + <dependencies> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-unboundid</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + <properties> + <ldapTestProvider>org.ldaptive.provider.unboundid.UnboundIDProvider</ldapTestProvider> + </properties> + </profile> + </profiles> +</project>
diff --git a/integration/run b/integration/run new file mode 100755 index 0000000..0cf28bb --- /dev/null +++ b/integration/run
@@ -0,0 +1,47 @@ +#!/bin/sh + +TEST_GROUP=core +#TEST_GROUP=pool +#TEST_GROUP=core-sysprops +while [ $# -gt 0 ] +do + case "$1" in + -host) + shift + HOST=$1;; + -baseDn) + shift + BASE_DN=$1;; + -bindDn) + shift + BIND_DN=$1;; + -bindCredential) + shift + BIND_CREDENTIAL=$1;; + -group) + shift + TEST_GROUP=$1;; + -provider) + shift + PROVIDER=$1;; + esac + shift +done +SSL_HOST=`echo ${HOST} |sed 's/389/636/'` + +MVN_CMD="clean verify" +if [ ! -z "${PROVIDER}" ]; then + MVN_CMD="-Pintegration,${PROVIDER} ${MVN_CMD}" +else + MVN_CMD="-Pintegration ${MVN_CMD}" +fi + +mvn \ + -DldapTestHost=ldap://${HOST} \ + -DldapSslTestHost=ldap://${SSL_HOST} \ + -DldapBaseDn="${BASE_DN}" \ + -DldapBindDn="${BIND_DN}" \ + -DldapBindCredential="${BIND_CREDENTIAL}" \ + -DldapTestGroup=${TEST_GROUP} \ + ${MVN_CMD} +
diff --git a/integration/src/test/java/org/ldaptive/AbstractTest.java b/integration/src/test/java/org/ldaptive/AbstractTest.java new file mode 100644 index 0000000..e07d07c --- /dev/null +++ b/integration/src/test/java/org/ldaptive/AbstractTest.java
@@ -0,0 +1,118 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.security.Security; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.ldaptive.ad.UnicodePwdAttribute; + +/** + * Contains functions common to all tests. + * + * @author Middleware Services + */ +public abstract class AbstractTest +{ + + /** Number of threads for threaded tests. */ + public static final int TEST_THREAD_POOL_SIZE = 2; + + /** Invocation count for threaded tests. */ + public static final int TEST_INVOCATION_COUNT = 10; + + /** Timeout for threaded tests. */ + public static final int TEST_TIME_OUT = 60000; + + /** + * Add the BC provider. + */ + static { + Security.addProvider(new BouncyCastleProvider()); + } + + + /** + * Creates the supplied ldap entry and confirms it exists in the ldap. + * + * @param entry to create. + * + * @throws Exception On failure. + */ + public void createLdapEntry(final LdapEntry entry) + throws Exception + { + try (Connection conn = TestUtils.createSetupConnection()) { + conn.open(); + + final AddOperation create = new AddOperation(conn); + create.execute(new AddRequest(entry.getDn(), entry.getAttributes())); + if (!entryExists(conn, entry)) { + throw new IllegalStateException("Could not add entry to LDAP"); + } + if (TestControl.isActiveDirectory() && entry.getAttribute("userPassword") != null) { + final ModifyOperation modify = new ModifyOperation(conn); + modify.execute( + new ModifyRequest( + entry.getDn(), + new AttributeModification( + AttributeModificationType.REPLACE, + new UnicodePwdAttribute("password" + entry.getAttribute("uid").getStringValue())), + new AttributeModification( + AttributeModificationType.REPLACE, + new LdapAttribute("userAccountControl", "512")))); + } + } catch (LdapException e) { + // ignore entry already exists + if (ResultCode.ENTRY_ALREADY_EXISTS != e.getResultCode()) { + throw e; + } + } + } + + + /** + * Deletes the supplied dn if it exists. + * + * @param dn to delete + * + * @throws Exception On failure. + */ + public void deleteLdapEntry(final String dn) + throws Exception + { + try (Connection conn = TestUtils.createSetupConnection()) { + conn.open(); + if (entryExists(conn, new LdapEntry(dn))) { + final DeleteOperation delete = new DeleteOperation(conn); + delete.execute(new DeleteRequest(dn)); + } + } + } + + + /** + * Performs a compare on the supplied entry to determine if it exists in the LDAP. + * + * @param conn to perform compare with + * @param entry to perform compare on + * + * @return whether the supplied entry exists + * + * @throws Exception On failure. + */ + protected boolean entryExists(final Connection conn, final LdapEntry entry) + throws Exception + { + final CompareOperation compare = new CompareOperation(conn); + final LdapAttribute la = new LdapAttribute(); + la.setName("CN"); + la.addStringValue(DnParser.getValue(entry.getDn(), "CN")); + try { + return compare.execute(new CompareRequest(entry.getDn(), la)).getResult(); + } catch (LdapException e) { + if (ResultCode.NO_SUCH_OBJECT == e.getResultCode()) { + return false; + } + throw e; + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/BindOperationTest.java b/integration/src/test/java/org/ldaptive/BindOperationTest.java new file mode 100644 index 0000000..60a9afd --- /dev/null +++ b/integration/src/test/java/org/ldaptive/BindOperationTest.java
@@ -0,0 +1,161 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.ldaptive.control.AuthorizationIdentityRequestControl; +import org.ldaptive.control.AuthorizationIdentityResponseControl; +import org.ldaptive.control.SessionTrackingControl; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link BindOperation}. + * + * @author Middleware Services + */ +public class BindOperationTest extends AbstractTest +{ + + /** Entry created for ldap tests. */ + private static LdapEntry testLdapEntry; + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry32") + @BeforeClass(groups = {"bind"}) + public void createLdapEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"bind"}) + public void deleteLdapEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + } + + + /** + * @param dn to bind as. + * + * @throws Exception On test failure. + */ + @Parameters("bindDn") + @Test(groups = {"bind"}) + public void bindFailure(final String dn) + throws Exception + { + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final BindOperation bind = new BindOperation(conn); + final Response<Void> response = bind.execute(new BindRequest(dn, new Credential("INVALID-PASSWD"))); + AssertJUnit.assertEquals(ResultCode.INVALID_CREDENTIALS, response.getResultCode()); + } catch (LdapException e) { + AssertJUnit.assertEquals(ResultCode.INVALID_CREDENTIALS, e.getResultCode()); + } + } + + + /** + * @param dn to bind as. + * @param passwd to bind with. + * + * @throws Exception On test failure. + */ + @Parameters({ "bindDn", "bindPasswd" }) + @Test(groups = {"bind"}) + public void bindSuccess(final String dn, final String passwd) + throws Exception + { + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final BindOperation bind = new BindOperation(conn); + final Response<Void> response = bind.execute(new BindRequest(dn, new Credential(passwd))); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + } + } + + + /** + * @param dn to bind as. + * @param passwd to bind with. + * + * @throws Exception On test failure. + */ + @Parameters({ "bindDn", "bindPasswd" }) + @Test(groups = {"bind"}) + public void bindIdentityControl(final String dn, final String passwd) + throws Exception + { + // provider doesn't support this control + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP does not support this control"); + } + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final BindOperation bind = new BindOperation(conn); + final BindRequest request = new BindRequest(dn, new Credential(passwd)); + request.setControls(new AuthorizationIdentityRequestControl()); + + final Response<Void> response = bind.execute(request); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + + final AuthorizationIdentityResponseControl ctrl = (AuthorizationIdentityResponseControl) response.getControl( + AuthorizationIdentityResponseControl.OID); + if (ctrl == null) { + throw new UnsupportedOperationException("Authorization Identity Control not supported"); + } + AssertJUnit.assertEquals("dn:" + dn.toLowerCase(), ctrl.getAuthorizationId().toLowerCase()); + } + } + + + /** + * @param dn to bind as. + * @param passwd to bind with. + * + * @throws Exception On test failure. + */ + @Parameters({ "bindDn", "bindPasswd" }) + @Test(groups = {"bind"}) + public void bindSessionTrackingControl(final String dn, final String passwd) + throws Exception + { + // provider doesn't support this control + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP does not support this control"); + } + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final BindOperation bind = new BindOperation(conn); + final BindRequest request = new BindRequest(dn, new Credential(passwd)); + request.setControls( + new SessionTrackingControl( + "151.101.32.133", + "www.ldaptive.org", + SessionTrackingControl.USERNAME_ACCT_OID, + "")); + + final Response<Void> response = bind.execute(request); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/CompareOperationTest.java b/integration/src/test/java/org/ldaptive/CompareOperationTest.java new file mode 100644 index 0000000..496ddfb --- /dev/null +++ b/integration/src/test/java/org/ldaptive/CompareOperationTest.java
@@ -0,0 +1,149 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.ldaptive.referral.CompareReferralHandler; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link CompareOperation}. + * + * @author Middleware Services + */ +public class CompareOperationTest extends AbstractTest +{ + + /** Entry created for ldap tests. */ + private static LdapEntry testLdapEntry; + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry3") + @BeforeClass(groups = {"compare"}) + public void createLdapEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"compare"}) + public void deleteLdapEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + } + + + /** + * @param dn to compare. + * @param attrName to compare with. + * @param attrValue to compare with. + * + * @throws Exception On test failure. + */ + @Parameters({ "compareDn", "compareAttrName", "compareAttrValue" }) + @Test( + groups = {"compare"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void compare(final String dn, final String attrName, final String attrValue) + throws Exception + { + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final CompareOperation compare = new CompareOperation(conn); + LdapAttribute la = new LdapAttribute(); + la.setName("cn"); + la.addStringValue("not-a-name"); + AssertJUnit.assertFalse(compare.execute(new CompareRequest(dn, la)).getResult()); + + la = new LdapAttribute(); + la.setName(attrName); + la.addStringValue(attrValue); + AssertJUnit.assertTrue(compare.execute(new CompareRequest(dn, la)).getResult()); + } + } + + + /** + * @param dn to compare. + * @param attrName to compare with. + * @param attrValue to compare with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "compareReferralDn", + "compareReferralAttrName", + "compareReferralAttrValue" + }) + @Test(groups = {"compare"}) + public void compareReferral(final String dn, final String attrName, final String attrValue) + throws Exception + { + if (TestControl.isActiveDirectory()) { + return; + } + + // expects a referral on the dn ou=referrals + final String referralDn = "ou=referrals," + DnParser.substring(dn, 1); + final Connection conn = TestUtils.createConnection(); + try { + conn.open(); + + final CompareOperation compare = new CompareOperation(conn); + try { + final CompareRequest request = new CompareRequest(referralDn, new LdapAttribute(attrName, attrValue)); + final Response<Boolean> response = compare.execute(request); + AssertJUnit.assertEquals(ResultCode.REFERRAL, response.getResultCode()); + AssertJUnit.assertTrue(response.getReferralURLs().length > 0); + for (String s : response.getReferralURLs()) { + AssertJUnit.assertTrue(response.getReferralURLs()[0].startsWith(conn.getConnectionConfig().getLdapUrl())); + } + } catch (LdapException e) { + AssertJUnit.assertEquals(ResultCode.REFERRAL, e.getResultCode()); + AssertJUnit.assertTrue(e.getReferralURLs().length > 0); + for (String s : e.getReferralURLs()) { + AssertJUnit.assertTrue(e.getReferralURLs()[0].startsWith(conn.getConnectionConfig().getLdapUrl())); + } + } + } finally { + conn.close(); + } + + try { + conn.open(); + + final CompareOperation compare = new CompareOperation(conn); + try { + final CompareRequest request = new CompareRequest(referralDn, new LdapAttribute(attrName, attrValue)); + request.setReferralHandler(new CompareReferralHandler()); + + final Response<Boolean> response = compare.execute(request); + if (response.getResultCode() == ResultCode.COMPARE_TRUE) { + AssertJUnit.assertTrue(response.getResult()); + } else { + // some providers don't support authenticated referrals + AssertJUnit.assertEquals(ResultCode.REFERRAL, response.getResultCode()); + } + } catch (UnsupportedOperationException e) { + // ignore this test if not supported + AssertJUnit.assertNotNull(e); + } + } finally { + conn.close(); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/ConnectionTest.java b/integration/src/test/java/org/ldaptive/ConnectionTest.java new file mode 100644 index 0000000..ce6e87f --- /dev/null +++ b/integration/src/test/java/org/ldaptive/ConnectionTest.java
@@ -0,0 +1,246 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterSuite; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link Connection}. + * + * @author Middleware Services + */ +public class ConnectionTest +{ + + /** Entry created for ldap tests. */ + private static LdapEntry testLdapEntry; + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry15") + @BeforeClass(groups = {"conn"}) + public void add(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final AddOperation add = new AddOperation(conn); + final Response<Void> response = add.execute(new AddRequest(testLdapEntry.getDn(), testLdapEntry.getAttributes())); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + } + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"conn"}) + public void compare() + throws Exception + { + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final CompareOperation compare = new CompareOperation(conn); + AssertJUnit.assertTrue( + compare.execute(new CompareRequest(testLdapEntry.getDn(), testLdapEntry.getAttribute("mail"))).getResult()); + } + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"conn"}) + public void delete() + throws Exception + { + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final DeleteOperation delete = new DeleteOperation(conn); + final Response<Void> response = delete.execute(new DeleteRequest(testLdapEntry.getDn())); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + } + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"conn"}) + public void modify() + throws Exception + { + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final ModifyOperation modify = new ModifyOperation(conn); + final Response<Void> response = modify.execute( + new ModifyRequest( + testLdapEntry.getDn(), + new AttributeModification(AttributeModificationType.ADD, new LdapAttribute("title", "President")))); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + } + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"conn"}) + public void modifyDn() + throws Exception + { + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final ModifyDnOperation modifyDn = new ModifyDnOperation(conn); + Response<Void> response = modifyDn.execute( + new ModifyDnRequest( + testLdapEntry.getDn(), + "cn=James Buchanan Jr.," + DnParser.substring(testLdapEntry.getDn(), 1))); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + response = modifyDn.execute( + new ModifyDnRequest( + "cn=James Buchanan Jr.," + DnParser.substring(testLdapEntry.getDn(), 1), + testLdapEntry.getDn())); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + } + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"conn"}) + public void search() + throws Exception + { + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final SearchResult lr = search.execute( + new SearchRequest(DnParser.substring(testLdapEntry.getDn(), 1), new SearchFilter("(uid=15)"))).getResult(); + AssertJUnit.assertEquals(testLdapEntry.getDn().toLowerCase(), lr.getEntry().getDn().toLowerCase()); + } + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"conn"}) + public void strategyConnect() + throws Exception + { + ConnectionConfig cc = TestUtils.readConnectionConfig("classpath:/org/ldaptive/ldap.conn.properties"); + cc.setConnectionStrategy(new RoundRobinConnectionStrategy()); + DefaultConnectionFactory connFactory = new DefaultConnectionFactory(cc); + + Connection conn = connFactory.getConnection(); + + try { + conn.open(); + } finally { + conn.close(); + } + try { + conn.open(); + } finally { + conn.close(); + } + try { + conn.open(); + } finally { + conn.close(); + } + + cc = TestUtils.readConnectionConfig("classpath:/org/ldaptive/ldap.conn.properties"); + cc.setConnectionStrategy(new DefaultConnectionStrategy()); + connFactory = new DefaultConnectionFactory(cc); + conn = connFactory.getConnection(); + try { + conn.open(); + } finally { + conn.close(); + } + try { + conn.open(); + } finally { + conn.close(); + } + try { + conn.open(); + } finally { + conn.close(); + } + + cc = TestUtils.readConnectionConfig("classpath:/org/ldaptive/ldap.conn.properties"); + cc.setConnectionStrategy(new ActivePassiveConnectionStrategy()); + connFactory = new DefaultConnectionFactory(cc); + conn = connFactory.getConnection(); + try { + conn.open(); + } finally { + conn.close(); + } + try { + conn.open(); + } finally { + conn.close(); + } + try { + conn.open(); + } finally { + conn.close(); + } + + cc = TestUtils.readConnectionConfig("classpath:/org/ldaptive/ldap.conn.properties"); + cc.setConnectionStrategy(new RandomConnectionStrategy()); + connFactory = new DefaultConnectionFactory(cc); + conn = connFactory.getConnection(); + try { + conn.open(); + } finally { + conn.close(); + } + try { + conn.open(); + } finally { + conn.close(); + } + try { + conn.open(); + } finally { + conn.close(); + } + } + + + /** + * Sleeps at the end of all tests and checks open connections. + * + * @param host to check for connections with. + * @param sleepTime time to sleep for. + * + * @throws Exception On test failure. + */ + @Parameters({ "ldapTestHost", "sleepTime" }) + @AfterSuite(groups = {"conn"}) + public void sleep(final String host, final int sleepTime) + throws Exception + { + Thread.sleep(sleepTime); + + /* + * -- expected open connections -- + * SearchOperationTest: 1 + */ + final LdapURL ldapUrl = new LdapURL(host); + final int openConns = TestUtils.countOpenConnections( + ldapUrl.getEntry().getHostname().substring(0, ldapUrl.getEntry().getHostname().indexOf("."))); + AssertJUnit.assertEquals(1, openConns); + } +}
diff --git a/integration/src/test/java/org/ldaptive/LdapAttributeIgnoreCaseComparator.java b/integration/src/test/java/org/ldaptive/LdapAttributeIgnoreCaseComparator.java new file mode 100644 index 0000000..95c1340 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/LdapAttributeIgnoreCaseComparator.java
@@ -0,0 +1,95 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Comparator; +import org.ldaptive.io.ValueTranscoder; + +/** + * Compares two ldap attributes, ignoring the case of all attribute values. + * + * @author Middleware Services + */ +public class LdapAttributeIgnoreCaseComparator implements Comparator<LdapAttribute> +{ + + /** for lower casing values. */ + private static final LowerCaseValueTranscoder TRANSCODER = new LowerCaseValueTranscoder(); + + + /** + * Compares two ldap attributes, ignoring the case of their values. + * + * @param a first attribute for the comparison + * @param b second attribute for the comparison + * + * @return a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater + * than the second. + */ + public int compare(final LdapAttribute a, final LdapAttribute b) + { + return lowerCaseAttribute(a).hashCode() - lowerCaseAttribute(b).hashCode(); + } + + + /** + * Returns a new ldap attribute whose values have been lower cased. + * + * @param la attribute to copy values from + * + * @return ldap attribute with lower cased values + * + * @throws IllegalArgumentException if a binary attribute is supplied + */ + public static LdapAttribute lowerCaseAttribute(final LdapAttribute la) + { + try { + final LdapAttribute lowerCase = new LdapAttribute(la.getSortBehavior()); + lowerCase.setName(la.getName()); + lowerCase.addStringValues(la.getValues(TRANSCODER)); + return lowerCase; + } catch (UnsupportedOperationException e) { + throw new IllegalArgumentException(e); + } + } + + + /** Decodes and encodes a string by invoking {@link String#toLowerCase()}. */ + private static class LowerCaseValueTranscoder implements ValueTranscoder<String> + { + + + @Override + public String decodeStringValue(final String value) + { + return value.toLowerCase(); + } + + + @Override + public String decodeBinaryValue(final byte[] value) + { + throw new UnsupportedOperationException("Binary values cannot be lower cased"); + } + + + @Override + public String encodeStringValue(final String value) + { + return value.toLowerCase(); + } + + + @Override + public byte[] encodeBinaryValue(final String value) + { + throw new UnsupportedOperationException("Binary values cannot be lower cased"); + } + + + @Override + public Class<String> getType() + { + return String.class; + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/LdapEntryIgnoreCaseComparator.java b/integration/src/test/java/org/ldaptive/LdapEntryIgnoreCaseComparator.java new file mode 100644 index 0000000..12c1ecd --- /dev/null +++ b/integration/src/test/java/org/ldaptive/LdapEntryIgnoreCaseComparator.java
@@ -0,0 +1,85 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Comparator; + +/** + * Compares two ldap entries, ignoring the case of supplied attribute values. + * + * @author Middleware Services + */ +public class LdapEntryIgnoreCaseComparator implements Comparator<LdapEntry> +{ + + /** names of attributes to ignore the case of. */ + private final String[] attributeNames; + + + /** Creates a new ldap entry ignore case comparator that will ignore the case of all attribute values. */ + public LdapEntryIgnoreCaseComparator() + { + this((String[]) null); + } + + + /** + * Creates a new ldap entry ignore case comparator with the supplied names. If names is null all attributes will be + * case ignored. + * + * @param names of attributes whose case should be ignored + */ + public LdapEntryIgnoreCaseComparator(final String... names) + { + attributeNames = names; + } + + + /** + * Compares two ldap entries. + * + * @param a first entry for the comparison + * @param b second entry for the comparison + * + * @return a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater + * than the second. + */ + public int compare(final LdapEntry a, final LdapEntry b) + { + return lowerCaseEntry(a, attributeNames).hashCode() - lowerCaseEntry(b, attributeNames).hashCode(); + } + + + /** + * Returns a new ldap entry whose attribute values have been lower cased as configured. + * + * @param le entry to copy values from + * @param names of attributes whose case should be ignored + * + * @return ldap entry with lower cased attribute values + * + * @throws IllegalArgumentException if a binary attribute is lower cased + */ + public static LdapEntry lowerCaseEntry(final LdapEntry le, final String... names) + { + final LdapEntry lowerCase = new LdapEntry(le.getSortBehavior()); + lowerCase.setDn(le.getDn()); + for (LdapAttribute la : le.getAttributes()) { + if (names != null) { + boolean setAttr = false; + for (String name : names) { + if (name.equalsIgnoreCase(la.getName())) { + lowerCase.addAttribute(LdapAttributeIgnoreCaseComparator.lowerCaseAttribute(la)); + setAttr = true; + break; + } + } + if (!setAttr) { + lowerCase.addAttribute(la); + } + } else { + lowerCase.addAttribute(LdapAttributeIgnoreCaseComparator.lowerCaseAttribute(la)); + } + } + return lowerCase; + } +}
diff --git a/integration/src/test/java/org/ldaptive/ModifyDnOperationTest.java b/integration/src/test/java/org/ldaptive/ModifyDnOperationTest.java new file mode 100644 index 0000000..435f374 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/ModifyDnOperationTest.java
@@ -0,0 +1,96 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link ModifyDnOperation}. + * + * @author Middleware Services + */ +public class ModifyDnOperationTest extends AbstractTest +{ + + /** Entry created for ldap tests. */ + private static LdapEntry testLdapEntry; + + /** Entry created for ldap tests. */ + private static LdapEntry modifyDnLdapEntry; + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry5") + @BeforeClass(groups = {"modifyDn"}) + public void createLdapEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"modifyDn"}) + public void deleteLdapEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + if (modifyDnLdapEntry != null) { + super.deleteLdapEntry(modifyDnLdapEntry.getDn()); + } + } + + + /** + * @param oldDn to rename. + * @param newDn to rename to. + * + * @throws Exception On test failure. + */ + @Parameters({ "modifyOldDn", "modifyNewDn" }) + @Test(groups = {"modifyDn"}) + public void modifyDnLdapEntry(final String oldDn, final String newDn) + throws Exception + { + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + AssertJUnit.assertTrue(search.execute(SearchRequest.newObjectScopeSearchRequest(oldDn)).getResult().size() > 0); + + final ModifyDnOperation modifyDn = new ModifyDnOperation(conn); + Response<Void> response = modifyDn.execute(new ModifyDnRequest(oldDn, newDn)); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + modifyDnLdapEntry = search.execute(SearchRequest.newObjectScopeSearchRequest(newDn)).getResult().getEntry(); + AssertJUnit.assertNotNull(modifyDnLdapEntry); + try { + final Response<SearchResult> r = search.execute(SearchRequest.newObjectScopeSearchRequest(oldDn)); + AssertJUnit.assertEquals(ResultCode.NO_SUCH_OBJECT, r.getResultCode()); + } catch (LdapException e) { + AssertJUnit.assertEquals(ResultCode.NO_SUCH_OBJECT, e.getResultCode()); + } catch (Exception e) { + AssertJUnit.fail("Should have thrown LdapException, threw " + e); + } + response = modifyDn.execute(new ModifyDnRequest(newDn, oldDn)); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertTrue(search.execute(SearchRequest.newObjectScopeSearchRequest(oldDn)).getResult().size() > 0); + try { + final Response<SearchResult> r = search.execute(SearchRequest.newObjectScopeSearchRequest(newDn)); + AssertJUnit.assertEquals(ResultCode.NO_SUCH_OBJECT, r.getResultCode()); + } catch (LdapException e) { + AssertJUnit.assertEquals(ResultCode.NO_SUCH_OBJECT, e.getResultCode()); + } catch (Exception e) { + AssertJUnit.fail("Should have thrown LdapException, threw " + e); + } + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/ModifyOperationTest.java b/integration/src/test/java/org/ldaptive/ModifyOperationTest.java new file mode 100644 index 0000000..3f87c7a --- /dev/null +++ b/integration/src/test/java/org/ldaptive/ModifyOperationTest.java
@@ -0,0 +1,228 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link ModifyOperation}. + * + * @author Middleware Services + */ +public class ModifyOperationTest extends AbstractTest +{ + + /** Entry created for ldap tests. */ + private static LdapEntry testLdapEntry; + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry4") + @BeforeClass(groups = {"modify"}) + public void createLdapEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"modify"}) + public void deleteLdapEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + } + + + /** + * @param dn to modify. + * @param attrs to add. + * + * @throws Exception On test failure. + */ + @Parameters({ "addAttributeDn", "addAttributeAttribute" }) + @Test(groups = {"modify"}) + public void addAttribute(final String dn, final String attrs) + throws Exception + { + final LdapEntry expected = TestUtils.convertStringToEntry(dn, attrs); + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final ModifyOperation modify = new ModifyOperation(conn); + modify.execute( + new ModifyRequest(dn, new AttributeModification(AttributeModificationType.ADD, expected.getAttribute()))); + + final SearchOperation search = new SearchOperation(conn); + final SearchResult result = search.execute( + SearchRequest.newObjectScopeSearchRequest(dn, new String[] {expected.getAttribute().getName()})).getResult(); + AssertJUnit.assertEquals(expected.getAttribute(), result.getEntry().getAttribute()); + } + } + + + /** + * @param dn to modify. + * @param attrs to add. + * + * @throws Exception On test failure. + */ + @Parameters({ "addAttributesDn", "addAttributesAttributes" }) + @Test(groups = {"modify"}) + public void addAttributes(final String dn, final String attrs) + throws Exception + { + final LdapEntry expected = TestUtils.convertStringToEntry(dn, attrs); + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final ModifyOperation modify = new ModifyOperation(conn); + final AttributeModification[] mods = new AttributeModification[expected.size()]; + int i = 0; + for (LdapAttribute la : expected.getAttributes()) { + mods[i] = new AttributeModification(AttributeModificationType.ADD, la); + i++; + } + modify.execute(new ModifyRequest(dn, mods)); + + final SearchOperation search = new SearchOperation(conn); + final SearchResult result = search.execute( + SearchRequest.newObjectScopeSearchRequest(dn, expected.getAttributeNames())).getResult(); + TestUtils.assertEquals(expected, result.getEntry()); + } + } + + + /** + * @param dn to modify. + * @param attrs to replace. + * + * @throws Exception On test failure. + */ + @Parameters({ "replaceAttributeDn", "replaceAttributeAttribute" }) + @Test(groups = {"modify"}, dependsOnMethods = {"addAttribute"}) + public void replaceAttribute(final String dn, final String attrs) + throws Exception + { + final LdapEntry expected = TestUtils.convertStringToEntry(dn, attrs); + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final ModifyOperation modify = new ModifyOperation(conn); + modify.execute( + new ModifyRequest(dn, new AttributeModification(AttributeModificationType.REPLACE, expected.getAttribute()))); + + final SearchOperation search = new SearchOperation(conn); + final SearchResult result = search.execute( + SearchRequest.newObjectScopeSearchRequest(dn, new String[] {expected.getAttribute().getName()})).getResult(); + TestUtils.assertEquals(expected, result.getEntry()); + } + } + + + /** + * @param dn to modify. + * @param attrs to replace. + * + * @throws Exception On test failure. + */ + @Parameters({ "replaceAttributesDn", "replaceAttributesAttributes" }) + @Test(groups = {"modify"}, dependsOnMethods = {"addAttributes"}) + public void replaceAttributes(final String dn, final String attrs) + throws Exception + { + final LdapEntry expected = TestUtils.convertStringToEntry(dn, attrs); + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final ModifyOperation modify = new ModifyOperation(conn); + final AttributeModification[] mods = new AttributeModification[expected.size()]; + int i = 0; + for (LdapAttribute la : expected.getAttributes()) { + mods[i] = new AttributeModification(AttributeModificationType.REPLACE, la); + i++; + } + modify.execute(new ModifyRequest(dn, mods)); + + final SearchOperation search = new SearchOperation(conn); + final SearchResult result = search.execute( + SearchRequest.newObjectScopeSearchRequest(dn, expected.getAttributeNames())).getResult(); + TestUtils.assertEquals(expected, result.getEntry()); + } + } + + + /** + * @param dn to modify. + * @param attrs to remove. + * + * @throws Exception On test failure. + */ + @Parameters({ "removeAttributeDn", "removeAttributeAttribute" }) + @Test(groups = {"modify"}, dependsOnMethods = {"replaceAttribute"}) + public void removeAttribute(final String dn, final String attrs) + throws Exception + { + final LdapEntry expected = TestUtils.convertStringToEntry(dn, attrs); + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final ModifyOperation modify = new ModifyOperation(conn); + modify.execute( + new ModifyRequest(dn, new AttributeModification(AttributeModificationType.REMOVE, expected.getAttribute()))); + + final SearchOperation search = new SearchOperation(conn); + final SearchResult result = search.execute( + SearchRequest.newObjectScopeSearchRequest(dn, new String[] {expected.getAttribute().getName()})).getResult(); + AssertJUnit.assertEquals(0, result.getEntry().getAttributes().size()); + } + } + + + /** + * @param dn to modify. + * @param attrs to remove. + * + * @throws Exception On test failure. + */ + @Parameters({ "removeAttributesDn", "removeAttributesAttributes" }) + @Test(groups = {"modify"}, dependsOnMethods = {"replaceAttributes"}) + public void removeAttributes(final String dn, final String attrs) + throws Exception + { + final LdapEntry expected = TestUtils.convertStringToEntry(dn, attrs); + final LdapEntry remove = TestUtils.convertStringToEntry(dn, attrs); + + final String[] attrsName = remove.getAttributeNames(); + remove.getAttributes().remove(remove.getAttribute(attrsName[0])); + expected.getAttributes().remove(expected.getAttribute(attrsName[1])); + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final ModifyOperation modify = new ModifyOperation(conn); + final AttributeModification[] mods = new AttributeModification[expected.size()]; + int i = 0; + for (LdapAttribute la : remove.getAttributes()) { + mods[i++] = new AttributeModification(AttributeModificationType.REMOVE, la); + } + modify.execute(new ModifyRequest(dn, mods)); + + final SearchOperation search = new SearchOperation(conn); + final SearchResult result = search.execute( + SearchRequest.newObjectScopeSearchRequest(dn, expected.getAttributeNames())).getResult(); + TestUtils.assertEquals(expected, result.getEntry()); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/PropertiesTest.java b/integration/src/test/java/org/ldaptive/PropertiesTest.java new file mode 100644 index 0000000..8aa0b4f --- /dev/null +++ b/integration/src/test/java/org/ldaptive/PropertiesTest.java
@@ -0,0 +1,318 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.time.Duration; +import java.util.Arrays; +import javax.security.auth.login.LoginContext; +import org.ldaptive.auth.AuthenticationHandler; +import org.ldaptive.auth.AuthenticationRequest; +import org.ldaptive.auth.Authenticator; +import org.ldaptive.auth.PooledSearchDnResolver; +import org.ldaptive.control.PagedResultsControl; +import org.ldaptive.handler.DnAttributeEntryHandler; +import org.ldaptive.handler.MergeAttributeEntryHandler; +import org.ldaptive.handler.RecursiveEntryHandler; +import org.ldaptive.handler.SearchEntryHandler; +import org.ldaptive.jaas.RoleResolver; +import org.ldaptive.jaas.TestCallbackHandler; +import org.ldaptive.pool.BlockingConnectionPool; +import org.ldaptive.pool.IdlePruneStrategy; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.pool.PooledConnectionFactoryManager; +import org.ldaptive.props.AuthenticatorPropertySource; +import org.ldaptive.props.ConnectionConfigPropertySource; +import org.ldaptive.props.DefaultConnectionFactoryPropertySource; +import org.ldaptive.props.SearchRequestPropertySource; +import org.ldaptive.provider.Provider; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for property source implementations in the props package. + * + * @author Middleware Services + */ +public class PropertiesTest +{ + + + /** @throws Exception On test failure. */ + @BeforeClass(groups = {"props"}) + public void init() + throws Exception + { + System.setProperty("java.security.auth.login.config", "target/test-classes/ldap_jaas.config"); + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"props"}) + public void nullProperties() + throws Exception + { + final ConnectionConfig cc = new ConnectionConfig(); + final ConnectionConfigPropertySource ccSource = new ConnectionConfigPropertySource( + cc, + "classpath:/org/ldaptive/ldap.null.properties"); + ccSource.initialize(); + + AssertJUnit.assertNotNull(cc.getConnectionInitializer()); + AssertJUnit.assertNull(((BindConnectionInitializer) cc.getConnectionInitializer()).getBindSaslConfig()); + + final SearchRequest sr = new SearchRequest(); + final SearchRequestPropertySource srSource = new SearchRequestPropertySource( + sr, + "classpath:/org/ldaptive/ldap.null.properties"); + srSource.initialize(); + + AssertJUnit.assertNull(sr.getSearchEntryHandlers()); + } + + + /** + * @param bindDn used to make connections + * @param host that should match a property. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "ldapBindDn", + "ldapTestHost" + }) + @Test(groups = {"props"}) + public void parserProperties(final String bindDn, final String host) + throws Exception + { + final DefaultConnectionFactory cf = new DefaultConnectionFactory(); + final DefaultConnectionFactoryPropertySource cfSource = new DefaultConnectionFactoryPropertySource( + cf, + "classpath:/org/ldaptive/ldap.parser.properties"); + cfSource.initialize(); + + final ConnectionConfig cc = cf.getConnectionConfig(); + final BindConnectionInitializer ci = (BindConnectionInitializer) cc.getConnectionInitializer(); + + AssertJUnit.assertEquals(host, cc.getLdapUrl()); + AssertJUnit.assertEquals(bindDn, ci.getBindDn()); + AssertJUnit.assertEquals(Duration.ofSeconds(8), cc.getConnectTimeout()); + AssertJUnit.assertFalse(cc.getUseStartTLS()); + AssertJUnit.assertEquals(RoundRobinConnectionStrategy.class, cc.getConnectionStrategy().getClass()); + AssertJUnit.assertEquals( + org.ldaptive.provider.TestControlProcessor.class, + cf.getProvider().getProviderConfig().getControlProcessor().getClass()); + AssertJUnit.assertEquals(1, cf.getProvider().getProviderConfig().getProperties().size()); + AssertJUnit.assertEquals( + "true", + cf.getProvider().getProviderConfig().getProperties().get("java.naming.authoritative")); + + final SearchRequest sr = new SearchRequest(); + final SearchRequestPropertySource srSource = new SearchRequestPropertySource( + sr, + "classpath:/org/ldaptive/ldap.parser.properties"); + srSource.initialize(); + + AssertJUnit.assertEquals(DnParser.substring(bindDn, 1).toLowerCase(), sr.getBaseDn().toLowerCase()); + AssertJUnit.assertEquals(SearchScope.OBJECT, sr.getSearchScope()); + AssertJUnit.assertEquals(Duration.ofSeconds(5), sr.getTimeLimit()); + AssertJUnit.assertEquals("jpegPhoto", sr.getBinaryAttributes()[0]); + AssertJUnit.assertEquals(5, ((PagedResultsControl) sr.getControls()[0]).getSize()); + + for (SearchEntryHandler rh : sr.getSearchEntryHandlers()) { + if (RecursiveEntryHandler.class.isInstance(rh)) { + final RecursiveEntryHandler h = (RecursiveEntryHandler) rh; + AssertJUnit.assertEquals("member", h.getSearchAttribute()); + AssertJUnit.assertEquals( + Arrays.asList(new String[] {"mail", "department"}), + Arrays.asList(h.getMergeAttributes())); + } else if (MergeAttributeEntryHandler.class.isInstance(rh)) { + final MergeAttributeEntryHandler h = (MergeAttributeEntryHandler) rh; + AssertJUnit.assertNotNull(h); + } else if (DnAttributeEntryHandler.class.isInstance(rh)) { + final DnAttributeEntryHandler h = (DnAttributeEntryHandler) rh; + AssertJUnit.assertEquals("myDN", h.getDnAttributeName()); + } else { + throw new Exception("Unknown search result handler type " + rh); + } + } + + final Authenticator auth = new Authenticator(); + final AuthenticatorPropertySource aSource = new AuthenticatorPropertySource( + auth, + "classpath:/org/ldaptive/ldap.parser.properties"); + aSource.initialize(); + + final PooledSearchDnResolver dnResolver = (PooledSearchDnResolver) auth.getDnResolver(); + final BlockingConnectionPool authCp = + (BlockingConnectionPool) dnResolver.getConnectionFactory().getConnectionPool(); + AssertJUnit.assertEquals(1, authCp.getPoolConfig().getMinPoolSize()); + AssertJUnit.assertEquals(3, authCp.getPoolConfig().getMaxPoolSize()); + AssertJUnit.assertEquals(true, authCp.getPoolConfig().isValidatePeriodically()); + AssertJUnit.assertNotNull(authCp.getValidator()); + + final IdlePruneStrategy pruneStrategy = (IdlePruneStrategy) authCp.getPruneStrategy(); + AssertJUnit.assertEquals(Duration.ofMinutes(1), pruneStrategy.getPrunePeriod()); + AssertJUnit.assertEquals(Duration.ofMinutes(2), pruneStrategy.getIdleTime()); + AssertJUnit.assertNotNull(authCp.getActivator()); + AssertJUnit.assertNotNull(authCp.getPassivator()); + + final DefaultConnectionFactory authCf = authCp.getConnectionFactory(); + final ConnectionConfig authCc = authCf.getConnectionConfig(); + final BindConnectionInitializer authCi = (BindConnectionInitializer) authCc.getConnectionInitializer(); + AssertJUnit.assertEquals("ldap://ed-auth.middleware.vt.edu:14389", authCc.getLdapUrl()); + AssertJUnit.assertEquals(bindDn, authCi.getBindDn()); + AssertJUnit.assertEquals(Duration.ofSeconds(8), authCc.getConnectTimeout()); + AssertJUnit.assertTrue(authCc.getUseStartTLS()); + AssertJUnit.assertEquals(RoundRobinConnectionStrategy.class, authCc.getConnectionStrategy().getClass()); + AssertJUnit.assertEquals(1, authCf.getProvider().getProviderConfig().getProperties().size()); + AssertJUnit.assertEquals( + "true", + authCf.getProvider().getProviderConfig().getProperties().get("java.naming.authoritative")); + + if (auth.getDnResolver() instanceof PooledConnectionFactoryManager) { + final PooledConnectionFactoryManager cfm = (PooledConnectionFactoryManager) auth.getDnResolver(); + cfm.getConnectionFactory().getConnectionPool().close(); + } + + final AuthenticationHandler ah = auth.getAuthenticationHandler(); + if (ah instanceof PooledConnectionFactoryManager) { + final PooledConnectionFactoryManager cfm = (PooledConnectionFactoryManager) ah; + cfm.getConnectionFactory().getConnectionPool().close(); + } + } + + + /** + * @param bindDn used to make connections + * @param host that should match a property. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "ldapBindDn", + "ldapTestHost" + }) + @Test(groups = {"props"}) + public void jaasProperties(final String bindDn, final String host) + throws Exception + { + final LoginContext lc = new LoginContext("ldaptive-props", new TestCallbackHandler()); + lc.login(); + + Authenticator auth = null; + AuthenticationRequest authRequest = null; + RoleResolver roleResolver = null; + SearchRequest searchRequest = null; + for (Object o : lc.getSubject().getPublicCredentials()) { + if (o instanceof Authenticator) { + auth = (Authenticator) o; + } else if (o instanceof AuthenticationRequest) { + authRequest = (AuthenticationRequest) o; + } else if (o instanceof RoleResolver) { + roleResolver = (RoleResolver) o; + } else if (o instanceof SearchRequest) { + searchRequest = (SearchRequest) o; + } else { + throw new Exception("Unknown public credential found: " + o); + } + } + + final ConnectionFactoryManager cfm = (ConnectionFactoryManager) auth.getAuthenticationHandler(); + final DefaultConnectionFactory cf = (DefaultConnectionFactory) cfm.getConnectionFactory(); + final ConnectionConfig cc = cf.getConnectionConfig(); + final BindConnectionInitializer ci = (BindConnectionInitializer) cc.getConnectionInitializer(); + + AssertJUnit.assertNotNull(cf.getProvider().getClass()); + AssertJUnit.assertEquals(host, cc.getLdapUrl()); + AssertJUnit.assertEquals(bindDn, ci.getBindDn()); + AssertJUnit.assertEquals(Duration.ofSeconds(8), cc.getConnectTimeout()); + AssertJUnit.assertTrue(cc.getUseStartTLS()); + AssertJUnit.assertEquals(RoundRobinConnectionStrategy.class, cc.getConnectionStrategy().getClass()); + AssertJUnit.assertEquals(1, cf.getProvider().getProviderConfig().getProperties().size()); + AssertJUnit.assertEquals( + "true", + cf.getProvider().getProviderConfig().getProperties().get("java.naming.authoritative")); + + AssertJUnit.assertEquals(DnParser.substring(bindDn, 1).toLowerCase(), searchRequest.getBaseDn().toLowerCase()); + AssertJUnit.assertEquals(SearchScope.OBJECT, searchRequest.getSearchScope()); + AssertJUnit.assertEquals(Duration.ofSeconds(5), searchRequest.getTimeLimit()); + AssertJUnit.assertEquals("jpegPhoto", searchRequest.getBinaryAttributes()[0]); + + for (SearchEntryHandler srh : searchRequest.getSearchEntryHandlers()) { + if (RecursiveEntryHandler.class.isInstance(srh)) { + final RecursiveEntryHandler h = (RecursiveEntryHandler) srh; + AssertJUnit.assertEquals("member", h.getSearchAttribute()); + AssertJUnit.assertEquals( + Arrays.asList(new String[] {"mail", "department"}), + Arrays.asList(h.getMergeAttributes())); + } else if (MergeAttributeEntryHandler.class.isInstance(srh)) { + final MergeAttributeEntryHandler h = (MergeAttributeEntryHandler) srh; + AssertJUnit.assertNotNull(h); + } else if (DnAttributeEntryHandler.class.isInstance(srh)) { + final DnAttributeEntryHandler h = (DnAttributeEntryHandler) srh; + AssertJUnit.assertEquals("myDN", h.getDnAttributeName()); + } else { + throw new Exception("Unknown search result handler type " + srh); + } + } + + final PooledConnectionFactory authCf = ((PooledSearchDnResolver) auth.getDnResolver()).getConnectionFactory(); + final BlockingConnectionPool authCp = (BlockingConnectionPool) authCf.getConnectionPool(); + AssertJUnit.assertEquals(1, authCp.getPoolConfig().getMinPoolSize()); + AssertJUnit.assertEquals(3, authCp.getPoolConfig().getMaxPoolSize()); + AssertJUnit.assertEquals(true, authCp.getPoolConfig().isValidatePeriodically()); + AssertJUnit.assertNotNull(authCp.getValidator()); + + final IdlePruneStrategy pruneStrategy = (IdlePruneStrategy) authCp.getPruneStrategy(); + AssertJUnit.assertEquals(Duration.ofMinutes(1), pruneStrategy.getPrunePeriod()); + AssertJUnit.assertEquals(Duration.ofMinutes(2), pruneStrategy.getIdleTime()); + + final ConnectionConfig authCc = authCp.getConnectionFactory().getConnectionConfig(); + final BindConnectionInitializer authCi = (BindConnectionInitializer) authCc.getConnectionInitializer(); + final Provider<?> authP = authCp.getConnectionFactory().getProvider(); + AssertJUnit.assertEquals(host, authCc.getLdapUrl()); + AssertJUnit.assertEquals(bindDn, authCi.getBindDn()); + AssertJUnit.assertEquals(Duration.ofSeconds(8), authCc.getConnectTimeout()); + AssertJUnit.assertTrue(authCc.getUseStartTLS()); + AssertJUnit.assertEquals(RoundRobinConnectionStrategy.class, authCc.getConnectionStrategy().getClass()); + AssertJUnit.assertEquals(1, authP.getProviderConfig().getProperties().size()); + AssertJUnit.assertEquals("true", authP.getProviderConfig().getProperties().get("java.naming.authoritative")); + + AssertJUnit.assertEquals( + org.ldaptive.auth.CompareAuthenticationHandler.class, + auth.getAuthenticationHandler().getClass()); + AssertJUnit.assertEquals(org.ldaptive.auth.PooledSearchDnResolver.class, auth.getDnResolver().getClass()); + + if (auth.getDnResolver() instanceof PooledConnectionFactoryManager) { + final PooledConnectionFactoryManager resolverCfm = (PooledConnectionFactoryManager) auth.getDnResolver(); + resolverCfm.getConnectionFactory().getConnectionPool().close(); + } + + final AuthenticationHandler authHandler = auth.getAuthenticationHandler(); + if (authHandler instanceof PooledConnectionFactoryManager) { + final PooledConnectionFactoryManager handlerCfm = (PooledConnectionFactoryManager) authHandler; + handlerCfm.getConnectionFactory().getConnectionPool().close(); + } + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"props"}) + public void multipleProperties() + throws Exception + { + final SearchRequest sr = new SearchRequest(); + final SearchRequestPropertySource srSource = new SearchRequestPropertySource( + sr, + "classpath:/org/ldaptive/ldap.parser.properties", + "classpath:/org/ldaptive/ldap.null.properties"); + srSource.initialize(); + + AssertJUnit.assertEquals(SearchScope.SUBTREE, sr.getSearchScope()); + AssertJUnit.assertNotNull(sr.getControls()); + AssertJUnit.assertNull(sr.getSearchEntryHandlers()); + } +}
diff --git a/integration/src/test/java/org/ldaptive/RetrySearchOperation.java b/integration/src/test/java/org/ldaptive/RetrySearchOperation.java new file mode 100644 index 0000000..4ecc7da --- /dev/null +++ b/integration/src/test/java/org/ldaptive/RetrySearchOperation.java
@@ -0,0 +1,168 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +/** + * Provides a wrapper class for testing {@link org.ldaptive.handler.OperationExceptionHandler}. + * + * @author Middleware Services + */ +public class RetrySearchOperation extends SearchOperation +{ + + /** serial version uid. */ + private static final long serialVersionUID = 4247614583961731974L; + + /** exception to rethrow. */ + private final LdapException ex; + + /** whether to perform retries. */ + private boolean allowRetry = true; + + /** retry counter. */ + private int retryCount; + + /** run time counter. */ + private long runTime; + + /** stop counter. */ + private int stopCount; + + + /** + * Creates a new retry search operation. + * + * @param c connection + * @param e ldap exception + */ + public RetrySearchOperation(final Connection c, final LdapException e) + { + super(c); + ex = e; + setOperationExceptionHandler(new RetryExceptionHandler()); + } + + + /** + * Sets whether to allow retry. + * + * @param b whether to allow retry + */ + public void setAllowRetry(final boolean b) + { + allowRetry = b; + } + + + /** + * Returns the retry count. + * + * @return retry count + */ + public int getRetryCount() + { + return retryCount; + } + + + /** + * Returns the run time counter. + * + * @return run time + */ + public long getRunTime() + { + return runTime; + } + + + /** + * Sets the count at which to stop retries. + * + * @param i stop count + */ + public void setStopCount(final int i) + { + stopCount = i; + } + + + /** Resets all the counters. */ + public void reset() + { + retryCount = 0; + runTime = 0; + stopCount = 0; + } + + + /** + * See {@link ReopenOperationExceptionHandler#setRetry(int)}. + * + * @param i to set + */ + public void setReopenRetry(final int i) + { + ((ReopenOperationExceptionHandler) getOperationExceptionHandler()).setRetry(i); + } + + + /** + * See {@link ReopenOperationExceptionHandler#setRetryWait(long)}. + * + * @param l to set + */ + public void setReopenRetryWait(final long l) + { + ((ReopenOperationExceptionHandler) getOperationExceptionHandler()).setRetryWait(l); + } + + + /** + * See {@link ReopenOperationExceptionHandler#setRetryBackoff(int)}. + * + * @param i to set + */ + public void setReopenRetryBackoff(final int i) + { + ((ReopenOperationExceptionHandler) getOperationExceptionHandler()).setRetryBackoff(i); + } + + + /** Calculates the execution time of {@link ReopenOperationExceptionHandler}. */ + public class RetryExceptionHandler extends ReopenOperationExceptionHandler + { + + + @Override + public void handleInternal( + final Connection conn, + final SearchRequest request, + final Response<SearchResult> response) + throws LdapException + { + if (!allowRetry) { + return; + } + + final long t = System.currentTimeMillis(); + super.handleInternal(conn, request, response); + runTime += System.currentTimeMillis() - t; + throw ex; + } + + + @Override + protected boolean retry(final int count) + { + if (stopCount > 0 && retryCount == stopCount) { + return false; + } + + final boolean b = super.retry(count); + if (b) { + retryCount++; + } + return b; + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/SearchOperationTest.java b/integration/src/test/java/org/ldaptive/SearchOperationTest.java new file mode 100644 index 0000000..1ab5e5a --- /dev/null +++ b/integration/src/test/java/org/ldaptive/SearchOperationTest.java
@@ -0,0 +1,2274 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import org.ldaptive.ad.control.ForceUpdateControl; +import org.ldaptive.ad.control.GetStatsControl; +import org.ldaptive.ad.control.LazyCommitControl; +import org.ldaptive.ad.control.PermissiveModifyControl; +import org.ldaptive.ad.control.RangeRetrievalNoerrControl; +import org.ldaptive.ad.control.SearchOptionsControl; +import org.ldaptive.ad.control.ShowDeactivatedLinkControl; +import org.ldaptive.ad.control.ShowDeletedControl; +import org.ldaptive.ad.control.ShowRecycledControl; +import org.ldaptive.ad.handler.ObjectGuidHandler; +import org.ldaptive.ad.handler.ObjectSidHandler; +import org.ldaptive.ad.handler.PrimaryGroupIdHandler; +import org.ldaptive.ad.handler.RangeEntryHandler; +import org.ldaptive.control.PagedResultsControl; +import org.ldaptive.control.ProxyAuthorizationControl; +import org.ldaptive.control.SortKey; +import org.ldaptive.control.SortRequestControl; +import org.ldaptive.control.VirtualListViewRequestControl; +import org.ldaptive.control.VirtualListViewResponseControl; +import org.ldaptive.handler.CaseChangeEntryHandler; +import org.ldaptive.handler.CaseChangeEntryHandler.CaseChange; +import org.ldaptive.handler.DnAttributeEntryHandler; +import org.ldaptive.handler.HandlerResult; +import org.ldaptive.handler.MergeAttributeEntryHandler; +import org.ldaptive.handler.NoOpEntryHandler; +import org.ldaptive.handler.RecursiveEntryHandler; +import org.ldaptive.handler.SearchEntryHandler; +import org.ldaptive.handler.SearchReferenceHandler; +import org.ldaptive.io.GeneralizedTimeValueTranscoder; +import org.ldaptive.pool.BlockingConnectionPool; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.referral.SearchReferralHandler; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SearchOperation}. + * + * @author Middleware Services + */ +public class SearchOperationTest extends AbstractTest +{ + + /** Entry created for ldap tests. */ + private static LdapEntry testLdapEntry; + + /** Entry created for ldap tests. */ + private static LdapEntry specialCharsLdapEntry; + + /** Entries for group tests. */ + private static final Map<String, LdapEntry[]> GROUP_ENTRIES = new HashMap<>(); + + /** + * Initialize the map of group entries. + */ + static { + for (int i = 2; i <= 5; i++) { + GROUP_ENTRIES.put(String.valueOf(i), new LdapEntry[2]); + } + } + + /** Connection instance for concurrency testing. */ + protected Connection singleConn; + + + /** + * Default constructor. + * + * @throws Exception On test failure. + */ + public SearchOperationTest() + throws Exception + { + singleConn = TestUtils.createConnection(); + } + + + /** @throws Exception On test failure. */ + @BeforeClass(groups = {"search"}) + public void openConnection() + throws Exception + { + singleConn.open(); + } + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry2") + @BeforeClass(groups = {"search", "searchInit"}) + public void createLdapEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + } + + + /** + * @param ldifFile2 to create. + * @param ldifFile3 to create. + * @param ldifFile4 to create. + * @param ldifFile5 to create. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "createGroup2", + "createGroup3", + "createGroup4", + "createGroup5" + }) + @BeforeClass(groups = {"search"}, dependsOnGroups = {"searchInit"}) + public void createGroupEntry( + final String ldifFile2, + final String ldifFile3, + final String ldifFile4, + final String ldifFile5) + throws Exception + { + // CheckStyle:Indentation OFF + GROUP_ENTRIES.get("2")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile2)).getEntry(); + GROUP_ENTRIES.get("3")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile3)).getEntry(); + GROUP_ENTRIES.get("4")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile4)).getEntry(); + GROUP_ENTRIES.get("5")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile5)).getEntry(); + // CheckStyle:Indentation ON + + for (Map.Entry<String, LdapEntry[]> e : GROUP_ENTRIES.entrySet()) { + super.createLdapEntry(e.getValue()[0]); + } + + final String baseDn = DnParser.substring(GROUP_ENTRIES.get("2")[0].getDn(), 1); + // setup group relationships + try (Connection conn = TestUtils.createSetupConnection()) { + conn.open(); + + final ModifyOperation modify = new ModifyOperation(conn); + try { + modify.execute( + new ModifyRequest( + GROUP_ENTRIES.get("2")[0].getDn(), + new AttributeModification( + AttributeModificationType.ADD, + new LdapAttribute("member", "cn=Group 3," + baseDn)))); + } catch (LdapException e) { + // ignore attribute already exists + if (ResultCode.ATTRIBUTE_OR_VALUE_EXISTS != e.getResultCode()) { + throw e; + } + } + try { + modify.execute( + new ModifyRequest( + GROUP_ENTRIES.get("3")[0].getDn(), + new AttributeModification( + AttributeModificationType.ADD, + new LdapAttribute("member", "cn=Group 4," + baseDn, "cn=Group 5," + baseDn)))); + } catch (LdapException e) { + // ignore attribute already exists + if (ResultCode.ATTRIBUTE_OR_VALUE_EXISTS != e.getResultCode()) { + throw e; + } + } + try { + modify.execute( + new ModifyRequest( + GROUP_ENTRIES.get("4")[0].getDn(), + new AttributeModification( + AttributeModificationType.ADD, + new LdapAttribute("member", "cn=Group 2," + baseDn, "cn=Group 3," + baseDn)))); + } catch (LdapException e) { + // ignore attribute already exists + if (ResultCode.ATTRIBUTE_OR_VALUE_EXISTS != e.getResultCode()) { + throw e; + } + } + } + } + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createSpecialCharsEntry") + @BeforeClass(groups = {"search"}) + public void createSpecialCharsEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + specialCharsLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(specialCharsLdapEntry); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"search"}) + public void deleteLdapEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + super.deleteLdapEntry(specialCharsLdapEntry.getDn()); + super.deleteLdapEntry(GROUP_ENTRIES.get("2")[0].getDn()); + super.deleteLdapEntry(GROUP_ENTRIES.get("3")[0].getDn()); + super.deleteLdapEntry(GROUP_ENTRIES.get("4")[0].getDn()); + super.deleteLdapEntry(GROUP_ENTRIES.get("5")[0].getDn()); + } + + + /** + * @param createNew whether to construct a new connection. + * + * @return connection + * + * @throws Exception On connection failure. + */ + public Connection createLdapConnection(final boolean createNew) + throws Exception + { + if (createNew) { + return TestUtils.createConnection(); + } + return singleConn; + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param filterParameters to replace parameters in filter with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "searchDn", + "searchFilter", + "searchFilterParameters", + "searchReturnAttrs", + "searchResults" + }) + @Test( + groups = {"search"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void search( + final String dn, + final String filter, + final String filterParameters, + final String returnAttrs, + final String ldifFile) + throws Exception + { + final SearchOperation search = new SearchOperation(createLdapConnection(false)); + + final String expected = TestUtils.readFileIntoString(ldifFile); + + final SearchResult entryDnResult = TestUtils.convertLdifToResult(expected); + entryDnResult.getEntry().addAttribute(new LdapAttribute("entryDN", entryDnResult.getEntry().getDn())); + + // test searching + SearchResult result = search.execute( + new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), returnAttrs.split("\\|"))).getResult(); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), result); + + // test searching no attributes + result = search.execute( + new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), ReturnAttributes.NONE.value())).getResult(); + AssertJUnit.assertTrue(result.getEntry().getAttributes().isEmpty()); + + // test searching without handler + final SearchRequest sr = new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), + returnAttrs.split("\\|")); + sr.setSearchEntryHandlers(new SearchEntryHandler[0]); + result = search.execute(sr).getResult(); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), result); + + // test searching with multiple handlers + final DnAttributeEntryHandler srh = new DnAttributeEntryHandler(); + sr.setSearchEntryHandlers(new NoOpEntryHandler(), srh); + result = search.execute(sr).getResult(); + // ignore the case of entryDN; some directories return those in mixed case + AssertJUnit.assertEquals( + 0, + (new LdapEntryIgnoreCaseComparator("entryDN")).compare(entryDnResult.getEntry(), result.getEntry())); + + // test that entry dn handler is no-op if attribute name conflicts + srh.setDnAttributeName("givenName"); + sr.setSearchEntryHandlers(new NoOpEntryHandler(), srh); + result = search.execute(sr).getResult(); + // ignore the case of entryDN; some directories return those in mixed case + AssertJUnit.assertEquals( + 0, + (new LdapEntryIgnoreCaseComparator("entryDN")).compare( + TestUtils.convertLdifToResult(expected).getEntry(), + result.getEntry())); + } + + + /** + * @param filter to search with. + * @param filterParameters to replace parameters in filter with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "searchFilter", + "searchFilterParameters", + "searchReturnAttrs", + "searchResults" + }) + @Test(groups = {"search"}) + public void searchScopes( + final String filter, + final String filterParameters, + final String returnAttrs, + final String ldifFile) + throws Exception + { + final SearchResult expectedResult = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile)); + try (Connection conn = createLdapConnection(true)) { + conn.open(); + final SearchOperation search = new SearchOperation(conn); + + final SearchRequest subtreeRequest = new SearchRequest( + DnParser.substring(expectedResult.getEntry().getDn(), 2), + new SearchFilter(filter, filterParameters.split("\\|")), + returnAttrs.split("\\|")); + subtreeRequest.setSearchScope(SearchScope.SUBTREE); + SearchResult result = search.execute(subtreeRequest).getResult(); + TestUtils.assertEquals(expectedResult, result); + + final SearchRequest onelevelRequest = new SearchRequest( + DnParser.substring(expectedResult.getEntry().getDn(), 1), + new SearchFilter(filter, filterParameters.split("\\|")), + returnAttrs.split("\\|")); + onelevelRequest.setSearchScope(SearchScope.ONELEVEL); + result = search.execute(onelevelRequest).getResult(); + TestUtils.assertEquals(expectedResult, result); + + final SearchRequest objectRequest = new SearchRequest( + expectedResult.getEntry().getDn(), + new SearchFilter("(objectClass=*)"), + returnAttrs.split("\\|")); + objectRequest.setSearchScope(SearchScope.OBJECT); + result = search.execute(objectRequest).getResult(); + TestUtils.assertEquals(expectedResult, result); + } + } + + + /** + * @param filter to search with. + * @param filterParameters to replace parameters in filter with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "searchFilter", + "searchFilterParameters", + "searchReturnAttrs", + "searchResults" + }) + @Test(groups = {"search"}) + public void jndiSearchScopes( + final String filter, + final String filterParameters, + final String returnAttrs, + final String ldifFile) + throws Exception + { + if (!TestControl.isJndiProvider()) { + return; + } + final SearchResult expectedResult = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile)); + + // test URL with baseDn included + for (int i = 0; i <= 2; i++) { + final ConnectionConfig cc = TestUtils.readConnectionConfig(null); + cc.setLdapUrl(String.format("%s/%s", cc.getLdapUrl(), + LdapUtils.percentEncode(DnParser.substring(expectedResult.getEntry().getDn(), i)))); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation search = new SearchOperation(conn); + + final SearchRequest subtreeRequest = new SearchRequest( + i > 0 ? DnParser.substring(expectedResult.getEntry().getDn(), 0, i) : "", + new SearchFilter(filter, filterParameters.split("\\|")), + returnAttrs.split("\\|")); + subtreeRequest.setSearchScope(SearchScope.SUBTREE); + SearchResult result = search.execute(subtreeRequest).getResult(); + AssertJUnit.assertEquals(1, result.size()); + TestUtils.assertEquals(expectedResult, result); + + final SearchRequest onelevelRequest = new SearchRequest( + i > 0 ? DnParser.substring(expectedResult.getEntry().getDn(), 0, i) : "", + new SearchFilter(filter, filterParameters.split("\\|")), + returnAttrs.split("\\|")); + onelevelRequest.setSearchScope(SearchScope.ONELEVEL); + result = search.execute(onelevelRequest).getResult(); + AssertJUnit.assertEquals(0, result.size()); + + final SearchRequest objectRequest = new SearchRequest( + i > 0 ? DnParser.substring(expectedResult.getEntry().getDn(), 0, i) : "", + new SearchFilter("(objectClass=*)"), + returnAttrs.split("\\|")); + objectRequest.setSearchScope(SearchScope.OBJECT); + result = search.execute(objectRequest).getResult(); + AssertJUnit.assertEquals(1, result.size()); + TestUtils.assertEquals(expectedResult, result); + } + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param filterParameters to replace parameters in filter with. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "searchDn", + "searchFilter", + "searchFilterParameters", + "searchResults" + }) + @Test(groups = {"search"}) + public void returnAttributesSearch( + final String dn, + final String filter, + final String filterParameters, + final String ldifFile) + throws Exception + { + final SearchOperation search = new SearchOperation(createLdapConnection(false)); + + final String expected = TestUtils.readFileIntoString(ldifFile); + + final SearchResult entryDnResult = TestUtils.convertLdifToResult(expected); + + // test searching, no attributes + SearchResult result = search.execute( + new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), ReturnAttributes.NONE.value())).getResult(); + AssertJUnit.assertNotNull(result.getEntry()); + AssertJUnit.assertTrue(result.getEntry().getAttributes().isEmpty()); + + // test searching, user attributes + result = search.execute( + new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), ReturnAttributes.ALL_USER.value())).getResult(); + AssertJUnit.assertNotNull(result.getEntry()); + AssertJUnit.assertNotNull(result.getEntry().getAttribute("cn")); + AssertJUnit.assertNull(result.getEntry().getAttribute("createTimestamp")); + + // test searching, operations attributes + if (TestControl.isActiveDirectory() || TestControl.isOracleDirectory()) { + // directory ignores '+' + result = search.execute( + new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), + ReturnAttributes.ALL_OPERATIONAL.add("createTimestamp"))).getResult(); + } else { + result = search.execute( + new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), + ReturnAttributes.ALL_OPERATIONAL.value())).getResult(); + } + AssertJUnit.assertNotNull(result.getEntry()); + AssertJUnit.assertNull(result.getEntry().getAttribute("cn")); + AssertJUnit.assertNotNull(result.getEntry().getAttribute("createTimestamp")); + + // test searching, all attributes + if (TestControl.isActiveDirectory() || TestControl.isOracleDirectory()) { + // directory ignores '+' + result = search.execute( + new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), + ReturnAttributes.ALL.add("createTimestamp"))).getResult(); + } else { + result = search.execute( + new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), ReturnAttributes.ALL.value())).getResult(); + } + AssertJUnit.assertNotNull(result.getEntry()); + AssertJUnit.assertNotNull(result.getEntry().getAttribute("cn")); + AssertJUnit.assertNotNull(result.getEntry().getAttribute("createTimestamp")); + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "pagedSearchDn", + "pagedSearchFilter", + "pagedSearchReturnAttrs", + "pagedSearchResults" + }) + @Test(groups = {"search"}) + public void pagedSearch(final String dn, final String filter, final String returnAttrs, final String ldifFile) + throws Exception + { + final PagedResultsControl prc = new PagedResultsControl(1, true); + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final String expected = TestUtils.readFileIntoString(ldifFile); + + // test searching + final SearchRequest request = new SearchRequest(dn, new SearchFilter(filter), returnAttrs.split("\\|")); + request.setControls(prc); + + final SearchResult result = new SearchResult(); + byte[] cookie = null; + do { + prc.setCookie(cookie); + + final Response<SearchResult> response = search.execute(request); + result.addEntries(response.getResult().getEntries()); + cookie = null; + + final PagedResultsControl ctl = (PagedResultsControl) response.getControl(PagedResultsControl.OID); + if (ctl != null) { + if (ctl.getCookie() != null && ctl.getCookie().length > 0) { + cookie = ctl.getCookie(); + } + } + } while (cookie != null); + // ignore the case of member and contactPerson; + // some directories return those in mixed case + AssertJUnit.assertEquals( + 0, + (new SearchResultIgnoreCaseComparator("member", "contactPerson")).compare( + TestUtils.convertLdifToResult(expected), + result)); + } catch (LdapException e) { + // ignore this test if not supported by the server + AssertJUnit.assertEquals(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, e.getResultCode()); + } catch (UnsupportedOperationException e) { + // ignore this test if not supported + AssertJUnit.assertNotNull(e); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "virtualListViewSearchDn", + "virtualListViewSearchFilter", + "virtualListViewSearchReturnAttrs", + "virtualListViewSearchResults" + }) + @Test(groups = {"search"}) + public void virtualListViewSearch( + final String dn, + final String filter, + final String returnAttrs, + final String ldifFile) + throws Exception + { + // AD server says vlv is a supported control, but returns UNAVAIL_EXTENSION + // OracleDS returns protocol error + if (TestControl.isActiveDirectory() || TestControl.isOracleDirectory()) { + return; + } + + // provider doesn't support this control + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP does not support this control"); + } + + final SortRequestControl src = new SortRequestControl(new SortKey[] {new SortKey("uugid", "caseExactMatch")}, true); + VirtualListViewRequestControl vlvrc = new VirtualListViewRequestControl(3, 1, 1, true); + byte[] contextID; + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final String expected = TestUtils.readFileIntoString(ldifFile); + + // test searching + final SearchRequest request = new SearchRequest(dn, new SearchFilter(filter), returnAttrs.split("\\|")); + request.setControls(src, vlvrc); + + Response<SearchResult> response = search.execute(request); + SearchResult result = response.getResult(); + // ignore the case of member and contactPerson; + // some directories return those in mixed case + AssertJUnit.assertEquals( + 0, + (new SearchResultIgnoreCaseComparator("member", "contactPerson")).compare( + TestUtils.convertLdifToResult(expected), + result)); + contextID = + ((VirtualListViewResponseControl) response.getControl(VirtualListViewResponseControl.OID)).getContextID(); + + vlvrc = new VirtualListViewRequestControl("group4", 1, 1, contextID, true); + request.setControls(src, vlvrc); + response = search.execute(request); + result = response.getResult(); + // ignore the case of member and contactPerson; + // some directories return those in mixed case + AssertJUnit.assertEquals( + 0, + (new SearchResultIgnoreCaseComparator("member", "contactPerson")).compare( + TestUtils.convertLdifToResult(expected), + result)); + } catch (LdapException e) { + // ignore this test if not supported by the server + AssertJUnit.assertEquals(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, e.getResultCode()); + } catch (UnsupportedOperationException e) { + // ignore this test if not supported + AssertJUnit.assertNotNull(e); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "sortSearchDn", + "sortSearchFilter" + }) + @Test(groups = {"search"}) + public void sortedSearch(final String dn, final String filter) + throws Exception + { + // OracleDS returns protocol error + if (TestControl.isOracleDirectory()) { + return; + } + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + + final SearchRequest request = new SearchRequest(dn, new SearchFilter(filter)); + request.setSortBehavior(SortBehavior.ORDERED); + + // test sort by uugid + SortRequestControl src = new SortRequestControl(new SortKey[] {new SortKey("uugid", "caseExactMatch")}, true); + request.setControls(src); + + SearchResult result = search.execute(request).getResult(); + + // confirm sorted + int i = 2; + for (LdapEntry e : result.getEntries()) { + AssertJUnit.assertEquals(String.valueOf(2000 + i), e.getAttribute("uid").getStringValue()); + i++; + } + + // test sort by uid + src = new SortRequestControl(new SortKey[] {new SortKey("uid", "integerMatch", true)}, true); + request.setControls(src); + result = search.execute(request).getResult(); + + // confirm sorted + i = 5; + for (LdapEntry e : result.getEntries()) { + AssertJUnit.assertEquals(String.valueOf(2000 + i), e.getAttribute("uid").getStringValue()); + i--; + } + } catch (LdapException e) { + // ignore this test if not supported by the server + AssertJUnit.assertEquals(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, e.getResultCode()); + } catch (UnsupportedOperationException e) { + // ignore this test if not supported by the provider + AssertJUnit.assertNotNull(e); + } + } + + + /** + * @param authzFrom to proxy from + * @param authzTo to proxy to + * @param dn to search on. + * @param filter to search with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "proxyAuthzFrom", + "proxyAuthzTo", + "proxyAuthzSearchDn", + "proxyAuthzSearchFilter" + }) + @Test(groups = {"search"}) + public void proxyAuthzSearch(final String authzFrom, final String authzTo, final String dn, final String filter) + throws Exception + { + // provider doesn't support this control + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP does not support this control"); + } + + boolean addedAttribute = false; + final Connection conn = TestUtils.createSetupConnection(); + try { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + + final SearchRequest request = new SearchRequest(dn, new SearchFilter(filter)); + + // no authz + Response<SearchResult> response = search.execute(request); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertEquals(1, response.getResult().size()); + + // anonymous authz + request.setControls(new ProxyAuthorizationControl("dn:")); + response = search.execute(request); + if (ResultCode.UNAVAILABLE_CRITICAL_EXTENSION.equals(response.getResultCode())) { + // ignore this test if not supported by the server + throw new UnsupportedOperationException("LDAP server does not support this control"); + } + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertEquals(0, response.getResult().size()); + + // authz denied + request.setControls(new ProxyAuthorizationControl("dn:" + authzTo)); + try { + response = search.execute(request); + AssertJUnit.assertEquals(ResultCode.AUTHORIZATION_DENIED, response.getResultCode()); + } catch (LdapException e) { + AssertJUnit.assertEquals(ResultCode.AUTHORIZATION_DENIED, e.getResultCode()); + } + + // add authzTo + final ModifyOperation modify = new ModifyOperation(conn); + modify.execute( + new ModifyRequest( + authzFrom, + new AttributeModification(AttributeModificationType.ADD, new LdapAttribute("authzTo", "dn:" + authzTo)))); + addedAttribute = true; + + response = search.execute(request); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertEquals(1, response.getResult().size()); + + } catch (LdapException e) { + // ignore this test if not supported by the server + AssertJUnit.assertEquals(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, e.getResultCode()); + } catch (UnsupportedOperationException e) { + // ignore this test if not supported by the provider + AssertJUnit.assertNotNull(e); + } finally { + if (addedAttribute) { + try { + // remove authzTo + final ModifyOperation modify = new ModifyOperation(conn); + modify.execute( + new ModifyRequest( + authzFrom, + new AttributeModification(AttributeModificationType.REMOVE, new LdapAttribute("authzTo")))); + } catch (LdapException e) { + AssertJUnit.fail(e.getMessage()); + } + } + conn.close(); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param filterParameters to replace parameters in filter with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "recursiveSearchDn", + "recursiveSearchFilter", + "recursiveSearchFilterParameters", + "recursiveSearchReturnAttrs", + "recursiveHandlerResults" + }) + @Test(groups = {"search"}) + public void recursiveHandlerSearch( + final String dn, + final String filter, + final String filterParameters, + final String returnAttrs, + final String ldifFile) + throws Exception + { + final SearchOperation search = new SearchOperation(createLdapConnection(false)); + + final String expected = TestUtils.readFileIntoString(ldifFile); + + // test recursive searching + final RecursiveEntryHandler rsrh = new RecursiveEntryHandler("member", "uugid", "uid"); + + final SearchRequest sr = new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), + returnAttrs.split("\\|")); + sr.setSearchEntryHandlers(rsrh); + + final SearchResult result = search.execute(sr).getResult(); + // ignore the case of member and contactPerson; some directories return + // those in mixed case + AssertJUnit.assertEquals( + 0, + (new LdapEntryIgnoreCaseComparator("member", "contactPerson")).compare( + TestUtils.convertLdifToResult(expected).getEntry(), + result.getEntry())); + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "recursiveSearch2Dn", + "recursiveSearch2Filter", + "recursiveSearch2ReturnAttrs", + "recursiveHandlerResults2" + }) + @Test(groups = {"search"}) + public void recursiveHandlerSearch2( + final String dn, + final String filter, + final String returnAttrs, + final String ldifFile) + throws Exception + { + final SearchOperation search = new SearchOperation(createLdapConnection(false)); + + final String expected = TestUtils.readFileIntoString(ldifFile); + + // test recursive searching + final RecursiveEntryHandler rsrh = new RecursiveEntryHandler("member", "member"); + + final SearchRequest sr = new SearchRequest(dn, new SearchFilter(filter), returnAttrs.split("\\|")); + sr.setSearchEntryHandlers(rsrh); + + final SearchResult result = search.execute(sr).getResult(); + // ignore the case of member and contactPerson; some directories return + // those in mixed case + AssertJUnit.assertEquals( + 0, + (new LdapEntryIgnoreCaseComparator("member")).compare( + TestUtils.convertLdifToResult(expected).getEntry(), + result.getEntry())); + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "mergeSearchDn", + "mergeSearchFilter", + "mergeSearchReturnAttrs", + "mergeSearchResults" + }) + @Test(groups = {"search"}) + public void mergeSearch(final String dn, final String filter, final String returnAttrs, final String ldifFile) + throws Exception + { + try (Connection conn = createLdapConnection(true)) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + + final String expected = TestUtils.readFileIntoString(ldifFile); + + // test result merge + final SearchRequest sr = new SearchRequest(dn, new SearchFilter(filter), returnAttrs.split("\\|")); + sr.setSortBehavior(SortBehavior.SORTED); + + final SearchResult result = search.execute(sr).getResult(); + // ignore the case of member and contactPerson; some directories return + // those in mixed case + AssertJUnit.assertEquals( + 0, + (new LdapEntryIgnoreCaseComparator("member", "contactPerson")).compare( + TestUtils.convertLdifToResult(expected).getEntry(), + SearchResult.mergeEntries(result).getEntry())); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "mergeDuplicateSearchDn", + "mergeDuplicateSearchFilter", + "mergeDuplicateReturnAttrs", + "mergeDuplicateSearchResults" + }) + @Test(groups = {"search"}) + public void mergeDuplicateSearch( + final String dn, + final String filter, + final String returnAttrs, + final String ldifFile) + throws Exception + { + try (Connection conn = createLdapConnection(true)) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + + final String expected = TestUtils.readFileIntoString(ldifFile); + + // test result merge + final SearchRequest sr = new SearchRequest(dn, new SearchFilter(filter), returnAttrs.split("\\|")); + sr.setSortBehavior(SortBehavior.SORTED); + + final SearchResult result = search.execute(sr).getResult(); + // ignore the case of member and contactPerson; some directories return + // those in mixed case + AssertJUnit.assertEquals( + 0, + (new LdapEntryIgnoreCaseComparator("member", "contactPerson")).compare( + TestUtils.convertLdifToResult(expected).getEntry(), + SearchResult.mergeEntries(result).getEntry())); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "mergeAttributeSearchDn", + "mergeAttributeSearchFilter", + "mergeAttributeReturnAttrs", + "mergeAttributeSearchResults" + }) + @Test(groups = {"search"}) + public void mergeAttributeSearch( + final String dn, + final String filter, + final String returnAttrs, + final String ldifFile) + throws Exception + { + try (Connection conn = createLdapConnection(true)) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + + final String expected = TestUtils.readFileIntoString(ldifFile); + + // test merge searching + final MergeAttributeEntryHandler handler = new MergeAttributeEntryHandler(); + handler.setMergeAttributeName("cn"); + handler.setAttributeNames("displayName", "givenName", "sn"); + + final SearchRequest sr = new SearchRequest(dn, new SearchFilter(filter), returnAttrs.split("\\|")); + sr.setSearchEntryHandlers(handler); + sr.setSortBehavior(SortBehavior.SORTED); + + final SearchResult result = search.execute(sr).getResult(); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), result); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param returnAttr to return from search. + * @param base64Value to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "binarySearchDn", + "binarySearchFilter", + "binarySearchReturnAttr", + "binarySearchResult" + }) + @Test(groups = {"search"}) + public void binarySearch(final String dn, final String filter, final String returnAttr, final String base64Value) + throws Exception + { + final SearchOperation search = new SearchOperation(createLdapConnection(false)); + + // test binary searching + SearchRequest request = new SearchRequest(dn, new SearchFilter(filter), returnAttr); + request.setBinaryAttributes(returnAttr); + + SearchResult result = search.execute(request).getResult(); + AssertJUnit.assertTrue(result.getEntry().getAttribute().isBinary()); + AssertJUnit.assertEquals(base64Value, result.getEntry().getAttribute().getStringValue()); + + request = new SearchRequest(dn, new SearchFilter(filter), "sn"); + result = search.execute(request).getResult(); + AssertJUnit.assertFalse(result.getEntry().getAttribute().isBinary()); + AssertJUnit.assertNotNull(result.getEntry().getAttribute().getBinaryValue()); + + request = new SearchRequest(dn, new SearchFilter(filter), "sn"); + request.setBinaryAttributes("sn"); + result = search.execute(request).getResult(); + AssertJUnit.assertTrue(result.getEntry().getAttribute().isBinary()); + AssertJUnit.assertNotNull(result.getEntry().getAttribute().getBinaryValue()); + + request = new SearchRequest(dn, new SearchFilter(filter), "userCertificate;binary"); + result = search.execute(request).getResult(); + AssertJUnit.assertTrue(result.getEntry().getAttribute().isBinary()); + AssertJUnit.assertNotNull(result.getEntry().getAttribute().getBinaryValue()); + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param filterParameters to replace parameters in filter with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "searchDn", + "searchFilter", + "searchFilterParameters", + "searchReturnAttrs", + "searchResults" + }) + @Test(groups = {"search"}) + public void caseChangeSearch( + final String dn, + final String filter, + final String filterParameters, + final String returnAttrs, + final String ldifFile) + throws Exception + { + try (Connection conn = createLdapConnection(true)) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final CaseChangeEntryHandler srh = new CaseChangeEntryHandler(); + final String expected = TestUtils.readFileIntoString(ldifFile); + + // test no case change + final SearchResult noChangeResult = TestUtils.convertLdifToResult(expected); + SearchRequest sr = new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), + returnAttrs.split("\\|")); + sr.setSearchEntryHandlers(srh); + + SearchResult result = search.execute(sr).getResult(); + TestUtils.assertEquals(noChangeResult, result); + + // test lower case attribute values + srh.setAttributeNameCaseChange(CaseChange.NONE); + srh.setAttributeValueCaseChange(CaseChange.LOWER); + srh.setDnCaseChange(CaseChange.NONE); + + final SearchResult lcValuesChangeResult = TestUtils.convertLdifToResult(expected); + for (LdapAttribute la : lcValuesChangeResult.getEntry().getAttributes()) { + final Set<String> s = la.getStringValues().stream().map(String::toLowerCase).collect(Collectors.toSet()); + la.clear(); + la.addStringValues(s); + } + sr = new SearchRequest(dn, new SearchFilter(filter, filterParameters.split("\\|")), returnAttrs.split("\\|")); + sr.setSearchEntryHandlers(srh); + result = search.execute(sr).getResult(); + TestUtils.assertEquals(lcValuesChangeResult, result); + + // test upper case attribute names + srh.setAttributeNameCaseChange(CaseChange.UPPER); + srh.setAttributeValueCaseChange(CaseChange.NONE); + srh.setDnCaseChange(CaseChange.NONE); + + final SearchResult ucNamesChangeResult = TestUtils.convertLdifToResult(expected); + for (LdapAttribute la : ucNamesChangeResult.getEntry().getAttributes()) { + la.setName(la.getName().toUpperCase()); + } + sr = new SearchRequest(dn, new SearchFilter(filter, filterParameters.split("\\|")), returnAttrs.split("\\|")); + sr.setSearchEntryHandlers(srh); + result = search.execute(sr).getResult(); + TestUtils.assertEquals(ucNamesChangeResult, result); + + // test lower case everything + srh.setAttributeNameCaseChange(CaseChange.LOWER); + srh.setAttributeValueCaseChange(CaseChange.LOWER); + srh.setDnCaseChange(CaseChange.LOWER); + + final SearchResult lcAllChangeResult = TestUtils.convertLdifToResult(expected); + for (LdapAttribute la : ucNamesChangeResult.getEntry().getAttributes()) { + lcAllChangeResult.getEntry().setDn(lcAllChangeResult.getEntry().getDn().toLowerCase()); + la.setName(la.getName().toLowerCase()); + + final Set<String> s = la.getStringValues().stream().map(String::toLowerCase).collect(Collectors.toSet()); + la.clear(); + la.addStringValues(s); + } + sr = new SearchRequest(dn, new SearchFilter(filter, filterParameters.split("\\|")), returnAttrs.split("\\|")); + sr.setSearchEntryHandlers(srh); + result = search.execute(sr).getResult(); + TestUtils.assertEquals(ucNamesChangeResult, result); + + // test lower case specific attributes + srh.setAttributeNames("givenName"); + srh.setAttributeNameCaseChange(CaseChange.NONE); + srh.setAttributeValueCaseChange(CaseChange.LOWER); + srh.setDnCaseChange(CaseChange.NONE); + + final SearchResult lcgivenNameChangeResult = TestUtils.convertLdifToResult(expected); + lcgivenNameChangeResult.getEntry().getAttributes().stream().filter( + la -> la.getName().equals("givenName")).forEach(la -> { + final Set<String> s = la.getStringValues().stream().map(String::toLowerCase).collect(Collectors.toSet()); + la.clear(); + la.addStringValues(s); + }); + sr = new SearchRequest(dn, new SearchFilter(filter, filterParameters.split("\\|")), returnAttrs.split("\\|")); + sr.setSearchEntryHandlers(srh); + result = search.execute(sr).getResult(); + TestUtils.assertEquals(lcgivenNameChangeResult, result); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "rangeSearchDn", + "rangeSearchFilter", + "rangeSearchReturnAttrs", + "rangeHandlerResults" + }) + @Test(groups = {"search"}) + public void rangeHandlerSearch(final String dn, final String filter, final String returnAttrs, final String ldifFile) + throws Exception + { + if (!TestControl.isActiveDirectory()) { + return; + } + // OpenDJ will not parse DNs used by this entry handler + if (TestControl.isOpenDJProvider()) { + return; + } + + final String expected = TestUtils.readFileIntoString(ldifFile); + try (Connection conn = createLdapConnection(true)) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final SearchRequest sr = new SearchRequest(dn, new SearchFilter(filter), returnAttrs.split("\\|")); + sr.setSearchEntryHandlers(new RangeEntryHandler(), new ObjectSidHandler(), new ObjectGuidHandler()); + + final SearchResult result = search.execute(sr).getResult(); + // ignore the case of member; some directories return it in mixed case + AssertJUnit.assertEquals( + 0, + (new LdapEntryIgnoreCaseComparator("member")).compare( + TestUtils.convertLdifToResult(expected).getEntry(), + result.getEntry())); + } catch (LdapException e) { + // some providers don't support this DN syntax + AssertJUnit.assertEquals(ResultCode.DECODING_ERROR, e.getResultCode()); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "statsSearchDn", + "statsSearchFilter" + }) + @Test(groups = {"search"}) + public void getStatsSearch(final String dn, final String filter) + throws Exception + { + if (!TestControl.isActiveDirectory()) { + return; + } + + // provider doesn't support this control + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP does not support this control"); + } + + try (Connection conn = createLdapConnection(true)) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final SearchRequest sr = new SearchRequest(dn, new SearchFilter(filter)); + sr.setSearchEntryHandlers(new ObjectSidHandler(), new ObjectGuidHandler()); + sr.setControls(new GetStatsControl()); + + final Response<SearchResult> response = search.execute(sr); + final GetStatsControl ctrl = (GetStatsControl) response.getControl(GetStatsControl.OID); + AssertJUnit.assertTrue(ctrl.getStatistics().size() > 1); + + final LdapAttribute whenCreated = response.getResult().getEntry().getAttribute("whenCreated"); + AssertJUnit.assertNotNull(whenCreated.getValue(new GeneralizedTimeValueTranscoder())); + + final LdapAttribute whenChanged = response.getResult().getEntry().getAttribute("whenChanged"); + AssertJUnit.assertNotNull(whenChanged.getValue(new GeneralizedTimeValueTranscoder())); + } catch (UnsupportedOperationException e) { + // ignore this test if not supported by the provider + AssertJUnit.assertNotNull(e); + } + } + + + /** + * @param host for verify name + * @param dn to search on. + * @param filter to search with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "miscADControlsHost", + "miscADControlsDn", + "miscADControlsFilter" + }) + @Test(groups = {"search"}) + public void miscADControlsSearch(final String host, final String dn, final String filter) + throws Exception + { + if (!TestControl.isActiveDirectory()) { + return; + } + + // provider doesn't support this control + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP does not support this control"); + } + + try (Connection conn = createLdapConnection(true)) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final SearchRequest sr = new SearchRequest(dn, new SearchFilter(filter)); + sr.setSearchEntryHandlers(new ObjectSidHandler(), new ObjectGuidHandler()); + sr.setControls( + new ForceUpdateControl(), + new LazyCommitControl(), + /* + * new NotificationControl()); + * new VerifyNameControl(host)); + */ + new PermissiveModifyControl(), + new RangeRetrievalNoerrControl(), + new SearchOptionsControl(), + new ShowDeactivatedLinkControl(), + new ShowDeletedControl(), + new ShowRecycledControl()); + search.execute(sr); + } catch (UnsupportedOperationException e) { + // ignore this test if not supported by the provider + AssertJUnit.assertNotNull(e); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param filterParameters to replace parameters in filter with. + * @param binaryFilter to search for binary attributes. + * @param binaryFilterParameters to replace parameters in binary filter with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "specialCharSearchDn", + "specialCharSearchFilter", + "specialCharSearchFilterParameters", + "specialCharBinarySearchFilter", + "specialCharBinarySearchFilterParameters", + "specialCharReturnAttrs", + "specialCharSearchResults" + }) + @Test(groups = {"search"}) + public void specialCharsSearch( + final String dn, + final String filter, + final String filterParameters, + final String binaryFilter, + final String binaryFilterParameters, + final String returnAttrs, + final String ldifFile) + throws Exception + { + final SearchOperation search = new SearchOperation(createLdapConnection(false)); + final String expected = TestUtils.readFileIntoString(ldifFile); + final SearchResult specialCharsResult = TestUtils.convertLdifToResult(expected); + + SearchResult result = search.execute( + new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), returnAttrs.split("\\|"))).getResult(); + // DNs returned from JNDI may have escaped characters + result.getEntry().setDn(result.getEntry().getDn().replaceAll("\\\\", "")); + TestUtils.assertEquals(specialCharsResult, result); + + result = search.execute( + new SearchRequest( + dn, + new SearchFilter( + binaryFilter, + new Object[] {LdapUtils.base64Decode(binaryFilterParameters)}), + returnAttrs.split("\\|"))).getResult(); + // DNs returned from JNDI may have escaped characters + result.getEntry().setDn(result.getEntry().getDn().replaceAll("\\\\", "")); + TestUtils.assertEquals(specialCharsResult, result); + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "rewriteSearchDn", + "rewriteSearchFilter", + "rewriteSearchResults" + }) + @Test(groups = {"search"}) + public void rewriteSearch(final String dn, final String filter, final String ldifFile) + throws Exception + { + if (TestControl.isActiveDirectory()) { + return; + } + + final String expected = TestUtils.readFileIntoString(ldifFile); + final SearchResult specialCharsResult = TestUtils.convertLdifToResult(expected); + specialCharsResult.getEntry().setDn(specialCharsResult.getEntry().getDn().replaceAll("\\\\", "")); + + try (Connection conn = createLdapConnection(true)) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + + // test special character searching + final SearchRequest request = new SearchRequest(dn, new SearchFilter(filter)); + final SearchResult result = search.execute(request).getResult(); + TestUtils.assertEquals(specialCharsResult, result); + } catch (LdapException e) { + // ignore this test if not supported by the server + AssertJUnit.assertEquals(ResultCode.NO_SUCH_OBJECT, e.getResultCode()); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param resultsSize of search results. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "searchExceededDn", + "searchExceededFilter", + "searchExceededResultsSize" + }) + @Test(groups = {"search"}) + public void searchExceeded(final String dn, final String filter, final int resultsSize) + throws Exception + { + try (Connection conn = createLdapConnection(true)) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final SearchRequest request = new SearchRequest(); + request.setBaseDn(dn); + request.setSizeLimit(resultsSize); + + request.setSearchFilter(new SearchFilter("(uugid=*)")); + + Response<SearchResult> response = search.execute(request); + AssertJUnit.assertEquals(resultsSize, response.getResult().size()); + AssertJUnit.assertEquals(ResultCode.SIZE_LIMIT_EXCEEDED, response.getResultCode()); + + request.setSearchFilter(new SearchFilter(filter)); + response = search.execute(request); + AssertJUnit.assertEquals(resultsSize, response.getResult().size()); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "searchReferralDn", + "searchReferralFilter" + }) + @Test(groups = {"search"}) + public void searchReferral(final String dn, final String filter) + throws Exception + { + if (TestControl.isActiveDirectory() || TestControl.isOracleDirectory()) { + return; + } + + final Connection conn = createLdapConnection(true); + + // expects a referral on the dn ou=referrals + final String referralDn = "ou=referrals," + DnParser.substring(dn, 1); + final SearchRequest request = new SearchRequest(); + request.setBaseDn(referralDn); + request.setSearchScope(SearchScope.ONELEVEL); + request.setReturnAttributes(ReturnAttributes.NONE.value()); + request.setSearchFilter(new SearchFilter(filter)); + + try { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + try { + final Response<SearchResult> response = search.execute(request); + AssertJUnit.assertEquals(ResultCode.REFERRAL, response.getResultCode()); + AssertJUnit.assertTrue(response.getReferralURLs().length > 0); + for (String s : response.getReferralURLs()) { + AssertJUnit.assertTrue(response.getReferralURLs()[0].startsWith(conn.getConnectionConfig().getLdapUrl())); + } + } catch (LdapException e) { + AssertJUnit.assertEquals(ResultCode.REFERRAL, e.getResultCode()); + AssertJUnit.assertTrue(e.getReferralURLs().length > 0); + for (String s : e.getReferralURLs()) { + AssertJUnit.assertTrue(e.getReferralURLs()[0].startsWith(conn.getConnectionConfig().getLdapUrl())); + } + } + } finally { + conn.close(); + } + + request.setReferralHandler(new SearchReferralHandler()); + try { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + try { + final Response<SearchResult> response = search.execute(request); + if (response.getResultCode() == ResultCode.SUCCESS) { + AssertJUnit.assertTrue(response.getResult().size() > 0); + } else { + // some providers don't support authenticated referrals + AssertJUnit.assertEquals(ResultCode.REFERRAL, response.getResultCode()); + } + } catch (UnsupportedOperationException e) { + // ignore this test if not supported + AssertJUnit.assertNotNull(e); + } + } finally { + conn.close(); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "searchReferenceDn", + "searchReferenceFilter" + }) + @Test(groups = {"search"}) + public void searchReference(final String dn, final String filter) + throws Exception + { + if (TestControl.isActiveDirectory() || TestControl.isOracleDirectory()) { + return; + } + + final Connection conn = createLdapConnection(true); + final List<SearchReference> refs = new ArrayList<>(); + + // expects a referral on the root dn + final String referralDn = DnParser.substring(dn, 1); + final SearchRequest request = new SearchRequest(); + request.setBaseDn(referralDn); + request.setSearchScope(SearchScope.ONELEVEL); + request.setReturnAttributes(ReturnAttributes.NONE.value()); + request.setSearchFilter(new SearchFilter(filter)); + request.setSearchReferenceHandlers( + new SearchReferenceHandler() { + @Override + public HandlerResult<SearchReference> handle( + final Connection conn, + final SearchRequest request, + final SearchReference reference) + throws LdapException + { + refs.add(reference); + return new HandlerResult<>(reference); + } + + @Override + public void initializeRequest(final SearchRequest request) {} + }); + + try { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final Response<SearchResult> response = search.execute(request); + AssertJUnit.assertTrue(response.getResult().size() > 0); + // some providers don't support search references + // in that case URLs are provided on the response + if (refs.size() > 0) { + AssertJUnit.assertTrue(refs.size() > 0); + for (SearchReference r : refs) { + AssertJUnit.assertNotNull(r.getReferralUrls()); + for (String s : r.getReferralUrls()) { + AssertJUnit.assertNotNull(s); + } + } + } else { + AssertJUnit.assertTrue(response.getReferralURLs().length > 0); + for (String s : response.getReferralURLs()) { + AssertJUnit.assertTrue(response.getReferralURLs()[0].startsWith(conn.getConnectionConfig().getLdapUrl())); + } + } + // providers may return either result code + if (response.getResultCode() != ResultCode.SUCCESS && response.getResultCode() != ResultCode.REFERRAL) { + AssertJUnit.fail("Invalid result code: " + response); + } + } finally { + conn.close(); + } + + refs.clear(); + request.setReferralHandler(new SearchReferralHandler(3)); + try { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + try { + final Response<SearchResult> response = search.execute(request); + // providers may return either result code + if ( + response.getResultCode() != ResultCode.SUCCESS && + response.getResultCode() != ResultCode.REFERRAL && + response.getResultCode() != ResultCode.PARTIAL_RESULTS) { + AssertJUnit.fail("Invalid result code: " + response); + } + AssertJUnit.assertTrue(response.getResult().size() > 0); + } catch (LdapException e) { + if (e.getCause() instanceof UnsupportedOperationException) { + // ignore this test if not supported + AssertJUnit.assertNotNull(e); + } else { + AssertJUnit.assertEquals(ResultCode.REFERRAL, e.getResultCode()); + } + } catch (UnsupportedOperationException e) { + // ignore this test if not supported + AssertJUnit.assertNotNull(e); + } + } finally { + conn.close(); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "searchActiveDirectoryDn", + "searchActiveDirectoryFilter" + }) + @Test(groups = {"search"}) + public void searchActiveDirectory(final String dn, final String filter) + throws Exception + { + if (!TestControl.isActiveDirectory()) { + return; + } + + final Connection conn = createLdapConnection(true); + final List<SearchReference> refs = new ArrayList<>(); + + // expects a referral on the root dn + final String referralDn = DnParser.substring(dn, 1); + final SearchRequest request = new SearchRequest(); + request.setBaseDn(referralDn); + request.setSearchScope(SearchScope.ONELEVEL); + request.setReturnAttributes(ReturnAttributes.NONE.value()); + request.setSearchFilter(new SearchFilter(filter)); + request.setSearchEntryHandlers(new ObjectSidHandler(), new ObjectGuidHandler(), new PrimaryGroupIdHandler()); + request.setSearchReferenceHandlers( + new SearchReferenceHandler() { + @Override + public HandlerResult<SearchReference> handle( + final Connection conn, + final SearchRequest request, + final SearchReference reference) + throws LdapException + { + refs.add(reference); + return new HandlerResult<>(reference); + } + + @Override + public void initializeRequest(final SearchRequest request) {} + }); + + try { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final Response<SearchResult> response = search.execute(request); + AssertJUnit.assertTrue(response.getResult().size() > 0); + // some providers don't support search references + // in that case URLs are provided on the response + if (refs.size() > 0) { + AssertJUnit.assertTrue(refs.size() > 0); + for (SearchReference r : refs) { + AssertJUnit.assertNotNull(r.getReferralUrls()); + for (String s : r.getReferralUrls()) { + AssertJUnit.assertNotNull(s); + } + } + } else { + AssertJUnit.assertTrue(response.getReferralURLs().length > 0); + for (String s : response.getReferralURLs()) { + AssertJUnit.assertNotNull(s); + } + } + // AssertJUnit.assertTrue(response.getReferralURLs().length > 0); + // providers may return either result code + if (response.getResultCode() != ResultCode.SUCCESS && response.getResultCode() != ResultCode.REFERRAL) { + AssertJUnit.fail("Invalid result code: " + response); + } + } finally { + conn.close(); + } + + refs.clear(); + request.setReferralHandler(new SearchReferralHandler()); + try { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + try { + final Response<SearchResult> response = search.execute(request); + AssertJUnit.assertTrue(response.getResult().size() > 0); + // AssertJUnit.assertNull(response.getReferralURLs()); + // AD referrals cannot be followed + // providers may return either result code + if (response.getResultCode() != ResultCode.SUCCESS && response.getResultCode() != ResultCode.PARTIAL_RESULTS) { + AssertJUnit.fail("Invalid result code: " + response); + } + } catch (LdapException e) { + // some providers throw referral exception here + AssertJUnit.assertEquals(ResultCode.REFERRAL, e.getResultCode()); + } catch (UnsupportedOperationException e) { + // ignore this test if referrals not supported + AssertJUnit.assertNotNull(e); + } + } finally { + conn.close(); + } + } + + + /** + * @param dn to search on. + * @param resultCode to retry operations on. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "searchRetryDn", + "searchRetryResultCode" + }) + @Test(groups = {"search-with-retry"}, dependsOnGroups = {"search"}) + public void searchWithRetry(final String dn, final String resultCode) + throws Exception + { + final ResultCode retryResultCode = ResultCode.valueOf(resultCode); + final ConnectionConfig cc = TestUtils.readConnectionConfig(null); + DefaultConnectionFactory cf = new DefaultConnectionFactory(cc); + cf.getProvider().getProviderConfig().setOperationExceptionResultCodes(retryResultCode); + + Connection conn = cf.getConnection(); + RetrySearchOperation search = new RetrySearchOperation( + conn, + new LdapException("Retry search exception", ResultCode.NO_SUCH_OBJECT)); + + try { + conn.open(); + + // test no retry + search.setAllowRetry(false); + try { + final Response<SearchResult> response = search.execute( + new SearchRequest(dn, new SearchFilter("(objectclass=*)"))); + AssertJUnit.fail("Should have thrown LdapException, returned: " + response); + } catch (LdapException e) { + AssertJUnit.assertEquals(ResultCode.NO_SUCH_OBJECT, e.getResultCode()); + } + AssertJUnit.assertEquals(0, search.getRetryCount()); + AssertJUnit.assertEquals(0, search.getRunTime()); + } finally { + conn.close(); + } + + // test no exception + search.setAllowRetry(true); + cf = new DefaultConnectionFactory(cc); + cf.getProvider().getProviderConfig().setOperationExceptionResultCodes((ResultCode[]) null); + conn = cf.getConnection(); + search = new RetrySearchOperation(conn, new LdapException("Retry search exception", ResultCode.NO_SUCH_OBJECT)); + + try { + conn.open(); + try { + final Response<SearchResult> response = search.execute( + new SearchRequest(dn, new SearchFilter("(objectclass=*)"))); + AssertJUnit.assertEquals(ResultCode.NO_SUCH_OBJECT, response.getResultCode()); + } catch (LdapException e) { + AssertJUnit.assertEquals(ResultCode.NO_SUCH_OBJECT, e.getResultCode()); + } + AssertJUnit.assertEquals(0, search.getRetryCount()); + AssertJUnit.assertEquals(0, search.getRunTime()); + } finally { + conn.close(); + } + + // test retry count and wait time + cf = new DefaultConnectionFactory(cc); + cf.getProvider().getProviderConfig().setOperationExceptionResultCodes(retryResultCode); + conn = cf.getConnection(); + search = new RetrySearchOperation(conn, new LdapException("Retry search exception", ResultCode.NO_SUCH_OBJECT)); + search.setReopenRetry(3); + search.setReopenRetryWait(1); + + try { + conn.open(); + try { + final Response<SearchResult> response = search.execute( + new SearchRequest(dn, new SearchFilter("(objectclass=*)"))); + AssertJUnit.fail("Should have thrown LdapException, returned: " + response); + } catch (LdapException e) { + AssertJUnit.assertEquals(ResultCode.NO_SUCH_OBJECT, e.getResultCode()); + } + AssertJUnit.assertEquals(3, search.getRetryCount()); + AssertJUnit.assertTrue(search.getRunTime() > 0); + + // test backoff interval + search.reset(); + search.setReopenRetryBackoff(2); + try { + final Response<SearchResult> response = search.execute( + new SearchRequest(dn, new SearchFilter("(objectclass=*)"))); + AssertJUnit.fail("Should have thrown LdapException, returned: " + response); + } catch (LdapException e) { + AssertJUnit.assertEquals(ResultCode.NO_SUCH_OBJECT, e.getResultCode()); + } + AssertJUnit.assertEquals(3, search.getRetryCount()); + AssertJUnit.assertTrue(search.getRunTime() > 0); + + // test infinite retries + search.reset(); + search.setStopCount(10); + search.setReopenRetry(-1); + try { + final Response<SearchResult> response = search.execute( + new SearchRequest(dn, new SearchFilter("(objectclass=*)"))); + AssertJUnit.fail("Should have thrown LdapException, returned: " + response); + } catch (LdapException e) { + AssertJUnit.assertEquals(ResultCode.NO_SUCH_OBJECT, e.getResultCode()); + } + AssertJUnit.assertEquals(10, search.getRetryCount()); + AssertJUnit.assertTrue(search.getRunTime() > 0); + } finally { + conn.close(); + } + } + + + /** + * @param dn to search on. + * @param returnAttrs to return from search. + * @param results to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "getAttributesDn", + "getAttributesReturnAttrs", + "getAttributesResults" + }) + @Test( + groups = {"search"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void getAttributes(final String dn, final String returnAttrs, final String results) + throws Exception + { + final Connection conn = createLdapConnection(false); + final SearchOperation search = new SearchOperation(conn); + final SearchResult result = search.execute( + SearchRequest.newObjectScopeSearchRequest(dn, returnAttrs.split("\\|"))).getResult(); + TestUtils.assertEquals(TestUtils.convertStringToEntry(dn, results), result.getEntry()); + } + + + /** + * @param dn to search on. + * @param returnAttrs to return from search. + * @param results to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "getAttributesBase64Dn", + "getAttributesBase64ReturnAttrs", + "getAttributesBase64Results" + }) + @Test(groups = {"search"}) + public void getAttributesBase64(final String dn, final String returnAttrs, final String results) + throws Exception + { + try (Connection conn = createLdapConnection(true)) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final SearchRequest request = SearchRequest.newObjectScopeSearchRequest(dn, returnAttrs.split("\\|")); + request.setBinaryAttributes("jpegPhoto"); + + final SearchResult result = search.execute(request).getResult(); + AssertJUnit.assertEquals( + TestUtils.convertStringToEntry(dn, results).getAttribute("jpegPhoto").getStringValue(), + result.getEntry().getAttribute("jpegPhoto").getStringValue()); + } + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"search"}) + public void getSaslMechanisms() + throws Exception + { + try (Connection conn = createLdapConnection(true)) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final SearchResult result = search.execute( + SearchRequest.newObjectScopeSearchRequest("", new String[] {"supportedSASLMechanisms"})).getResult(); + AssertJUnit.assertTrue(result.getEntry().getAttributes().size() > 0); + } + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"search"}) + public void getSupportedControls() + throws Exception + { + try (Connection conn = createLdapConnection(true)) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final SearchResult result = search.execute( + SearchRequest.newObjectScopeSearchRequest("", new String[] {"supportedcontrol"})).getResult(); + AssertJUnit.assertTrue(result.getEntry().getAttributes().size() > 0); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param filterParameters to replace parameters in filter with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "digestMd5SearchDn", + "digestMd5SearchFilter", + "digestMd5SearchFilterParameters", + "digestMd5SearchReturnAttrs", + "digestMd5SearchResults" + }) + @Test(groups = {"search"}) + public void digestMd5Search( + final String dn, + final String filter, + final String filterParameters, + final String returnAttrs, + final String ldifFile) + throws Exception + { + // TODO ignore active directory until it's configured + if (TestControl.isActiveDirectory()) { + return; + } + + final String expected = TestUtils.readFileIntoString(ldifFile); + try (Connection conn = TestUtils.createDigestMd5Connection()) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final SearchResult result = search.execute( + new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), returnAttrs.split("\\|"))).getResult(); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), result); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param filterParameters to replace parameters in filter with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "cramMd5SearchDn", + "cramMd5SearchFilter", + "cramMd5SearchFilterParameters", + "cramMd5SearchReturnAttrs", + "cramMd5SearchResults" + }) + @Test(groups = {"search"}) + public void cramMd5Search( + final String dn, + final String filter, + final String filterParameters, + final String returnAttrs, + final String ldifFile) + throws Exception + { + // TODO ignore active directory until it's configured + if (TestControl.isActiveDirectory()) { + return; + } + + final String expected = TestUtils.readFileIntoString(ldifFile); + try (Connection conn = TestUtils.createCramMd5Connection()) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final SearchResult result = search.execute( + new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), returnAttrs.split("\\|"))).getResult(); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), result); + } catch (LdapException e) { + // ignore this test if not supported by the server + AssertJUnit.assertEquals(ResultCode.AUTH_METHOD_NOT_SUPPORTED, e.getResultCode()); + } catch (UnsupportedOperationException e) { + // ignore this test if not supported by the provider + AssertJUnit.assertNotNull(e); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param filterParameters to replace parameters in filter with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "saslExternalSearchDn", + "saslExternalSearchFilter", + "saslExternalSearchFilterParameters", + "saslExternalSearchReturnAttrs", + "saslExternalSearchResults" + }) + @Test(groups = {"search"}) + public void saslExternalSearch( + final String dn, + final String filter, + final String filterParameters, + final String returnAttrs, + final String ldifFile) + throws Exception + { + // TODO ignore active directory until it's configured + if (TestControl.isActiveDirectory()) { + return; + } + + final String expected = TestUtils.readFileIntoString(ldifFile); + Connection conn = null; + try { + conn = TestUtils.createSaslExternalConnection(); + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final SearchResult result = search.execute( + new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), returnAttrs.split("\\|"))).getResult(); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), result); + } catch (UnsupportedOperationException e) { + // ignore this test if not supported + AssertJUnit.assertNotNull(e); + } finally { + if (conn != null) { + conn.close(); + } + } + } + + + /** + * @param krb5Realm kerberos realm + * @param krb5Kdc kerberos kdc + * @param dn to search on. + * @param filter to search with. + * @param filterParameters to replace parameters in filter with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "krb5Realm", + "ldapTestHost", + "gssApiSearchDn", + "gssApiSearchFilter", + "gssApiSearchFilterParameters", + "gssApiSearchReturnAttrs", + "gssApiSearchResults" + }) + @Test(groups = {"search"}) + public void gssApiSearch( + final String krb5Realm, + final String krb5Kdc, + final String dn, + final String filter, + final String filterParameters, + final String returnAttrs, + final String ldifFile) + throws Exception + { + // ignore directory until it's configured + if (TestControl.isActiveDirectory() || TestControl.isOracleDirectory()) { + return; + } + + final LdapURL ldapUrl = new LdapURL(krb5Kdc); + System.setProperty("java.security.auth.login.config", "target/test-classes/ldap_jaas.config"); + System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); + System.setProperty("java.security.krb5.realm", krb5Realm); + System.setProperty("java.security.krb5.kdc", ldapUrl.getEntry().getHostname()); + + final String expected = TestUtils.readFileIntoString(ldifFile); + + try (Connection conn = TestUtils.createGssApiConnection()) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + final SearchResult result = search.execute( + new SearchRequest( + dn, + new SearchFilter(filter, filterParameters.split("\\|")), returnAttrs.split("\\|"))).getResult(); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), result); + } catch (UnsupportedOperationException e) { + // ignore this test if not supported + AssertJUnit.assertNotNull(e); + } finally { + System.clearProperty("java.security.auth.login.config"); + System.clearProperty("javax.security.auth.useSubjectCredsOnly"); + System.clearProperty("java.security.krb5.realm"); + System.clearProperty("java.security.krb5.kdc"); + + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param filterParameters to replace parameters in filter with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "searchDn", + "searchFilter", + "searchFilterParameters", + "searchReturnAttrs", + "searchResults" + }) + @Test(groups = {"search"}) + public void executorSearch( + final String dn, + final String filter, + final String filterParameters, + final String returnAttrs, + final String ldifFile) + throws Exception + { + final SearchExecutor executor = new SearchExecutor(); + executor.setBaseDn(dn); + executor.setSearchFilter(new SearchFilter(filter, filterParameters.split("\\|"))); + executor.setReturnAttributes(returnAttrs.split("\\|")); + + final String expected = TestUtils.readFileIntoString(ldifFile); + + final ConnectionFactory cf = new DefaultConnectionFactory(TestUtils.readConnectionConfig(null)); + SearchResult result = executor.search(cf).getResult(); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), result); + + BlockingConnectionPool pool = new BlockingConnectionPool( + new DefaultConnectionFactory(TestUtils.readConnectionConfig(null))); + pool.setConnectOnCreate(false); + pool.initialize(); + + PooledConnectionFactory pcf = new PooledConnectionFactory(pool); + result = executor.search(pcf).getResult(); + pool.close(); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), result); + + pool = new BlockingConnectionPool(new DefaultConnectionFactory(TestUtils.readConnectionConfig(null))); + pool.setConnectOnCreate(true); + pool.initialize(); + pcf = new PooledConnectionFactory(pool); + result = executor.search(pcf).getResult(); + pool.close(); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), result); + } +}
diff --git a/integration/src/test/java/org/ldaptive/SearchResultIgnoreCaseComparator.java b/integration/src/test/java/org/ldaptive/SearchResultIgnoreCaseComparator.java new file mode 100644 index 0000000..d6ab9bd --- /dev/null +++ b/integration/src/test/java/org/ldaptive/SearchResultIgnoreCaseComparator.java
@@ -0,0 +1,70 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.util.Comparator; + +/** + * Compares two ldap results, ignoring the case of supplied attribute values. + * + * @author Middleware Services + */ +public class SearchResultIgnoreCaseComparator implements Comparator<SearchResult> +{ + + /** names of attributes to ignore the case of. */ + private final String[] attributeNames; + + + /** Creates a new ldap result ignore case comparator that will ignore the case of all attribute values. */ + public SearchResultIgnoreCaseComparator() + { + this((String[]) null); + } + + + /** + * Creates a new ldap result ignore case comparator with the supplied names. If names is null all attributes will be + * case ignored. + * + * @param names of attributes whose case should be ignored + */ + public SearchResultIgnoreCaseComparator(final String... names) + { + attributeNames = names; + } + + + /** + * Compares two ldap results. + * + * @param a first result for the comparison + * @param b second result for the comparison + * + * @return a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater + * than the second. + */ + public int compare(final SearchResult a, final SearchResult b) + { + return lowerCaseResult(a, attributeNames).hashCode() - lowerCaseResult(b, attributeNames).hashCode(); + } + + + /** + * Returns a new ldap result whose attribute values have been lower cased as configured. + * + * @param lr result to copy values from + * @param names of attributes whose case should be ignored + * + * @return ldap result with lower cased attribute values + * + * @throws IllegalArgumentException if a binary attribute is lower cased + */ + public static SearchResult lowerCaseResult(final SearchResult lr, final String... names) + { + final SearchResult lowerCase = new SearchResult(lr.getSortBehavior()); + for (LdapEntry le : lr.getEntries()) { + lowerCase.addEntry(LdapEntryIgnoreCaseComparator.lowerCaseEntry(le, names)); + } + return lowerCase; + } +}
diff --git a/integration/src/test/java/org/ldaptive/SearchResultTest.java b/integration/src/test/java/org/ldaptive/SearchResultTest.java new file mode 100644 index 0000000..396822f --- /dev/null +++ b/integration/src/test/java/org/ldaptive/SearchResultTest.java
@@ -0,0 +1,76 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SearchResult}. + * + * @author Middleware Services + */ +public class SearchResultTest extends AbstractTest +{ + + /** Entry created for tests. */ + private static LdapEntry testLdapEntry; + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry7") + @BeforeClass(groups = {"bean"}) + public void createLdapEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"bean"}) + public void deleteLdapEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + } + + + /** + * @param dn to search for. + * @param filter to search with. + * @param returnAttrs attributes to return from search + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "toSearchResultsDn", + "toSearchResultsFilter", + "toSearchResultsAttrs", + "toSearchResultsResults" + }) + @Test(groups = {"bean"}) + public void toSearchResults(final String dn, final String filter, final String returnAttrs, final String ldifFile) + throws Exception + { + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + + final SearchResult result = search.execute( + new SearchRequest(dn, new SearchFilter(filter), returnAttrs.split("\\|"))).getResult(); + final String expected = TestUtils.readFileIntoString(ldifFile); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), result); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/SkipTestInvokedMethodListener.java b/integration/src/test/java/org/ldaptive/SkipTestInvokedMethodListener.java new file mode 100644 index 0000000..0173109 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/SkipTestInvokedMethodListener.java
@@ -0,0 +1,32 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.testng.IInvokedMethod; +import org.testng.IInvokedMethodListener; +import org.testng.ITestResult; + +/** + * Marks a test as skipped if it's results indicate such. + * + * @author Middleware Services + */ +public class SkipTestInvokedMethodListener implements IInvokedMethodListener +{ + + + @Override + public void afterInvocation(final IInvokedMethod method, final ITestResult testResult) + { + final Throwable t = testResult.getThrowable(); + final String msg = t != null ? t.getMessage() : null; + if (t instanceof UnsupportedOperationException) { + testResult.setStatus(ITestResult.SKIP); + } else if (msg != null && msg.startsWith(UnsupportedOperationException.class.getName())) { + testResult.setStatus(ITestResult.SKIP); + } + } + + + @Override + public void beforeInvocation(final IInvokedMethod method, final ITestResult testResult) {} +}
diff --git a/integration/src/test/java/org/ldaptive/SpringTest.java b/integration/src/test/java/org/ldaptive/SpringTest.java new file mode 100644 index 0000000..fa2b9a9 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/SpringTest.java
@@ -0,0 +1,61 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.ldaptive.pool.BlockingConnectionPool; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.testng.AssertJUnit; +import org.testng.annotations.Test; + +/** + * Unit test for Spring integration. + * + * @author Middleware Services + */ +public class SpringTest +{ + + + /** + * Attempts to load all Spring application context XML files to verify proper wiring. + * + * @throws Exception On test failure. + */ + @Test(groups = {"spring"}) + public void testSpringWiring() + throws Exception + { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + new String[] {"/spring-context.xml", }); + AssertJUnit.assertTrue(context.getBeanDefinitionCount() > 0); + + ConnectionFactory cf = context.getBean("connectionFactory", ConnectionFactory.class); + Connection conn = cf.getConnection(); + try { + conn.open(); + } finally { + conn.close(); + } + + final ClassPathXmlApplicationContext factoryContext = new ClassPathXmlApplicationContext( + new String[] {"/spring-factory-context.xml", }); + AssertJUnit.assertTrue(factoryContext.getBeanDefinitionCount() > 0); + cf = factoryContext.getBean("connectionFactory", ConnectionFactory.class); + conn = cf.getConnection(); + try { + conn.open(); + } finally { + conn.close(); + } + + final ClassPathXmlApplicationContext poolContext = new ClassPathXmlApplicationContext( + new String[] {"/spring-pool-context.xml", }); + AssertJUnit.assertTrue(poolContext.getBeanDefinitionCount() > 0); + + BlockingConnectionPool pool = null; + try { + pool = poolContext.getBean("pool", BlockingConnectionPool.class); + } finally { + pool.close(); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/TestControl.java b/integration/src/test/java/org/ldaptive/TestControl.java new file mode 100644 index 0000000..ddae799 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/TestControl.java
@@ -0,0 +1,233 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import org.ldaptive.provider.Provider; +import org.testng.annotations.AfterSuite; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Parameters; + +/** + * Contains functions that run before and after all tests. + * + * @author Middleware Services + */ +public class TestControl +{ + + /** Attribute to block on. */ + public static final LdapAttribute ATTR_IDLE = new LdapAttribute("mail", "test-idle@ldaptive.org"); + + /** Attribute to block on. */ + public static final LdapAttribute ATTR_RUNNING = new LdapAttribute("mail", "test-running@ldaptive.org"); + + /** Time to wait before checking if lock is available. */ + public static final int WAIT_TIME = 60000; + + /** Type of directory being tested. */ + private static String directoryType; + + /** Type of provider being tested. */ + private static String providerType; + + + /** + * Used by tests to determine if Active Directory is being tested. + * + * @return whether active directory is being tested + */ + public static boolean isActiveDirectory() + { + return "ACTIVE_DIRECTORY".equals(directoryType); + } + + + /** + * Used by tests to determine if Oracle Directory server is being tested. + * + * @return whether oracle directory server is being tested + */ + public static boolean isOracleDirectory() + { + return "ORACLE".equals(directoryType); + } + + + /** + * Used by tests to determine if the JNDI provider is being tested. + * + * @return whether the jndi provider is being tested + */ + public static boolean isJndiProvider() + { + return "JNDI".equals(providerType); + } + + + /** + * Used by tests to determine if the Apache provider is being tested. + * + * @return whether the apache provider is being tested + */ + public static boolean isApacheProvider() + { + return "APACHE".equals(providerType); + } + + + /** + * Used by tests to determine if the OpenDJ provider is being tested. + * + * @return whether the opendj provider is being tested + */ + public static boolean isOpenDJProvider() + { + return "OPENDJ".equals(providerType); + } + + + /** + * Obtains the lock before running all tests. + * + * @param ignoreLock whether to check for the global test lock + * @param bindDn to lock on + * + * @throws Exception on test failure + */ + @BeforeSuite(alwaysRun = true) + @Parameters({ "ldapTestsIgnoreLock", "ldapBindDn" }) + public void setup(final String ignoreLock, final String bindDn) + throws Exception + { + final Provider<?> provider = DefaultConnectionFactory.getDefaultProvider(); + if (provider.getClass().getName().contains("Jndi")) { + providerType = "JNDI"; + } else if (provider.getClass().getName().contains("Apache")) { + providerType = "APACHE"; + } else if (provider.getClass().getName().contains("JLdap")) { + providerType = "JLDAP"; + } else if (provider.getClass().getName().contains("OpenDJ")) { + providerType = "OPENDJ"; + } else if (provider.getClass().getName().contains("UnboundID")) { + providerType = "UNBOUNDID"; + } else { + throw new IllegalStateException("Unknown provider: " + provider); + } + + final Connection conn = TestUtils.createSetupConnection(); + if (!Boolean.valueOf(ignoreLock)) { + boolean isTestRunning = true; + // wait for other tests to finish + int i = 1; + while (isTestRunning) { + try { + conn.open(); + + final CompareOperation compare = new CompareOperation(conn); + isTestRunning = !compare.execute(new CompareRequest(bindDn, ATTR_IDLE)).getResult(); + } finally { + conn.close(); + if (isTestRunning) { + System.err.println("Waiting for test lock..."); + Thread.sleep(WAIT_TIME * i++); + } + } + } + } + try { + conn.open(); + + final ModifyOperation modify = new ModifyOperation(conn); + modify.execute( + new ModifyRequest(bindDn, new AttributeModification(AttributeModificationType.REPLACE, ATTR_RUNNING))); + if (isAD(conn, bindDn)) { + directoryType = "ACTIVE_DIRECTORY"; + } else if (isOracle(conn)) { + directoryType = "ORACLE"; + } else { + directoryType = "LDAP"; + } + } finally { + conn.close(); + } + } + + + /** + * Performs an object level search for the sAMAccountName attribute used by Active Directory. + * + * @param conn to perform compare with + * @param bindDn to perform search on + * + * @return whether the supplied entry is in active directory + * + * @throws Exception On failure. + */ + protected boolean isAD(final Connection conn, final String bindDn) + throws Exception + { + final SearchOperation search = new SearchOperation(conn); + final SearchRequest request = SearchRequest.newObjectScopeSearchRequest( + bindDn, + ReturnAttributes.NONE.value(), + new SearchFilter("(sAMAccountName=*)")); + try { + return search.execute(request).getResult().size() == 1; + } catch (LdapException e) { + if (ResultCode.NO_SUCH_OBJECT == e.getResultCode() || ResultCode.NO_SUCH_ATTRIBUTE == e.getResultCode()) { + return false; + } + throw e; + } + } + + + /** + * Performs an object level search on the root DSE for the vendorName attribute used by Oracle DS. + * + * @param conn to perform compare with + * + * @return whether the supplied entry contains a vendorName attribute identified by Oracle + * + * @throws Exception On failure. + */ + protected boolean isOracle(final Connection conn) + throws Exception + { + final SearchOperation search = new SearchOperation(conn); + final SearchRequest request = SearchRequest.newObjectScopeSearchRequest("", new String[] {"vendorName"}); + try { + final LdapEntry rootDSE = search.execute(request).getResult().getEntry(); + return + rootDSE.getAttribute("vendorName") != null && + rootDSE.getAttribute("vendorName").getStringValue().contains("Oracle"); + } catch (LdapException e) { + if (ResultCode.NO_SUCH_OBJECT == e.getResultCode() || ResultCode.NO_SUCH_ATTRIBUTE == e.getResultCode()) { + return false; + } + throw e; + } + } + + + /** + * Releases the lock after running all tests. + * + * @param bindDn to lock on + * + * @throws Exception on test failure + */ + @AfterSuite(alwaysRun = true) + @Parameters("ldapBindDn") + public void teardown(final String bindDn) + throws Exception + { + try (Connection conn = TestUtils.createSetupConnection()) { + conn.open(); + + // set attribute when tests are finished + final ModifyOperation modify = new ModifyOperation(conn); + modify.execute( + new ModifyRequest(bindDn, new AttributeModification(AttributeModificationType.REPLACE, ATTR_IDLE))); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/TestUtils.java b/integration/src/test/java/org/ldaptive/TestUtils.java new file mode 100644 index 0000000..f39577f --- /dev/null +++ b/integration/src/test/java/org/ldaptive/TestUtils.java
@@ -0,0 +1,406 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; +import org.ldaptive.auth.Authenticator; +import org.ldaptive.auth.NoOpDnResolver; +import org.ldaptive.io.LdifReader; +import org.ldaptive.props.AuthenticatorPropertySource; +import org.ldaptive.props.ConnectionConfigPropertySource; +import org.testng.AssertJUnit; +import org.testng.annotations.DataProvider; + +/** + * Utility methods for ldap tests. + * + * @author Middleware Services + */ +public final class TestUtils +{ + + /** Location of the hostname in the output of netstat. */ + public static final int NETSTAT_HOST_INDEX = 4; + + + /** Default constructor. */ + private TestUtils() {} + + + /** + * @param path to read properties from, if null use default properties + * + * @return connection config + */ + public static ConnectionConfig readConnectionConfig(final String path) + { + final ConnectionConfig cc = new ConnectionConfig(); + ConnectionConfigPropertySource ccSource; + if (path != null) { + ccSource = new ConnectionConfigPropertySource(cc, path); + } else { + ccSource = new ConnectionConfigPropertySource(cc); + } + ccSource.initialize(); + return cc; + } + + + /** + * @param path to read properties from, if null use default properties + * + * @return authenticator + */ + public static Authenticator readAuthenticator(final String path) + { + final Authenticator a = new Authenticator(); + AuthenticatorPropertySource aSource; + if (path != null) { + aSource = new AuthenticatorPropertySource(a, path); + } else { + aSource = new AuthenticatorPropertySource(a); + } + aSource.initialize(); + return a; + } + + + /** + * @return connection + * + * @throws Exception On test failure. + */ + @DataProvider(name = "setup-ldap") + public static Connection createSetupConnection() + throws Exception + { + return + DefaultConnectionFactory.getConnection(readConnectionConfig("classpath:/org/ldaptive/ldap.setup.properties")); + } + + + /** + * @return connection + * + * @throws Exception On test failure. + */ + @DataProvider(name = "ldap") + public static Connection createConnection() + throws Exception + { + return DefaultConnectionFactory.getConnection(readConnectionConfig(null)); + } + + + /** + * @return connection + * + * @throws Exception On test failure. + */ + @DataProvider(name = "sasl-external-ldap") + public static Connection createSaslExternalConnection() + throws Exception + { + return + DefaultConnectionFactory.getConnection(readConnectionConfig("classpath:/org/ldaptive/ldap.external.properties")); + } + + + /** + * @return connection + * + * @throws Exception On test failure. + */ + @DataProvider(name = "digest-md5-ldap") + public static Connection createDigestMd5Connection() + throws Exception + { + return + DefaultConnectionFactory.getConnection( + readConnectionConfig("classpath:/org/ldaptive/ldap.digest-md5.properties")); + } + + + /** + * @return connection + * + * @throws Exception On test failure. + */ + @DataProvider(name = "cram-md5-ldap") + public static Connection createCramMd5Connection() + throws Exception + { + return + DefaultConnectionFactory.getConnection(readConnectionConfig("classpath:/org/ldaptive/ldap.cram-md5.properties")); + } + + + /** + * @return connection + * + * @throws Exception On test failure. + */ + @DataProvider(name = "gss-api-ldap") + public static Connection createGssApiConnection() + throws Exception + { + return + DefaultConnectionFactory.getConnection(readConnectionConfig("classpath:/org/ldaptive/ldap.gssapi.properties")); + } + + + /** + * @return authenticator + * + * @throws Exception On test failure. + */ + @DataProvider(name = "ssl-auth") + public static Authenticator createSSLAuthenticator() + throws Exception + { + return readAuthenticator("classpath:/org/ldaptive/ldap.ssl.properties"); + } + + + /** + * @return authenticator + * + * @throws Exception On test failure. + */ + @DataProvider(name = "ssl-dn-auth") + public static Authenticator createSSLDnAuthenticator() + throws Exception + { + final Authenticator auth = readAuthenticator("classpath:/org/ldaptive/ldap.ssl.properties"); + auth.setDnResolver(new NoOpDnResolver()); + return auth; + } + + + /** + * @return authenticator + * + * @throws Exception On test failure. + */ + @DataProvider(name = "tls-auth") + public static Authenticator createTLSAuthenticator() + throws Exception + { + return readAuthenticator("classpath:/org/ldaptive/ldap.tls.properties"); + } + + + /** + * @return authenticator + * + * @throws Exception On test failure. + */ + @DataProvider(name = "tls-dn-auth") + public static Authenticator createTLSDnAuthenticator() + throws Exception + { + final Authenticator auth = readAuthenticator("classpath:/org/ldaptive/ldap.tls.properties"); + auth.setDnResolver(new NoOpDnResolver()); + return auth; + } + + + /** + * @return authenticator + * + * @throws Exception On test failure. + */ + @DataProvider(name = "digest-md5-auth") + public static Authenticator createDigestMD5Authenticator() + throws Exception + { + final Authenticator auth = readAuthenticator("classpath:/org/ldaptive/ldap.digest-md5.properties"); + auth.setDnResolver(new NoOpDnResolver()); + return auth; + } + + + /** + * @return authenticator + * + * @throws Exception On test failure. + */ + @DataProvider(name = "cram-md5-auth") + public static Authenticator createCramMD5Authenticator() + throws Exception + { + final Authenticator auth = readAuthenticator("classpath:/org/ldaptive/ldap.cram-md5.properties"); + auth.setDnResolver(new NoOpDnResolver()); + return auth; + } + + + /** + * Reads a file on the classpath into a reader. + * + * @param filename to open. + * + * @return reader. + * + * @throws Exception If file cannot be read. + */ + public static BufferedReader readFile(final String filename) + throws Exception + { + return new BufferedReader(new InputStreamReader(TestUtils.class.getResourceAsStream(filename))); + } + + + /** + * Reads a file on the classpath into a string. + * + * @param filename to open. + * + * @return string. + * + * @throws Exception If file cannot be read. + */ + public static String readFileIntoString(final String filename) + throws Exception + { + final StringBuilder result = new StringBuilder(); + try (BufferedReader br = readFile(filename)) { + String line; + while ((line = br.readLine()) != null) { + result.append(line).append(System.getProperty("line.separator")); + } + } + return result.toString(); + } + + + /** + * Converts an ldif to a ldap result. + * + * @param ldif to convert. + * + * @return ldap result. + * + * @throws Exception if ldif cannot be read + */ + public static SearchResult convertLdifToResult(final String ldif) + throws Exception + { + final LdifReader reader = new LdifReader(new StringReader(ldif)); + return reader.read(); + } + + + /** + * Converts a string of the form: givenName=John|sn=Doe into a ldap attributes and stores them in an ldap entry. + * + * @param dn of the entry + * @param attrs to convert. + * + * @return ldap entry with attributes but no dn. + */ + public static LdapEntry convertStringToEntry(final String dn, final String attrs) + { + final LdapEntry le = new LdapEntry(dn); + for (String s : attrs.split("\\|")) { + final String[] nameValuePairs = s.trim().split("=", 2); + if (le.getAttribute(nameValuePairs[0]) != null) { + le.getAttribute(nameValuePairs[0]).addStringValue(nameValuePairs[1]); + } else { + le.addAttribute(new LdapAttribute(nameValuePairs[0], nameValuePairs[1])); + } + } + return le; + } + + + /** + * Invokes {@link AssertJUnit#assertEquals(Object, Object)} after converting the entries in actual from SearchEntry to + * LdapEntry. + * + * @param expected value + * @param actual value + */ + public static void assertEquals(final SearchResult expected, final SearchResult actual) + { + final SearchResult newResult = new SearchResult(); + for (LdapEntry e : actual.getEntries()) { + newResult.addEntry(new LdapEntry(e.getDn(), e.getAttributes())); + } + AssertJUnit.assertEquals(expected, newResult); + } + + + /** + * Invokes {@link AssertJUnit#assertEquals(Object, Object)} after converting the actual entry to an LdapEntry. + * + * @param expected value + * @param actual value + */ + public static void assertEquals(final LdapEntry expected, final LdapEntry actual) + { + final LdapEntry newEntry = new LdapEntry(actual.getDn(), actual.getAttributes()); + AssertJUnit.assertEquals(expected, newEntry); + } + + + /** + * Returns the number of open connections to the supplied host. Uses 'netstat -al' to uncover open sockets. + * + * @param host host to look for. + * + * @return number of open connections. + * + * @throws IOException if the process cannot be run + */ + public static int countOpenConnections(final String host) + throws IOException + { + final String[] cmd = new String[] {"netstat", "-al"}; + final Process p = new ProcessBuilder(cmd).start(); + final BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); + String line; + final List<String> openConns = new ArrayList<>(); + while ((line = br.readLine()) != null) { + if (line.matches("(.*)ESTABLISHED(.*)")) { + final String s = line.split("\\s+")[NETSTAT_HOST_INDEX]; + openConns.add(s); + } + } + + int count = 0; + for (String o : openConns) { + if (o.contains(host)) { + count++; + } + } + return count; + } + + + /** + * Returns a string representation of the supplied byte array in hex format. + * + * @param bytes to create hex string with + * + * @return hex string + */ + public static String bytesToString(final byte[] bytes) + { + final StringBuilder sb = new StringBuilder(bytes.length * 2); + // CheckStyle:MagicNumber OFF + for (byte b : bytes) { + final int v = b & 0xff; + if (v < 16) { + sb.append('0'); + } + sb.append(Integer.toHexString(v)).append(":"); + } + // CheckStyle:MagicNumber ON + return sb.toString().toUpperCase(); + } +}
diff --git a/integration/src/test/java/org/ldaptive/ad/control/util/DirSyncClientTest.java b/integration/src/test/java/org/ldaptive/ad/control/util/DirSyncClientTest.java new file mode 100644 index 0000000..1caf5f3 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/ad/control/util/DirSyncClientTest.java
@@ -0,0 +1,150 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control.util; + +import org.ldaptive.AbstractTest; +import org.ldaptive.Connection; +import org.ldaptive.LdapEntry; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.ldaptive.ad.control.DirSyncControl; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link DirSyncClient}. + * + * @author Middleware Services + */ +public class DirSyncClientTest extends AbstractTest +{ + + /** Entries created for ldap tests. */ + private static LdapEntry[] testLdapEntries; + + + /** + * @param ldifFile1 to create. + * @param ldifFile2 to create. + * @param ldifFile3 to create. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "createEntry27", + "createEntry28", + "createEntry29" + }) + @BeforeClass(groups = {"control-util"}) + public void createLdapEntry(final String ldifFile1, final String ldifFile2, final String ldifFile3) + throws Exception + { + testLdapEntries = new LdapEntry[3]; + testLdapEntries[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile1)).getEntry(); + super.createLdapEntry(testLdapEntries[0]); + testLdapEntries[1] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile2)).getEntry(); + super.createLdapEntry(testLdapEntries[1]); + testLdapEntries[2] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile3)).getEntry(); + super.createLdapEntry(testLdapEntries[2]); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"control-util"}) + public void deleteLdapEntry() + throws Exception + { + for (LdapEntry testLdapEntry : testLdapEntries) { + super.deleteLdapEntry(testLdapEntry.getDn()); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "dsSearchDn", + "dsSearchFilter" + }) + @Test(groups = {"control-util"}) + public void execute(final String dn, final String filter) + throws Exception + { + if (!TestControl.isActiveDirectory()) { + return; + } + if (TestControl.isOpenDJProvider()) { + throw new UnsupportedOperationException("OpenDJ will not parse DNs used by this control"); + } + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final DirSyncClient client = new DirSyncClient( + conn, + new DirSyncControl.Flag[] {DirSyncControl.Flag.ANCESTORS_FIRST_ORDER, }); + + final SearchRequest request = new SearchRequest( + dn.substring(dn.indexOf(",") + 1, dn.length()), + new SearchFilter(filter), + "uid"); + final Response<SearchResult> response = client.execute(request); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertTrue(response.getResult().size() > 0); + AssertJUnit.assertFalse(client.hasMore(response)); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "dsSearchDn", + "dsSearchFilter" + }) + @Test(groups = {"control-util"}) + public void executeToCompletion(final String dn, final String filter) + throws Exception + { + if (!TestControl.isActiveDirectory()) { + return; + } + if (TestControl.isOpenDJProvider()) { + throw new UnsupportedOperationException("OpenDJ will not parse DNs used by this control"); + } + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final DirSyncClient client = new DirSyncClient( + conn, + new DirSyncControl.Flag[] {DirSyncControl.Flag.ANCESTORS_FIRST_ORDER, }); + + final SearchRequest request = new SearchRequest( + dn.substring(dn.indexOf(",") + 1, dn.length()), + new SearchFilter(filter), + "uid"); + final Response<SearchResult> response = client.executeToCompletion(request); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertTrue(response.getResult().size() > 0); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/ad/control/util/NotificationClientTest.java b/integration/src/test/java/org/ldaptive/ad/control/util/NotificationClientTest.java new file mode 100644 index 0000000..8c090cd --- /dev/null +++ b/integration/src/test/java/org/ldaptive/ad/control/util/NotificationClientTest.java
@@ -0,0 +1,100 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ad.control.util; + +import java.util.Random; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import org.ldaptive.AbstractTest; +import org.ldaptive.AttributeModification; +import org.ldaptive.AttributeModificationType; +import org.ldaptive.Connection; +import org.ldaptive.LdapAttribute; +import org.ldaptive.ModifyOperation; +import org.ldaptive.ModifyRequest; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchScope; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.ldaptive.async.AsyncRequest; +import org.testng.AssertJUnit; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link NotificationClient}. + * + * @author Middleware Services + */ +public class NotificationClientTest extends AbstractTest +{ + + + /** + * @param dn to search on. + * + * @throws Exception On test failure. + */ + @Parameters("ncSearchDn") + @Test(groups = {"control-util"}) + public void execute(final String dn) + throws Exception + { + if (!TestControl.isActiveDirectory()) { + return; + } + + // provider doesn't support this control + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP does not support this control"); + } + + final Connection conn = TestUtils.createConnection(); + try { + conn.open(); + + final NotificationClient client = new NotificationClient(conn); + + final SearchRequest request = new SearchRequest( + "ou=test,dc=middleware,dc=vt,dc=edu", + new SearchFilter("(objectClass=*)")); + request.setSearchScope(SearchScope.ONELEVEL); + + final BlockingQueue<NotificationClient.NotificationItem> results = client.execute(request); + + NotificationClient.NotificationItem item = results.poll(5, TimeUnit.SECONDS); + AssertJUnit.assertNotNull(item); + if (item.isException()) { + throw item.getException(); + } + AssertJUnit.assertTrue(item.isAsyncRequest()); + AssertJUnit.assertTrue(item.getAsyncRequest().getMessageId() > 0); + + final AsyncRequest asyncRequest = item.getAsyncRequest(); + + final ModifyOperation modify = new ModifyOperation(conn); + modify.execute( + new ModifyRequest( + dn, + new AttributeModification( + AttributeModificationType.REPLACE, + new LdapAttribute("sn", Integer.toString(new Random().nextInt(1000000)))))); + + item = results.poll(5, TimeUnit.SECONDS); + AssertJUnit.assertNotNull(item); + AssertJUnit.assertTrue(item.isEntry()); + AssertJUnit.assertNotNull(item.getEntry()); + + asyncRequest.abandon(); + + } finally { + final ModifyOperation modify = new ModifyOperation(conn); + modify.execute( + new ModifyRequest( + dn, + new AttributeModification(AttributeModificationType.REPLACE, new LdapAttribute("sn", "Admin")))); + + conn.close(); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/async/AsyncSearchOperationTest.java b/integration/src/test/java/org/ldaptive/async/AsyncSearchOperationTest.java new file mode 100644 index 0000000..a6d861b --- /dev/null +++ b/integration/src/test/java/org/ldaptive/async/AsyncSearchOperationTest.java
@@ -0,0 +1,91 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.async; + +import java.util.concurrent.ExecutionException; +import org.ldaptive.AbstractTest; +import org.ldaptive.Connection; +import org.ldaptive.LdapEntry; +import org.ldaptive.ResultCode; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.TestUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link AsyncSearchOperation}. + * + * @author Middleware Services + */ +public class AsyncSearchOperationTest extends AbstractTest +{ + + /** Entry created for ldap tests. */ + private static LdapEntry testLdapEntry; + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry17") + @BeforeClass(groups = {"async"}) + public void createLdapEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"async"}) + public void deleteLdapEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + } + + + /** + * @param dn to search on. + * @param filter to search with. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "searchAsyncDn", + "searchAsyncFilter", + "searchAsyncReturnAttrs", + "searchAsyncResults" + }) + @Test(groups = {"async"}) + public void search(final String dn, final String filter, final String returnAttrs, final String ldifFile) + throws Exception + { + + final String expected = TestUtils.readFileIntoString(ldifFile); + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final AsyncSearchOperation search = new AsyncSearchOperation(conn); + final SearchRequest request = new SearchRequest(dn, new SearchFilter(filter), returnAttrs.split("\\|")); + final FutureResponse<SearchResult> response = search.execute(request); + AssertJUnit.assertTrue(response.getResult().size() > 0); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), response.getResult()); + } catch (ExecutionException | IllegalStateException e) { + throw (Exception) e.getCause(); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/auth/AuthenticatorLoadTest.java b/integration/src/test/java/org/ldaptive/auth/AuthenticatorLoadTest.java new file mode 100644 index 0000000..93e5436 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/auth/AuthenticatorLoadTest.java
@@ -0,0 +1,383 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.HashMap; +import java.util.Map; +import org.ldaptive.AbstractTest; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.ConnectionFactoryManager; +import org.ldaptive.Credential; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.LdapEntry; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.ldaptive.ad.extended.FastBindOperation; +import org.ldaptive.pool.BlockingConnectionPool; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.pool.PooledConnectionFactoryManager; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Load test for {@link Authenticator}. + * + * @author Middleware Services + */ +public class AuthenticatorLoadTest extends AbstractTest +{ + + /** Invalid password test data. */ + public static final String INVALID_PASSWD = "not-a-password"; + + /** Invalid filter test data. */ + public static final String INVALID_FILTER = "(departmentNumber=1111)"; + + /** Entries for auth tests. */ + private static final Map<String, LdapEntry[]> ENTRIES = new HashMap<>(); + + /** + * Initialize the map of entries. + */ + static { + for (int i = 2; i <= 10; i++) { + ENTRIES.put(String.valueOf(i), new LdapEntry[2]); + } + } + + /** Authenticator instance for concurrency testing. */ + private final Authenticator singleTLSAuth; + + /** Authenticator instance for concurrency testing. */ + private final Authenticator pooledTLSAuth; + + /** Authenticator instance for concurrency testing. */ + private final Authenticator singleADFastBind; + + /** Authenticator instance for concurrency testing. */ + private final Authenticator pooledADFastBind; + + + /** + * Default constructor. + * + * @throws Exception if ldap cannot be constructed + */ + public AuthenticatorLoadTest() + throws Exception + { + singleTLSAuth = TestUtils.readAuthenticator("classpath:/org/ldaptive/ldap.tls.load.properties"); + pooledTLSAuth = TestUtils.readAuthenticator("classpath:/org/ldaptive/ldap.tls.load.properties"); + singleADFastBind = TestUtils.readAuthenticator("classpath:/org/ldaptive/ldap.tls.load.properties"); + pooledADFastBind = TestUtils.readAuthenticator("classpath:/org/ldaptive/ldap.tls.load.properties"); + } + + + /** + * @param ldifFile2 to create. + * @param ldifFile3 to create. + * @param ldifFile4 to create. + * @param ldifFile5 to create. + * @param ldifFile6 to create. + * @param ldifFile7 to create. + * @param ldifFile8 to create. + * @param ldifFile9 to create. + * @param ldifFile10 to create. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "createEntry2", + "createEntry3", + "createEntry4", + "createEntry5", + "createEntry6", + "createEntry7", + "createEntry8", + "createEntry9", + "createEntry10" + }) + @BeforeClass(groups = {"authload"}) + // CheckStyle:ParameterNumber OFF + public void createAuthEntry( + final String ldifFile2, + final String ldifFile3, + final String ldifFile4, + final String ldifFile5, + final String ldifFile6, + final String ldifFile7, + final String ldifFile8, + final String ldifFile9, + final String ldifFile10) + throws Exception + { + // initialize the pooled authenticator + DefaultConnectionFactory drcf = (DefaultConnectionFactory) + ((ConnectionFactoryManager) pooledTLSAuth.getDnResolver()).getConnectionFactory(); + BlockingConnectionPool resolverCp = new BlockingConnectionPool(drcf); + resolverCp.initialize(); + + PooledConnectionFactory drFactory = new PooledConnectionFactory(resolverCp); + PooledSearchDnResolver dr = new PooledSearchDnResolver(drFactory); + dr.setBaseDn(((SearchDnResolver) pooledTLSAuth.getDnResolver()).getBaseDn()); + dr.setUserFilter(((SearchDnResolver) pooledTLSAuth.getDnResolver()).getUserFilter()); + pooledTLSAuth.setDnResolver(dr); + + DefaultConnectionFactory ahcf = (DefaultConnectionFactory) + ((ConnectionFactoryManager) pooledTLSAuth.getAuthenticationHandler()).getConnectionFactory(); + ConnectionConfig ahcc = ConnectionConfig.newConnectionConfig(ahcf.getConnectionConfig()); + ahcc.setConnectionInitializer(null); + ahcf.setConnectionConfig(ahcc); + + BlockingConnectionPool ahCp = new BlockingConnectionPool(ahcf); + ahCp.initialize(); + + PooledConnectionFactory ahFactory = new PooledConnectionFactory(ahCp); + pooledTLSAuth.setAuthenticationHandler(new PooledBindAuthenticationHandler(ahFactory)); + + // initialize the ad authenticator + if (TestControl.isActiveDirectory()) { + ahcf = (DefaultConnectionFactory) + ((ConnectionFactoryManager) singleADFastBind.getAuthenticationHandler()).getConnectionFactory(); + ahcc = ConnectionConfig.newConnectionConfig(ahcf.getConnectionConfig()); + ahcc.setConnectionInitializer(new FastBindOperation.FastBindConnectionInitializer()); + ((BindAuthenticationHandler) singleADFastBind.getAuthenticationHandler()).setConnectionFactory( + new DefaultConnectionFactory(ahcc)); + // initialize the pooled ad authenticator + drcf = (DefaultConnectionFactory) ((SearchDnResolver) pooledADFastBind.getDnResolver()).getConnectionFactory(); + resolverCp = new BlockingConnectionPool(drcf); + resolverCp.initialize(); + drFactory = new PooledConnectionFactory(resolverCp); + dr = new PooledSearchDnResolver(drFactory); + dr.setBaseDn(((SearchDnResolver) pooledADFastBind.getDnResolver()).getBaseDn()); + dr.setUserFilter(((SearchDnResolver) pooledADFastBind.getDnResolver()).getUserFilter()); + pooledADFastBind.setDnResolver(dr); + + ahcf = (DefaultConnectionFactory) + ((ConnectionFactoryManager) pooledADFastBind.getAuthenticationHandler()).getConnectionFactory(); + ahcc = ConnectionConfig.newConnectionConfig(ahcf.getConnectionConfig()); + ahcc.setConnectionInitializer(new FastBindOperation.FastBindConnectionInitializer()); + ahCp = new BlockingConnectionPool(new DefaultConnectionFactory(ahcc)); + ahCp.initialize(); + ahFactory = new PooledConnectionFactory(ahCp); + pooledADFastBind.setAuthenticationHandler(new PooledBindAuthenticationHandler(ahFactory)); + } + + // CheckStyle:Indentation OFF + ENTRIES.get("2")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile2)).getEntry(); + ENTRIES.get("3")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile3)).getEntry(); + ENTRIES.get("4")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile4)).getEntry(); + ENTRIES.get("5")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile5)).getEntry(); + ENTRIES.get("6")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile6)).getEntry(); + ENTRIES.get("7")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile7)).getEntry(); + ENTRIES.get("8")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile8)).getEntry(); + ENTRIES.get("9")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile9)).getEntry(); + ENTRIES.get("10")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile10)).getEntry(); + // CheckStyle:Indentation ON + + for (Map.Entry<String, LdapEntry[]> e : ENTRIES.entrySet()) { + super.createLdapEntry(e.getValue()[0]); + } + } + // CheckStyle:ParameterNumber ON + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"authload"}) + public void deleteAuthEntry() + throws Exception + { + super.deleteLdapEntry(ENTRIES.get("2")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("3")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("4")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("5")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("6")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("7")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("8")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("9")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("10")[0].getDn()); + + final DnResolver dr = pooledTLSAuth.getDnResolver(); + ((PooledConnectionFactoryManager) dr).getConnectionFactory().getConnectionPool().close(); + + final AuthenticationHandler ah = pooledTLSAuth.getAuthenticationHandler(); + ((PooledConnectionFactoryManager) ah).getConnectionFactory().getConnectionPool().close(); + } + + + /** + * Sample authentication data. + * + * @return user authentication data + */ + @DataProvider(name = "auth-data") + public Object[][] createAuthData() + { + return + new Object[][] { + { + "jadams@ldaptive.org", + "password2", + "cn", + "cn=John Adams", + }, + { + "tjefferson@ldaptive.org", + "password3", + "givenName|sn", + "givenName=Thomas|sn=Jefferson", + }, + { + "jmadison@ldaptive.org", + "password4", + "givenName|sn", + "givenName=James|sn=Madison", + }, + { + "jmonroe@ldaptive.org", + "password5", + "givenName|sn", + "givenName=James|sn=Monroe", + }, + { + "jqadams@ldaptive.org", + "password6", + "cn", + "cn=John Quincy Adams", + }, + { + "ajackson@ldaptive.org", + "password7", + "givenName|sn", + "givenName=Andrew|sn=Jackson", + }, + { + "mvburen@ldaptive.org", + "password8", + "givenName|sn", + "givenName=Martin|sn=Buren", + }, + { + "whharrison@ldaptive.org", + "password9", + "givenName|sn", + "givenName=William|sn=Harrison", + }, + { + "jtyler@ldaptive.org", + "password10", + "givenName|sn", + "givenName=John|sn=Tyler", + }, + }; + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * @param returnAttrs to search for. + * @param expectedAttrs to expect from the search. + * + * @throws Exception On test failure. + */ + @Test(groups = "authload", dataProvider = "auth-data", threadPoolSize = 50, invocationCount = 1000, timeOut = 60000) + public void authenticate( + final String user, + final String credential, + final String returnAttrs, + final String expectedAttrs) + throws Exception + { + // test auth with return attributes + final LdapEntry expected = TestUtils.convertStringToEntry(null, expectedAttrs); + final AuthenticationResponse response = singleTLSAuth.authenticate( + new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|"))); + expected.setDn(response.getLdapEntry().getDn()); + TestUtils.assertEquals(expected, response.getLdapEntry()); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * @param returnAttrs to search for. + * @param expectedAttrs to expect from the search. + * + * @throws Exception On test failure. + */ + @Test(groups = {"authload"}, dataProvider = "auth-data", threadPoolSize = 50, invocationCount = 1000, timeOut = 60000) + public void authenticatePooled( + final String user, + final String credential, + final String returnAttrs, + final String expectedAttrs) + throws Exception + { + // test auth with return attributes + final LdapEntry expected = TestUtils.convertStringToEntry(null, expectedAttrs); + final AuthenticationResponse response = pooledTLSAuth.authenticate( + new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|"))); + expected.setDn(response.getLdapEntry().getDn()); + TestUtils.assertEquals(expected, response.getLdapEntry()); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * @param returnAttrs to search for. + * @param expectedAttrs to expect from the search. + * + * @throws Exception On test failure. + */ + @Test(groups = {"authload"}, dataProvider = "auth-data", threadPoolSize = 5, invocationCount = 50, timeOut = 60000) + public void authenticateADFastBind( + final String user, + final String credential, + final String returnAttrs, + final String expectedAttrs) + throws Exception + { + if (!TestControl.isActiveDirectory()) { + return; + } + + // test auth with fast bind + final AuthenticationResponse response = singleADFastBind.authenticate( + new AuthenticationRequest(user, new Credential(credential))); + AssertJUnit.assertTrue(response.getResult()); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * @param returnAttrs to search for. + * @param expectedAttrs to expect from the search. + * + * @throws Exception On test failure. + */ + @Test(groups = {"authload"}, dataProvider = "auth-data", threadPoolSize = 5, invocationCount = 50, timeOut = 60000) + public void authenticatePooledADFastBind( + final String user, + final String credential, + final String returnAttrs, + final String expectedAttrs) + throws Exception + { + if (!TestControl.isActiveDirectory()) { + return; + } + + // test auth with return attributes + final LdapEntry expected = TestUtils.convertStringToEntry(null, expectedAttrs); + final AuthenticationResponse response = pooledADFastBind.authenticate( + new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|"))); + AssertJUnit.assertTrue(response.getResult()); + } +}
diff --git a/integration/src/test/java/org/ldaptive/auth/AuthenticatorTest.java b/integration/src/test/java/org/ldaptive/auth/AuthenticatorTest.java new file mode 100644 index 0000000..77f06cd --- /dev/null +++ b/integration/src/test/java/org/ldaptive/auth/AuthenticatorTest.java
@@ -0,0 +1,1453 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.HashMap; +import java.util.Map; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.ldaptive.AbstractTest; +import org.ldaptive.AttributeModification; +import org.ldaptive.AttributeModificationType; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionFactoryManager; +import org.ldaptive.Credential; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.ModifyOperation; +import org.ldaptive.ModifyRequest; +import org.ldaptive.ResultCode; +import org.ldaptive.ReturnAttributes; +import org.ldaptive.SearchResult; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.ldaptive.auth.ext.ActiveDirectoryAccountState; +import org.ldaptive.auth.ext.ActiveDirectoryAuthenticationResponseHandler; +import org.ldaptive.auth.ext.PasswordPolicyAuthenticationRequestHandler; +import org.ldaptive.auth.ext.PasswordPolicyAuthenticationResponseHandler; +import org.ldaptive.control.AuthorizationIdentityRequestControl; +import org.ldaptive.control.PasswordPolicyControl; +import org.ldaptive.control.RequestControl; +import org.ldaptive.control.SessionTrackingControl; +import org.ldaptive.pool.BlockingConnectionPool; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.pool.PooledConnectionFactoryManager; +import org.ldaptive.velocity.TemplateSearchDnResolver; +import org.ldaptive.velocity.UserContext; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link Authenticator}. + * + * @author Middleware Services + */ +public class AuthenticatorTest extends AbstractTest +{ + + /** Invalid password test data. */ + public static final String INVALID_PASSWD = "not-a-password"; + + /** Invalid filter test data. */ + public static final String INVALID_FILTER = "(departmentNumber=1111)"; + + /** Entry created for auth tests. */ + private static LdapEntry testLdapEntry; + + /** Entry created for auth tests. */ + private static LdapEntry specialCharsLdapEntry2; + + /** Entry created for auth tests. */ + private static LdapEntry specialCharsLdapEntry3; + + /** Authenticator instance for concurrency testing. */ + private Authenticator singleTLSAuth; + + /** Authenticator instance for concurrency testing. */ + private Authenticator singleSSLAuth; + + /** Authenticator instance for concurrency testing. */ + private Authenticator singleTLSDnAuth; + + /** Authenticator instance for concurrency testing. */ + private Authenticator singleSSLDnAuth; + + /** Authenticator instance for concurrency testing. */ + private Authenticator pooledTLSAuth; + + /** + * Default constructor. + * + * @throws Exception if ldap cannot be constructed + */ + public AuthenticatorTest() + throws Exception + { + singleTLSAuth = TestUtils.createTLSAuthenticator(); + singleSSLAuth = TestUtils.createSSLAuthenticator(); + singleTLSDnAuth = TestUtils.createTLSDnAuthenticator(); + singleSSLDnAuth = TestUtils.createSSLDnAuthenticator(); + pooledTLSAuth = TestUtils.createTLSAuthenticator(); + } + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry6") + @BeforeClass(groups = {"auth"}) + public void createAuthEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + + final AuthenticationHandler ah = pooledTLSAuth.getAuthenticationHandler(); + final DefaultConnectionFactory cf = + (DefaultConnectionFactory) ((ConnectionFactoryManager) ah).getConnectionFactory(); + final BlockingConnectionPool cp = new BlockingConnectionPool(cf); + final PooledConnectionFactory pcf = new PooledConnectionFactory(cp); + pooledTLSAuth.setAuthenticationHandler(new PooledBindAuthenticationHandler(pcf)); + try { + cp.initialize(); + } catch (UnsupportedOperationException e) { + // ignore if not supported + AssertJUnit.assertNotNull(e); + } + } + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createSpecialCharsEntry2") + @BeforeClass(groups = {"auth"}) + public void createSpecialCharsEntry2(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + specialCharsLdapEntry2 = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(specialCharsLdapEntry2); + } + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createSpecialCharsEntry3") + @BeforeClass(groups = {"auth"}) + public void createSpecialCharsEntry3(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + specialCharsLdapEntry3 = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(specialCharsLdapEntry3); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"auth"}, dependsOnGroups = {"authAccountState"}) + public void deleteAuthEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + super.deleteLdapEntry(specialCharsLdapEntry2.getDn()); + super.deleteLdapEntry(specialCharsLdapEntry3.getDn()); + + final AuthenticationHandler ah = pooledTLSAuth.getAuthenticationHandler(); + try { + (((PooledConnectionFactoryManager) ah).getConnectionFactory().getConnectionPool()).close(); + } catch (IllegalStateException e) { + AssertJUnit.fail(e.getMessage()); + } + } + + + /** + * @param createNew whether to construct a new authenticator. + * + * @return authenticator + * + * @throws Exception On authenticator construction failure. + */ + public Authenticator createTLSAuthenticator(final boolean createNew) + throws Exception + { + if (createNew) { + return TestUtils.createTLSAuthenticator(); + } + return singleTLSAuth; + } + + + /** + * @param createNew whether to construct a new authenticator. + * + * @return authenticator + * + * @throws Exception On authenticator construction failure. + */ + public Authenticator createTLSDnAuthenticator(final boolean createNew) + throws Exception + { + if (createNew) { + return TestUtils.createTLSDnAuthenticator(); + } + return singleTLSDnAuth; + } + + + /** + * @param createNew whether to construct a new authenticator. + * + * @return authenticator + * + * @throws Exception On authenticator construction failure. + */ + public Authenticator createSSLAuthenticator(final boolean createNew) + throws Exception + { + if (createNew) { + return TestUtils.createSSLAuthenticator(); + } + return singleSSLAuth; + } + + + /** + * @param createNew whether to construct a new authenticator. + * + * @return authenticator + * + * @throws Exception On authenticator construction failure. + */ + public Authenticator createSSLDnAuthenticator(final boolean createNew) + throws Exception + { + if (createNew) { + return TestUtils.createSSLDnAuthenticator(); + } + return singleSSLDnAuth; + } + + + /** + * @param ldapUrl to check + * @param baseDn to check + */ + @Parameters({ "loadPropertiesUrl", "loadPropertiesBaseDn" }) + @Test(groups = {"auth"}) + public void loadProperties(final String ldapUrl, final String baseDn) + { + final Authenticator auth = TestUtils.readAuthenticator("classpath:/org/ldaptive/ldap.tls.properties"); + final SearchDnResolver dnResolver = (SearchDnResolver) auth.getDnResolver(); + final DefaultConnectionFactory resolverCf = (DefaultConnectionFactory) dnResolver.getConnectionFactory(); + AssertJUnit.assertEquals(ldapUrl, resolverCf.getConnectionConfig().getLdapUrl()); + AssertJUnit.assertEquals(baseDn, ((SearchDnResolver) auth.getDnResolver()).getBaseDn()); + } + + + /** + * @param cn to get dn for. + * @param user to get dn for. + * @param duplicateFilter for user lookups + * + * @throws Exception On test failure. + */ + @Parameters({ "getDnCn", "getDnUser", "getDnDuplicateFilter" }) + @Test(groups = {"auth"}) + public void resolveDn(final String cn, final String user, final String duplicateFilter) + throws Exception + { + final Authenticator auth = createTLSAuthenticator(true); + + // test input + AssertJUnit.assertNull(auth.resolveDn(null)); + AssertJUnit.assertNull(auth.resolveDn(new User(""))); + + final SearchDnResolver resolver = (SearchDnResolver) auth.getDnResolver(); + + // test one level searching + AssertJUnit.assertEquals(testLdapEntry.getDn().toLowerCase(), auth.resolveDn(new User(user)).toLowerCase()); + + // test duplicate DNs + final String filter = resolver.getUserFilter(); + resolver.setUserFilter(duplicateFilter); + try { + auth.resolveDn(new User(user)); + AssertJUnit.fail("Should have thrown LdapException"); + } catch (Exception e) { + AssertJUnit.assertEquals(LdapException.class, e.getClass()); + } + + resolver.setAllowMultipleDns(true); + auth.resolveDn(new User(user)); + resolver.setUserFilter(filter); + resolver.setAllowMultipleDns(false); + + // test subtree searching + resolver.setSubtreeSearch(true); + + final String baseDn = resolver.getBaseDn(); + resolver.setBaseDn(baseDn.substring(baseDn.indexOf(",") + 1)); + AssertJUnit.assertEquals(testLdapEntry.getDn().toLowerCase(), auth.resolveDn(new User(user)).toLowerCase()); + } + + + /** + * @param cn to get dn for. + * @param user to get dn for. + * @param duplicateFilter for user lookups + * + * @throws Exception On test failure. + */ + @Parameters({ "getDnCn", "getDnUser", "getDnDuplicateFilter" }) + @Test(groups = {"auth"}) + public void resolveDnFormat(final String cn, final String user, final String duplicateFilter) + throws Exception + { + final Authenticator auth = createTLSAuthenticator(true); + final SearchDnResolver resolver = (SearchDnResolver) auth.getDnResolver(); + + auth.setDnResolver(new FormatDnResolver("cn=%s,%s", new Object[] {resolver.getBaseDn()})); + AssertJUnit.assertEquals(testLdapEntry.getDn(), auth.resolveDn(new User(cn))); + } + + + /** + * @param cn to get dn for. + * @param user to get dn for. + * @param duplicateFilter for user lookups + * + * @throws Exception On test failure. + */ + @Parameters({ "getDnCn", "getDnUser", "getDnDuplicateFilter" }) + @Test(groups = {"auth"}) + public void resolveDnVelocity(final String cn, final String user, final String duplicateFilter) + throws Exception + { + final Authenticator auth = createTLSAuthenticator(true); + final SearchDnResolver resolver = (SearchDnResolver) auth.getDnResolver(); + + final VelocityEngine engine = new VelocityEngine(); + engine.addProperty("string.resource.loader.class", + "org.apache.velocity.runtime.resource.loader.StringResourceLoader"); + engine.addProperty("resource.loader", "string"); + engine.addProperty("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.NullLogChute"); + engine.init(); + + final VelocityContext context = new VelocityContext(); + context.put("context", new UserContext(user)); + final TemplateSearchDnResolver velocityResolver = new TemplateSearchDnResolver( + resolver.getConnectionFactory(), + engine, + "(|(uid=$context.principal)(mail=$context.principal))"); + velocityResolver.setBaseDn(resolver.getBaseDn()); + auth.setDnResolver(velocityResolver); + AssertJUnit.assertEquals( + testLdapEntry.getDn().toLowerCase(), + auth.resolveDn(new User(null, context)).toLowerCase()); + } + + + /** + * @param user to get dn for. + * + * @throws Exception On test failure. + */ + @Parameters("getDnUser") + @Test(groups = {"auth"}) + public void resolveDnAggregate(final String user) + throws Exception + { + final Authenticator auth = createTLSAuthenticator(true); + final SearchDnResolver sr1 = (SearchDnResolver) auth.getDnResolver(); + final SearchDnResolver sr2 = new SearchDnResolver(); + sr2.setAllowMultipleDns(sr1.getAllowMultipleDns()); + sr2.setConnectionFactory(sr1.getConnectionFactory()); + sr2.setBaseDn(sr1.getBaseDn()); + sr2.setSubtreeSearch(sr1.getSubtreeSearch()); + sr2.setUserFilter(sr1.getUserFilter()); + sr2.setUserFilterParameters(sr1.getUserFilterParameters()); + + final Map<String, DnResolver> resolvers = new HashMap<>(); + resolvers.put("resolver1", sr1); + resolvers.put("resolver2", sr2); + + final AggregateDnResolver resolver = new AggregateDnResolver(resolvers); + auth.setDnResolver(resolver); + + // test input + AssertJUnit.assertNull(auth.resolveDn(null)); + AssertJUnit.assertNull(auth.resolveDn(new User(""))); + + // test duplicate DNs + resolver.setAllowMultipleDns(false); + try { + auth.resolveDn(new User(user)); + AssertJUnit.fail("Should have thrown LdapException"); + } catch (UnsupportedOperationException e) { + // ignore this test if not supported by the provider + AssertJUnit.assertNotNull(e); + } catch (Exception e) { + AssertJUnit.assertEquals(LdapException.class, e.getClass()); + } + + resolver.setAllowMultipleDns(true); + AssertJUnit.assertEquals( + testLdapEntry.getDn().toLowerCase(), auth.resolveDn(new User(user)).toLowerCase().split(":")[1]); + } + + + /** + * @param dn to authenticate. + * @param credential to authenticate with. + * @param returnAttrs to search for. + * @param ldifFile to expect from the search. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateDn", + "authenticateDnCredential", + "authenticateDnReturnAttrs", + "authenticateDnResults" + }) + @Test( + groups = {"auth"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void authenticateDn(final String dn, final String credential, final String returnAttrs, final String ldifFile) + throws Exception + { + // test plain auth + final Authenticator auth = createTLSDnAuthenticator(false); + AuthenticationResponse response = auth.authenticate(new AuthenticationRequest(dn, new Credential(INVALID_PASSWD))); + AssertJUnit.assertFalse(response.getResult()); + + response = auth.authenticate(new AuthenticationRequest(dn, new Credential(credential))); + AssertJUnit.assertTrue(response.getResult()); + + // test auth with return attributes + final String expected = TestUtils.readFileIntoString(ldifFile); + response = auth.authenticate(new AuthenticationRequest(dn, new Credential(credential), returnAttrs.split("\\|"))); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry())); + } + + + /** + * @param dn to authenticate. + * @param credential to authenticate with. + * @param returnAttrs to search for. + * @param ldifFile to expect from the search. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateDn", + "authenticateDnCredential", + "authenticateDnReturnAttrs", + "authenticateDnResults" + }) + @Test( + groups = {"auth"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void authenticateDnSsl( + final String dn, + final String credential, + final String returnAttrs, + final String ldifFile) + throws Exception + { + // test plain auth + final Authenticator auth = createSSLDnAuthenticator(false); + AuthenticationResponse response = auth.authenticate(new AuthenticationRequest(dn, new Credential(INVALID_PASSWD))); + AssertJUnit.assertFalse(response.getResult()); + + response = auth.authenticate(new AuthenticationRequest(dn, new Credential(credential))); + AssertJUnit.assertTrue(response.getResult()); + + // test auth with return attributes + final String expected = TestUtils.readFileIntoString(ldifFile); + response = auth.authenticate(new AuthenticationRequest(dn, new Credential(credential), returnAttrs.split("\\|"))); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry())); + } + + + /** + * @param dn to authenticate. + * @param credential to authenticate with. + * @param filter to authorize with. + * @param filterParameters to authorize with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateDn", + "authenticateDnCredential", + "authenticateDnFilter", + "authenticateDnFilterParameters" + }) + @Test(groups = {"auth"}) + public void authenticateDnHandler( + final String dn, + final String credential, + final String filter, + final String filterParameters) + throws Exception + { + final Authenticator auth = createTLSDnAuthenticator(true); + + final TestAuthenticationResponseHandler authHandler = new TestAuthenticationResponseHandler(); + auth.setAuthenticationResponseHandlers(authHandler); + + AuthenticationResponse response = auth.authenticate(new AuthenticationRequest(dn, new Credential(INVALID_PASSWD))); + AssertJUnit.assertFalse(response.getResult()); + AssertJUnit.assertTrue(!authHandler.getResults().isEmpty()); + AssertJUnit.assertFalse(authHandler.getResults().get(dn)); + + response = auth.authenticate(new AuthenticationRequest(dn, new Credential(credential))); + AssertJUnit.assertTrue(response.getResult()); + AssertJUnit.assertTrue(authHandler.getResults().get(dn)); + + authHandler.getResults().clear(); + + response = auth.authenticate(new AuthenticationRequest(dn, new Credential(credential))); + AssertJUnit.assertTrue(response.getResult()); + AssertJUnit.assertTrue(authHandler.getResults().get(dn)); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters({ "digestMd5User", "digestMd5Credential" }) + @Test(groups = {"auth"}) + public void authenticateDigestMd5(final String user, final String credential) + throws Exception + { + // TODO ignore active directory until it's configured + if (TestControl.isActiveDirectory()) { + return; + } + + final Authenticator auth = TestUtils.createDigestMD5Authenticator(); + + AuthenticationResponse response = auth.authenticate( + new AuthenticationRequest(user, new Credential(INVALID_PASSWD), ReturnAttributes.NONE.value())); + AssertJUnit.assertFalse(response.getResult()); + + response = auth.authenticate( + new AuthenticationRequest(user, new Credential(credential), ReturnAttributes.NONE.value())); + AssertJUnit.assertTrue(response.getResult()); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters({ "cramMd5User", "cramMd5Credential" }) + @Test(groups = {"auth"}) + public void authenticateCramMd5(final String user, final String credential) + throws Exception + { + // TODO ignore active directory until it's configured + if (TestControl.isActiveDirectory()) { + return; + } + + try { + final Authenticator auth = TestUtils.createCramMD5Authenticator(); + AuthenticationResponse response = auth.authenticate( + new AuthenticationRequest(user, new Credential(INVALID_PASSWD), ReturnAttributes.NONE.value())); + AssertJUnit.assertFalse(response.getResult()); + + response = auth.authenticate( + new AuthenticationRequest(user, new Credential(credential), ReturnAttributes.NONE.value())); + AssertJUnit.assertTrue(response.getResult()); + } catch (LdapException e) { + // ignore this test if not supported by the server + AssertJUnit.assertEquals(ResultCode.AUTH_METHOD_NOT_SUPPORTED, e.getResultCode()); + } catch (UnsupportedOperationException e) { + // ignore this test if not supported by the provider + AssertJUnit.assertNotNull(e); + } + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * @param returnAttrs to search for. + * @param ldifFile to expect from the search. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateUser", + "authenticateCredential", + "authenticateReturnAttrs", + "authenticateResults" + }) + @Test( + groups = {"auth"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void authenticate(final String user, final String credential, final String returnAttrs, final String ldifFile) + throws Exception + { + final Authenticator auth = createTLSAuthenticator(false); + + // test invalid user + AuthenticationResponse response = auth.authenticate( + new AuthenticationRequest("i-do-not-exist", new Credential(credential))); + AssertJUnit.assertFalse(response.getResult()); + AssertJUnit.assertEquals(AuthenticationResultCode.DN_RESOLUTION_FAILURE, response.getAuthenticationResultCode()); + AssertJUnit.assertNull(response.getResultCode()); + AssertJUnit.assertNotNull(response.getMessage()); + + // test failed auth with return attributes + response = auth.authenticate( + new AuthenticationRequest(user, new Credential(INVALID_PASSWD), returnAttrs.split("\\|"))); + AssertJUnit.assertFalse(response.getResult()); + AssertJUnit.assertEquals( + AuthenticationResultCode.AUTHENTICATION_HANDLER_FAILURE, + response.getAuthenticationResultCode()); + AssertJUnit.assertEquals(ResultCode.INVALID_CREDENTIALS, response.getResultCode()); + + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential))); + AssertJUnit.assertTrue(response.getResult()); + AssertJUnit.assertEquals( + AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS, + response.getAuthenticationResultCode()); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + + // test auth with return attributes + final String expected = TestUtils.readFileIntoString(ldifFile); + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|"))); + AssertJUnit.assertTrue(response.getResult()); + AssertJUnit.assertEquals( + AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS, + response.getAuthenticationResultCode()); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry())); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * @param returnAttrs to search for. + * @param ldifFile to expect from the search. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateUser", + "authenticateCredential", + "authenticateReturnAttrs", + "authenticateResults" + }) + @Test( + groups = {"auth"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void authenticateSsl( + final String user, + final String credential, + final String returnAttrs, + final String ldifFile) + throws Exception + { + final Authenticator auth = createSSLAuthenticator(false); + + // test plain auth + AuthenticationResponse response = auth.authenticate( + new AuthenticationRequest(user, new Credential(INVALID_PASSWD))); + AssertJUnit.assertFalse(response.getResult()); + + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential))); + AssertJUnit.assertTrue(response.getResult()); + + // test auth with return attributes + final String expected = TestUtils.readFileIntoString(ldifFile); + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|"))); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry())); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * @param filter to authorize with. + * @param returnAttrs to search for. + * @param ldifFile to expect from the search. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateUser", + "authenticateCredential", + "authenticateFilter", + "authenticateReturnAttrs", + "authenticateResults" + }) + @Test( + groups = {"auth"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void authenticatePooled( + final String user, + final String credential, + final String filter, + final String returnAttrs, + final String ldifFile) + throws Exception + { + // test plain auth + AuthenticationResponse response = pooledTLSAuth.authenticate( + new AuthenticationRequest(user, new Credential(INVALID_PASSWD))); + AssertJUnit.assertFalse(response.getResult()); + + response = pooledTLSAuth.authenticate(new AuthenticationRequest(user, new Credential(credential))); + AssertJUnit.assertTrue(response.getResult()); + + // test auth with return attributes + final String expected = TestUtils.readFileIntoString(ldifFile); + response = pooledTLSAuth.authenticate( + new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|"))); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry())); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * @param filter to authorize with. + * @param returnAttrs to search for. + * @param ldifFile to expect from the search. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateUser", + "authenticateCredential", + "authenticateFilter", + "authenticateReturnAttrs", + "authenticateResults" + }) + @Test(groups = {"auth"}) + public void authenticateVelocity( + final String user, + final String credential, + final String filter, + final String returnAttrs, + final String ldifFile) + throws Exception + { + final Authenticator auth = createTLSAuthenticator(true); + final SearchDnResolver resolver = (SearchDnResolver) auth.getDnResolver(); + + final VelocityEngine engine = new VelocityEngine(); + engine.addProperty("string.resource.loader.class", + "org.apache.velocity.runtime.resource.loader.StringResourceLoader"); + engine.addProperty("resource.loader", "string"); + engine.addProperty("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.NullLogChute"); + engine.init(); + + final VelocityContext context = new VelocityContext(); + context.put("context", new UserContext(user)); + final TemplateSearchDnResolver velocityResolver = new TemplateSearchDnResolver( + resolver.getConnectionFactory(), + engine, + "(|(uid=$context.principal)(mail=$context.principal))"); + velocityResolver.setBaseDn(resolver.getBaseDn()); + auth.setDnResolver(velocityResolver); + + // test plain auth + AuthenticationResponse response = auth.authenticate( + new AuthenticationRequest(new User(null, context), new Credential(INVALID_PASSWD))); + AssertJUnit.assertFalse(response.getResult()); + + response = auth.authenticate(new AuthenticationRequest(new User(null, context), new Credential(credential))); + AssertJUnit.assertTrue(response.getResult()); + + // test auth with return attributes + final String expected = TestUtils.readFileIntoString(ldifFile); + response = auth.authenticate( + new AuthenticationRequest(new User(null, context), new Credential(credential), returnAttrs.split("\\|"))); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry())); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * @param returnAttrs to search for. + * @param ldifFile to expect from the search. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateUser", + "authenticateCredential", + "authenticateReturnAttrs", + "authenticateResults" + }) + @Test(groups = {"auth"}) + public void authenticateAggregate( + final String user, + final String credential, + final String returnAttrs, + final String ldifFile) + throws Exception + { + final Authenticator auth = createTLSAuthenticator(true); + final SearchDnResolver sr1 = (SearchDnResolver) auth.getDnResolver(); + final SearchDnResolver sr2 = new SearchDnResolver(); + sr2.setAllowMultipleDns(sr1.getAllowMultipleDns()); + sr2.setConnectionFactory(sr1.getConnectionFactory()); + sr2.setBaseDn(sr1.getBaseDn()); + sr2.setSubtreeSearch(sr1.getSubtreeSearch()); + sr2.setUserFilter(sr1.getUserFilter()); + sr2.setUserFilterParameters(sr1.getUserFilterParameters()); + + final Map<String, DnResolver> dnResolvers = new HashMap<>(); + dnResolvers.put("system1", sr1); + dnResolvers.put("system2", sr2); + + final AggregateDnResolver dnResolver = new AggregateDnResolver(dnResolvers); + auth.setDnResolver(dnResolver); + + final Map<String, AuthenticationHandler> authHandlers = new HashMap<>(); + authHandlers.put("system1", auth.getAuthenticationHandler()); + authHandlers.put("system2", auth.getAuthenticationHandler()); + + final AggregateDnResolver.AuthenticationHandler authHandler = new AggregateDnResolver.AuthenticationHandler(); + authHandler.setAuthenticationHandlers(authHandlers); + auth.setAuthenticationHandler(authHandler); + + // test invalid user + AuthenticationResponse response = auth.authenticate( + new AuthenticationRequest("i-do-not-exist", new Credential(credential))); + AssertJUnit.assertFalse(response.getResult()); + AssertJUnit.assertEquals(AuthenticationResultCode.DN_RESOLUTION_FAILURE, response.getAuthenticationResultCode()); + AssertJUnit.assertNull(response.getResultCode()); + AssertJUnit.assertNotNull(response.getMessage()); + + // test multiple DNs + try { + auth.authenticate(new AuthenticationRequest(user, new Credential(INVALID_PASSWD))); + AssertJUnit.fail("Should have thrown LdapException"); + } catch (Exception e) { + AssertJUnit.assertEquals(LdapException.class, e.getClass()); + } + dnResolver.setAllowMultipleDns(true); + + // test failed auth with return attributes + response = auth.authenticate( + new AuthenticationRequest(user, new Credential(INVALID_PASSWD), returnAttrs.split("\\|"))); + AssertJUnit.assertFalse(response.getResult()); + AssertJUnit.assertEquals( + AuthenticationResultCode.AUTHENTICATION_HANDLER_FAILURE, + response.getAuthenticationResultCode()); + AssertJUnit.assertEquals(ResultCode.INVALID_CREDENTIALS, response.getResultCode()); + + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential))); + AssertJUnit.assertTrue(response.getResult()); + AssertJUnit.assertEquals( + AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS, + response.getAuthenticationResultCode()); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + + // test auth with return attributes + final String expected = TestUtils.readFileIntoString(ldifFile); + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|"))); + AssertJUnit.assertTrue(response.getResult()); + AssertJUnit.assertEquals( + AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS, + response.getAuthenticationResultCode()); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry())); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * @param returnAttrs to search for. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateUser", + "authenticateCredential", + "authenticateReturnAttrs" + }) + @Test(groups = {"auth"}) + public void authenticateInvalidInput(final String user, final String credential, final String returnAttrs) + throws Exception + { + final Authenticator auth = createTLSAuthenticator(true); + + AuthenticationResponse response = auth.authenticate( + new AuthenticationRequest(user, null, returnAttrs.split("\\|"))); + AssertJUnit.assertEquals(AuthenticationResultCode.INVALID_CREDENTIAL, response.getAuthenticationResultCode()); + AssertJUnit.assertNull(response.getResultCode()); + AssertJUnit.assertNotNull(response.getMessage()); + + response = auth.authenticate( + new AuthenticationRequest(user, new Credential(new byte[0]), returnAttrs.split("\\|"))); + AssertJUnit.assertEquals(AuthenticationResultCode.INVALID_CREDENTIAL, response.getAuthenticationResultCode()); + AssertJUnit.assertNull(response.getResultCode()); + AssertJUnit.assertNotNull(response.getMessage()); + + response = auth.authenticate(new AuthenticationRequest(user, new Credential(""), returnAttrs.split("\\|"))); + AssertJUnit.assertEquals(AuthenticationResultCode.INVALID_CREDENTIAL, response.getAuthenticationResultCode()); + AssertJUnit.assertNull(response.getResultCode()); + AssertJUnit.assertNotNull(response.getMessage()); + + response = auth.authenticate( + new AuthenticationRequest((String) null, new Credential(credential), returnAttrs.split("\\|"))); + AssertJUnit.assertEquals(AuthenticationResultCode.DN_RESOLUTION_FAILURE, response.getAuthenticationResultCode()); + AssertJUnit.assertNull(response.getResultCode()); + AssertJUnit.assertNotNull(response.getMessage()); + + response = auth.authenticate(new AuthenticationRequest("", new Credential(credential), returnAttrs.split("\\|"))); + AssertJUnit.assertEquals(AuthenticationResultCode.DN_RESOLUTION_FAILURE, response.getAuthenticationResultCode()); + AssertJUnit.assertNull(response.getResultCode()); + AssertJUnit.assertNotNull(response.getMessage()); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * @param returnAttrs to search for. + * @param ldifFile to expect from the search. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateUser", + "authenticateCredential", + "authenticateReturnAttrs", + "authenticateResults" + }) + @Test(groups = {"auth"}) + public void authenticateReturnAttributes( + final String user, + final String credential, + final String returnAttrs, + final String ldifFile) + throws Exception + { + final String expected = TestUtils.readFileIntoString(ldifFile); + final Authenticator auth = createTLSAuthenticator(true); + + // no attributes + AuthenticationResponse response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential))); + AssertJUnit.assertEquals( + AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS, + response.getAuthenticationResultCode()); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertEquals(0, response.getLdapEntry().getAttributes().size()); + + // attributes on the request + response = auth.authenticate( + new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|"))); + AssertJUnit.assertEquals( + AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS, + response.getAuthenticationResultCode()); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry())); + + // attributes on the authenticator + auth.setReturnAttributes(returnAttrs.split("\\|")); + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential))); + AssertJUnit.assertEquals( + AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS, + response.getAuthenticationResultCode()); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry())); + auth.setReturnAttributes((String) null); + + // NONE attributes on the authenticator + auth.setReturnAttributes(ReturnAttributes.NONE.value()); + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|"))); + AssertJUnit.assertEquals( + AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS, + response.getAuthenticationResultCode()); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry())); + auth.setReturnAttributes((String) null); + + // NONE attributes on the authenticator and request + auth.setReturnAttributes(ReturnAttributes.NONE.value()); + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential))); + AssertJUnit.assertEquals( + AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS, + response.getAuthenticationResultCode()); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertEquals(0, response.getLdapEntry().getAttributes().size()); + auth.setReturnAttributes((String) null); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateSpecialCharsUser2", + "authenticateSpecialCharsCredential2" + }) + @Test(groups = {"auth"}) + public void authenticateSpecialChars2(final String user, final String credential) + throws Exception + { + final Authenticator auth = createTLSAuthenticator(true); + + // test without rewrite + AuthenticationResponse response = auth.authenticate( + new AuthenticationRequest(user, new Credential(INVALID_PASSWD))); + AssertJUnit.assertFalse(response.getResult()); + + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential))); + AssertJUnit.assertTrue(response.getResult()); + + // test with rewrite + + // TODO ignore active directory until it's configured + if (TestControl.isActiveDirectory()) { + return; + } + + ((SearchDnResolver) auth.getDnResolver()).setBaseDn("dc=blah"); + ((SearchDnResolver) auth.getDnResolver()).setSubtreeSearch(true); + response = auth.authenticate(new AuthenticationRequest(user, new Credential(INVALID_PASSWD))); + AssertJUnit.assertFalse(response.getResult()); + + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential))); + AssertJUnit.assertTrue(response.getResult()); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateSpecialCharsUser3", + "authenticateSpecialCharsCredential3" + }) + @Test(groups = {"auth"}) + public void authenticateSpecialChars3(final String user, final String credential) + throws Exception + { + final Authenticator auth = createTLSAuthenticator(true); + + AuthenticationResponse response = auth.authenticate( + new AuthenticationRequest(user, new Credential(INVALID_PASSWD))); + AssertJUnit.assertFalse(response.getResult()); + + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential))); + AssertJUnit.assertTrue(response.getResult()); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * @param returnAttrs to search for. + * @param ldifFile to expect from the search. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateUser", + "authenticateCredential", + "authenticateReturnAttrs", + "authenticateResults" + }) + @Test( + groups = {"auth"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void authenticateSearchEntry( + final String user, + final String credential, + final String returnAttrs, + final String ldifFile) + throws Exception + { + final Authenticator auth = createTLSAuthenticator(false); + final SearchDnResolver dnResolver = (SearchDnResolver) auth.getDnResolver(); + final SearchEntryResolver entryResolver = new SearchEntryResolver(); + entryResolver.setUserFilter(dnResolver.getUserFilter()); + entryResolver.setBaseDn(dnResolver.getBaseDn()); + entryResolver.setSubtreeSearch(dnResolver.getSubtreeSearch()); + auth.setEntryResolver(entryResolver); + + final String expected = TestUtils.readFileIntoString(ldifFile); + final AuthenticationResponse response = auth.authenticate( + new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|"))); + AssertJUnit.assertTrue(response.getResult()); + AssertJUnit.assertEquals( + AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS, + response.getAuthenticationResultCode()); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry())); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * @param returnAttrs to search for. + * @param ldifFile to expect from the search. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateUser", + "authenticateCredential", + "authenticateReturnAttrs", + "authenticateResults" + }) + @Test(groups = {"auth"}) + public void authenticateWhoAmI( + final String user, + final String credential, + final String returnAttrs, + final String ldifFile) + throws Exception + { + if (TestControl.isActiveDirectory()) { + return; + } + + // provider doesn't support this operation + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP does not support this operation"); + } + + final Authenticator auth = createTLSAuthenticator(true); + auth.setEntryResolver(new WhoAmIEntryResolver()); + + final String expected = TestUtils.readFileIntoString(ldifFile); + final AuthenticationResponse response = auth.authenticate( + new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|"))); + AssertJUnit.assertTrue(response.getResult()); + AssertJUnit.assertEquals( + AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS, + response.getAuthenticationResultCode()); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry())); + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * @param returnAttrs to search for. + * @param ldifFile to expect from the search. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateUser", + "authenticateCredential", + "authenticateReturnAttrs", + "authenticateResults" + }) + @Test(groups = {"auth"}) + public void authenticateAuthorizationIdentity( + final String user, + final String credential, + final String returnAttrs, + final String ldifFile) + throws Exception + { + // provider doesn't support this control + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP does not support this control"); + } + + final Authenticator auth = createTLSAuthenticator(true); + final BindAuthenticationHandler ah = (BindAuthenticationHandler) auth.getAuthenticationHandler(); + ah.setAuthenticationControls(new AuthorizationIdentityRequestControl()); + auth.setEntryResolver(new AuthorizationIdentityEntryResolver()); + + final String expected = TestUtils.readFileIntoString(ldifFile); + try { + final AuthenticationResponse response = auth.authenticate( + new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|"))); + AssertJUnit.assertTrue(response.getResult()); + AssertJUnit.assertEquals( + AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS, + response.getAuthenticationResultCode()); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry())); + } catch (IllegalStateException e) { + throw new UnsupportedOperationException("LDAP server does not support this control"); + } + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * @param returnAttrs to search for. + * @param ldifFile to expect from the search. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateUser", + "authenticateCredential", + "authenticateReturnAttrs", + "authenticateResults" + }) + @Test(groups = {"auth"}) + public void authenticateSessionTracking( + final String user, + final String credential, + final String returnAttrs, + final String ldifFile) + throws Exception + { + // provider doesn't support this control + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP does not support this control"); + } + + final Authenticator auth = createTLSAuthenticator(true); + auth.setAuthenticationRequestHandlers( + new AddControlAuthenticationRequestHandler( + (dn, arUser) -> new RequestControl[] { + new SessionTrackingControl("151.101.32.133", "", SessionTrackingControl.USERNAME_ACCT_OID, ""), })); + final String expected = TestUtils.readFileIntoString(ldifFile); + try { + final AuthenticationRequest request = new AuthenticationRequest( + user, + new Credential(credential), + returnAttrs.split("\\|")); + final AuthenticationResponse response = auth.authenticate(request); + AssertJUnit.assertTrue(response.getResult()); + AssertJUnit.assertEquals( + AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS, + response.getAuthenticationResultCode()); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry())); + } catch (IllegalStateException e) { + throw new UnsupportedOperationException("LDAP server does not support this control"); + } + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateUser", + "authenticateCredential" + }) + @AfterClass(groups = {"auth", "authAccountState"}) + public void authenticatePasswordPolicy(final String user, final String credential) + throws Exception + { + if (TestControl.isActiveDirectory()) { + return; + } + + AuthenticationResponse response; + PasswordPolicyControl ppcResponse; + final Authenticator auth = createTLSAuthenticator(true); + auth.setAuthenticationRequestHandlers(new PasswordPolicyAuthenticationRequestHandler()); + auth.setAuthenticationResponseHandlers(new PasswordPolicyAuthenticationResponseHandler()); + try (Connection conn = TestUtils.createSetupConnection()) { + conn.open(); + + // test bind sending ppolicy control + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential))); + + final LdapEntry entry = response.getLdapEntry(); + + // test bind on locked account + final ModifyOperation modify = new ModifyOperation(conn); + modify.execute( + new ModifyRequest( + entry.getDn(), + new AttributeModification( + AttributeModificationType.ADD, + new LdapAttribute("pwdAccountLockedTime", "000001010000Z")))); + + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential))); + AssertJUnit.assertFalse(response.getResult()); + ppcResponse = (PasswordPolicyControl) response.getControl(PasswordPolicyControl.OID); + AssertJUnit.assertEquals(PasswordPolicyControl.Error.ACCOUNT_LOCKED, ppcResponse.getError()); + AssertJUnit.assertEquals( + PasswordPolicyControl.Error.ACCOUNT_LOCKED.getCode(), + response.getAccountState().getError().getCode()); + + // test bind with expiration time + modify.execute( + new ModifyRequest( + entry.getDn(), + new AttributeModification(AttributeModificationType.REMOVE, new LdapAttribute("pwdAccountLockedTime")))); + + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential))); + ppcResponse = (PasswordPolicyControl) response.getControl(PasswordPolicyControl.OID); + AssertJUnit.assertTrue(ppcResponse.getTimeBeforeExpiration() > 0); + AssertJUnit.assertNotNull(response.getAccountState().getWarning().getExpiration()); + + } catch (UnsupportedOperationException e) { + // ignore this test if not supported + AssertJUnit.assertNotNull(e); + } + } + + + /** + * @param user to authenticate. + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "authenticateUser", + "authenticateCredential" + }) + @AfterClass(groups = {"auth", "authAccountState"}) + public void authenticateActiveDirectory(final String user, final String credential) + throws Exception + { + if (!TestControl.isActiveDirectory()) { + return; + } + + final Authenticator auth = createTLSAuthenticator(true); + auth.setAuthenticationResponseHandlers(new ActiveDirectoryAuthenticationResponseHandler()); + auth.setResolveEntryOnFailure(true); + + // success, store the entry for modify operations + // setting return attributes uses the search entry resolver + AuthenticationResponse response = auth.authenticate( + new AuthenticationRequest(user, new Credential(credential), ReturnAttributes.ALL_USER.value())); + AssertJUnit.assertTrue(response.getResult()); + AssertJUnit.assertNull(response.getAccountState()); + + LdapEntry entry = response.getLdapEntry(); + AssertJUnit.assertNotNull(entry.getAttribute("pwdLastSet")); + AssertJUnit.assertNotNull(entry.getAttribute("userAccountControl")); + + // bad password + // setting return attributes uses the search entry resolver + response = auth.authenticate( + new AuthenticationRequest(user, new Credential(INVALID_PASSWD), ReturnAttributes.ALL_USER.value())); + AssertJUnit.assertFalse(response.getResult()); + AssertJUnit.assertEquals(ActiveDirectoryAccountState.Error.LOGON_FAILURE, response.getAccountState().getError()); + entry = response.getLdapEntry(); + AssertJUnit.assertNull(entry.getAttribute("pwdLastSet")); + AssertJUnit.assertNull(entry.getAttribute("userAccountControl")); + + // bad password, no return attributes + response = auth.authenticate(new AuthenticationRequest(user, new Credential(INVALID_PASSWD))); + AssertJUnit.assertFalse(response.getResult()); + AssertJUnit.assertEquals(ActiveDirectoryAccountState.Error.LOGON_FAILURE, response.getAccountState().getError()); + entry = response.getLdapEntry(); + AssertJUnit.assertNull(entry.getAttribute("pwdLastSet")); + AssertJUnit.assertNull(entry.getAttribute("userAccountControl")); + + // bad password, leverage an existing connection factory for entry + // resolution on a failed bind + final BindAuthenticationHandler ah = (BindAuthenticationHandler) singleTLSAuth.getAuthenticationHandler(); + auth.setEntryResolver(new SearchEntryResolver(ah.getConnectionFactory())); + response = auth.authenticate( + new AuthenticationRequest(user, new Credential(INVALID_PASSWD), ReturnAttributes.ALL_USER.value())); + AssertJUnit.assertFalse(response.getResult()); + AssertJUnit.assertEquals(ActiveDirectoryAccountState.Error.LOGON_FAILURE, response.getAccountState().getError()); + entry = response.getLdapEntry(); + AssertJUnit.assertNotNull(entry.getAttribute("pwdLastSet")); + AssertJUnit.assertNotNull(entry.getAttribute("userAccountControl")); + auth.setEntryResolver(null); + + try (Connection conn = TestUtils.createSetupConnection()) { + conn.open(); + + final ModifyOperation modify = new ModifyOperation(conn); + + // account disabled + final String userAccountControl = entry.getAttribute("userAccountControl").getStringValue(); + modify.execute( + new ModifyRequest( + entry.getDn(), + new AttributeModification( + AttributeModificationType.REPLACE, + new LdapAttribute("userAccountControl", "514")))); + + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential))); + AssertJUnit.assertFalse(response.getResult()); + AssertJUnit.assertEquals( + ActiveDirectoryAccountState.Error.ACCOUNT_DISABLED, + response.getAccountState().getError()); + + modify.execute( + new ModifyRequest( + entry.getDn(), + new AttributeModification( + AttributeModificationType.REPLACE, + new LdapAttribute("userAccountControl", userAccountControl)))); + + // account must change password + modify.execute( + new ModifyRequest( + entry.getDn(), + new AttributeModification(AttributeModificationType.REPLACE, new LdapAttribute("pwdLastSet", "0")))); + + response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential))); + AssertJUnit.assertFalse(response.getResult()); + AssertJUnit.assertEquals( + ActiveDirectoryAccountState.Error.PASSWORD_MUST_CHANGE, + response.getAccountState().getError()); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/auth/TestAuthenticationResponseHandler.java b/integration/src/test/java/org/ldaptive/auth/TestAuthenticationResponseHandler.java new file mode 100644 index 0000000..8b2771d --- /dev/null +++ b/integration/src/test/java/org/ldaptive/auth/TestAuthenticationResponseHandler.java
@@ -0,0 +1,35 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.auth; + +import java.util.HashMap; +import java.util.Map; + +/** + * Class for testing that authentication response handlers are firing. + * + * @author Middleware Services + */ +public class TestAuthenticationResponseHandler implements AuthenticationResponseHandler +{ + + /** results. */ + private final Map<String, Boolean> results = new HashMap<>(); + + + @Override + public void handle(final AuthenticationResponse response) + { + results.put(response.getLdapEntry().getDn(), response.getResult()); + } + + + /** + * Returns the authentication results. + * + * @return authentication results + */ + public Map<String, Boolean> getResults() + { + return results; + } +}
diff --git a/integration/src/test/java/org/ldaptive/beans/LdapEntryMapperTest.java b/integration/src/test/java/org/ldaptive/beans/LdapEntryMapperTest.java new file mode 100644 index 0000000..a752b81 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/beans/LdapEntryMapperTest.java
@@ -0,0 +1,137 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans; + +import org.ldaptive.AbstractTest; +import org.ldaptive.BindConnectionInitializer; +import org.ldaptive.Connection; +import org.ldaptive.LdapEntry; +import org.ldaptive.ReturnAttributes; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.ldaptive.beans.generate.InetOrgPerson; +import org.ldaptive.beans.generate.OrganizationalPerson; +import org.ldaptive.beans.reflect.DefaultLdapEntryMapper; +import org.ldaptive.beans.spring.SpringLdapEntryMapper; +import org.ldaptive.io.GeneralizedTimeValueTranscoder; +import org.ldaptive.io.UUIDValueTranscoder; +import org.testng.AssertJUnit; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link LdapEntryMapper} implementations. + * + * @author Middleware Services + */ +public class LdapEntryMapperTest extends AbstractTest +{ + + + /** + * Mappers to test. + * + * @return ldap entry mappers + * + * @throws Exception On test failure. + */ + @DataProvider(name = "mappers") + public Object[][] createMappers() + throws Exception + { + LdapEntry entry = null; + try (Connection conn = TestUtils.createSetupConnection()) { + conn.open(); + + final BindConnectionInitializer ci = + (BindConnectionInitializer) conn.getConnectionConfig().getConnectionInitializer(); + final SearchOperation op = new SearchOperation(conn); + final SearchRequest request = SearchRequest.newObjectScopeSearchRequest(ci.getBindDn()); + request.setReturnAttributes(ReturnAttributes.ALL.value()); + entry = op.execute(request).getResult().getEntry(); + } + + return + new Object[][] { + new Object[] {new DefaultLdapEntryMapper(), entry}, + new Object[] {new SpringLdapEntryMapper(), entry}, + }; + } + + + /** + * @param mapper to test + * @param entry to compare + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-mapper"}, dataProvider = "mappers") + public void mapToObject(final LdapEntryMapper<Object> mapper, final LdapEntry entry) + throws Exception + { + if (TestControl.isActiveDirectory()) { + final OrganizationalPerson person = new OrganizationalPerson(); + mapper.map(entry, person); + AssertJUnit.assertEquals(entry.getAttribute("cn").getStringValue(), person.getCn()); + AssertJUnit.assertEquals(entry.getDn(), person.getDn()); + AssertJUnit.assertEquals(entry.getAttribute("countryCode").getStringValue(), person.getCountryCode()); + } else { + final InetOrgPerson person = new InetOrgPerson(); + mapper.map(entry, person); + AssertJUnit.assertEquals( + entry.getAttribute("cn").getStringValues().iterator().next(), + person.getCn().iterator().next()); + AssertJUnit.assertEquals( + entry.getAttribute("createTimestamp").getValue(new GeneralizedTimeValueTranscoder()), + person.getCreateTimestamp()); + AssertJUnit.assertEquals(entry.getDn(), person.getDn()); + AssertJUnit.assertEquals( + entry.getAttribute("entryUUID").getValue(new UUIDValueTranscoder()), + person.getEntryUUID()); + } + } + + + /** + * @param mapper to test + * @param entry to compare + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-mapper"}, dataProvider = "mappers") + public void mapToLdapEntry(final LdapEntryMapper<Object> mapper, final LdapEntry entry) + throws Exception + { + final LdapEntry mapped = new LdapEntry(); + if (TestControl.isActiveDirectory()) { + final OrganizationalPerson person = new OrganizationalPerson(); + person.setCn(entry.getAttribute("cn").getStringValue()); + person.setDn(entry.getDn()); + person.setCountryCode(entry.getAttribute("countryCode").getStringValue()); + mapper.map(person, mapped); + AssertJUnit.assertEquals(person.getCn(), mapped.getAttribute("cn").getStringValue()); + AssertJUnit.assertEquals(person.getDn(), mapped.getDn()); + AssertJUnit.assertEquals(person.getCountryCode(), mapped.getAttribute("countryCode").getStringValue()); + AssertJUnit.assertEquals("customvalue1", mapped.getAttribute("customname1").getStringValue()); + } else { + final InetOrgPerson person = new InetOrgPerson(); + person.setCn(entry.getAttribute("cn").getStringValues()); + person.setCreateTimestamp(entry.getAttribute("createTimestamp").getValue(new GeneralizedTimeValueTranscoder())); + person.setDn(entry.getDn()); + person.setEntryUUID(entry.getAttribute("entryUUID").getValue(new UUIDValueTranscoder())); + mapper.map(person, mapped); + AssertJUnit.assertEquals( + person.getCn().iterator().next(), + mapped.getAttribute("cn").getStringValues().iterator().next()); + AssertJUnit.assertEquals( + person.getCreateTimestamp(), + mapped.getAttribute("createTimestamp").getValue(new GeneralizedTimeValueTranscoder())); + AssertJUnit.assertEquals(person.getDn(), mapped.getDn()); + AssertJUnit.assertEquals( + person.getEntryUUID(), + mapped.getAttribute("entryUUID").getValue(new UUIDValueTranscoder())); + AssertJUnit.assertEquals("customvalue1", mapped.getAttribute("customname1").getStringValue()); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/beans/generate/BeanGeneratorTest.java b/integration/src/test/java/org/ldaptive/beans/generate/BeanGeneratorTest.java new file mode 100644 index 0000000..53506ab --- /dev/null +++ b/integration/src/test/java/org/ldaptive/beans/generate/BeanGeneratorTest.java
@@ -0,0 +1,79 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.generate; + +import org.ldaptive.AbstractTest; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.ldaptive.schema.Schema; +import org.ldaptive.schema.SchemaFactory; +import org.testng.annotations.Test; + +/** + * Unit test for {@link BeanGenerator}. + * + * @author Middleware Services + */ +public class BeanGeneratorTest extends AbstractTest +{ + + + /** @throws Exception On test failure. */ + @Test(groups = {"beans-generate"}) + public void generate() + throws Exception + { + if (TestControl.isActiveDirectory()) { + return; + } + + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP has a dead lock bug"); + } + + final DefaultConnectionFactory factory = new DefaultConnectionFactory( + TestUtils.readConnectionConfig("classpath:/org/ldaptive/ldap.setup.properties")); + final Schema schema = SchemaFactory.createSchema(factory); + final BeanGenerator generator = new BeanGenerator(); + generator.setSchema(schema); + generator.setExcludedNames("objectClass"); + generator.setObjectClasses("inetOrgPerson"); + generator.setPackageName("org.ldaptive.beans.schema"); + generator.setUseOperationalAttributes(true); + generator.setUseOptionalAttributes(true); + generator.setIncludeSuperiorClasses(true); + generator.generate(); + generator.write("target/generated-test-sources/ldaptive"); + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"beans-generate"}) + public void generateAD() + throws Exception + { + if (!TestControl.isActiveDirectory()) { + return; + } + + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP has a dead lock bug"); + } + + final DefaultConnectionFactory factory = new DefaultConnectionFactory( + TestUtils.readConnectionConfig("classpath:/org/ldaptive/ldap.setup.properties")); + final Schema schema = org.ldaptive.ad.schema.SchemaFactory.createSchema( + factory, + "CN=Schema,CN=Configuration,DC=middleware,DC=vt,DC=edu"); + final BeanGenerator generator = new BeanGenerator(); + generator.setSchema(schema); + generator.setExcludedNames("objectClass"); + generator.setObjectClasses("organizationalPerson"); + generator.setPackageName("org.ldaptive.beans.schema"); + generator.setUseOperationalAttributes(true); + generator.setUseOptionalAttributes(true); + generator.setIncludeSuperiorClasses(true); + generator.generate(); + generator.write("target/generated-test-sources/ldaptive"); + } +}
diff --git a/integration/src/test/java/org/ldaptive/beans/generate/InetOrgPerson.java b/integration/src/test/java/org/ldaptive/beans/generate/InetOrgPerson.java new file mode 100644 index 0000000..94b5461 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/beans/generate/InetOrgPerson.java
@@ -0,0 +1,758 @@ + +package org.ldaptive.beans.generate; + +import java.security.cert.Certificate; +import java.time.ZonedDateTime; +import java.util.Collection; +import java.util.UUID; +import org.ldaptive.LdapUtils; +import org.ldaptive.beans.Attribute; +import org.ldaptive.beans.Entry; + + +/** + * Ldaptive generated bean for objectClass 'inetOrgPerson' + * + */ +@Entry(dn = "dn", attributes = { + @Attribute(name = "customname1", values = "customvalue1"), + @Attribute(name = "customname2", values = {"customvalue1", "customvalue2"}), + @Attribute(name = "attributeTypes"), + @Attribute(name = "audio", binary = true), + @Attribute(name = "businessCategory"), + @Attribute(name = "carLicense"), + @Attribute(name = "cn"), + @Attribute(name = "createTimestamp"), + @Attribute(name = "creatorsName"), + @Attribute(name = "departmentNumber"), + @Attribute(name = "description"), + @Attribute(name = "destinationIndicator"), + @Attribute(name = "displayName"), + @Attribute(name = "employeeNumber"), + @Attribute(name = "employeeType"), + @Attribute(name = "entryDN"), + @Attribute(name = "entryUUID"), + @Attribute(name = "facsimileTelephoneNumber"), + @Attribute(name = "givenName"), + @Attribute(name = "hasSubordinates"), + @Attribute(name = "homePhone"), + @Attribute(name = "homePostalAddress"), + @Attribute(name = "initials"), + @Attribute(name = "internationaliSDNNumber"), + @Attribute(name = "jpegPhoto", binary = true), + @Attribute(name = "l"), + @Attribute(name = "labeledURI"), + @Attribute(name = "ldapSyntaxes"), + @Attribute(name = "mail"), + @Attribute(name = "manager"), + @Attribute(name = "matchingRuleUse"), + @Attribute(name = "matchingRules"), + @Attribute(name = "mobile"), + @Attribute(name = "modifiersName"), + @Attribute(name = "modifyTimestamp"), + @Attribute(name = "o"), + @Attribute(name = "objectClasses"), + @Attribute(name = "ou"), + @Attribute(name = "pager"), + @Attribute(name = "photo"), + @Attribute(name = "physicalDeliveryOfficeName"), + @Attribute(name = "postOfficeBox"), + @Attribute(name = "postalAddress"), + @Attribute(name = "postalCode"), + @Attribute(name = "preferredDeliveryMethod"), + @Attribute(name = "preferredLanguage"), + @Attribute(name = "pwdAccountLockedTime"), + @Attribute(name = "pwdChangedTime"), + @Attribute(name = "pwdFailureTime"), + @Attribute(name = "pwdGraceUseTime"), + @Attribute(name = "pwdHistory"), + @Attribute(name = "pwdPolicySubentry"), + @Attribute(name = "pwdReset"), + @Attribute(name = "registeredAddress"), + @Attribute(name = "roomNumber"), + @Attribute(name = "secretary"), + @Attribute(name = "seeAlso"), + @Attribute(name = "sn"), + @Attribute(name = "st"), + @Attribute(name = "street"), + @Attribute(name = "structuralObjectClass"), + @Attribute(name = "subschemaSubentry"), + @Attribute(name = "telephoneNumber"), + @Attribute(name = "teletexTerminalIdentifier"), + @Attribute(name = "telexNumber"), + @Attribute(name = "title"), + @Attribute(name = "uid"), + @Attribute(name = "userCertificate"), + @Attribute(name = "userPKCS12", binary = true), + @Attribute(name = "userPassword"), + @Attribute(name = "userSMIMECertificate", binary = true), + @Attribute(name = "x121Address"), + @Attribute(name = "x500UniqueIdentifier") +}) +public class InetOrgPerson { + + private String dn; + private Collection<String> attributeTypes; + private Collection<byte[]> audio; + private Collection<String> businessCategory; + private Collection<String> carLicense; + private Collection<String> cn; + private ZonedDateTime createTimestamp; + private String creatorsName; + private Collection<String> departmentNumber; + private Collection<String> description; + private Collection<String> destinationIndicator; + private String displayName; + private String employeeNumber; + private Collection<String> employeeType; + private String entryDN; + private UUID entryUUID; + private Collection<String> facsimileTelephoneNumber; + private Collection<String> givenName; + private Boolean hasSubordinates; + private Collection<String> homePhone; + private Collection<String> homePostalAddress; + private Collection<String> initials; + private Collection<Integer> internationaliSDNNumber; + private Collection<byte[]> jpegPhoto; + private Collection<String> l; + private Collection<String> labeledURI; + private Collection<String> ldapSyntaxes; + private Collection<String> mail; + private Collection<String> manager; + private Collection<String> matchingRuleUse; + private Collection<String> matchingRules; + private Collection<String> mobile; + private String modifiersName; + private ZonedDateTime modifyTimestamp; + private Collection<String> o; + private Collection<String> objectClasses; + private Collection<String> ou; + private Collection<String> pager; + private Collection<String> photo; + private Collection<String> physicalDeliveryOfficeName; + private Collection<String> postOfficeBox; + private Collection<String> postalAddress; + private Collection<String> postalCode; + private String preferredDeliveryMethod; + private String preferredLanguage; + private ZonedDateTime pwdAccountLockedTime; + private ZonedDateTime pwdChangedTime; + private Collection<ZonedDateTime> pwdFailureTime; + private Collection<ZonedDateTime> pwdGraceUseTime; + private Collection<String> pwdHistory; + private String pwdPolicySubentry; + private Boolean pwdReset; + private Collection<String> registeredAddress; + private Collection<String> roomNumber; + private Collection<String> secretary; + private Collection<String> seeAlso; + private Collection<String> sn; + private Collection<String> st; + private Collection<String> street; + private String structuralObjectClass; + private String subschemaSubentry; + private Collection<String> telephoneNumber; + private Collection<String> teletexTerminalIdentifier; + private Collection<String> telexNumber; + private Collection<String> title; + private Collection<String> uid; + private Collection<Certificate> userCertificate; + private Collection<byte[]> userPKCS12; + private Collection<String> userPassword; + private Collection<byte[]> userSMIMECertificate; + private Collection<Integer> x121Address; + private Collection<String> x500UniqueIdentifier; + + public String getDn() { + return dn; + } + + public void setDn(String s) { + this.dn = s; + } + + public Collection<String> getAttributeTypes() { + return attributeTypes; + } + + public void setAttributeTypes(Collection<String> c) { + this.attributeTypes = c; + } + + public Collection<byte[]> getAudio() { + return audio; + } + + public void setAudio(Collection<byte[]> c) { + this.audio = c; + } + + public Collection<String> getBusinessCategory() { + return businessCategory; + } + + public void setBusinessCategory(Collection<String> c) { + this.businessCategory = c; + } + + public Collection<String> getCarLicense() { + return carLicense; + } + + public void setCarLicense(Collection<String> c) { + this.carLicense = c; + } + + public Collection<String> getCn() { + return cn; + } + + public void setCn(Collection<String> c) { + this.cn = c; + } + + public ZonedDateTime getCreateTimestamp() { + return createTimestamp; + } + + public void setCreateTimestamp(ZonedDateTime s) { + this.createTimestamp = s; + } + + public String getCreatorsName() { + return creatorsName; + } + + public void setCreatorsName(String s) { + this.creatorsName = s; + } + + public Collection<String> getDepartmentNumber() { + return departmentNumber; + } + + public void setDepartmentNumber(Collection<String> c) { + this.departmentNumber = c; + } + + public Collection<String> getDescription() { + return description; + } + + public void setDescription(Collection<String> c) { + this.description = c; + } + + public Collection<String> getDestinationIndicator() { + return destinationIndicator; + } + + public void setDestinationIndicator(Collection<String> c) { + this.destinationIndicator = c; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String s) { + this.displayName = s; + } + + public String getEmployeeNumber() { + return employeeNumber; + } + + public void setEmployeeNumber(String s) { + this.employeeNumber = s; + } + + public Collection<String> getEmployeeType() { + return employeeType; + } + + public void setEmployeeType(Collection<String> c) { + this.employeeType = c; + } + + public String getEntryDN() { + return entryDN; + } + + public void setEntryDN(String s) { + this.entryDN = s; + } + + public UUID getEntryUUID() { + return entryUUID; + } + + public void setEntryUUID(UUID s) { + this.entryUUID = s; + } + + public Collection<String> getFacsimileTelephoneNumber() { + return facsimileTelephoneNumber; + } + + public void setFacsimileTelephoneNumber(Collection<String> c) { + this.facsimileTelephoneNumber = c; + } + + public Collection<String> getGivenName() { + return givenName; + } + + public void setGivenName(Collection<String> c) { + this.givenName = c; + } + + public Boolean getHasSubordinates() { + return hasSubordinates; + } + + public void setHasSubordinates(Boolean s) { + this.hasSubordinates = s; + } + + public Collection<String> getHomePhone() { + return homePhone; + } + + public void setHomePhone(Collection<String> c) { + this.homePhone = c; + } + + public Collection<String> getHomePostalAddress() { + return homePostalAddress; + } + + public void setHomePostalAddress(Collection<String> c) { + this.homePostalAddress = c; + } + + public Collection<String> getInitials() { + return initials; + } + + public void setInitials(Collection<String> c) { + this.initials = c; + } + + public Collection<Integer> getInternationaliSDNNumber() { + return internationaliSDNNumber; + } + + public void setInternationaliSDNNumber(Collection<Integer> c) { + this.internationaliSDNNumber = c; + } + + public Collection<byte[]> getJpegPhoto() { + return jpegPhoto; + } + + public void setJpegPhoto(Collection<byte[]> c) { + this.jpegPhoto = c; + } + + public Collection<String> getL() { + return l; + } + + public void setL(Collection<String> c) { + this.l = c; + } + + public Collection<String> getLabeledURI() { + return labeledURI; + } + + public void setLabeledURI(Collection<String> c) { + this.labeledURI = c; + } + + public Collection<String> getLdapSyntaxes() { + return ldapSyntaxes; + } + + public void setLdapSyntaxes(Collection<String> c) { + this.ldapSyntaxes = c; + } + + public Collection<String> getMail() { + return mail; + } + + public void setMail(Collection<String> c) { + this.mail = c; + } + + public Collection<String> getManager() { + return manager; + } + + public void setManager(Collection<String> c) { + this.manager = c; + } + + public Collection<String> getMatchingRuleUse() { + return matchingRuleUse; + } + + public void setMatchingRuleUse(Collection<String> c) { + this.matchingRuleUse = c; + } + + public Collection<String> getMatchingRules() { + return matchingRules; + } + + public void setMatchingRules(Collection<String> c) { + this.matchingRules = c; + } + + public Collection<String> getMobile() { + return mobile; + } + + public void setMobile(Collection<String> c) { + this.mobile = c; + } + + public String getModifiersName() { + return modifiersName; + } + + public void setModifiersName(String s) { + this.modifiersName = s; + } + + public ZonedDateTime getModifyTimestamp() { + return modifyTimestamp; + } + + public void setModifyTimestamp(ZonedDateTime s) { + this.modifyTimestamp = s; + } + + public Collection<String> getO() { + return o; + } + + public void setO(Collection<String> c) { + this.o = c; + } + + public Collection<String> getObjectClasses() { + return objectClasses; + } + + public void setObjectClasses(Collection<String> c) { + this.objectClasses = c; + } + + public Collection<String> getOu() { + return ou; + } + + public void setOu(Collection<String> c) { + this.ou = c; + } + + public Collection<String> getPager() { + return pager; + } + + public void setPager(Collection<String> c) { + this.pager = c; + } + + public Collection<String> getPhoto() { + return photo; + } + + public void setPhoto(Collection<String> c) { + this.photo = c; + } + + public Collection<String> getPhysicalDeliveryOfficeName() { + return physicalDeliveryOfficeName; + } + + public void setPhysicalDeliveryOfficeName(Collection<String> c) { + this.physicalDeliveryOfficeName = c; + } + + public Collection<String> getPostOfficeBox() { + return postOfficeBox; + } + + public void setPostOfficeBox(Collection<String> c) { + this.postOfficeBox = c; + } + + public Collection<String> getPostalAddress() { + return postalAddress; + } + + public void setPostalAddress(Collection<String> c) { + this.postalAddress = c; + } + + public Collection<String> getPostalCode() { + return postalCode; + } + + public void setPostalCode(Collection<String> c) { + this.postalCode = c; + } + + public String getPreferredDeliveryMethod() { + return preferredDeliveryMethod; + } + + public void setPreferredDeliveryMethod(String s) { + this.preferredDeliveryMethod = s; + } + + public String getPreferredLanguage() { + return preferredLanguage; + } + + public void setPreferredLanguage(String s) { + this.preferredLanguage = s; + } + + public ZonedDateTime getPwdAccountLockedTime() { + return pwdAccountLockedTime; + } + + public void setPwdAccountLockedTime(ZonedDateTime s) { + this.pwdAccountLockedTime = s; + } + + public ZonedDateTime getPwdChangedTime() { + return pwdChangedTime; + } + + public void setPwdChangedTime(ZonedDateTime s) { + this.pwdChangedTime = s; + } + + public Collection<ZonedDateTime> getPwdFailureTime() { + return pwdFailureTime; + } + + public void setPwdFailureTime(Collection<ZonedDateTime> c) { + this.pwdFailureTime = c; + } + + public Collection<ZonedDateTime> getPwdGraceUseTime() { + return pwdGraceUseTime; + } + + public void setPwdGraceUseTime(Collection<ZonedDateTime> c) { + this.pwdGraceUseTime = c; + } + + public Collection<String> getPwdHistory() { + return pwdHistory; + } + + public void setPwdHistory(Collection<String> c) { + this.pwdHistory = c; + } + + public String getPwdPolicySubentry() { + return pwdPolicySubentry; + } + + public void setPwdPolicySubentry(String s) { + this.pwdPolicySubentry = s; + } + + public Boolean getPwdReset() { + return pwdReset; + } + + public void setPwdReset(Boolean s) { + this.pwdReset = s; + } + + public Collection<String> getRegisteredAddress() { + return registeredAddress; + } + + public void setRegisteredAddress(Collection<String> c) { + this.registeredAddress = c; + } + + public Collection<String> getRoomNumber() { + return roomNumber; + } + + public void setRoomNumber(Collection<String> c) { + this.roomNumber = c; + } + + public Collection<String> getSecretary() { + return secretary; + } + + public void setSecretary(Collection<String> c) { + this.secretary = c; + } + + public Collection<String> getSeeAlso() { + return seeAlso; + } + + public void setSeeAlso(Collection<String> c) { + this.seeAlso = c; + } + + public Collection<String> getSn() { + return sn; + } + + public void setSn(Collection<String> c) { + this.sn = c; + } + + public Collection<String> getSt() { + return st; + } + + public void setSt(Collection<String> c) { + this.st = c; + } + + public Collection<String> getStreet() { + return street; + } + + public void setStreet(Collection<String> c) { + this.street = c; + } + + public String getStructuralObjectClass() { + return structuralObjectClass; + } + + public void setStructuralObjectClass(String s) { + this.structuralObjectClass = s; + } + + public String getSubschemaSubentry() { + return subschemaSubentry; + } + + public void setSubschemaSubentry(String s) { + this.subschemaSubentry = s; + } + + public Collection<String> getTelephoneNumber() { + return telephoneNumber; + } + + public void setTelephoneNumber(Collection<String> c) { + this.telephoneNumber = c; + } + + public Collection<String> getTeletexTerminalIdentifier() { + return teletexTerminalIdentifier; + } + + public void setTeletexTerminalIdentifier(Collection<String> c) { + this.teletexTerminalIdentifier = c; + } + + public Collection<String> getTelexNumber() { + return telexNumber; + } + + public void setTelexNumber(Collection<String> c) { + this.telexNumber = c; + } + + public Collection<String> getTitle() { + return title; + } + + public void setTitle(Collection<String> c) { + this.title = c; + } + + public Collection<String> getUid() { + return uid; + } + + public void setUid(Collection<String> c) { + this.uid = c; + } + + public Collection<Certificate> getUserCertificate() { + return userCertificate; + } + + public void setUserCertificate(Collection<Certificate> c) { + this.userCertificate = c; + } + + public Collection<byte[]> getUserPKCS12() { + return userPKCS12; + } + + public void setUserPKCS12(Collection<byte[]> c) { + this.userPKCS12 = c; + } + + public Collection<String> getUserPassword() { + return userPassword; + } + + public void setUserPassword(Collection<String> c) { + this.userPassword = c; + } + + public Collection<byte[]> getUserSMIMECertificate() { + return userSMIMECertificate; + } + + public void setUserSMIMECertificate(Collection<byte[]> c) { + this.userSMIMECertificate = c; + } + + public Collection<Integer> getX121Address() { + return x121Address; + } + + public void setX121Address(Collection<Integer> c) { + this.x121Address = c; + } + + public Collection<String> getX500UniqueIdentifier() { + return x500UniqueIdentifier; + } + + public void setX500UniqueIdentifier(Collection<String> c) { + this.x500UniqueIdentifier = c; + } + + @Override + public int hashCode() { + return LdapUtils.computeHashCode(7919, this.dn, this.attributeTypes, this.audio, this.businessCategory, this.carLicense, this.cn, this.createTimestamp, this.creatorsName, this.departmentNumber, this.description, this.destinationIndicator, this.displayName, this.employeeNumber, this.employeeType, this.entryDN, this.entryUUID, this.facsimileTelephoneNumber, this.givenName, this.hasSubordinates, this.homePhone, this.homePostalAddress, this.initials, this.internationaliSDNNumber, this.jpegPhoto, this.l, this.labeledURI, this.ldapSyntaxes, this.mail, this.manager, this.matchingRuleUse, this.matchingRules, this.mobile, this.modifiersName, this.modifyTimestamp, this.o, this.objectClasses, this.ou, this.pager, this.photo, this.physicalDeliveryOfficeName, this.postOfficeBox, this.postalAddress, this.postalCode, this.preferredDeliveryMethod, this.preferredLanguage, this.pwdAccountLockedTime, this.pwdChangedTime, this.pwdFailureTime, this.pwdGraceUseTime, this.pwdHistory, this.pwdPolicySubentry, this.pwdReset, this.registeredAddress, this.roomNumber, this.secretary, this.seeAlso, this.sn, this.st, this.street, this.structuralObjectClass, this.subschemaSubentry, this.telephoneNumber, this.teletexTerminalIdentifier, this.telexNumber, this.title, this.uid, this.userCertificate, this.userPKCS12, this.userPassword, this.userSMIMECertificate, this.x121Address, this.x500UniqueIdentifier); + } + + @Override + public boolean equals(Object o) { + return LdapUtils.areEqual(this, o); + } + + @Override + public String toString() { + return String.format("[%s@%d::dn=%s, attributeTypes=%s, audio=%s, businessCategory=%s, carLicense=%s, cn=%s, createTimestamp=%s, creatorsName=%s, departmentNumber=%s, description=%s, destinationIndicator=%s, displayName=%s, employeeNumber=%s, employeeType=%s, entryDN=%s, entryUUID=%s, facsimileTelephoneNumber=%s, givenName=%s, hasSubordinates=%s, homePhone=%s, homePostalAddress=%s, initials=%s, internationaliSDNNumber=%s, jpegPhoto=%s, l=%s, labeledURI=%s, ldapSyntaxes=%s, mail=%s, manager=%s, matchingRuleUse=%s, matchingRules=%s, mobile=%s, modifiersName=%s, modifyTimestamp=%s, o=%s, objectClasses=%s, ou=%s, pager=%s, photo=%s, physicalDeliveryOfficeName=%s, postOfficeBox=%s, postalAddress=%s, postalCode=%s, preferredDeliveryMethod=%s, preferredLanguage=%s, pwdAccountLockedTime=%s, pwdChangedTime=%s, pwdFailureTime=%s, pwdGraceUseTime=%s, pwdHistory=%s, pwdPolicySubentry=%s, pwdReset=%s, registeredAddress=%s, roomNumber=%s, secretary=%s, seeAlso=%s, sn=%s, st=%s, street=%s, structuralObjectClass=%s, subschemaSubentry=%s, telephoneNumber=%s, teletexTerminalIdentifier=%s, telexNumber=%s, title=%s, uid=%s, userCertificate=%s, userPKCS12=%s, userPassword=%s, userSMIMECertificate=%s, x121Address=%s, x500UniqueIdentifier=%s]", this.getClass().getName(), this.hashCode(), this.dn, this.attributeTypes, this.audio, this.businessCategory, this.carLicense, this.cn, this.createTimestamp, this.creatorsName, this.departmentNumber, this.description, this.destinationIndicator, this.displayName, this.employeeNumber, this.employeeType, this.entryDN, this.entryUUID, this.facsimileTelephoneNumber, this.givenName, this.hasSubordinates, this.homePhone, this.homePostalAddress, this.initials, this.internationaliSDNNumber, this.jpegPhoto, this.l, this.labeledURI, this.ldapSyntaxes, this.mail, this.manager, this.matchingRuleUse, this.matchingRules, this.mobile, this.modifiersName, this.modifyTimestamp, this.o, this.objectClasses, this.ou, this.pager, this.photo, this.physicalDeliveryOfficeName, this.postOfficeBox, this.postalAddress, this.postalCode, this.preferredDeliveryMethod, this.preferredLanguage, this.pwdAccountLockedTime, this.pwdChangedTime, this.pwdFailureTime, this.pwdGraceUseTime, this.pwdHistory, this.pwdPolicySubentry, this.pwdReset, this.registeredAddress, this.roomNumber, this.secretary, this.seeAlso, this.sn, this.st, this.street, this.structuralObjectClass, this.subschemaSubentry, this.telephoneNumber, this.teletexTerminalIdentifier, this.telexNumber, this.title, this.uid, this.userCertificate, this.userPKCS12, this.userPassword, this.userSMIMECertificate, this.x121Address, this.x500UniqueIdentifier); + } + +}
diff --git a/integration/src/test/java/org/ldaptive/beans/generate/OrganizationalPerson.java b/integration/src/test/java/org/ldaptive/beans/generate/OrganizationalPerson.java new file mode 100644 index 0000000..c166629 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/beans/generate/OrganizationalPerson.java
@@ -0,0 +1,925 @@ + +package org.ldaptive.beans.generate; + +import java.util.Collection; +import org.ldaptive.LdapUtils; +import org.ldaptive.beans.Attribute; +import org.ldaptive.beans.Entry; + + +/** + * Ldaptive generated bean for objectClass 'organizationalPerson' + * + */ +@Entry(dn = "dn", attributes = { + @Attribute(name = "customname1", values = "customvalue1"), + @Attribute(name = "customname2", values = {"customvalue1", "customvalue2"}), + @Attribute(name = "bridgeheadTransportList"), + @Attribute(name = "businessCategory"), + @Attribute(name = "c"), + @Attribute(name = "cn"), + @Attribute(name = "co"), + @Attribute(name = "countryCode"), + @Attribute(name = "dNSHostName"), + @Attribute(name = "dSHeuristics"), + @Attribute(name = "defaultGroup"), + @Attribute(name = "description"), + @Attribute(name = "desktopProfile"), + @Attribute(name = "destinationIndicator"), + @Attribute(name = "facsimileTelephoneNumber"), + @Attribute(name = "gPLink"), + @Attribute(name = "gPOptions"), + @Attribute(name = "garbageCollPeriod"), + @Attribute(name = "homePostalAddress"), + @Attribute(name = "houseIdentifier"), + @Attribute(name = "internationalISDNNumber"), + @Attribute(name = "l"), + @Attribute(name = "location"), + @Attribute(name = "mSMQInterval1"), + @Attribute(name = "mSMQInterval2"), + @Attribute(name = "mSMQNt4Stub"), + @Attribute(name = "mSMQSiteForeign"), + @Attribute(name = "mSMQSiteID"), + @Attribute(name = "mailAddress"), + @Attribute(name = "managedBy"), + @Attribute(name = "msCOM-UserPartitionSetLink", property = "msCOMUserPartitionSetLink"), + @Attribute(name = "msDS-AllowedDNSSuffixes", property = "msDSAllowedDNSSuffixes"), + @Attribute(name = "msDS-AzApplicationData", property = "msDSAzApplicationData"), + @Attribute(name = "msDS-AzApplicationName", property = "msDSAzApplicationName"), + @Attribute(name = "msDS-AzApplicationVersion", property = "msDSAzApplicationVersion"), + @Attribute(name = "msDS-AzClassId", property = "msDSAzClassId"), + @Attribute(name = "msDS-AzDomainTimeout", property = "msDSAzDomainTimeout"), + @Attribute(name = "msDS-AzGenerateAudits", property = "msDSAzGenerateAudits"), + @Attribute(name = "msDS-AzGenericData", property = "msDSAzGenericData"), + @Attribute(name = "msDS-AzMajorVersion", property = "msDSAzMajorVersion"), + @Attribute(name = "msDS-AzMinorVersion", property = "msDSAzMinorVersion"), + @Attribute(name = "msDS-AzObjectGuid", property = "msDSAzObjectGuid"), + @Attribute(name = "msDS-AzScopeName", property = "msDSAzScopeName"), + @Attribute(name = "msDS-AzScriptEngineCacheMax", property = "msDSAzScriptEngineCacheMax"), + @Attribute(name = "msDS-AzScriptTimeout", property = "msDSAzScriptTimeout"), + @Attribute(name = "msDS-Behavior-Version", property = "msDSBehaviorVersion"), + @Attribute(name = "msDS-BridgeHeadServersUsed", property = "msDSBridgeHeadServersUsed"), + @Attribute(name = "msDS-DeletedObjectLifetime", property = "msDSDeletedObjectLifetime"), + @Attribute(name = "msDS-EnabledFeature", property = "msDSEnabledFeature"), + @Attribute(name = "msDS-HABSeniorityIndex", property = "msDSHABSeniorityIndex"), + @Attribute(name = "msDS-IsUserCachableAtRodc", property = "msDSIsUserCachableAtRodc"), + @Attribute(name = "msDS-ObjectReference", property = "msDSObjectReference"), + @Attribute(name = "msDS-Other-Settings", property = "msDSOtherSettings"), + @Attribute(name = "msDS-PhoneticCompanyName", property = "msDSPhoneticCompanyName"), + @Attribute(name = "msDS-PhoneticDepartment", property = "msDSPhoneticDepartment"), + @Attribute(name = "msDS-PhoneticDisplayName", property = "msDSPhoneticDisplayName"), + @Attribute(name = "msDS-PhoneticFirstName", property = "msDSPhoneticFirstName"), + @Attribute(name = "msDS-PhoneticLastName", property = "msDSPhoneticLastName"), + @Attribute(name = "msDS-SiteName", property = "msDSSiteName"), + @Attribute(name = "msDS-USNLastSyncSuccess", property = "msDSUSNLastSyncSuccess"), + @Attribute(name = "msDS-isGC", property = "msDSisGC"), + @Attribute(name = "msDS-isRODC", property = "msDSisRODC"), + @Attribute(name = "msExchHouseIdentifier"), + @Attribute(name = "notificationList"), + @Attribute(name = "o"), + @Attribute(name = "ou"), + @Attribute(name = "physicalDeliveryOfficeName"), + @Attribute(name = "physicalLocationObject"), + @Attribute(name = "postOfficeBox"), + @Attribute(name = "postalAddress"), + @Attribute(name = "postalCode"), + @Attribute(name = "preferredDeliveryMethod"), + @Attribute(name = "registeredAddress"), + @Attribute(name = "replTopologyStayOfExecution"), + @Attribute(name = "sPNMappings"), + @Attribute(name = "searchGuide"), + @Attribute(name = "seeAlso"), + @Attribute(name = "serialNumber"), + @Attribute(name = "serverReference"), + @Attribute(name = "siteObject"), + @Attribute(name = "st"), + @Attribute(name = "street"), + @Attribute(name = "telephoneNumber"), + @Attribute(name = "teletexTerminalIdentifier"), + @Attribute(name = "telexNumber"), + @Attribute(name = "thumbnailLogo"), + @Attribute(name = "tombstoneLifetime"), + @Attribute(name = "uPNSuffixes"), + @Attribute(name = "userPassword"), + @Attribute(name = "x121Address") +}) +public class OrganizationalPerson { + + private String dn; + private Collection<String> bridgeheadTransportList; + private Collection<String> businessCategory; + private String c; + private String cn; + private String co; + private String countryCode; + private String dNSHostName; + private String dSHeuristics; + private String defaultGroup; + private Collection<String> description; + private String desktopProfile; + private Collection<String> destinationIndicator; + private String facsimileTelephoneNumber; + private String gPLink; + private String gPOptions; + private String garbageCollPeriod; + private String homePostalAddress; + private Collection<String> houseIdentifier; + private Collection<String> internationalISDNNumber; + private String l; + private String location; + private String mSMQInterval1; + private String mSMQInterval2; + private Collection<String> mSMQNt4Stub; + private Collection<String> mSMQSiteForeign; + private String mSMQSiteID; + private String mailAddress; + private String managedBy; + private String msCOMUserPartitionSetLink; + private Collection<String> msDSAllowedDNSSuffixes; + private String msDSAzApplicationData; + private String msDSAzApplicationName; + private String msDSAzApplicationVersion; + private String msDSAzClassId; + private String msDSAzDomainTimeout; + private String msDSAzGenerateAudits; + private String msDSAzGenericData; + private String msDSAzMajorVersion; + private String msDSAzMinorVersion; + private String msDSAzObjectGuid; + private String msDSAzScopeName; + private String msDSAzScriptEngineCacheMax; + private String msDSAzScriptTimeout; + private String msDSBehaviorVersion; + private Collection<String> msDSBridgeHeadServersUsed; + private String msDSDeletedObjectLifetime; + private Collection<String> msDSEnabledFeature; + private String msDSHABSeniorityIndex; + private String msDSIsUserCachableAtRodc; + private Collection<String> msDSObjectReference; + private Collection<String> msDSOtherSettings; + private String msDSPhoneticCompanyName; + private String msDSPhoneticDepartment; + private String msDSPhoneticDisplayName; + private String msDSPhoneticFirstName; + private String msDSPhoneticLastName; + private String msDSSiteName; + private String msDSUSNLastSyncSuccess; + private String msDSisGC; + private String msDSisRODC; + private String msExchHouseIdentifier; + private String notificationList; + private Collection<String> o; + private Collection<String> ou; + private String physicalDeliveryOfficeName; + private String physicalLocationObject; + private Collection<String> postOfficeBox; + private Collection<String> postalAddress; + private String postalCode; + private Collection<String> preferredDeliveryMethod; + private Collection<String> registeredAddress; + private String replTopologyStayOfExecution; + private Collection<String> sPNMappings; + private Collection<String> searchGuide; + private Collection<String> seeAlso; + private Collection<String> serialNumber; + private String serverReference; + private String siteObject; + private String st; + private String street; + private String telephoneNumber; + private Collection<String> teletexTerminalIdentifier; + private Collection<String> telexNumber; + private String thumbnailLogo; + private String tombstoneLifetime; + private Collection<String> uPNSuffixes; + private Collection<String> userPassword; + private Collection<String> x121Address; + + public String getDn() { + return dn; + } + + public void setDn(String s) { + this.dn = s; + } + + public Collection<String> getBridgeheadTransportList() { + return bridgeheadTransportList; + } + + public void setBridgeheadTransportList(Collection<String> c) { + this.bridgeheadTransportList = c; + } + + public Collection<String> getBusinessCategory() { + return businessCategory; + } + + public void setBusinessCategory(Collection<String> c) { + this.businessCategory = c; + } + + public String getC() { + return c; + } + + public void setC(String s) { + this.c = s; + } + + public String getCn() { + return cn; + } + + public void setCn(String s) { + this.cn = s; + } + + public String getCo() { + return co; + } + + public void setCo(String s) { + this.co = s; + } + + public String getCountryCode() { + return countryCode; + } + + public void setCountryCode(String s) { + this.countryCode = s; + } + + public String getDNSHostName() { + return dNSHostName; + } + + public void setDNSHostName(String s) { + this.dNSHostName = s; + } + + public String getDSHeuristics() { + return dSHeuristics; + } + + public void setDSHeuristics(String s) { + this.dSHeuristics = s; + } + + public String getDefaultGroup() { + return defaultGroup; + } + + public void setDefaultGroup(String s) { + this.defaultGroup = s; + } + + public Collection<String> getDescription() { + return description; + } + + public void setDescription(Collection<String> c) { + this.description = c; + } + + public String getDesktopProfile() { + return desktopProfile; + } + + public void setDesktopProfile(String s) { + this.desktopProfile = s; + } + + public Collection<String> getDestinationIndicator() { + return destinationIndicator; + } + + public void setDestinationIndicator(Collection<String> c) { + this.destinationIndicator = c; + } + + public String getFacsimileTelephoneNumber() { + return facsimileTelephoneNumber; + } + + public void setFacsimileTelephoneNumber(String s) { + this.facsimileTelephoneNumber = s; + } + + public String getGPLink() { + return gPLink; + } + + public void setGPLink(String s) { + this.gPLink = s; + } + + public String getGPOptions() { + return gPOptions; + } + + public void setGPOptions(String s) { + this.gPOptions = s; + } + + public String getGarbageCollPeriod() { + return garbageCollPeriod; + } + + public void setGarbageCollPeriod(String s) { + this.garbageCollPeriod = s; + } + + public String getHomePostalAddress() { + return homePostalAddress; + } + + public void setHomePostalAddress(String s) { + this.homePostalAddress = s; + } + + public Collection<String> getHouseIdentifier() { + return houseIdentifier; + } + + public void setHouseIdentifier(Collection<String> c) { + this.houseIdentifier = c; + } + + public Collection<String> getInternationalISDNNumber() { + return internationalISDNNumber; + } + + public void setInternationalISDNNumber(Collection<String> c) { + this.internationalISDNNumber = c; + } + + public String getL() { + return l; + } + + public void setL(String s) { + this.l = s; + } + + public String getLocation() { + return location; + } + + public void setLocation(String s) { + this.location = s; + } + + public String getMSMQInterval1() { + return mSMQInterval1; + } + + public void setMSMQInterval1(String s) { + this.mSMQInterval1 = s; + } + + public String getMSMQInterval2() { + return mSMQInterval2; + } + + public void setMSMQInterval2(String s) { + this.mSMQInterval2 = s; + } + + public Collection<String> getMSMQNt4Stub() { + return mSMQNt4Stub; + } + + public void setMSMQNt4Stub(Collection<String> c) { + this.mSMQNt4Stub = c; + } + + public Collection<String> getMSMQSiteForeign() { + return mSMQSiteForeign; + } + + public void setMSMQSiteForeign(Collection<String> c) { + this.mSMQSiteForeign = c; + } + + public String getMSMQSiteID() { + return mSMQSiteID; + } + + public void setMSMQSiteID(String s) { + this.mSMQSiteID = s; + } + + public String getMailAddress() { + return mailAddress; + } + + public void setMailAddress(String s) { + this.mailAddress = s; + } + + public String getManagedBy() { + return managedBy; + } + + public void setManagedBy(String s) { + this.managedBy = s; + } + + public String getMsCOMUserPartitionSetLink() { + return msCOMUserPartitionSetLink; + } + + public void setMsCOMUserPartitionSetLink(String s) { + this.msCOMUserPartitionSetLink = s; + } + + public Collection<String> getMsDSAllowedDNSSuffixes() { + return msDSAllowedDNSSuffixes; + } + + public void setMsDSAllowedDNSSuffixes(Collection<String> c) { + this.msDSAllowedDNSSuffixes = c; + } + + public String getMsDSAzApplicationData() { + return msDSAzApplicationData; + } + + public void setMsDSAzApplicationData(String s) { + this.msDSAzApplicationData = s; + } + + public String getMsDSAzApplicationName() { + return msDSAzApplicationName; + } + + public void setMsDSAzApplicationName(String s) { + this.msDSAzApplicationName = s; + } + + public String getMsDSAzApplicationVersion() { + return msDSAzApplicationVersion; + } + + public void setMsDSAzApplicationVersion(String s) { + this.msDSAzApplicationVersion = s; + } + + public String getMsDSAzClassId() { + return msDSAzClassId; + } + + public void setMsDSAzClassId(String s) { + this.msDSAzClassId = s; + } + + public String getMsDSAzDomainTimeout() { + return msDSAzDomainTimeout; + } + + public void setMsDSAzDomainTimeout(String s) { + this.msDSAzDomainTimeout = s; + } + + public String getMsDSAzGenerateAudits() { + return msDSAzGenerateAudits; + } + + public void setMsDSAzGenerateAudits(String s) { + this.msDSAzGenerateAudits = s; + } + + public String getMsDSAzGenericData() { + return msDSAzGenericData; + } + + public void setMsDSAzGenericData(String s) { + this.msDSAzGenericData = s; + } + + public String getMsDSAzMajorVersion() { + return msDSAzMajorVersion; + } + + public void setMsDSAzMajorVersion(String s) { + this.msDSAzMajorVersion = s; + } + + public String getMsDSAzMinorVersion() { + return msDSAzMinorVersion; + } + + public void setMsDSAzMinorVersion(String s) { + this.msDSAzMinorVersion = s; + } + + public String getMsDSAzObjectGuid() { + return msDSAzObjectGuid; + } + + public void setMsDSAzObjectGuid(String s) { + this.msDSAzObjectGuid = s; + } + + public String getMsDSAzScopeName() { + return msDSAzScopeName; + } + + public void setMsDSAzScopeName(String s) { + this.msDSAzScopeName = s; + } + + public String getMsDSAzScriptEngineCacheMax() { + return msDSAzScriptEngineCacheMax; + } + + public void setMsDSAzScriptEngineCacheMax(String s) { + this.msDSAzScriptEngineCacheMax = s; + } + + public String getMsDSAzScriptTimeout() { + return msDSAzScriptTimeout; + } + + public void setMsDSAzScriptTimeout(String s) { + this.msDSAzScriptTimeout = s; + } + + public String getMsDSBehaviorVersion() { + return msDSBehaviorVersion; + } + + public void setMsDSBehaviorVersion(String s) { + this.msDSBehaviorVersion = s; + } + + public Collection<String> getMsDSBridgeHeadServersUsed() { + return msDSBridgeHeadServersUsed; + } + + public void setMsDSBridgeHeadServersUsed(Collection<String> c) { + this.msDSBridgeHeadServersUsed = c; + } + + public String getMsDSDeletedObjectLifetime() { + return msDSDeletedObjectLifetime; + } + + public void setMsDSDeletedObjectLifetime(String s) { + this.msDSDeletedObjectLifetime = s; + } + + public Collection<String> getMsDSEnabledFeature() { + return msDSEnabledFeature; + } + + public void setMsDSEnabledFeature(Collection<String> c) { + this.msDSEnabledFeature = c; + } + + public String getMsDSHABSeniorityIndex() { + return msDSHABSeniorityIndex; + } + + public void setMsDSHABSeniorityIndex(String s) { + this.msDSHABSeniorityIndex = s; + } + + public String getMsDSIsUserCachableAtRodc() { + return msDSIsUserCachableAtRodc; + } + + public void setMsDSIsUserCachableAtRodc(String s) { + this.msDSIsUserCachableAtRodc = s; + } + + public Collection<String> getMsDSObjectReference() { + return msDSObjectReference; + } + + public void setMsDSObjectReference(Collection<String> c) { + this.msDSObjectReference = c; + } + + public Collection<String> getMsDSOtherSettings() { + return msDSOtherSettings; + } + + public void setMsDSOtherSettings(Collection<String> c) { + this.msDSOtherSettings = c; + } + + public String getMsDSPhoneticCompanyName() { + return msDSPhoneticCompanyName; + } + + public void setMsDSPhoneticCompanyName(String s) { + this.msDSPhoneticCompanyName = s; + } + + public String getMsDSPhoneticDepartment() { + return msDSPhoneticDepartment; + } + + public void setMsDSPhoneticDepartment(String s) { + this.msDSPhoneticDepartment = s; + } + + public String getMsDSPhoneticDisplayName() { + return msDSPhoneticDisplayName; + } + + public void setMsDSPhoneticDisplayName(String s) { + this.msDSPhoneticDisplayName = s; + } + + public String getMsDSPhoneticFirstName() { + return msDSPhoneticFirstName; + } + + public void setMsDSPhoneticFirstName(String s) { + this.msDSPhoneticFirstName = s; + } + + public String getMsDSPhoneticLastName() { + return msDSPhoneticLastName; + } + + public void setMsDSPhoneticLastName(String s) { + this.msDSPhoneticLastName = s; + } + + public String getMsDSSiteName() { + return msDSSiteName; + } + + public void setMsDSSiteName(String s) { + this.msDSSiteName = s; + } + + public String getMsDSUSNLastSyncSuccess() { + return msDSUSNLastSyncSuccess; + } + + public void setMsDSUSNLastSyncSuccess(String s) { + this.msDSUSNLastSyncSuccess = s; + } + + public String getMsDSisGC() { + return msDSisGC; + } + + public void setMsDSisGC(String s) { + this.msDSisGC = s; + } + + public String getMsDSisRODC() { + return msDSisRODC; + } + + public void setMsDSisRODC(String s) { + this.msDSisRODC = s; + } + + public String getMsExchHouseIdentifier() { + return msExchHouseIdentifier; + } + + public void setMsExchHouseIdentifier(String s) { + this.msExchHouseIdentifier = s; + } + + public String getNotificationList() { + return notificationList; + } + + public void setNotificationList(String s) { + this.notificationList = s; + } + + public Collection<String> getO() { + return o; + } + + public void setO(Collection<String> c) { + this.o = c; + } + + public Collection<String> getOu() { + return ou; + } + + public void setOu(Collection<String> c) { + this.ou = c; + } + + public String getPhysicalDeliveryOfficeName() { + return physicalDeliveryOfficeName; + } + + public void setPhysicalDeliveryOfficeName(String s) { + this.physicalDeliveryOfficeName = s; + } + + public String getPhysicalLocationObject() { + return physicalLocationObject; + } + + public void setPhysicalLocationObject(String s) { + this.physicalLocationObject = s; + } + + public Collection<String> getPostOfficeBox() { + return postOfficeBox; + } + + public void setPostOfficeBox(Collection<String> c) { + this.postOfficeBox = c; + } + + public Collection<String> getPostalAddress() { + return postalAddress; + } + + public void setPostalAddress(Collection<String> c) { + this.postalAddress = c; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String s) { + this.postalCode = s; + } + + public Collection<String> getPreferredDeliveryMethod() { + return preferredDeliveryMethod; + } + + public void setPreferredDeliveryMethod(Collection<String> c) { + this.preferredDeliveryMethod = c; + } + + public Collection<String> getRegisteredAddress() { + return registeredAddress; + } + + public void setRegisteredAddress(Collection<String> c) { + this.registeredAddress = c; + } + + public String getReplTopologyStayOfExecution() { + return replTopologyStayOfExecution; + } + + public void setReplTopologyStayOfExecution(String s) { + this.replTopologyStayOfExecution = s; + } + + public Collection<String> getSPNMappings() { + return sPNMappings; + } + + public void setSPNMappings(Collection<String> c) { + this.sPNMappings = c; + } + + public Collection<String> getSearchGuide() { + return searchGuide; + } + + public void setSearchGuide(Collection<String> c) { + this.searchGuide = c; + } + + public Collection<String> getSeeAlso() { + return seeAlso; + } + + public void setSeeAlso(Collection<String> c) { + this.seeAlso = c; + } + + public Collection<String> getSerialNumber() { + return serialNumber; + } + + public void setSerialNumber(Collection<String> c) { + this.serialNumber = c; + } + + public String getServerReference() { + return serverReference; + } + + public void setServerReference(String s) { + this.serverReference = s; + } + + public String getSiteObject() { + return siteObject; + } + + public void setSiteObject(String s) { + this.siteObject = s; + } + + public String getSt() { + return st; + } + + public void setSt(String s) { + this.st = s; + } + + public String getStreet() { + return street; + } + + public void setStreet(String s) { + this.street = s; + } + + public String getTelephoneNumber() { + return telephoneNumber; + } + + public void setTelephoneNumber(String s) { + this.telephoneNumber = s; + } + + public Collection<String> getTeletexTerminalIdentifier() { + return teletexTerminalIdentifier; + } + + public void setTeletexTerminalIdentifier(Collection<String> c) { + this.teletexTerminalIdentifier = c; + } + + public Collection<String> getTelexNumber() { + return telexNumber; + } + + public void setTelexNumber(Collection<String> c) { + this.telexNumber = c; + } + + public String getThumbnailLogo() { + return thumbnailLogo; + } + + public void setThumbnailLogo(String s) { + this.thumbnailLogo = s; + } + + public String getTombstoneLifetime() { + return tombstoneLifetime; + } + + public void setTombstoneLifetime(String s) { + this.tombstoneLifetime = s; + } + + public Collection<String> getUPNSuffixes() { + return uPNSuffixes; + } + + public void setUPNSuffixes(Collection<String> c) { + this.uPNSuffixes = c; + } + + public Collection<String> getUserPassword() { + return userPassword; + } + + public void setUserPassword(Collection<String> c) { + this.userPassword = c; + } + + public Collection<String> getX121Address() { + return x121Address; + } + + public void setX121Address(Collection<String> c) { + this.x121Address = c; + } + + @Override + public int hashCode() { + return LdapUtils.computeHashCode(7919, this.dn, this.bridgeheadTransportList, this.businessCategory, this.c, this.cn, this.co, this.countryCode, this.dNSHostName, this.dSHeuristics, this.defaultGroup, this.description, this.desktopProfile, this.destinationIndicator, this.facsimileTelephoneNumber, this.gPLink, this.gPOptions, this.garbageCollPeriod, this.homePostalAddress, this.houseIdentifier, this.internationalISDNNumber, this.l, this.location, this.mSMQInterval1, this.mSMQInterval2, this.mSMQNt4Stub, this.mSMQSiteForeign, this.mSMQSiteID, this.mailAddress, this.managedBy, this.msCOMUserPartitionSetLink, this.msDSAllowedDNSSuffixes, this.msDSAzApplicationData, this.msDSAzApplicationName, this.msDSAzApplicationVersion, this.msDSAzClassId, this.msDSAzDomainTimeout, this.msDSAzGenerateAudits, this.msDSAzGenericData, this.msDSAzMajorVersion, this.msDSAzMinorVersion, this.msDSAzObjectGuid, this.msDSAzScopeName, this.msDSAzScriptEngineCacheMax, this.msDSAzScriptTimeout, this.msDSBehaviorVersion, this.msDSBridgeHeadServersUsed, this.msDSDeletedObjectLifetime, this.msDSEnabledFeature, this.msDSHABSeniorityIndex, this.msDSIsUserCachableAtRodc, this.msDSObjectReference, this.msDSOtherSettings, this.msDSPhoneticCompanyName, this.msDSPhoneticDepartment, this.msDSPhoneticDisplayName, this.msDSPhoneticFirstName, this.msDSPhoneticLastName, this.msDSSiteName, this.msDSUSNLastSyncSuccess, this.msDSisGC, this.msDSisRODC, this.msExchHouseIdentifier, this.notificationList, this.o, this.ou, this.physicalDeliveryOfficeName, this.physicalLocationObject, this.postOfficeBox, this.postalAddress, this.postalCode, this.preferredDeliveryMethod, this.registeredAddress, this.replTopologyStayOfExecution, this.sPNMappings, this.searchGuide, this.seeAlso, this.serialNumber, this.serverReference, this.siteObject, this.st, this.street, this.telephoneNumber, this.teletexTerminalIdentifier, this.telexNumber, this.thumbnailLogo, this.tombstoneLifetime, this.uPNSuffixes, this.userPassword, this.x121Address); + } + + @Override + public boolean equals(Object o) { + return LdapUtils.areEqual(this, o); + } + + @Override + public String toString() { + return String.format("[%s@%d::dn=%s, bridgeheadTransportList=%s, businessCategory=%s, c=%s, cn=%s, co=%s, countryCode=%s, dNSHostName=%s, dSHeuristics=%s, defaultGroup=%s, description=%s, desktopProfile=%s, destinationIndicator=%s, facsimileTelephoneNumber=%s, gPLink=%s, gPOptions=%s, garbageCollPeriod=%s, homePostalAddress=%s, houseIdentifier=%s, internationalISDNNumber=%s, l=%s, location=%s, mSMQInterval1=%s, mSMQInterval2=%s, mSMQNt4Stub=%s, mSMQSiteForeign=%s, mSMQSiteID=%s, mailAddress=%s, managedBy=%s, msCOMUserPartitionSetLink=%s, msDSAllowedDNSSuffixes=%s, msDSAzApplicationData=%s, msDSAzApplicationName=%s, msDSAzApplicationVersion=%s, msDSAzClassId=%s, msDSAzDomainTimeout=%s, msDSAzGenerateAudits=%s, msDSAzGenericData=%s, msDSAzMajorVersion=%s, msDSAzMinorVersion=%s, msDSAzObjectGuid=%s, msDSAzScopeName=%s, msDSAzScriptEngineCacheMax=%s, msDSAzScriptTimeout=%s, msDSBehaviorVersion=%s, msDSBridgeHeadServersUsed=%s, msDSDeletedObjectLifetime=%s, msDSEnabledFeature=%s, msDSHABSeniorityIndex=%s, msDSIsUserCachableAtRodc=%s, msDSObjectReference=%s, msDSOtherSettings=%s, msDSPhoneticCompanyName=%s, msDSPhoneticDepartment=%s, msDSPhoneticDisplayName=%s, msDSPhoneticFirstName=%s, msDSPhoneticLastName=%s, msDSSiteName=%s, msDSUSNLastSyncSuccess=%s, msDSisGC=%s, msDSisRODC=%s, msExchHouseIdentifier=%s, notificationList=%s, o=%s, ou=%s, physicalDeliveryOfficeName=%s, physicalLocationObject=%s, postOfficeBox=%s, postalAddress=%s, postalCode=%s, preferredDeliveryMethod=%s, registeredAddress=%s, replTopologyStayOfExecution=%s, sPNMappings=%s, searchGuide=%s, seeAlso=%s, serialNumber=%s, serverReference=%s, siteObject=%s, st=%s, street=%s, telephoneNumber=%s, teletexTerminalIdentifier=%s, telexNumber=%s, thumbnailLogo=%s, tombstoneLifetime=%s, uPNSuffixes=%s, userPassword=%s, x121Address=%s]", this.getClass().getName(), this.hashCode(), this.dn, this.bridgeheadTransportList, this.businessCategory, this.c, this.cn, this.co, this.countryCode, this.dNSHostName, this.dSHeuristics, this.defaultGroup, this.description, this.desktopProfile, this.destinationIndicator, this.facsimileTelephoneNumber, this.gPLink, this.gPOptions, this.garbageCollPeriod, this.homePostalAddress, this.houseIdentifier, this.internationalISDNNumber, this.l, this.location, this.mSMQInterval1, this.mSMQInterval2, this.mSMQNt4Stub, this.mSMQSiteForeign, this.mSMQSiteID, this.mailAddress, this.managedBy, this.msCOMUserPartitionSetLink, this.msDSAllowedDNSSuffixes, this.msDSAzApplicationData, this.msDSAzApplicationName, this.msDSAzApplicationVersion, this.msDSAzClassId, this.msDSAzDomainTimeout, this.msDSAzGenerateAudits, this.msDSAzGenericData, this.msDSAzMajorVersion, this.msDSAzMinorVersion, this.msDSAzObjectGuid, this.msDSAzScopeName, this.msDSAzScriptEngineCacheMax, this.msDSAzScriptTimeout, this.msDSBehaviorVersion, this.msDSBridgeHeadServersUsed, this.msDSDeletedObjectLifetime, this.msDSEnabledFeature, this.msDSHABSeniorityIndex, this.msDSIsUserCachableAtRodc, this.msDSObjectReference, this.msDSOtherSettings, this.msDSPhoneticCompanyName, this.msDSPhoneticDepartment, this.msDSPhoneticDisplayName, this.msDSPhoneticFirstName, this.msDSPhoneticLastName, this.msDSSiteName, this.msDSUSNLastSyncSuccess, this.msDSisGC, this.msDSisRODC, this.msExchHouseIdentifier, this.notificationList, this.o, this.ou, this.physicalDeliveryOfficeName, this.physicalLocationObject, this.postOfficeBox, this.postalAddress, this.postalCode, this.preferredDeliveryMethod, this.registeredAddress, this.replTopologyStayOfExecution, this.sPNMappings, this.searchGuide, this.seeAlso, this.serialNumber, this.serverReference, this.siteObject, this.st, this.street, this.telephoneNumber, this.teletexTerminalIdentifier, this.telexNumber, this.thumbnailLogo, this.tombstoneLifetime, this.uPNSuffixes, this.userPassword, this.x121Address); + } + +}
diff --git a/integration/src/test/java/org/ldaptive/beans/persistence/LdapEntryManagerTest.java b/integration/src/test/java/org/ldaptive/beans/persistence/LdapEntryManagerTest.java new file mode 100644 index 0000000..ee9426c --- /dev/null +++ b/integration/src/test/java/org/ldaptive/beans/persistence/LdapEntryManagerTest.java
@@ -0,0 +1,94 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.persistence; + +import org.ldaptive.AbstractTest; +import org.ldaptive.BindConnectionInitializer; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.LdapEntry; +import org.ldaptive.ReturnAttributes; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.ldaptive.beans.generate.InetOrgPerson; +import org.ldaptive.beans.reflect.DefaultLdapEntryMapper; +import org.ldaptive.io.GeneralizedTimeValueTranscoder; +import org.ldaptive.io.UUIDValueTranscoder; +import org.testng.AssertJUnit; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link LdapEntryManager} implementations. + * + * @author Middleware Services + */ +public class LdapEntryManagerTest extends AbstractTest +{ + + + /** + * Managers to test. + * + * @return ldap entry managers + * + * @throws Exception On test failure. + */ + @DataProvider(name = "managers") + public Object[][] createManagers() + throws Exception + { + final ConnectionFactory cf = new DefaultConnectionFactory( + TestUtils.readConnectionConfig("classpath:/org/ldaptive/ldap.setup.properties")); + LdapEntry entry = null; + try (Connection conn = cf.getConnection()) { + conn.open(); + + final BindConnectionInitializer ci = + (BindConnectionInitializer) conn.getConnectionConfig().getConnectionInitializer(); + final SearchOperation op = new SearchOperation(conn); + final SearchRequest request = SearchRequest.newObjectScopeSearchRequest(ci.getBindDn()); + request.setReturnAttributes(ReturnAttributes.ALL.value()); + entry = op.execute(request).getResult().getEntry(); + } + + return + new Object[][] { + new Object[] { + new DefaultLdapEntryManager<>(new DefaultLdapEntryMapper<>(), cf), entry, + }, + }; + } + + + /** + * @param manager to test + * @param entry to compare + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-manager"}, dataProvider = "managers") + public void find(final LdapEntryManager<InetOrgPerson> manager, final LdapEntry entry) + throws Exception + { + if (TestControl.isActiveDirectory()) { + return; + } else { + final InetOrgPerson emptyPerson = new InetOrgPerson(); + emptyPerson.setDn(entry.getDn()); + final InetOrgPerson person = manager.find(emptyPerson); + AssertJUnit.assertEquals( + entry.getAttribute("cn").getStringValues().iterator().next(), + person.getCn().iterator().next()); + AssertJUnit.assertEquals( + entry.getAttribute("createTimestamp").getValue(new GeneralizedTimeValueTranscoder()), + person.getCreateTimestamp()); + AssertJUnit.assertEquals(entry.getDn(), person.getDn()); + AssertJUnit.assertEquals( + entry.getAttribute("entryUUID").getValue(new UUIDValueTranscoder()), + person.getEntryUUID()); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/beans/spring/NamespaceHandlerTest.java b/integration/src/test/java/org/ldaptive/beans/spring/NamespaceHandlerTest.java new file mode 100644 index 0000000..c3273cf --- /dev/null +++ b/integration/src/test/java/org/ldaptive/beans/spring/NamespaceHandlerTest.java
@@ -0,0 +1,696 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.beans.spring; + +import java.time.Duration; +import java.time.Period; +import org.ldaptive.BindConnectionInitializer; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.ConnectionFactoryManager; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.LdapException; +import org.ldaptive.SearchExecutor; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchScope; +import org.ldaptive.SortBehavior; +import org.ldaptive.TestControl; +import org.ldaptive.auth.AbstractBindAuthenticationHandler; +import org.ldaptive.auth.AbstractSearchDnResolver; +import org.ldaptive.auth.AggregateDnResolver; +import org.ldaptive.auth.AuthenticationHandler; +import org.ldaptive.auth.AuthenticationResponseHandler; +import org.ldaptive.auth.Authenticator; +import org.ldaptive.auth.BindAuthenticationHandler; +import org.ldaptive.auth.DnResolver; +import org.ldaptive.auth.EntryResolver; +import org.ldaptive.auth.FormatDnResolver; +import org.ldaptive.auth.PooledBindAuthenticationHandler; +import org.ldaptive.auth.PooledSearchDnResolver; +import org.ldaptive.auth.ext.ActiveDirectoryAuthenticationResponseHandler; +import org.ldaptive.auth.ext.FreeIPAAuthenticationResponseHandler; +import org.ldaptive.auth.ext.PasswordExpirationAuthenticationResponseHandler; +import org.ldaptive.auth.ext.PasswordPolicyAuthenticationResponseHandler; +import org.ldaptive.concurrent.AggregatePooledSearchExecutor; +import org.ldaptive.concurrent.AggregateSearchExecutor; +import org.ldaptive.concurrent.ParallelPooledSearchExecutor; +import org.ldaptive.concurrent.ParallelSearchExecutor; +import org.ldaptive.control.PasswordPolicyControl; +import org.ldaptive.pool.BlockingConnectionPool; +import org.ldaptive.pool.IdlePruneStrategy; +import org.ldaptive.pool.PoolConfig; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.pool.PooledConnectionFactoryManager; +import org.ldaptive.pool.SearchValidator; +import org.ldaptive.sasl.Mechanism; +import org.ldaptive.sasl.QualityOfProtection; +import org.ldaptive.sasl.SaslConfig; +import org.ldaptive.sasl.SecurityStrength; +import org.ldaptive.ssl.CredentialConfig; +import org.ldaptive.ssl.KeyStoreCredentialConfig; +import org.ldaptive.ssl.X509CredentialConfig; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Unit test for {@link NamespaceHandler}. + * + * @author Middleware Services + */ +public class NamespaceHandlerTest +{ + + /** Enum to aid in testing authenticator types. */ + public enum AuthenticatorType { + + /** anonymous search. */ + ANON_SEARCH, + + /** bind search. */ + BIND_SEARCH, + + /** sasl search. */ + SASL_SEARCH, + + /** direct. */ + DIRECT, + + /** active directory. */ + AD + } + + /** Spring context to test. */ + private ClassPathXmlApplicationContext context; + + + /** @throws Exception On test failure. */ + @BeforeClass(groups = {"beans-spring"}) + public void loadContext() + throws Exception + { + context = new ClassPathXmlApplicationContext(new String[] {"/spring-ext-context.xml", }); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"beans-spring"}) + public void closePools() + throws Exception + { + closeConnectionPools(context.getBean("anonymous-search-authenticator", Authenticator.class)); + closeConnectionPools(context.getBean("bind-search-authenticator", Authenticator.class)); + closeConnectionPools(context.getBean("direct-authenticator", Authenticator.class)); + closeConnectionPools(context.getBean("ad-authenticator", Authenticator.class)); + closeConnectionPools(context.getBean("sasl-auth", Authenticator.class)); + closeConnectionPools(context.getBean("aggregate-authenticator", Authenticator.class)); + + context.getBean("pooled-connection-factory", PooledConnectionFactory.class).getConnectionPool().close(); + context.getBean("connection-pool", BlockingConnectionPool.class).close(); + } + + + /** + * Closing any authentication handler and DN resolver connection pools. + * + * @param auth to inspect for connection pools + */ + private void closeConnectionPools(final Authenticator auth) + { + final AuthenticationHandler authHandler = auth.getAuthenticationHandler(); + if (authHandler instanceof PooledConnectionFactoryManager) { + ((PooledConnectionFactoryManager) authHandler).getConnectionFactory().getConnectionPool().close(); + } else if (authHandler instanceof AggregateDnResolver.AuthenticationHandler) { + ((AggregateDnResolver.AuthenticationHandler) authHandler).getAuthenticationHandlers().values().stream().filter( + handler -> handler instanceof PooledConnectionFactoryManager).forEach( + handler -> ((PooledConnectionFactoryManager) handler).getConnectionFactory().getConnectionPool().close()); + } + final DnResolver dnResolver = auth.getDnResolver(); + if (dnResolver instanceof PooledConnectionFactoryManager) { + ((PooledConnectionFactoryManager) dnResolver).getConnectionFactory().getConnectionPool().close(); + } else if (dnResolver instanceof AggregateDnResolver) { + ((AggregateDnResolver) dnResolver).getDnResolvers().values().stream().filter( + resolver -> resolver instanceof PooledConnectionFactoryManager).forEach( + resolver -> ((PooledConnectionFactoryManager) resolver).getConnectionFactory().getConnectionPool().close()); + } + final EntryResolver entryResolver = auth.getEntryResolver(); + if (entryResolver instanceof PooledConnectionFactoryManager) { + ((PooledConnectionFactoryManager) entryResolver).getConnectionFactory().getConnectionPool().close(); + } else if (entryResolver instanceof AggregateDnResolver.EntryResolver) { + ((AggregateDnResolver.EntryResolver) entryResolver).getEntryResolvers().values().stream().filter( + resolver -> resolver instanceof PooledConnectionFactoryManager).forEach( + resolver -> ((PooledConnectionFactoryManager) resolver).getConnectionFactory().getConnectionPool().close()); + } + } + + + /** + * Attempts to load a Spring application context XML files to verify proper wiring. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testSpringWiring() + throws Exception + { + AssertJUnit.assertEquals(7, context.getBeansOfType(Authenticator.class).size()); + AssertJUnit.assertEquals(1, context.getBeansOfType(PooledConnectionFactory.class).size()); + AssertJUnit.assertEquals(1, context.getBeansOfType(DefaultConnectionFactory.class).size()); + AssertJUnit.assertEquals(1, context.getBeansOfType(SearchExecutor.class).size()); + AssertJUnit.assertEquals(1, context.getBeansOfType(BlockingConnectionPool.class).size()); + AssertJUnit.assertEquals(1, context.getBeansOfType(ConnectionConfig.class).size()); + } + + + /** + * Test anonymous search authenticator. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testAnonSearchAuthenticator() + throws Exception + { + final Authenticator anonSearchAuthenticator = context.getBean( + "anonymous-search-authenticator", + Authenticator.class); + AssertJUnit.assertNotNull(anonSearchAuthenticator); + testBindConnectionPool(anonSearchAuthenticator); + testSearchDnResolver(anonSearchAuthenticator, AuthenticatorType.ANON_SEARCH); + AssertJUnit.assertNotNull(anonSearchAuthenticator.getEntryResolver()); + AssertJUnit.assertNull(anonSearchAuthenticator.getAuthenticationResponseHandlers()); + AssertJUnit.assertNull( + ((PooledBindAuthenticationHandler) + anonSearchAuthenticator.getAuthenticationHandler()).getAuthenticationControls()); + } + + + /** + * Test bind search authenticator. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testBindSearchAuthenticator() + throws Exception + { + final Authenticator bindSearchAuthenticator = context.getBean("bind-search-authenticator", Authenticator.class); + AssertJUnit.assertNotNull(bindSearchAuthenticator); + testBindConnectionPool(bindSearchAuthenticator); + testSearchDnResolver(bindSearchAuthenticator, AuthenticatorType.BIND_SEARCH); + AssertJUnit.assertNotNull(bindSearchAuthenticator.getEntryResolver()); + AssertJUnit.assertNotNull(bindSearchAuthenticator.getAuthenticationResponseHandlers()); + AssertJUnit.assertEquals( + PasswordPolicyAuthenticationResponseHandler.class, + bindSearchAuthenticator.getAuthenticationResponseHandlers()[0].getClass()); + AssertJUnit.assertEquals( + PasswordPolicyControl.class, + ((PooledBindAuthenticationHandler) + bindSearchAuthenticator.getAuthenticationHandler()).getAuthenticationControls()[0].getClass()); + } + + + /** + * Test bind search authenticator. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testBindSearchAuthenticatorNoPooling() + throws Exception + { + final Authenticator bindSearchAuthenticator = context.getBean("bind-search-disable-pool", Authenticator.class); + AssertJUnit.assertNotNull(bindSearchAuthenticator); + testBindConnectionPool(bindSearchAuthenticator); + testSearchDnResolver(bindSearchAuthenticator, AuthenticatorType.BIND_SEARCH); + AssertJUnit.assertNotNull(bindSearchAuthenticator.getEntryResolver()); + AssertJUnit.assertNotNull(bindSearchAuthenticator.getAuthenticationResponseHandlers()); + AssertJUnit.assertEquals( + PasswordPolicyAuthenticationResponseHandler.class, + bindSearchAuthenticator.getAuthenticationResponseHandlers()[0].getClass()); + AssertJUnit.assertEquals( + PasswordPolicyControl.class, + ((BindAuthenticationHandler) + bindSearchAuthenticator.getAuthenticationHandler()).getAuthenticationControls()[0].getClass()); + } + + + /** + * Test sasl bind search authenticator. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testSaslBindSearchAuthenticator() + throws Exception + { + if (TestControl.isActiveDirectory()) { + return; + } + final Authenticator saslBindSearchAuthenticator = context.getBean("sasl-auth", Authenticator.class); + AssertJUnit.assertNotNull(saslBindSearchAuthenticator); + testBindConnectionPool(saslBindSearchAuthenticator); + testSearchDnResolver(saslBindSearchAuthenticator, AuthenticatorType.SASL_SEARCH); + AssertJUnit.assertNotNull(saslBindSearchAuthenticator.getEntryResolver()); + AssertJUnit.assertNotNull(saslBindSearchAuthenticator.getAuthenticationResponseHandlers()); + AssertJUnit.assertEquals( + PasswordExpirationAuthenticationResponseHandler.class, + saslBindSearchAuthenticator.getAuthenticationResponseHandlers()[0].getClass()); + AssertJUnit.assertNull( + ((PooledBindAuthenticationHandler) + saslBindSearchAuthenticator.getAuthenticationHandler()).getAuthenticationControls()); + } + + + /** + * Test direct authenticator. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testDirectAuthenticator() + throws Exception + { + final Authenticator directAuthenticator = context.getBean("direct-authenticator", Authenticator.class); + AssertJUnit.assertNotNull(directAuthenticator); + testBindConnectionPool(directAuthenticator); + AssertJUnit.assertNotNull(((FormatDnResolver) directAuthenticator.getDnResolver()).getFormat()); + AssertJUnit.assertTrue( + ((FormatDnResolver) directAuthenticator.getDnResolver()).getFormat().startsWith("cn=%1$s")); + AssertJUnit.assertNotNull(directAuthenticator.getAuthenticationResponseHandlers()); + final FreeIPAAuthenticationResponseHandler handler = + (FreeIPAAuthenticationResponseHandler) directAuthenticator.getAuthenticationResponseHandlers()[0]; + AssertJUnit.assertNotNull(handler); + AssertJUnit.assertEquals(Period.ofDays(90), handler.getExpirationPeriod()); + AssertJUnit.assertEquals(Period.ofDays(15), handler.getWarningPeriod()); + AssertJUnit.assertEquals(4, handler.getMaxLoginFailures()); + AssertJUnit.assertNull( + ((PooledBindAuthenticationHandler) + directAuthenticator.getAuthenticationHandler()).getAuthenticationControls()); + } + + + /** + * Test AD authenticator. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testADAuthenticator() + throws Exception + { + final Authenticator adAuthenticator = context.getBean("ad-authenticator", Authenticator.class); + AssertJUnit.assertNotNull(adAuthenticator); + testBindConnectionPool(adAuthenticator); + testSearchDnResolver(adAuthenticator, AuthenticatorType.AD); + AssertJUnit.assertNotNull(adAuthenticator.getEntryResolver()); + AssertJUnit.assertNotNull(adAuthenticator.getAuthenticationResponseHandlers()); + AssertJUnit.assertNotNull(adAuthenticator.getReturnAttributes()); + final ActiveDirectoryAuthenticationResponseHandler handler = + (ActiveDirectoryAuthenticationResponseHandler) adAuthenticator.getAuthenticationResponseHandlers()[0]; + AssertJUnit.assertNotNull(handler); + AssertJUnit.assertEquals(Period.ofDays(90), handler.getExpirationPeriod()); + AssertJUnit.assertEquals(Period.ofDays(15), handler.getWarningPeriod()); + AssertJUnit.assertNull( + ((PooledBindAuthenticationHandler) + adAuthenticator.getAuthenticationHandler()).getAuthenticationControls()); + } + + + /** + * Test aggregate authenticator. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testAggregateAuthenticator() + throws Exception + { + final Authenticator aggregateAuthenticator = context.getBean( + "aggregate-authenticator", + Authenticator.class); + AssertJUnit.assertNotNull(aggregateAuthenticator); + AssertJUnit.assertTrue(aggregateAuthenticator.getDnResolver() instanceof AggregateDnResolver); + final AggregateDnResolver dnResolvers = (AggregateDnResolver) aggregateAuthenticator.getDnResolver(); + for (DnResolver dnResolver : dnResolvers.getDnResolvers().values()) { + testSearchDnResolver((AbstractSearchDnResolver) dnResolver, null); + } + + AssertJUnit.assertNotNull(aggregateAuthenticator.getEntryResolver()); + + AssertJUnit.assertTrue( + aggregateAuthenticator.getAuthenticationHandler() instanceof AggregateDnResolver.AuthenticationHandler); + final AggregateDnResolver.AuthenticationHandler authHandlers = + (AggregateDnResolver.AuthenticationHandler) aggregateAuthenticator.getAuthenticationHandler(); + for (AuthenticationHandler authHandler : authHandlers.getAuthenticationHandlers().values()) { + testBindConnectionPool((AbstractBindAuthenticationHandler) authHandler); + } + + if (aggregateAuthenticator.getAuthenticationResponseHandlers() != null) { + final AggregateDnResolver.AuthenticationResponseHandler responseHandlers = + (AggregateDnResolver.AuthenticationResponseHandler) + aggregateAuthenticator.getAuthenticationResponseHandlers()[0]; + for (AuthenticationResponseHandler[] responseHandler : + responseHandlers.getAuthenticationResponseHandlers().values()) { + for (AuthenticationResponseHandler handler : responseHandler) { + AssertJUnit.assertNotNull(handler); + } + } + } + } + + + /** + * Test pooled connection factory. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testPooledConnectionFactory() + throws Exception + { + final PooledConnectionFactory pooledConnectionFactory = context.getBean( + "pooled-connection-factory", + PooledConnectionFactory.class); + AssertJUnit.assertNotNull(pooledConnectionFactory); + testConnectionPool((BlockingConnectionPool) pooledConnectionFactory.getConnectionPool(), null); + } + + + /** + * Test connection factory. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testConnectionFactory() + throws Exception + { + final DefaultConnectionFactory connectionFactory = context.getBean( + "connection-factory", + DefaultConnectionFactory.class); + AssertJUnit.assertNotNull(connectionFactory); + testConnectionConfig(connectionFactory.getConnectionConfig(), null); + } + + + /** + * Test search executor. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testSearchExecutor() + throws Exception + { + final SearchExecutor executor = context.getBean("search-executor", SearchExecutor.class); + AssertJUnit.assertNotNull(executor); + testSearchRequest(executor); + } + + + /** + * Test parallel search executor. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testParallelSearchExecutor() + throws Exception + { + final ParallelSearchExecutor executor = context.getBean("parallel-search-executor", ParallelSearchExecutor.class); + AssertJUnit.assertNotNull(executor); + testSearchRequest(executor); + } + + + /** + * Test parallel pooled search executor. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testParallelPooledSearchExecutor() + throws Exception + { + final ParallelPooledSearchExecutor executor = context.getBean( + "parallel-pooled-search-executor", + ParallelPooledSearchExecutor.class); + AssertJUnit.assertNotNull(executor); + testSearchRequest(executor); + } + + + /** + * Test aggregate search executor. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testAggregateSearchExecutor() + throws Exception + { + final AggregateSearchExecutor executor = context.getBean( + "aggregate-search-executor", + AggregateSearchExecutor.class); + AssertJUnit.assertNotNull(executor); + testSearchRequest(executor); + } + + + /** + * Test aggregate pooled search executor. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testAggregatePooledSearchExecutor() + throws Exception + { + final AggregatePooledSearchExecutor executor = context.getBean( + "aggregate-pooled-search-executor", + AggregatePooledSearchExecutor.class); + AssertJUnit.assertNotNull(executor); + testSearchRequest(executor); + } + + + /** + * Test connection pool. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testConnectionPool() + throws Exception + { + final BlockingConnectionPool connectionPool = context.getBean("connection-pool", BlockingConnectionPool.class); + AssertJUnit.assertNotNull(connectionPool); + testConnectionPool(connectionPool, null); + } + + + /** + * Test connection config. + * + * @throws Exception On test failure. + */ + @Test(groups = {"beans-spring"}) + public void testConnectionConfig() + throws Exception + { + final ConnectionConfig config = context.getBean("connection-config", ConnectionConfig.class); + AssertJUnit.assertNotNull(config); + testConnectionConfig(config, null); + } + + + /** + * Runs asserts against the bind connection pool. + * + * @param auth authenticator + */ + private void testBindConnectionPool(final Authenticator auth) + { + testBindConnectionPool((AbstractBindAuthenticationHandler) auth.getAuthenticationHandler()); + } + + + /** + * Runs asserts against the bind connection pool. + * + * @param authHandler authenticator handler + */ + private void testBindConnectionPool(final AbstractBindAuthenticationHandler authHandler) + { + if (authHandler instanceof PooledBindAuthenticationHandler) { + final BlockingConnectionPool pool = + (BlockingConnectionPool) + ((PooledConnectionFactoryManager) authHandler).getConnectionFactory().getConnectionPool(); + testConnectionPool(pool, null); + } else { + Connection conn = null; + try { + conn = ((ConnectionFactoryManager) authHandler).getConnectionFactory().getConnection(); + testConnectionConfig(conn.getConnectionConfig(), null); + } catch (LdapException e) { + AssertJUnit.fail("Error getting connection: " + e.getMessage()); + } finally { + if (conn != null) { + conn.close(); + } + } + } + } + + + /** + * Runs asserts against the DN resolver. + * + * @param auth authenticator + * @param authType authenticator type + */ + private void testSearchDnResolver(final Authenticator auth, final AuthenticatorType authType) + { + testSearchDnResolver((AbstractSearchDnResolver) auth.getDnResolver(), authType); + } + + + /** + * Runs asserts against the DN resolver. + * + * @param dnResolver dn resolver + * @param authType authenticator type + */ + private void testSearchDnResolver(final AbstractSearchDnResolver dnResolver, final AuthenticatorType authType) + { + AssertJUnit.assertNotNull(dnResolver.getBaseDn()); + AssertJUnit.assertEquals("(mail={user})", dnResolver.getUserFilter()); + if (dnResolver instanceof PooledSearchDnResolver) { + final BlockingConnectionPool pool = + (BlockingConnectionPool) + ((PooledConnectionFactoryManager) dnResolver).getConnectionFactory().getConnectionPool(); + testConnectionPool(pool, authType); + } else { + Connection conn = null; + try { + conn = ((ConnectionFactoryManager) dnResolver).getConnectionFactory().getConnection(); + testConnectionConfig(conn.getConnectionConfig(), authType); + } catch (LdapException e) { + AssertJUnit.fail("Error getting connection: " + e.getMessage()); + } finally { + if (conn != null) { + conn.close(); + } + } + } + } + + + /** + * Runs asserts against the connection pool. + * + * @param pool to test + * @param authType authenticator type or null + */ + private void testConnectionPool(final BlockingConnectionPool pool, final AuthenticatorType authType) + { + AssertJUnit.assertEquals(Duration.ofSeconds(3), pool.getBlockWaitTime()); + AssertJUnit.assertFalse(pool.getFailFastInitialize()); + AssertJUnit.assertEquals(Duration.ofMinutes(5), pool.getPruneStrategy().getPrunePeriod()); + AssertJUnit.assertEquals(Duration.ofMinutes(10), ((IdlePruneStrategy) pool.getPruneStrategy()).getIdleTime()); + AssertJUnit.assertEquals(SearchValidator.class, pool.getValidator().getClass()); + + final PoolConfig poolConfig = pool.getPoolConfig(); + AssertJUnit.assertEquals(3, poolConfig.getMinPoolSize()); + AssertJUnit.assertEquals(10, poolConfig.getMaxPoolSize()); + AssertJUnit.assertEquals(Duration.ofMinutes(5), poolConfig.getValidatePeriod()); + AssertJUnit.assertFalse(poolConfig.isValidateOnCheckOut()); + AssertJUnit.assertTrue(poolConfig.isValidatePeriodically()); + + Connection conn = null; + try { + conn = pool.getConnection(); + testConnectionConfig(conn.getConnectionConfig(), authType); + } catch (LdapException e) { + AssertJUnit.fail("Error getting connection from pool: " + e.getMessage()); + } finally { + if (conn != null) { + conn.close(); + } + } + } + + + /** + * Runs asserts against the connection config. + * + * @param connectionConfig to test + * @param authType authenticator type or null + */ + private void testConnectionConfig(final ConnectionConfig connectionConfig, final AuthenticatorType authType) + { + AssertJUnit.assertNotNull(connectionConfig.getLdapUrl()); + AssertJUnit.assertTrue(connectionConfig.getUseStartTLS()); + AssertJUnit.assertFalse(connectionConfig.getUseSSL()); + AssertJUnit.assertEquals(Duration.ofSeconds(3), connectionConfig.getConnectTimeout()); + final CredentialConfig credentialConfig = connectionConfig.getSslConfig().getCredentialConfig(); + if (credentialConfig instanceof X509CredentialConfig) { + AssertJUnit.assertNotNull(((X509CredentialConfig) credentialConfig).getTrustCertificates()); + } else if (credentialConfig instanceof KeyStoreCredentialConfig) { + AssertJUnit.assertNotNull(((KeyStoreCredentialConfig) credentialConfig).getTrustStore()); + } + + if (authType != null) { + final BindConnectionInitializer ci = (BindConnectionInitializer) connectionConfig.getConnectionInitializer(); + switch(authType) { + case ANON_SEARCH: + AssertJUnit.assertNull(ci); + break; + case BIND_SEARCH: + AssertJUnit.assertNotNull(ci); + AssertJUnit.assertNotNull(ci.getBindDn()); + AssertJUnit.assertNotNull(ci.getBindCredential()); + break; + case SASL_SEARCH: + AssertJUnit.assertNotNull(ci); + final SaslConfig sc = ci.getBindSaslConfig(); + AssertJUnit.assertNotNull(sc); + AssertJUnit.assertEquals(Mechanism.DIGEST_MD5, sc.getMechanism()); + AssertJUnit.assertEquals(QualityOfProtection.AUTH_INT, sc.getQualityOfProtection()); + AssertJUnit.assertEquals(SecurityStrength.MEDIUM, sc.getSecurityStrength()); + break; + case DIRECT: + AssertJUnit.assertNull(ci); + break; + case AD: + AssertJUnit.assertNotNull(ci); + AssertJUnit.assertNotNull(ci.getBindDn()); + AssertJUnit.assertNotNull(ci.getBindCredential()); + break; + default: + throw new IllegalStateException("Unknown type"); + } + } + } + + + /** + * Runs asserts against the search request. + * + * @param request to test + */ + private void testSearchRequest(final SearchRequest request) + { + AssertJUnit.assertNotNull(request.getBaseDn()); + AssertJUnit.assertTrue(request.getBaseDn().length() > 0); + AssertJUnit.assertNotNull(request.getSearchFilter()); + AssertJUnit.assertTrue(request.getReturnAttributes().length > 0); + AssertJUnit.assertEquals(SearchScope.ONELEVEL, request.getSearchScope()); + AssertJUnit.assertEquals(Duration.ofSeconds(5), request.getTimeLimit()); + AssertJUnit.assertEquals(10, request.getSizeLimit()); + AssertJUnit.assertTrue(request.getBinaryAttributes().length > 0); + AssertJUnit.assertEquals(SortBehavior.ORDERED, request.getSortBehavior()); + } +}
diff --git a/integration/src/test/java/org/ldaptive/cli/AuthenticatorCliTest.java b/integration/src/test/java/org/ldaptive/cli/AuthenticatorCliTest.java new file mode 100644 index 0000000..9d95611 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/cli/AuthenticatorCliTest.java
@@ -0,0 +1,135 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.cli; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.security.Permission; +import org.ldaptive.AbstractTest; +import org.ldaptive.LdapEntry; +import org.ldaptive.TestUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link AuthenticatorCli} class. + * + * @author Middleware Services + */ +public class AuthenticatorCliTest extends AbstractTest +{ + + /** Entry created for ldap tests. */ + private static LdapEntry testLdapEntry; + + /** System security manager. */ + private final SecurityManager securityManager = System.getSecurityManager(); + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry9") + @BeforeClass(groups = {"authcli"}) + public void createLdapEntry(final String ldifFile) + throws Exception + { + // don't allow System#exit + System.setSecurityManager( + new SecurityManager() { + @Override + public void checkPermission(final Permission permission) + { + if (permission.getName().startsWith("exitVM")) { + throw new SecurityException("System.exit blocked."); + } + } + }); + + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + + System.setProperty("javax.net.ssl.trustStore", "target/test-classes/ldaptive.truststore"); + System.setProperty("javax.net.ssl.trustStoreType", "BKS"); + System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"authcli"}) + public void deleteLdapEntry() + throws Exception + { + System.clearProperty("javax.net.ssl.trustStore"); + System.clearProperty("javax.net.ssl.trustStoreType"); + System.clearProperty("javax.net.ssl.trustStorePassword"); + + super.deleteLdapEntry(testLdapEntry.getDn()); + System.setSecurityManager(securityManager); + } + + + /** + * @param args List of delimited arguments to pass to the CLI. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters({ "cliAuthTLSArgs", "cliAuthResults" }) + @Test(groups = {"authcli"}) + public void authenticateTLS(final String args, final String ldifFile) + throws Exception + { + authenticate(args, ldifFile); + } + + + /** + * @param args List of delimited arguments to pass to the CLI. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters({ "cliAuthSSLArgs", "cliAuthResults" }) + @Test(groups = {"authcli"}) + public void authenticateSSL(final String args, final String ldifFile) + throws Exception + { + authenticate(args, ldifFile); + } + + + /** + * @param args List of delimited arguments to pass to the CLI. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + private void authenticate(final String args, final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + final PrintStream oldStdOut = System.out; + try { + final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outStream)); + + try { + AuthenticatorCli.main(args.split("\\|")); + } catch (SecurityException e) { + AssertJUnit.fail(e.getMessage()); + } + AssertJUnit.assertEquals( + TestUtils.convertLdifToResult(ldif), + TestUtils.convertLdifToResult(outStream.toString())); + } finally { + // Restore STDOUT + System.setOut(oldStdOut); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/cli/OperationCliTest.java b/integration/src/test/java/org/ldaptive/cli/OperationCliTest.java new file mode 100644 index 0000000..7ecbc70 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/cli/OperationCliTest.java
@@ -0,0 +1,148 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.cli; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.security.Permission; +import org.ldaptive.AbstractTest; +import org.ldaptive.TestUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for ldap operation cli classes. + * + * @author Middleware Services + */ +public class OperationCliTest extends AbstractTest +{ + + /** System security manager. */ + private final SecurityManager securityManager = System.getSecurityManager(); + + /** + * @param args list of delimited arguments to pass to the CLI + * + * @throws Exception On test failure + */ + @Parameters("cliAddArgs") + @BeforeClass(groups = {"cli"}) + public void createLdapEntry(final String args) + throws Exception + { + // don't allow System#exit + System.setSecurityManager( + new SecurityManager() { + @Override + public void checkPermission(final Permission permission) + { + if (permission.getName().startsWith("exitVM")) { + throw new SecurityException("System.exit blocked."); + } + } + }); + + final PrintStream oldStdOut = System.out; + try { + final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outStream)); + + AddOperationCli.main(args.split("\\|")); + } catch (SecurityException e) { + AssertJUnit.assertNotNull(e); + } finally { + // Restore STDOUT + System.setOut(oldStdOut); + } + } + + + /** + * @param args list of delimited arguments to pass to the CLI + * + * @throws Exception On test failure + */ + @Parameters("cliDeleteArgs") + @AfterClass(groups = {"cli"}) + public void deleteLdapEntry(final String args) + throws Exception + { + final PrintStream oldStdOut = System.out; + try { + final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outStream)); + + DeleteOperationCli.main(args.split("\\|")); + } catch (SecurityException e) { + AssertJUnit.assertNotNull(e); + } finally { + // Restore STDOUT + System.setOut(oldStdOut); + } + + System.setSecurityManager(securityManager); + } + + + /** + * @param args list of delimited arguments to pass to the CLI + * @param ldifFile to compare with + * + * @throws Exception On test failure + */ + @Parameters({ "cliSearchArgs", "cliSearchResults" }) + @Test(groups = {"cli"}) + public void search(final String args, final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + final PrintStream oldStdOut = System.out; + try { + final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outStream)); + + try { + SearchOperationCli.main(args.split("\\|")); + } catch (SecurityException e) { + AssertJUnit.assertNotNull(e); + } + AssertJUnit.assertEquals( + TestUtils.convertLdifToResult(ldif), + TestUtils.convertLdifToResult(outStream.toString())); + } finally { + // Restore STDOUT + System.setOut(oldStdOut); + } + } + + + /** + * @param args list of delimited arguments to pass to the CLI + * + * @throws Exception On test failure. + */ + @Parameters("cliCompareArgs") + @Test(groups = {"cli"}) + public void compare(final String args) + throws Exception + { + final PrintStream oldStdOut = System.out; + try { + final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outStream)); + + try { + CompareOperationCli.main(args.split("\\|")); + } catch (SecurityException e) { + AssertJUnit.assertNotNull(e); + } + AssertJUnit.assertEquals("true", outStream.toString().trim()); + } finally { + // Restore STDOUT + System.setOut(oldStdOut); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/control/util/PagedResultsClientTest.java b/integration/src/test/java/org/ldaptive/control/util/PagedResultsClientTest.java new file mode 100644 index 0000000..b930028 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/control/util/PagedResultsClientTest.java
@@ -0,0 +1,160 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control.util; + +import java.util.Iterator; +import org.ldaptive.AbstractTest; +import org.ldaptive.Connection; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.SortBehavior; +import org.ldaptive.TestUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link PagedResultsClient}. + * + * @author Middleware Services + */ +public class PagedResultsClientTest extends AbstractTest +{ + + /** Entries created for ldap tests. */ + private static LdapEntry[] testLdapEntries; + + + /** + * @param ldifFile1 to create. + * @param ldifFile2 to create. + * @param ldifFile3 to create. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "createEntry22", + "createEntry23", + "createEntry25" + }) + @BeforeClass(groups = {"control-util"}) + public void createLdapEntry(final String ldifFile1, final String ldifFile2, final String ldifFile3) + throws Exception + { + testLdapEntries = new LdapEntry[3]; + testLdapEntries[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile1)).getEntry(); + super.createLdapEntry(testLdapEntries[0]); + testLdapEntries[1] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile2)).getEntry(); + super.createLdapEntry(testLdapEntries[1]); + testLdapEntries[2] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile3)).getEntry(); + super.createLdapEntry(testLdapEntries[2]); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"control-util"}) + public void deleteLdapEntry() + throws Exception + { + for (LdapEntry testLdapEntry : testLdapEntries) { + super.deleteLdapEntry(testLdapEntry.getDn()); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "prSearchDn", + "prSearchFilter" + }) + @Test(groups = {"control-util"}) + public void execute(final String dn, final String filter) + throws Exception + { + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final PagedResultsClient client = new PagedResultsClient(conn, 1); + + final SearchRequest request = new SearchRequest(dn, new SearchFilter(filter)); + Response<SearchResult> response = client.execute(request); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertEquals(1, response.getResult().size()); + AssertJUnit.assertEquals( + testLdapEntries[0].getDn().toLowerCase(), + response.getResult().getEntry().getDn().toLowerCase()); + + int i = 1; + while (client.hasMore(response)) { + response = client.execute(request, response); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertEquals(1, response.getResult().size()); + AssertJUnit.assertEquals( + testLdapEntries[i].getDn().toLowerCase(), + response.getResult().getEntry().getDn().toLowerCase()); + i++; + } + + try { + client.execute(request, response); + } catch (IllegalArgumentException e) { + AssertJUnit.assertNotNull(e); + } + } catch (LdapException e) { + // ignore this test if not supported by the server + AssertJUnit.assertEquals(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, e.getResultCode()); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "prSearchDn", + "prSearchFilter" + }) + @Test(groups = {"control-util"}) + public void executeToCompletion(final String dn, final String filter) + throws Exception + { + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final PagedResultsClient client = new PagedResultsClient(conn, 1); + + final SearchRequest request = new SearchRequest(dn, new SearchFilter(filter)); + request.setSortBehavior(SortBehavior.SORTED); + + final Response<SearchResult> response = client.executeToCompletion(request); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertEquals(3, response.getResult().size()); + + final Iterator<LdapEntry> i = response.getResult().getEntries().iterator(); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertEquals(testLdapEntries[1].getDn().toLowerCase(), i.next().getDn().toLowerCase()); + AssertJUnit.assertEquals(testLdapEntries[0].getDn().toLowerCase(), i.next().getDn().toLowerCase()); + AssertJUnit.assertEquals(testLdapEntries[2].getDn().toLowerCase(), i.next().getDn().toLowerCase()); + } catch (LdapException e) { + // ignore this test if not supported by the server + AssertJUnit.assertEquals(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, e.getResultCode()); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/control/util/PersistentSearchClientTest.java b/integration/src/test/java/org/ldaptive/control/util/PersistentSearchClientTest.java new file mode 100644 index 0000000..8e1ac3b --- /dev/null +++ b/integration/src/test/java/org/ldaptive/control/util/PersistentSearchClientTest.java
@@ -0,0 +1,228 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control.util; + +import java.util.EnumSet; +import java.util.concurrent.BlockingQueue; +import org.ldaptive.AbstractTest; +import org.ldaptive.AttributeModification; +import org.ldaptive.AttributeModificationType; +import org.ldaptive.Connection; +import org.ldaptive.DnParser; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.ModifyDnOperation; +import org.ldaptive.ModifyDnRequest; +import org.ldaptive.ModifyOperation; +import org.ldaptive.ModifyRequest; +import org.ldaptive.ResultCode; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.ldaptive.async.AsyncRequest; +import org.ldaptive.control.PersistentSearchChangeType; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link PersistentSearchClient}. + * + * @author Middleware Services + */ +public class PersistentSearchClientTest extends AbstractTest +{ + + /** Entry created for ldap tests. */ + private static LdapEntry testLdapEntry; + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry31") + @BeforeClass(groups = {"control-util"}) + public void createLdapEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"control-util"}) + public void deleteLdapEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + } + + + /** + * @param dn to search on. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "persistentSearchDn", + "persistentSearchReturnAttrs", + "persistentSearchResults" + }) + @Test(groups = {"control-util"}) + public void persistentSearch(final String dn, final String returnAttrs, final String ldifFile) + throws Exception + { + if (TestControl.isActiveDirectory()) { + return; + } + + final String expected = TestUtils.readFileIntoString(ldifFile); + final SearchResult expectedResult = TestUtils.convertLdifToResult(expected); + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final PersistentSearchClient client = new PersistentSearchClient( + conn, + EnumSet.allOf(PersistentSearchChangeType.class), + true, + true); + final SearchRequest request = SearchRequest.newObjectScopeSearchRequest(dn, returnAttrs.split("\\|")); + final BlockingQueue<PersistentSearchItem> results = client.execute(request); + + // test the async request + PersistentSearchItem item = results.take(); + if (item.isException()) { + throw item.getException(); + } + + AsyncRequest asyncRequest = null; + if (item.isAsyncRequest()) { + asyncRequest = item.getAsyncRequest(); + // some providers don't support the request object + AssertJUnit.assertTrue(item.getAsyncRequest().getMessageId() > 0); + } + checkItem(item); + + // make a change + final LdapAttribute modAttr = new LdapAttribute("initials", "PSC"); + final ModifyOperation modify = new ModifyOperation(conn); + modify.execute(new ModifyRequest(dn, new AttributeModification(AttributeModificationType.REPLACE, modAttr))); + item = results.take(); + checkItem(item); + AssertJUnit.assertTrue(item.isEntry()); + AssertJUnit.assertEquals( + PersistentSearchChangeType.MODIFY, + item.getEntry().getEntryChangeNotificationControl().getChangeType()); + expectedResult.getEntry().addAttribute(modAttr); + TestUtils.assertEquals( + expectedResult, + new SearchResult(createCompareEntry(expectedResult.getEntry(), item.getEntry().getSearchEntry()))); + + // modify dn + final String modDn = "CN=PSC," + DnParser.substring(dn, 1); + final LdapAttribute cn = expectedResult.getEntry().getAttribute("cn"); + final ModifyDnOperation modifyDn = new ModifyDnOperation(conn); + modifyDn.execute(new ModifyDnRequest(dn, modDn)); + item = results.take(); + AssertJUnit.assertTrue(item.isEntry()); + AssertJUnit.assertEquals( + PersistentSearchChangeType.MODDN, + item.getEntry().getEntryChangeNotificationControl().getChangeType()); + expectedResult.getEntry().setDn(modDn); + expectedResult.getEntry().addAttribute(new LdapAttribute("CN", "PSC")); + TestUtils.assertEquals( + expectedResult, + new SearchResult(createCompareEntry(expectedResult.getEntry(), item.getEntry().getSearchEntry()))); + + // modify dn back + modifyDn.execute(new ModifyDnRequest(modDn, dn)); + item = results.take(); + AssertJUnit.assertTrue(item.isEntry()); + AssertJUnit.assertEquals( + PersistentSearchChangeType.MODDN, + item.getEntry().getEntryChangeNotificationControl().getChangeType()); + expectedResult.getEntry().setDn(dn); + expectedResult.getEntry().addAttribute(cn); + TestUtils.assertEquals( + expectedResult, + new SearchResult(createCompareEntry(expectedResult.getEntry(), item.getEntry().getSearchEntry()))); + + asyncRequest.abandon(); + if (!results.isEmpty()) { + item = results.take(); + if (item.isResponse()) { + AssertJUnit.assertEquals(ResultCode.USER_CANCELLED, item.getResponse().getResultCode()); + } else if (item.isException()) { + final LdapException e = (LdapException) item.getException(); + AssertJUnit.assertEquals(ResultCode.USER_CANCELLED, e.getResultCode()); + } else { + AssertJUnit.fail("Unknown result type"); + } + } + AssertJUnit.assertTrue(results.isEmpty()); + } + } + + + /** + * Check that the supplied item isn't a response or exception. + * + * @param item to check + * + * @throws UnsupportedOperationException if the server doesn't support this control + * @throws IllegalStateException if the item is a response or exception + */ + private void checkItem(final PersistentSearchItem item) + { + if (item.isResponse()) { + if (ResultCode.UNAVAILABLE_CRITICAL_EXTENSION.equals(item.getResponse().getResultCode())) { + // ignore this test if not supported by the server + throw new UnsupportedOperationException("LDAP server does not support this control"); + } else { + throw new IllegalStateException("Unexpected response: " + item.getResponse()); + } + } else if (item.isException()) { + final LdapException e = (LdapException) item.getException(); + if (ResultCode.UNAVAILABLE_CRITICAL_EXTENSION.equals(e.getResultCode())) { + // ignore this test if not supported by the server + throw new UnsupportedOperationException("LDAP server does not support this control"); + } else { + throw new IllegalStateException("Unexpected exception: " + e); + } + } + } + + + /** + * Creates an ldap entry to compare with expected results. Removes any extra attributes returned from using the + * persistent search control. + * + * @param expectedEntry to compare with + * @param searchEntry returned from a persistent search + * + * @return sanitized entry to compare with + * + * @throws Exception if an error occurs + */ + private LdapEntry createCompareEntry(final LdapEntry expectedEntry, final SearchEntry searchEntry) + throws Exception + { + final LdapEntry compareEntry = new LdapEntry(expectedEntry.getDn()); + for (String attr : expectedEntry.getAttributeNames()) { + compareEntry.addAttribute(searchEntry.getAttribute(attr)); + } + return compareEntry; + } +}
diff --git a/integration/src/test/java/org/ldaptive/control/util/SyncReplClientTest.java b/integration/src/test/java/org/ldaptive/control/util/SyncReplClientTest.java new file mode 100644 index 0000000..a42d0e3 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/control/util/SyncReplClientTest.java
@@ -0,0 +1,223 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control.util; + +import java.util.concurrent.BlockingQueue; +import org.ldaptive.AbstractTest; +import org.ldaptive.AttributeModification; +import org.ldaptive.AttributeModificationType; +import org.ldaptive.Connection; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.ModifyOperation; +import org.ldaptive.ModifyRequest; +import org.ldaptive.ResultCode; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.ldaptive.control.SyncStateControl; +import org.ldaptive.intermediate.SyncInfoMessage; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SyncReplClient}. + * + * @author Middleware Services + */ +public class SyncReplClientTest extends AbstractTest +{ + + /** Entry created for ldap tests. */ + private static LdapEntry testLdapEntry; + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry18") + @BeforeClass(groups = {"control-util"}) + public void createLdapEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"control-util"}) + public void deleteLdapEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + } + + + /** + * @param dn to search on. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "syncReplSearchDn", + "syncReplSearchReturnAttrs", + "syncReplSearchResults" + }) + @Test(groups = {"control-util"}) + public void syncReplRefreshOnly(final String dn, final String returnAttrs, final String ldifFile) + throws Exception + { + if (TestControl.isActiveDirectory()) { + return; + } + + final String expected = TestUtils.readFileIntoString(ldifFile); + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final SyncReplClient client = new SyncReplClient(conn, false); + final SearchRequest request = SearchRequest.newObjectScopeSearchRequest(dn, returnAttrs.split("\\|")); + final BlockingQueue<SyncReplItem> results = client.execute(request, new DefaultCookieManager()); + + SyncReplItem item = results.take(); + if (item.isException()) { + throw item.getException(); + } + if (item.isAsyncRequest()) { + // some providers don't support the request object + AssertJUnit.assertTrue(item.isAsyncRequest()); + AssertJUnit.assertTrue(item.getAsyncRequest().getMessageId() > 0); + item = results.take(); + } + AssertJUnit.assertTrue(item.isEntry()); + AssertJUnit.assertEquals(SyncStateControl.State.ADD, item.getEntry().getSyncStateControl().getSyncState()); + AssertJUnit.assertNotNull(item.getEntry().getSyncStateControl().getEntryUuid()); + AssertJUnit.assertNull(item.getEntry().getSyncStateControl().getCookie()); + + item = results.take(); + AssertJUnit.assertTrue(item.isResponse()); + AssertJUnit.assertEquals(true, item.getResponse().getSyncDoneControl().getRefreshDeletes()); + AssertJUnit.assertNotNull(item.getResponse().getSyncDoneControl().getCookie()); + } + } + + + /** + * @param dn to search on. + * @param returnAttrs to return from search. + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "syncReplSearchDn", + "syncReplSearchReturnAttrs", + "syncReplSearchResults" + }) + @Test(groups = {"control-util"}) + public void syncReplRefreshAndPersist(final String dn, final String returnAttrs, final String ldifFile) + throws Exception + { + if (TestControl.isActiveDirectory()) { + return; + } + + // provider doesn't support cancel + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP does not support cancel"); + } + if (TestControl.isOpenDJProvider()) { + throw new UnsupportedOperationException("OpenDJ does not support cancel"); + } + + final String expected = TestUtils.readFileIntoString(ldifFile); + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final SyncReplClient client = new SyncReplClient(conn, true); + final SearchRequest request = SearchRequest.newObjectScopeSearchRequest(dn, returnAttrs.split("\\|")); + final BlockingQueue<SyncReplItem> results = client.execute(request, new DefaultCookieManager()); + + // test the async request + SyncReplItem item = results.take(); + if (item.isException()) { + throw item.getException(); + } + if (item.isAsyncRequest()) { + // some providers don't support the request object + AssertJUnit.assertTrue(item.isAsyncRequest()); + AssertJUnit.assertTrue(item.getAsyncRequest().getMessageId() > 0); + item = results.take(); + } + + // test the first entry + AssertJUnit.assertTrue(item.isEntry()); + AssertJUnit.assertEquals(SyncStateControl.State.ADD, item.getEntry().getSyncStateControl().getSyncState()); + AssertJUnit.assertNotNull(item.getEntry().getSyncStateControl().getEntryUuid()); + AssertJUnit.assertNull(item.getEntry().getSyncStateControl().getCookie()); + TestUtils.assertEquals( + TestUtils.convertLdifToResult(expected), + new SearchResult(item.getEntry().getSearchEntry())); + + // test the info message + item = results.take(); + if (item.isException()) { + throw item.getException(); + } + AssertJUnit.assertTrue(item.isMessage()); + AssertJUnit.assertEquals(SyncInfoMessage.Type.REFRESH_DELETE, item.getMessage().getMessageType()); + AssertJUnit.assertNotNull(item.getMessage().getCookie()); + AssertJUnit.assertFalse(item.getMessage().getRefreshDeletes()); + AssertJUnit.assertTrue(item.getMessage().getRefreshDone()); + + // make a change + final ModifyOperation modify = new ModifyOperation(conn); + modify.execute( + new ModifyRequest( + dn, + new AttributeModification(AttributeModificationType.ADD, new LdapAttribute("employeeType", "Employee")))); + item = results.take(); + AssertJUnit.assertTrue(item.isEntry()); + AssertJUnit.assertEquals(SyncStateControl.State.MODIFY, item.getEntry().getSyncStateControl().getSyncState()); + AssertJUnit.assertNotNull(item.getEntry().getSyncStateControl().getEntryUuid()); + AssertJUnit.assertNotNull(item.getEntry().getSyncStateControl().getCookie()); + + // change it back + modify.execute( + new ModifyRequest( + dn, + new AttributeModification(AttributeModificationType.REMOVE, new LdapAttribute("employeeType")))); + item = results.take(); + AssertJUnit.assertTrue(item.isEntry()); + AssertJUnit.assertEquals(SyncStateControl.State.MODIFY, item.getEntry().getSyncStateControl().getSyncState()); + AssertJUnit.assertNotNull(item.getEntry().getSyncStateControl().getEntryUuid()); + AssertJUnit.assertNotNull(item.getEntry().getSyncStateControl().getCookie()); + TestUtils.assertEquals( + TestUtils.convertLdifToResult(expected), + new SearchResult(item.getEntry().getSearchEntry())); + + client.cancel(item.getEntry().getSearchEntry().getMessageId()); + + item = results.take(); + if (item.isException()) { + throw item.getException(); + } + AssertJUnit.assertTrue(item.isResponse()); + AssertJUnit.assertTrue(results.isEmpty()); + AssertJUnit.assertEquals(ResultCode.CANCELED, item.getResponse().getResponse().getResultCode()); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/control/util/VirtualListViewClientTest.java b/integration/src/test/java/org/ldaptive/control/util/VirtualListViewClientTest.java new file mode 100644 index 0000000..09c5580 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/control/util/VirtualListViewClientTest.java
@@ -0,0 +1,158 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.control.util; + +import java.util.Iterator; +import org.ldaptive.AbstractTest; +import org.ldaptive.Connection; +import org.ldaptive.LdapEntry; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.SortBehavior; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.ldaptive.control.SortKey; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link VirtualListViewClient}. + * + * @author Middleware Services + */ +public class VirtualListViewClientTest extends AbstractTest +{ + + /** Entries created for ldap tests. */ + private static LdapEntry[] testLdapEntries; + + + /** + * @param ldifFile1 to create. + * @param ldifFile2 to create. + * @param ldifFile3 to create. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "createEntry19", + "createEntry20", + "createEntry21" + }) + @BeforeClass(groups = {"control-util"}) + public void createLdapEntry(final String ldifFile1, final String ldifFile2, final String ldifFile3) + throws Exception + { + testLdapEntries = new LdapEntry[3]; + testLdapEntries[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile1)).getEntry(); + super.createLdapEntry(testLdapEntries[0]); + testLdapEntries[1] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile2)).getEntry(); + super.createLdapEntry(testLdapEntries[1]); + testLdapEntries[2] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile3)).getEntry(); + super.createLdapEntry(testLdapEntries[2]); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"control-util"}) + public void deleteLdapEntry() + throws Exception + { + for (LdapEntry testLdapEntry : testLdapEntries) { + super.deleteLdapEntry(testLdapEntry.getDn()); + } + } + + + /** + * @param dn to search on. + * @param filter to search with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "vlvSearchDn", + "vlvSearchFilter" + }) + @Test(groups = {"control-util"}) + public void execute(final String dn, final String filter) + throws Exception + { + // AD server says vlv is a supported control, but returns UNAVAIL_EXTENSION + if (TestControl.isActiveDirectory() || TestControl.isOracleDirectory()) { + return; + } + + // provider doesn't support this control + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP does not support this control"); + } + + final Connection conn = TestUtils.createConnection(); + try { + conn.open(); + + final VirtualListViewClient client = new VirtualListViewClient( + conn, + new SortKey("uid", "caseExactMatch"), + new SortKey("givenName", "caseIgnoreMatch")); + + final SearchRequest request = new SearchRequest(dn, new SearchFilter(filter)); + request.setSortBehavior(SortBehavior.ORDERED); + Response<SearchResult> response = client.execute(request, new VirtualListViewParams(1, 0, 1)); + Iterator<LdapEntry> i = response.getResult().getEntries().iterator(); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertEquals(testLdapEntries[0].getDn(), i.next().getDn()); + AssertJUnit.assertEquals(testLdapEntries[1].getDn(), i.next().getDn()); + + response = client.execute(request, new VirtualListViewParams(2, 1, 1), response); + i = response.getResult().getEntries().iterator(); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertEquals(testLdapEntries[0].getDn(), i.next().getDn()); + AssertJUnit.assertEquals(testLdapEntries[1].getDn(), i.next().getDn()); + AssertJUnit.assertEquals(testLdapEntries[2].getDn(), i.next().getDn()); + + } catch (UnsupportedOperationException e) { + // ignore this test if not supported + AssertJUnit.assertNotNull(e); + } finally { + conn.close(); + } + + // VLV does not give a clean way to destroy the server side sorted entries + // list. Open a new connection. + try { + conn.open(); + + final VirtualListViewClient client = new VirtualListViewClient(conn, new SortKey("uid", "caseExactMatch")); + + final SearchRequest request = new SearchRequest(dn, new SearchFilter(filter)); + request.setSortBehavior(SortBehavior.ORDERED); + Response<SearchResult> response = client.execute(request, new VirtualListViewParams("21", 1, 0)); + Iterator<LdapEntry> i = response.getResult().getEntries().iterator(); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertEquals(testLdapEntries[1].getDn(), i.next().getDn()); + AssertJUnit.assertEquals(testLdapEntries[2].getDn(), i.next().getDn()); + + response = client.execute(request, new VirtualListViewParams("19", 0, 2), response); + i = response.getResult().getEntries().iterator(); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + AssertJUnit.assertEquals(testLdapEntries[0].getDn(), i.next().getDn()); + AssertJUnit.assertEquals(testLdapEntries[1].getDn(), i.next().getDn()); + AssertJUnit.assertEquals(testLdapEntries[2].getDn(), i.next().getDn()); + + } catch (UnsupportedOperationException e) { + // ignore this test if not supported + AssertJUnit.assertNotNull(e); + } finally { + conn.close(); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/doc/ClassGenerator.java b/integration/src/test/java/org/ldaptive/doc/ClassGenerator.java new file mode 100644 index 0000000..b9ec43e --- /dev/null +++ b/integration/src/test/java/org/ldaptive/doc/ClassGenerator.java
@@ -0,0 +1,335 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.doc; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import com.sun.codemodel.JClassAlreadyExistsException; +import com.sun.codemodel.JCodeModel; +import com.sun.codemodel.JDefinedClass; +import com.sun.codemodel.JDocComment; +import com.sun.codemodel.JMethod; +import com.sun.codemodel.JMod; + +/** + * Utility class for creating Java POJOs from documentation source. + * + * @author Middleware Services + */ +public class ClassGenerator +{ + + /** Package to create classes in. */ + private static final String PACKAGE_TO_CREATE = "org.ldaptive.doc"; + + /** Packages to import for compilation. */ + private static final String[] PACKAGES_TO_IMPORT = new String[] { + "java.io", + "java.security.cert", + "java.time", + "java.util", + "java.util.concurrent", + "org.ldaptive", + "org.ldaptive.ad", + "org.ldaptive.ad.control", + "org.ldaptive.ad.control.util", + "org.ldaptive.ad.extended", + "org.ldaptive.ad.handler", + "org.ldaptive.async", + "org.ldaptive.async.handler", + "org.ldaptive.auth", + "org.ldaptive.auth.ext", + "org.ldaptive.beans", + "org.ldaptive.beans.generate", + "org.ldaptive.beans.persistence", + "org.ldaptive.beans.reflect", + "org.ldaptive.cache", + "org.ldaptive.concurrent", + "org.ldaptive.control", + "org.ldaptive.control.util", + "org.ldaptive.extended", + "org.ldaptive.intermediate", + "org.ldaptive.handler", + "org.ldaptive.io", + "org.ldaptive.pool", + "org.ldaptive.props", + "org.ldaptive.provider", + "org.ldaptive.referral", + "org.ldaptive.sasl", + "org.ldaptive.schema", + "org.ldaptive.ssl", + "org.ldaptive.templates", + }; + + /** String containing all import statements. */ + private static final String IMPORT_STATEMENTS; + + /** Code model for java class creation. */ + private final JCodeModel codeModel = new JCodeModel(); + + /** Sections to build beans for. */ + private final Map<String, List<String>> sections = new HashMap<>(); + + /** Initialize {@link #IMPORT_STATEMENTS}. */ + static { + final StringBuilder sb = new StringBuilder(); + for (String p : PACKAGES_TO_IMPORT) { + sb.append("import ").append(p).append(".*;").append("\n"); + } + IMPORT_STATEMENTS = sb.toString(); + } + + + /** + * Creates a new class generator. + * + * @param url to download zipped source from + * @param path to write files to + * + * @throws IOException if the source cannot be downloaded, unzipped and read + */ + public ClassGenerator(final String url, final String path) + throws IOException + { + // download the zipped source + download(url, path + "/source.zip"); + + // unzip the source + unzip(path + "/source.zip", path + "/doc-sources"); + + // read the source files + final Path sourceDir = Paths.get(path + "/doc-sources"); + Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) + throws IOException + { + if (attrs.isRegularFile()) { + final String content = new String(Files.readAllBytes(file), StandardCharsets.UTF_8); + final String name = file.getName(file.getNameCount() - 2).toString(); + final List<String> l; + if (sections.containsKey(name)) { + l = sections.get(name); + } else { + l = new ArrayList<>(); + } + l.add(content); + sections.put(name, l); + } + return FileVisitResult.CONTINUE; + } + }); + } + + + /** + * Download a file. + * + * @param url to download + * @param destination to write the file at + * + * @throws IOException if an error occurs + */ + private static void download(final String url, final String destination) + throws IOException + { + final URL download = new URL(url); + final ReadableByteChannel rbc = Channels.newChannel(download.openStream()); + final FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.flush(); + rbc.close(); + } + + + /** + * Unzip a file. + * + * @param file to unzip + * @param destination to expand the file at + * + * @throws IOException if an error occurs + */ + private static void unzip(final String file, final String destination) + throws IOException + { + final File directory = new File(destination); + // if the output directory doesn't exist, create it + if (!directory.exists()) { + directory.mkdirs(); + } + // buffer for read and write data to file + final byte[] buffer = new byte[2048]; + final ZipInputStream zipInput = new ZipInputStream(new FileInputStream(file)); + ZipEntry entry = zipInput.getNextEntry(); + try { + while (entry != null) { + final String entryName = entry.getName(); + final File f = new File(destination + File.separator + entryName); + // create the directories of the zip directory + if (entry.isDirectory()) { + final File newDir = new File(f.getAbsolutePath()); + if (!newDir.exists()) { + newDir.mkdirs(); + } + } else { + try (FileOutputStream fOutput = new FileOutputStream(f)) { + int count; + while ((count = zipInput.read(buffer)) > 0) { + // write 'count' bytes to the file output stream + fOutput.write(buffer, 0, count); + } + } + } + // close ZipEntry and take the next one + zipInput.closeEntry(); + entry = zipInput.getNextEntry(); + } + } finally { + // close the last ZipEntry + zipInput.closeEntry(); + zipInput.close(); + } + } + + + /** + * Generates a class for each doc section. + */ + public void generate() + { + for (Map.Entry<String, List<String>> entry : sections.entrySet()) { + final JDefinedClass definedClass = createClass(PACKAGE_TO_CREATE, entry.getKey()); + final JDocComment jDocComment = definedClass.javadoc(); + jDocComment.add(String.format("Ldaptive generated bean for section '%s'", entry.getKey())); + + final List<String> names = entry.getValue(); + for (int i = 0; i < names.size(); i++) { + createMethod(definedClass, entry.getKey() + (i + 1), names.get(i)); + } + } + } + + + /** + * Creates a class in the supplied package. + * + * @param classPackage to place the class in + * @param className to create + * + * @return class + * + * @throws IllegalArgumentException if the class already exists + */ + protected JDefinedClass createClass(final String classPackage, final String className) + { + String fqClassName; + if (!Character.isUpperCase(className.charAt(0))) { + fqClassName = String.format( + "%s.%s", + classPackage, + className.substring(0, 1).toUpperCase() + className.substring(1, className.length())); + } else { + fqClassName = String.format("%s.%s", classPackage, className); + } + + try { + return codeModel._class(fqClassName); + } catch (JClassAlreadyExistsException e) { + throw new IllegalArgumentException("Class already exists: " + fqClassName, e); + } + } + + + /** + * Creates a method on the supplied class with the supplied name. + * + * @param clazz to put getter and setter methods on + * @param name of the property + * @param body content of the method + */ + protected void createMethod(final JDefinedClass clazz, final String name, final String body) + { + final JMethod method = clazz.method(JMod.PUBLIC, Void.TYPE, name); + method._throws(Exception.class); + method.body().directStatement(body); + } + + + /** + * Writes the generated classes to disk at the supplied path. + * + * @param path to write the classes to + * + * @throws IOException if the write fails + */ + public void write(final String path) + throws IOException + { + final File f = new File(path); + if (!f.exists()) { + f.mkdirs(); + } + codeModel.build(f); + + // add imports + final Path sourceDir = Paths.get(path); + Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) + throws IOException + { + if (attrs.isRegularFile()) { + String content = new String(Files.readAllBytes(file), StandardCharsets.UTF_8); + content = content.replaceFirst( + "package org.ldaptive.doc;", + "package org.ldaptive.doc;\n\n" + IMPORT_STATEMENTS); + Files.write(file, content.getBytes(StandardCharsets.UTF_8)); + } + return FileVisitResult.CONTINUE; + } + }); + + } + + + /** + * Provides command line access to a {@link ClassGenerator}. Expects two arguments: + * + * <ol> + * <li>url to source zip file</li> + * <li>target directory to write files to</li> + * </ol> + * + * @param args command line arguments + * + * @throws Exception if any error occurs + */ + public static void main(final String[] args) + throws Exception + { + final String url = args[0]; + final String targetPath = args[1]; + + final ClassGenerator generator = new ClassGenerator(url, targetPath); + generator.generate(); + generator.write(targetPath + "/generated-test-sources/ldaptive-docs"); + } +}
diff --git a/integration/src/test/java/org/ldaptive/doc/MyObject.java b/integration/src/test/java/org/ldaptive/doc/MyObject.java new file mode 100644 index 0000000..e675ab8 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/doc/MyObject.java
@@ -0,0 +1,32 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.doc; + +import org.ldaptive.beans.Attribute; +import org.ldaptive.beans.Entry; + +/** + * Sample object used in docs. + */ +@Entry( + dn = "dn", + attributes = { + @Attribute(name = "name"), + @Attribute(name = "email"), + @Attribute(name = "phoneNumber")}) +public class MyObject { + private String dn; + private String name; + private String email; + private String phoneNumber; + + public MyObject() {} + public MyObject(String s) { setDn(s); } + public String getDn() { return dn; } + public void setDn(String s) { dn = s; } + public String getName() { return name; } + public void setName(String s) { name = s; } + public String getEmail() { return email; } + public void setEmail(String s) { email = s; } + public String getPhoneNumber() { return phoneNumber; } + public void setPhoneNumber(String s) { phoneNumber = s; } +} \ No newline at end of file
diff --git a/integration/src/test/java/org/ldaptive/ext/MergeOperationTest.java b/integration/src/test/java/org/ldaptive/ext/MergeOperationTest.java new file mode 100644 index 0000000..5b3a1e7 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/ext/MergeOperationTest.java
@@ -0,0 +1,128 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ext; + +import org.ldaptive.AbstractTest; +import org.ldaptive.Connection; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link MergeOperation}. + * + * @author Middleware Services + */ +public class MergeOperationTest extends AbstractTest +{ + + /** Entry created for ldap tests. */ + private static LdapEntry testLdapEntry; + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry30") + @BeforeClass(groups = {"merge"}) + public void createLdapEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + AssertJUnit.assertFalse(super.entryExists(conn, testLdapEntry)); + + final MergeOperation merge = new MergeOperation(conn); + merge.execute(new MergeRequest(testLdapEntry)); + AssertJUnit.assertTrue(super.entryExists(conn, testLdapEntry)); + } + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"merge"}) + public void deleteLdapEntry() + throws Exception + { + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + AssertJUnit.assertTrue(super.entryExists(conn, testLdapEntry)); + + final MergeOperation merge = new MergeOperation(conn); + merge.execute(new MergeRequest(testLdapEntry, true)); + AssertJUnit.assertFalse(super.entryExists(conn, testLdapEntry)); + merge.execute(new MergeRequest(testLdapEntry, true)); + } + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"merge"}) + public void merge() + throws Exception + { + final LdapEntry source = new LdapEntry(testLdapEntry.getDn()); + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final MergeOperation merge = new MergeOperation(conn); + final MergeRequest request = new MergeRequest(source); + if (TestControl.isActiveDirectory()) { + // remove objectClass for comparison testing related to AD + testLdapEntry.removeAttribute("objectClass"); + source.addAttributes(testLdapEntry.getAttributes()); + // these attributes are single value in AD + source.addAttribute(new LdapAttribute("givenName", "John")); + source.addAttribute(new LdapAttribute("initials", "JC")); + request.setIncludeAttributes("uid"); + } else { + source.addAttributes(testLdapEntry.getAttributes()); + + final LdapAttribute gn = new LdapAttribute("givenName"); + gn.addStringValues(testLdapEntry.getAttribute("givenName").getStringValues()); + gn.addStringValue("John"); + source.addAttribute(gn); + + final LdapAttribute initials = new LdapAttribute("initials"); + initials.addStringValues(testLdapEntry.getAttribute("initials").getStringValues()); + initials.addStringValue("JC"); + source.addAttribute(initials); + request.setExcludeAttributes("givenName", "initials"); + } + // no-op, include/exclude should prevent a modify from occurring + merge.execute(request); + + final SearchOperation search = new SearchOperation(conn); + SearchResult result = search.execute( + SearchRequest.newObjectScopeSearchRequest( + testLdapEntry.getDn(), + testLdapEntry.getAttributeNames())).getResult(); + TestUtils.assertEquals(testLdapEntry, result.getEntry()); + + if (TestControl.isActiveDirectory()) { + request.setIncludeAttributes("givenName", "initials"); + } else { + request.setExcludeAttributes((String[]) null); + } + merge.execute(request); + + result = search.execute( + SearchRequest.newObjectScopeSearchRequest(source.getDn(), source.getAttributeNames())).getResult(); + TestUtils.assertEquals(source, result.getEntry()); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/extended/CancelOperationTest.java b/integration/src/test/java/org/ldaptive/extended/CancelOperationTest.java new file mode 100644 index 0000000..5350992 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/extended/CancelOperationTest.java
@@ -0,0 +1,92 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +import org.ldaptive.AbstractTest; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.ldaptive.async.AsyncSearchOperation; +import org.ldaptive.control.SyncRequestControl; +import org.ldaptive.handler.HandlerResult; +import org.ldaptive.handler.SearchEntryHandler; +import org.testng.AssertJUnit; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link CancelOperation}. + * + * @author Middleware Services + */ +public class CancelOperationTest extends AbstractTest +{ + + + /** + * @param dn to search on. + * + * @throws Exception On test failure. + */ + @Parameters("cancelDn") + @Test(groups = {"extended"}) + public void cancel(final String dn) + throws Exception + { + // AD server returns UNAVAILABLE_CRITICAL_EXTENSION + if (TestControl.isActiveDirectory()) { + return; + } + // provider doesn't support cancel + if (TestControl.isOpenDJProvider()) { + throw new UnsupportedOperationException("OpenDJ does not support cancel"); + } + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final AsyncSearchOperation search = new AsyncSearchOperation(conn); + // needed to perform operations inside a handler + search.setUseMultiThreadedListener(true); + search.setExceptionHandler( + (conn1, request, exception) -> { + throw new UnsupportedOperationException(exception); + }); + + final SearchRequest request = SearchRequest.newObjectScopeSearchRequest(dn); + request.setSearchEntryHandlers( + new SearchEntryHandler() { + @Override + public HandlerResult<SearchEntry> handle( + final Connection conn, + final SearchRequest request, + final SearchEntry entry) + throws LdapException + { + try { + final CancelOperation cancel = new CancelOperation(conn); + final Response<Void> response = cancel.execute(new CancelRequest(entry.getMessageId())); + AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode()); + return new HandlerResult<>(null); + } catch (LdapException e) { + return new HandlerResult<>(null, true); + } + } + + @Override + public void initializeRequest(final SearchRequest request) {} + }); + request.setControls(new SyncRequestControl(SyncRequestControl.Mode.REFRESH_AND_PERSIST, true)); + + final Response<SearchResult> response = search.execute(request); + AssertJUnit.assertEquals(ResultCode.CANCELED, response.getResultCode()); + } catch (IllegalStateException e) { + throw (Exception) e.getCause(); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/extended/PasswordModifyOperationTest.java b/integration/src/test/java/org/ldaptive/extended/PasswordModifyOperationTest.java new file mode 100644 index 0000000..a9dac82 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/extended/PasswordModifyOperationTest.java
@@ -0,0 +1,120 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +import org.ldaptive.AbstractTest; +import org.ldaptive.Connection; +import org.ldaptive.Credential; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.ldaptive.auth.AuthenticationRequest; +import org.ldaptive.auth.AuthenticationResponse; +import org.ldaptive.auth.Authenticator; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link PasswordModifyOperation}. + * + * @author Middleware Services + */ +public class PasswordModifyOperationTest extends AbstractTest +{ + + /** Invalid password test data. */ + public static final String INVALID_PASSWD = "not-a-password"; + + /** Entry created for ldap tests. */ + private static LdapEntry testLdapEntry; + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry16") + @BeforeClass(groups = {"extended"}) + public void createLdapEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"extended"}) + public void deleteLdapEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + } + + + /** + * @param dn to modify. + * @param oldPass to change. + * @param newPass to change to. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "passwordModifyDn", + "passwordModifyOldPass", + "passwordModifyNewPass" + }) + @Test(groups = {"extended"}) + public void modify(final String dn, final String oldPass, final String newPass) + throws Exception + { + if (TestControl.isActiveDirectory()) { + return; + } + + final Authenticator auth = TestUtils.createSSLDnAuthenticator(); + AuthenticationResponse response = auth.authenticate(new AuthenticationRequest(dn, new Credential(oldPass))); + AssertJUnit.assertTrue(response.getResult()); + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final PasswordModifyOperation modify = new PasswordModifyOperation(conn); + // invalid password + try { + final Response<Credential> res = modify.execute( + new PasswordModifyRequest(dn, new Credential(INVALID_PASSWD), new Credential(newPass))); + AssertJUnit.assertEquals(ResultCode.UNWILLING_TO_PERFORM, res.getResultCode()); + } catch (LdapException e) { + AssertJUnit.assertEquals(ResultCode.UNWILLING_TO_PERFORM, e.getResultCode()); + } + + // change password + Response<Credential> modifyResponse = modify.execute( + new PasswordModifyRequest(dn, new Credential(oldPass), new Credential(newPass))); + AssertJUnit.assertNotNull(modifyResponse); + AssertJUnit.assertNull(modifyResponse.getResult()); + response = auth.authenticate(new AuthenticationRequest(dn, new Credential(oldPass))); + AssertJUnit.assertFalse(response.getResult()); + response = auth.authenticate(new AuthenticationRequest(dn, new Credential(newPass))); + AssertJUnit.assertTrue(response.getResult()); + + // generate password + modifyResponse = modify.execute(new PasswordModifyRequest(dn)); + AssertJUnit.assertNotNull(modifyResponse); + AssertJUnit.assertNotNull(modifyResponse.getResult()); + response = auth.authenticate(new AuthenticationRequest(dn, new Credential(newPass))); + AssertJUnit.assertFalse(response.getResult()); + response = auth.authenticate(new AuthenticationRequest(dn, modifyResponse.getResult())); + AssertJUnit.assertTrue(response.getResult()); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/extended/WhoAmIOperationTest.java b/integration/src/test/java/org/ldaptive/extended/WhoAmIOperationTest.java new file mode 100644 index 0000000..627fb3a --- /dev/null +++ b/integration/src/test/java/org/ldaptive/extended/WhoAmIOperationTest.java
@@ -0,0 +1,47 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.extended; + +import org.ldaptive.AbstractTest; +import org.ldaptive.BindConnectionInitializer; +import org.ldaptive.Connection; +import org.ldaptive.Response; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.Test; + +/** + * Unit test for {@link WhoAmIOperation}. + * + * @author Middleware Services + */ +public class WhoAmIOperationTest extends AbstractTest +{ + + + /** @throws Exception On test failure. */ + @Test(groups = {"extended"}) + public void whoami() + throws Exception + { + // AD supports whoami, but returns a completely different value + if (TestControl.isActiveDirectory()) { + return; + } + + // provider doesn't support this operation + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP does not support this operation"); + } + + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final WhoAmIOperation whoami = new WhoAmIOperation(conn); + final Response<String> res = whoami.execute(new WhoAmIRequest()); + final BindConnectionInitializer ci = + (BindConnectionInitializer) conn.getConnectionConfig().getConnectionInitializer(); + AssertJUnit.assertEquals("dn:" + ci.getBindDn(), res.getResult()); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/handler/NoOpEntryHandler.java b/integration/src/test/java/org/ldaptive/handler/NoOpEntryHandler.java new file mode 100644 index 0000000..c2441a4 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/handler/NoOpEntryHandler.java
@@ -0,0 +1,23 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.handler; + +import org.ldaptive.LdapUtils; + +/** + * Entry handler that does nothing. + * + * @author Middleware Services + */ +public class NoOpEntryHandler extends AbstractSearchEntryHandler +{ + + /** hash code seed. */ + private static final int HASH_CODE_SEED = 887; + + + @Override + public int hashCode() + { + return LdapUtils.computeHashCode(HASH_CODE_SEED, (Object) null); + } +}
diff --git a/integration/src/test/java/org/ldaptive/io/DsmlTest.java b/integration/src/test/java/org/ldaptive/io/DsmlTest.java new file mode 100644 index 0000000..39feee8 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/io/DsmlTest.java
@@ -0,0 +1,128 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.io.StringReader; +import java.io.StringWriter; +import org.ldaptive.AbstractTest; +import org.ldaptive.Connection; +import org.ldaptive.LdapEntry; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.SortBehavior; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link Dsmlv1Reader} and {@link Dsmlv1Writer}. + * + * @author Middleware Services + */ +public class DsmlTest extends AbstractTest +{ + + /** Entry created for ldap tests. */ + private static LdapEntry testLdapEntry; + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry13") + @BeforeClass(groups = {"dsml"}) + public void createLdapEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"dsml"}) + public void deleteLdapEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + } + + + /** + * @param dn to search on. + * @param filter to search with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "dsmlSearchDn", + "dsmlSearchFilter" + }) + @Test(groups = {"dsml"}) + public void searchAndCompareDsmlv1(final String dn, final String filter) + throws Exception + { + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + + final SearchRequest request = new SearchRequest(dn, new SearchFilter(filter)); + if (TestControl.isActiveDirectory()) { + request.setBinaryAttributes("objectSid", "objectGUID", "jpegPhoto"); + } else { + request.setBinaryAttributes("jpegPhoto"); + } + + final SearchResult result1 = search.execute(request).getResult(); + + final StringWriter writer = new StringWriter(); + final Dsmlv1Writer dsmlWriter = new Dsmlv1Writer(writer); + dsmlWriter.write(result1); + + final StringReader reader = new StringReader(writer.toString()); + final Dsmlv1Reader dsmlReader = new Dsmlv1Reader(reader); + final SearchResult result2 = dsmlReader.read(); + + TestUtils.assertEquals(result2, result1); + } + } + + + /** + * @param dsmlFile to test with. + * @param dsmlSortedFile to test with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "dsmlv1Entry", + "dsmlv1SortedEntry" + }) + @Test(groups = {"dsml"}) + public void readAndCompareDsmlv1(final String dsmlFile, final String dsmlSortedFile) + throws Exception + { + final String dsmlStringSorted = TestUtils.readFileIntoString(dsmlSortedFile); + final Dsmlv1Reader dsmlReader = new Dsmlv1Reader( + new StringReader(TestUtils.readFileIntoString(dsmlFile)), + SortBehavior.SORTED); + final SearchResult result = dsmlReader.read(); + + final StringWriter writer = new StringWriter(); + final Dsmlv1Writer dsmlWriter = new Dsmlv1Writer(writer); + dsmlWriter.write(result); + + AssertJUnit.assertEquals(dsmlStringSorted, writer.toString()); + } +}
diff --git a/integration/src/test/java/org/ldaptive/io/LdifTest.java b/integration/src/test/java/org/ldaptive/io/LdifTest.java new file mode 100644 index 0000000..e1e45c8 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/io/LdifTest.java
@@ -0,0 +1,156 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.io.StringReader; +import java.io.StringWriter; +import org.ldaptive.AbstractTest; +import org.ldaptive.Connection; +import org.ldaptive.LdapEntry; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.SortBehavior; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link LdifReader} and {@link LdifWriter}. + * + * @author Middleware Services + */ +public class LdifTest extends AbstractTest +{ + + /** Entry created for ldap tests. */ + private static LdapEntry testLdapEntry; + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry14") + @BeforeClass(groups = {"ldif"}) + public void createLdapEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"ldif"}) + public void deleteLdapEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + } + + + /** + * @param dn to search on. + * @param filter to search with. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "ldifSearchDn", + "ldifSearchFilter" + }) + @Test(groups = {"ldif"}) + public void searchAndCompareLdif(final String dn, final String filter) + throws Exception + { + try (Connection conn = TestUtils.createConnection()) { + conn.open(); + + final SearchOperation search = new SearchOperation(conn); + + final SearchRequest request = new SearchRequest(dn, new SearchFilter(filter)); + if (TestControl.isActiveDirectory()) { + request.setBinaryAttributes("objectSid", "objectGUID", "jpegPhoto"); + } else { + request.setBinaryAttributes("jpegPhoto"); + } + + final SearchResult result1 = search.execute(request).getResult(); + + final StringWriter writer = new StringWriter(); + final LdifWriter ldifWriter = new LdifWriter(writer); + ldifWriter.write(result1); + + final StringReader reader = new StringReader(writer.toString()); + final LdifReader ldifReader = new LdifReader(reader); + final SearchResult result2 = ldifReader.read(); + + TestUtils.assertEquals(result2, result1); + } + } + + + /** + * @param ldifFile to create with + * @param ldifSortedFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "ldifEntry", + "ldifSortedEntry" + }) + @Test(groups = {"ldif"}) + public void readAndCompareSortedLdif(final String ldifFile, final String ldifSortedFile) + throws Exception + { + final String ldifStringSorted = TestUtils.readFileIntoString(ldifSortedFile); + final LdifReader ldifReader = new LdifReader( + new StringReader(TestUtils.readFileIntoString(ldifFile)), + SortBehavior.SORTED); + final SearchResult result = ldifReader.read(); + + final StringWriter writer = new StringWriter(); + final LdifWriter ldifWriter = new LdifWriter(writer); + ldifWriter.write(result); + + AssertJUnit.assertEquals(ldifStringSorted, writer.toString()); + } + + + /** + * @param ldifFileIn to create with + * @param ldifFileOut to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "multipleLdifResultsIn", + "multipleLdifResultsOut" + }) + @Test(groups = {"ldif"}) + public void readAndCompareMultipleLdif(final String ldifFileIn, final String ldifFileOut) + throws Exception + { + final String ldifStringIn = TestUtils.readFileIntoString(ldifFileIn); + LdifReader ldifReader = new LdifReader(new StringReader(ldifStringIn)); + final SearchResult result1 = ldifReader.read(); + + final String ldifStringOut = TestUtils.readFileIntoString(ldifFileOut); + ldifReader = new LdifReader(new StringReader(ldifStringOut)); + + final SearchResult result2 = ldifReader.read(); + + AssertJUnit.assertEquals(result1, result2); + } +}
diff --git a/integration/src/test/java/org/ldaptive/jaas/LdapLoginModuleTest.java b/integration/src/test/java/org/ldaptive/jaas/LdapLoginModuleTest.java new file mode 100644 index 0000000..cfc044b --- /dev/null +++ b/integration/src/test/java/org/ldaptive/jaas/LdapLoginModuleTest.java
@@ -0,0 +1,627 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.security.Principal; +import java.security.acl.Group; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; +import org.ldaptive.AbstractTest; +import org.ldaptive.AttributeModification; +import org.ldaptive.AttributeModificationType; +import org.ldaptive.Connection; +import org.ldaptive.DnParser; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.ModifyOperation; +import org.ldaptive.ModifyRequest; +import org.ldaptive.ResultCode; +import org.ldaptive.TestControl; +import org.ldaptive.TestUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link LdapLoginModule}. + * + * @author Middleware Services + */ +public class LdapLoginModuleTest extends AbstractTest +{ + + /** Invalid password test data. */ + public static final String INVALID_PASSWD = "not-a-password"; + + /** Entry created for auth tests. */ + private static LdapEntry testLdapEntry; + + /** Entries for group tests. */ + private static final Map<String, LdapEntry[]> GROUP_ENTRIES = new HashMap<>(); + + /** + * Initialize the map of group entries. + */ + static { + for (int i = 6; i <= 9; i++) { + GROUP_ENTRIES.put(String.valueOf(i), new LdapEntry[2]); + } + } + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry10") + @BeforeClass(groups = {"jaas", "jaasInit"}) + public void createAuthEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + + System.setProperty("java.security.auth.login.config", "target/test-classes/ldap_jaas.config"); + } + + + /** + * @param ldifFile6 to create. + * @param ldifFile7 to create. + * @param ldifFile8 to create. + * @param ldifFile9 to create. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "createGroup6", + "createGroup7", + "createGroup8", + "createGroup9" + }) + @BeforeClass(groups = {"jaas"}, dependsOnGroups = {"jaasInit"}) + public void createGroupEntry( + final String ldifFile6, + final String ldifFile7, + final String ldifFile8, + final String ldifFile9) + throws Exception + { + // CheckStyle:Indentation OFF + GROUP_ENTRIES.get("6")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile6)).getEntry(); + GROUP_ENTRIES.get("7")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile7)).getEntry(); + GROUP_ENTRIES.get("8")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile8)).getEntry(); + GROUP_ENTRIES.get("9")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile9)).getEntry(); + // CheckStyle:Indentation ON + + for (Map.Entry<String, LdapEntry[]> e : GROUP_ENTRIES.entrySet()) { + super.createLdapEntry(e.getValue()[0]); + } + + // setup group relationships + try (Connection conn = TestUtils.createSetupConnection()) { + conn.open(); + + final ModifyOperation modify = new ModifyOperation(conn); + try { + modify.execute( + new ModifyRequest( + GROUP_ENTRIES.get("6")[0].getDn(), + new AttributeModification( + AttributeModificationType.ADD, + new LdapAttribute( + "member", + "cn=John Tyler," + DnParser.substring(testLdapEntry.getDn(), 1), + "cn=Group 7," + DnParser.substring(testLdapEntry.getDn(), 1))))); + } catch (LdapException e) { + // ignore attribute already exists + if (ResultCode.ATTRIBUTE_OR_VALUE_EXISTS != e.getResultCode()) { + throw e; + } + } + try { + modify.execute( + new ModifyRequest( + GROUP_ENTRIES.get("7")[0].getDn(), + new AttributeModification( + AttributeModificationType.ADD, + new LdapAttribute( + "member", + "cn=Group 8," + DnParser.substring(testLdapEntry.getDn(), 1), + "cn=Group 9," + DnParser.substring(testLdapEntry.getDn(), 1))))); + } catch (LdapException e) { + // ignore attribute already exists + if (ResultCode.ATTRIBUTE_OR_VALUE_EXISTS != e.getResultCode()) { + throw e; + } + } + try { + modify.execute( + new ModifyRequest( + GROUP_ENTRIES.get("8")[0].getDn(), + new AttributeModification( + AttributeModificationType.ADD, + new LdapAttribute("member", "cn=Group 7," + DnParser.substring(testLdapEntry.getDn(), 1))))); + } catch (LdapException e) { + // ignore attribute already exists + if (ResultCode.ATTRIBUTE_OR_VALUE_EXISTS != e.getResultCode()) { + throw e; + } + } + } + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"jaas"}) + public void deleteAuthEntry() + throws Exception + { + System.clearProperty("java.security.auth.login.config"); + + super.deleteLdapEntry(testLdapEntry.getDn()); + super.deleteLdapEntry(GROUP_ENTRIES.get("6")[0].getDn()); + super.deleteLdapEntry(GROUP_ENTRIES.get("7")[0].getDn()); + super.deleteLdapEntry(GROUP_ENTRIES.get("8")[0].getDn()); + super.deleteLdapEntry(GROUP_ENTRIES.get("9")[0].getDn()); + + try { + PropertiesAuthenticatorFactory.close(); + } catch (UnsupportedOperationException e) { + // ignore if not supported + AssertJUnit.assertNotNull(e); + } + try { + PropertiesRoleResolverFactory.close(); + } catch (UnsupportedOperationException e) { + // ignore if not supported + AssertJUnit.assertNotNull(e); + } + try { + SpringAuthenticatorFactory.close(); + } catch (UnsupportedOperationException e) { + // ignore if not supported + AssertJUnit.assertNotNull(e); + } + } + + + /** + * @param dn of this user + * @param user to authenticate. + * @param role to set for this user + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters({ "jaasDn", "jaasUser", "jaasUserRole", "jaasCredential" }) + @Test( + groups = {"jaas"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void contextTest(final String dn, final String user, final String role, final String credential) + throws Exception + { + doContextTest("ldaptive", dn, user, role, credential, false); + } + + + /** + * @param dn of this user + * @param user to authenticate. + * @param role to set for this user + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters({ "jaasDn", "jaasUser", "jaasUserRole", "jaasCredential" }) + @Test( + groups = {"jaas"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void contextSslTest(final String dn, final String user, final String role, final String credential) + throws Exception + { + doContextTest("ldaptive-ssl", dn, user, role, credential, false); + } + + + /** + * @param dn of this user + * @param user to authenticate. + * @param role to set for this user + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters({ "jaasDn", "jaasUser", "jaasUserRole", "jaasCredential" }) + @Test( + groups = {"jaas"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void randomContextTest(final String dn, final String user, final String role, final String credential) + throws Exception + { + // provider times out on this test + if (TestControl.isApacheProvider()) { + throw new UnsupportedOperationException("Apache LDAP times out"); + } + doContextTest("ldaptive-random", dn, user, role, credential, true); + } + + + /** + * @param dn of this user + * @param user to authenticate. + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters({ "jaasDn", "jaasUser", "jaasCredential" }) + @Test( + groups = {"jaas"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void pooledDnResolverContextTest(final String dn, final String user, final String credential) + throws Exception + { + doContextTest("ldaptive-pooled-dnr", dn, user, "", credential, false); + } + + + /** + * @param dn of this user + * @param user to authenticate. + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters({ "jaasDn", "jaasUser", "jaasCredential" }) + @Test( + groups = {"jaas"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void springPooledDnResolverContextTest(final String dn, final String user, final String credential) + throws Exception + { + doContextTest("ldaptive-pooled-dnr-spring", dn, user, "", credential, false); + } + + + /** + * @param dn of this user + * @param user to authenticate. + * @param role to set for this user + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters({ "jaasDn", "jaasUser", "jaasRoleCombined", "jaasCredential" }) + @Test( + groups = {"jaas"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void rolesContextTest(final String dn, final String user, final String role, final String credential) + throws Exception + { + doContextTest("ldaptive-roles", dn, user, role, credential, false); + } + + + /** + * @param dn of this user + * @param user to authenticate. + * @param role to set for this user + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters({ "jaasDn", "jaasUser", "jaasRoleCombinedRecursive", "jaasCredential" }) + @Test(groups = {"jaas"}) + public void rolesRecursiveContextTest(final String dn, final String user, final String role, final String credential) + throws Exception + { + doContextTest("ldaptive-roles-recursive", dn, user, role, credential, false); + } + + + /** + * @param dn of this user + * @param user to authenticate. + * @param role to set for this user + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters({ "jaasDn", "jaasUser", "jaasUserRoleDefault", "jaasCredential" }) + @Test(groups = {"jaas"}) + public void useFirstContextTest(final String dn, final String user, final String role, final String credential) + throws Exception + { + doContextTest("ldaptive-use-first", dn, user, role, credential, false); + } + + + /** + * @param dn of this user + * @param user to authenticate. + * @param role to set for this user + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters({ "jaasDn", "jaasUser", "jaasRoleCombined", "jaasCredential" }) + @Test(groups = {"jaas"}) + public void tryFirstContextTest(final String dn, final String user, final String role, final String credential) + throws Exception + { + doContextTest("ldaptive-try-first", dn, user, role, credential, false); + } + + + /** + * @param dn of this user + * @param user to authenticate. + * @param role to set for this user + * @param credential to authenticate with. + * + * @throws Exception On test failure. + */ + @Parameters({ "jaasDn", "jaasUser", "jaasUserRole", "jaasCredential" }) + @Test(groups = {"jaas"}) + public void sufficientContextTest(final String dn, final String user, final String role, final String credential) + throws Exception + { + doContextTest("ldaptive-sufficient", dn, user, role, credential, false); + } + + + /** + * @param name of the jaas configuration + * @param dn of this user + * @param user to authenticate. + * @param role to set for this user + * @param credential to authenticate with. + * @param checkLdapDn whether to check the LdapDnPrincipal + * + * @throws Exception On test failure. + */ + private void doContextTest( + final String name, + final String dn, + final String user, + final String role, + final String credential, + final boolean checkLdapDn) + throws Exception + { + final TestCallbackHandler callback = new TestCallbackHandler(); + callback.setName(user); + callback.setPassword(INVALID_PASSWD); + + LoginContext lc = new LoginContext(name, callback); + try { + lc.login(); + AssertJUnit.fail("Invalid password, login should have failed"); + } catch (UnsupportedOperationException e) { + throw e; + } catch (Exception e) { + AssertJUnit.assertEquals(e.getClass(), LoginException.class); + } + + callback.setPassword(credential); + lc = new LoginContext(name, callback); + try { + lc.login(); + } catch (UnsupportedOperationException e) { + throw e; + } catch (Exception e) { + AssertJUnit.fail(e.getMessage()); + } + + final Set<LdapPrincipal> principals = lc.getSubject().getPrincipals(LdapPrincipal.class); + AssertJUnit.assertEquals(1, principals.size()); + + final LdapPrincipal p = principals.iterator().next(); + AssertJUnit.assertEquals(p.getName(), user); + if (!"".equals(role)) { + AssertJUnit.assertTrue(p.getLdapEntry().getAttributes().size() > 0); + } + + final Set<LdapDnPrincipal> dnPrincipals = lc.getSubject().getPrincipals(LdapDnPrincipal.class); + if (checkLdapDn) { + AssertJUnit.assertEquals(1, dnPrincipals.size()); + + final LdapDnPrincipal dnP = dnPrincipals.iterator().next(); + AssertJUnit.assertEquals(dnP.getName().toLowerCase(), dn.toLowerCase()); + if (!"".equals(role)) { + AssertJUnit.assertTrue(dnP.getLdapEntry().getAttributes().size() > 0); + } + } else { + AssertJUnit.assertEquals(0, dnPrincipals.size()); + } + + final Set<LdapRole> roles = lc.getSubject().getPrincipals(LdapRole.class); + + final Iterator<LdapRole> roleIter = roles.iterator(); + String[] checkRoles = role.split("\\|"); + if (checkRoles.length == 1 && "".equals(checkRoles[0])) { + checkRoles = new String[0]; + } + AssertJUnit.assertEquals(checkRoles.length, roles.size()); + while (roleIter.hasNext()) { + final LdapRole r = roleIter.next(); + boolean match = false; + for (String s : checkRoles) { + if (s.equals(r.getName())) { + match = true; + } + } + AssertJUnit.assertTrue(match); + } + + final Set<LdapCredential> credentials = lc.getSubject().getPrivateCredentials(LdapCredential.class); + AssertJUnit.assertEquals(1, credentials.size()); + + final LdapCredential c = credentials.iterator().next(); + AssertJUnit.assertEquals(new String((char[]) c.getCredential()), credential); + + try { + lc.logout(); + } catch (Exception e) { + AssertJUnit.fail(e.getMessage()); + } + + AssertJUnit.assertEquals(0, lc.getSubject().getPrincipals().size()); + AssertJUnit.assertEquals(0, lc.getSubject().getPrivateCredentials().size()); + } + + + /** + * @param dn of this user + * @param user to authenticate. + * @param role to set for this user + * + * @throws Exception On test failure. + */ + @Parameters({ "jaasDn", "jaasUser", "jaasRoleCombined" }) + @Test( + groups = {"jaas"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void rolesOnlyContextTest(final String dn, final String user, final String role) + throws Exception + { + doRolesContextTest("ldaptive-roles-only", dn, user, role); + } + + + /** + * @param dn of this user + * @param user to authenticate. + * @param role to set for this user + * + * @throws Exception On test failure. + */ + @Parameters({ "jaasDn", "jaasUser", "jaasRoleCombined" }) + @Test( + groups = {"jaas"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void dnRolesOnlyContextTest(final String dn, final String user, final String role) + throws Exception + { + doRolesContextTest("ldaptive-dn-roles-only", dn, user, role); + } + + + /** + * @param dn of this user + * @param user to authenticate. + * @param role to set for this user + * + * @throws Exception On test failure. + */ + @Parameters({ "jaasDn", "jaasUser", "jaasRoleCombined" }) + @Test( + groups = {"jaas"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT, + timeOut = TEST_TIME_OUT) + public void dnRolesOnlyPooledContextTest(final String dn, final String user, final String role) + throws Exception + { + doRolesContextTest("ldaptive-roles-only-pooled", dn, user, role); + } + + + /** + * @param name of the jaas configuration + * @param dn of this user + * @param user to authenticate. + * @param role to set for this user + * + * @throws Exception On test failure. + */ + private void doRolesContextTest(final String name, final String dn, final String user, final String role) + throws Exception + { + final TestCallbackHandler callback = new TestCallbackHandler(); + callback.setName(user); + + final LoginContext lc = new LoginContext(name, callback); + try { + lc.login(); + } catch (UnsupportedOperationException e) { + throw e; + } catch (Exception e) { + AssertJUnit.fail(e.getMessage()); + } + + final Set<LdapRole> roles = lc.getSubject().getPrincipals(LdapRole.class); + + final Iterator<LdapRole> roleIter = roles.iterator(); + final String[] checkRoles = role.split("\\|"); + AssertJUnit.assertEquals(checkRoles.length, roles.size()); + while (roleIter.hasNext()) { + final LdapRole r = roleIter.next(); + boolean match = false; + for (String s : checkRoles) { + if (s.equals(r.getName())) { + match = true; + } + } + AssertJUnit.assertTrue(match); + } + + final Set<Group> roleGroups = lc.getSubject().getPrincipals(Group.class); + AssertJUnit.assertTrue(roleGroups.size() == 2); + for (Group g : roleGroups) { + if ("Roles".equals(g.getName())) { + final Enumeration<? extends Principal> members = g.members(); + int count = 0; + while (members.hasMoreElements()) { + final Principal p = members.nextElement(); + boolean match = false; + for (LdapRole lr : lc.getSubject().getPrincipals(LdapRole.class)) { + if (lr.getName().equals(p.getName())) { + match = true; + } + } + AssertJUnit.assertTrue(match); + count++; + } + AssertJUnit.assertEquals(count, lc.getSubject().getPrincipals(LdapRole.class).size()); + } else if ("Principals".equals(g.getName())) { + final Enumeration<? extends Principal> members = g.members(); + int count = 0; + while (members.hasMoreElements()) { + final Principal p = members.nextElement(); + boolean match = false; + for (LdapPrincipal lp : lc.getSubject().getPrincipals(LdapPrincipal.class)) { + if (lp.getName().equals(p.getName())) { + match = true; + } + } + AssertJUnit.assertTrue(match); + count++; + } + AssertJUnit.assertEquals(count, lc.getSubject().getPrincipals(LdapPrincipal.class).size()); + } else { + AssertJUnit.fail("Found invalid group"); + } + } + + final Set<?> credentials = lc.getSubject().getPrivateCredentials(); + AssertJUnit.assertEquals(0, credentials.size()); + + try { + lc.logout(); + } catch (Exception e) { + AssertJUnit.fail(e.getMessage()); + } + + AssertJUnit.assertEquals(0, lc.getSubject().getPrincipals().size()); + AssertJUnit.assertEquals(0, lc.getSubject().getPrivateCredentials().size()); + } +}
diff --git a/integration/src/test/java/org/ldaptive/jaas/PropsLoginModule.java b/integration/src/test/java/org/ldaptive/jaas/PropsLoginModule.java new file mode 100644 index 0000000..4065aa3 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/jaas/PropsLoginModule.java
@@ -0,0 +1,87 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.util.Map; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.login.LoginException; +import org.ldaptive.SearchRequest; +import org.ldaptive.auth.AuthenticationRequest; +import org.ldaptive.auth.Authenticator; + +/** + * Login module for testing configuration properties. + * + * @author Middleware Services + */ +public class PropsLoginModule extends AbstractLoginModule +{ + + /** Authenticator to load properties for. */ + private Authenticator auth; + + /** Authentication request to load properties for. */ + private AuthenticationRequest authRequest; + + /** Role resolver to load properties for. */ + private RoleResolver roleResolver; + + /** Search request to load properties for. */ + private SearchRequest searchRequest; + + + @Override + public void initialize( + final Subject subject, + final CallbackHandler callbackHandler, + final Map<String, ?> sharedState, + final Map<String, ?> options) + { + super.initialize(subject, callbackHandler, sharedState, options); + + final AuthenticatorFactory authenticatorFactory = new PropertiesAuthenticatorFactory(); + auth = authenticatorFactory.createAuthenticator(options); + authRequest = authenticatorFactory.createAuthenticationRequest(options); + + final RoleResolverFactory roleResolverFactory = new PropertiesRoleResolverFactory(); + roleResolver = roleResolverFactory.createRoleResolver(options); + searchRequest = roleResolverFactory.createSearchRequest(options); + } + + + @Override + protected boolean login(final NameCallback nameCb, final PasswordCallback passCb) + throws LoginException + { + return true; + } + + + @Override + public boolean commit() + throws LoginException + { + subject.getPublicCredentials().add(auth); + subject.getPublicCredentials().add(authRequest); + subject.getPublicCredentials().add(roleResolver); + subject.getPublicCredentials().add(searchRequest); + return true; + } + + + @Override + public boolean abort() + { + loginSuccess = false; + return true; + } + + + @Override + public boolean logout() + { + return true; + } +}
diff --git a/integration/src/test/java/org/ldaptive/jaas/SpringAuthenticatorFactory.java b/integration/src/test/java/org/ldaptive/jaas/SpringAuthenticatorFactory.java new file mode 100644 index 0000000..55c7b74 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/jaas/SpringAuthenticatorFactory.java
@@ -0,0 +1,77 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.util.Map; +import org.ldaptive.auth.AuthenticationHandler; +import org.ldaptive.auth.AuthenticationRequest; +import org.ldaptive.auth.Authenticator; +import org.ldaptive.pool.PooledConnectionFactoryManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * Provides an authentication factory implementation that uses a spring context. + * + * @author Middleware Services + */ +public class SpringAuthenticatorFactory implements AuthenticatorFactory +{ + + /** Application context. */ + private static ClassPathXmlApplicationContext context; + + /** + * Initialize the context. + */ + static { + try { + context = new ClassPathXmlApplicationContext( + new String[] {"/spring-jaas-context.xml", }); + } catch (Exception e) { + final Logger logger = LoggerFactory.getLogger(SpringAuthenticatorFactory.class); + logger.warn("Could not create spring context", e.getMessage()); + } + } + + + @Override + public Authenticator createAuthenticator(final Map<String, ?> jaasOptions) + { + if (context == null) { + throw new UnsupportedOperationException("Could not initialize spring context"); + } + return context.getBean("authenticator", Authenticator.class); + } + + + @Override + public AuthenticationRequest createAuthenticationRequest(final Map<String, ?> jaasOptions) + { + if (context == null) { + throw new UnsupportedOperationException("Could not initialize spring context"); + } + return context.getBean("authenticationRequest", AuthenticationRequest.class); + } + + + /** Closes the authenticator dn resolver if it is a managed dn resolver. */ + public static void close() + { + if (context == null) { + throw new UnsupportedOperationException("Could not initialize spring context"); + } + + final Authenticator a = context.getBean("authenticator", Authenticator.class); + if (a.getDnResolver() instanceof PooledConnectionFactoryManager) { + final PooledConnectionFactoryManager cfm = (PooledConnectionFactoryManager) a.getDnResolver(); + cfm.getConnectionFactory().getConnectionPool().close(); + } + + final AuthenticationHandler ah = a.getAuthenticationHandler(); + if (ah instanceof PooledConnectionFactoryManager) { + final PooledConnectionFactoryManager cfm = (PooledConnectionFactoryManager) ah; + cfm.getConnectionFactory().getConnectionPool().close(); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/jaas/TestCallbackHandler.java b/integration/src/test/java/org/ldaptive/jaas/TestCallbackHandler.java new file mode 100644 index 0000000..76089bf --- /dev/null +++ b/integration/src/test/java/org/ldaptive/jaas/TestCallbackHandler.java
@@ -0,0 +1,63 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.io.IOException; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; + +/** + * Class that implements a callback handler to help with jaas testing. + * + * @author Middleware Services + */ +public class TestCallbackHandler implements CallbackHandler +{ + + /** test name. */ + private String name; + + /** test password. */ + private String password; + + + /** @param s to set name with */ + public void setName(final String s) + { + name = s; + } + + + /** @param s to set password with */ + public void setPassword(final String s) + { + password = s; + } + + + /** + * @param callbacks to handle + * + * @throws IOException if an input or output error occurs + * @throws UnsupportedCallbackException if a supplied callback cannot be handled + */ + public void handle(final Callback[] callbacks) + throws IOException, UnsupportedCallbackException + { + for (Callback callback : callbacks) { + if (callback instanceof NameCallback) { + final NameCallback nc = (NameCallback) callback; + nc.setName(name); + } else if (callback instanceof PasswordCallback) { + final PasswordCallback pc = (PasswordCallback) callback; + if (password != null) { + pc.setPassword(password.toCharArray()); + } + } else { + throw new UnsupportedCallbackException(callback, "Unsupported"); + } + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/jaas/TestLoginModule.java b/integration/src/test/java/org/ldaptive/jaas/TestLoginModule.java new file mode 100644 index 0000000..5173748 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/jaas/TestLoginModule.java
@@ -0,0 +1,91 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.jaas; + +import java.io.IOException; +import java.util.Map; +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; + +/** + * Login module for testing. + * + * @author Middleware Services + */ +public class TestLoginModule implements LoginModule +{ + + /** Initialized subject. */ + protected Subject subject; + + /** Initialized callback handler. */ + protected CallbackHandler callbackHandler; + + /** Shared state from other login module. */ + protected Map sharedState; + + /** Whether authentication was successful. */ + protected boolean success; + + + @Override + public void initialize( + final Subject s, + final CallbackHandler ch, + final Map<String, ?> ss, + final Map<String, ?> options) + { + subject = s; + callbackHandler = ch; + sharedState = ss; + } + + + @SuppressWarnings("unchecked") + @Override + public boolean login() + throws LoginException + { + try { + final NameCallback nameCb = new NameCallback("Enter user: "); + final PasswordCallback passCb = new PasswordCallback("Enter user password: ", false); + callbackHandler.handle(new Callback[] {nameCb, passCb}); + + sharedState.put(LdapLoginModule.LOGIN_NAME, nameCb.getName()); + sharedState.put(LdapLoginModule.LOGIN_PASSWORD, passCb.getPassword()); + success = true; + } catch (IOException | UnsupportedCallbackException e) { + success = false; + throw new LoginException(e.toString()); + } + return true; + } + + + @Override + public boolean commit() + throws LoginException + { + return true; + } + + + @Override + public boolean abort() + { + success = false; + return true; + } + + + @Override + public boolean logout() + { + return true; + } +}
diff --git a/integration/src/test/java/org/ldaptive/pool/CompareValidatorTest.java b/integration/src/test/java/org/ldaptive/pool/CompareValidatorTest.java new file mode 100644 index 0000000..c381c85 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/pool/CompareValidatorTest.java
@@ -0,0 +1,62 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import org.ldaptive.AbstractTest; +import org.ldaptive.CompareRequest; +import org.ldaptive.Connection; +import org.ldaptive.LdapAttribute; +import org.ldaptive.TestUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Test for {@link CompareValidator}. + * + * @author Middleware Services + */ +public class CompareValidatorTest extends AbstractTest +{ + + + /** @throws Exception On test failure. */ + @Test(groups = {"validator"}) + public void defaultSettings() + throws Exception + { + final Connection c = TestUtils.createConnection(); + final CompareValidator sv = new CompareValidator(); + try { + c.open(); + AssertJUnit.assertTrue(sv.validate(c)); + } finally { + c.close(); + } + AssertJUnit.assertFalse(sv.validate(c)); + } + + + /** + * @param compareDn to test with + * + * @throws Exception On test failure. + */ + @Test(groups = {"validator"}) + @Parameters("ldapBindDn") + public void customSettings(final String compareDn) + throws Exception + { + final Connection c = TestUtils.createConnection(); + final CompareValidator cv = new CompareValidator( + new CompareRequest(compareDn, new LdapAttribute("objectClass", "inetOrgPerson"))); + try { + c.open(); + AssertJUnit.assertTrue(cv.validate(c)); + cv.getCompareRequest().setDn("cn=does-not-exist"); + AssertJUnit.assertFalse(cv.validate(c)); + } finally { + c.close(); + } + AssertJUnit.assertFalse(cv.validate(c)); + } +}
diff --git a/integration/src/test/java/org/ldaptive/pool/ConnectionPoolTest.java b/integration/src/test/java/org/ldaptive/pool/ConnectionPoolTest.java new file mode 100644 index 0000000..808a7b2 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/pool/ConnectionPoolTest.java
@@ -0,0 +1,663 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import java.io.StringWriter; +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; +import org.ldaptive.AbstractTest; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.LdapEntry; +import org.ldaptive.RoundRobinConnectionStrategy; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.TestUtils; +import org.ldaptive.io.LdifWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Load test for connection pools. + * + * @author Middleware Services + */ +public class ConnectionPoolTest extends AbstractTest +{ + + /** Entries for pool tests. */ + private static final Map<String, LdapEntry[]> ENTRIES = new HashMap<>(); + + /** + * Initialize the map of entries. + */ + static { + for (int i = 2; i <= 10; i++) { + ENTRIES.put(String.valueOf(i), new LdapEntry[2]); + } + } + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Base DN for searching. */ + private String searchBaseDn; + + /** LdapPool instance for concurrency testing. */ + private SoftLimitConnectionPool softLimitPool; + + /** LdapPool instance for concurrency testing. */ + private BlockingConnectionPool blockingPool; + + /** LdapPool instance for concurrency testing. */ + private BlockingConnectionPool blockingTimeoutPool; + + /** LdapPool instance for concurrency testing. */ + private BlockingConnectionPool connStrategyPool; + + /** Time in millis it takes the pool test to run. */ + private long softLimitRuntime; + + /** Time in millis it takes the pool test to run. */ + private long blockingRuntime; + + /** Time in millis it takes the pool test to run. */ + private long blockingTimeoutRuntime; + + + /** + * @param host to connect to. + * @param dn base DN for searching. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "ldapTestHost", + "ldapBaseDn" + }) + @BeforeClass( + groups = { + "softlimitpool", + "blockingpool", + "blockingtimeoutpool", + "connstrategypool"}) + public void createPools(final String host, final String dn) + throws Exception + { + searchBaseDn = dn; + + final ConnectionConfig cc = TestUtils.readConnectionConfig(null); + + final PoolConfig softLimitPc = new PoolConfig(); + softLimitPc.setValidateOnCheckIn(true); + softLimitPc.setValidateOnCheckOut(true); + softLimitPc.setValidatePeriodically(true); + softLimitPc.setValidatePeriod(Duration.ofSeconds(5)); + softLimitPool = new SoftLimitConnectionPool(softLimitPc, new DefaultConnectionFactory(cc)); + softLimitPool.setPruneStrategy(new IdlePruneStrategy(Duration.ofSeconds(5), Duration.ofSeconds(1))); + softLimitPool.setValidator(new SearchValidator()); + + final PoolConfig blockingPc = new PoolConfig(); + blockingPc.setValidateOnCheckIn(true); + blockingPc.setValidateOnCheckOut(true); + blockingPc.setValidatePeriodically(true); + blockingPc.setValidatePeriod(Duration.ofSeconds(5)); + blockingPool = new BlockingConnectionPool(blockingPc, new DefaultConnectionFactory(cc)); + blockingPool.setPruneStrategy(new IdlePruneStrategy(Duration.ofSeconds(5), Duration.ofSeconds(1))); + blockingPool.setValidator(new SearchValidator()); + + final PoolConfig blockingTimeoutPc = new PoolConfig(); + blockingTimeoutPc.setValidateOnCheckIn(true); + blockingTimeoutPc.setValidateOnCheckOut(true); + blockingTimeoutPc.setValidatePeriodically(true); + blockingTimeoutPc.setValidatePeriod(Duration.ofSeconds(5)); + blockingTimeoutPool = new BlockingConnectionPool(blockingTimeoutPc, new DefaultConnectionFactory(cc)); + blockingTimeoutPool.setPruneStrategy(new IdlePruneStrategy(Duration.ofSeconds(5), Duration.ofSeconds(1))); + blockingTimeoutPool.setBlockWaitTime(Duration.ofSeconds(1)); + blockingTimeoutPool.setValidator(new SearchValidator()); + + final ConnectionConfig connStrategyCc = TestUtils.readConnectionConfig(null); + connStrategyCc.setLdapUrl(String.format("%s ldap://dne.middleware.vt.edu", host)); + connStrategyCc.setConnectionStrategy(new RoundRobinConnectionStrategy()); + final DefaultConnectionFactory connStrategyCf = new DefaultConnectionFactory(connStrategyCc); + + connStrategyPool = new BlockingConnectionPool(new PoolConfig(), connStrategyCf); + } + + + /** + * @param ldifFile2 to create. + * @param ldifFile3 to create. + * @param ldifFile4 to create. + * @param ldifFile5 to create. + * @param ldifFile6 to create. + * @param ldifFile7 to create. + * @param ldifFile8 to create. + * @param ldifFile9 to create. + * @param ldifFile10 to create. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "createEntry2", + "createEntry3", + "createEntry4", + "createEntry5", + "createEntry6", + "createEntry7", + "createEntry8", + "createEntry9", + "createEntry10" + }) + @BeforeClass( + groups = { + "softlimitpool", + "blockingpool", + "blockingtimeoutpool", + "connstrategypool" + }, + dependsOnMethods = {"createPools"}) + // CheckStyle:ParameterNumber OFF + public void createPoolEntry( + final String ldifFile2, + final String ldifFile3, + final String ldifFile4, + final String ldifFile5, + final String ldifFile6, + final String ldifFile7, + final String ldifFile8, + final String ldifFile9, + final String ldifFile10) + throws Exception + { + // CheckStyle:Indentation OFF + ENTRIES.get("2")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile2)).getEntry(); + ENTRIES.get("3")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile3)).getEntry(); + ENTRIES.get("4")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile4)).getEntry(); + ENTRIES.get("5")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile5)).getEntry(); + ENTRIES.get("6")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile6)).getEntry(); + ENTRIES.get("7")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile7)).getEntry(); + ENTRIES.get("8")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile8)).getEntry(); + ENTRIES.get("9")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile9)).getEntry(); + ENTRIES.get("10")[0] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile10)).getEntry(); + // CheckStyle:Indentation ON + + for (Map.Entry<String, LdapEntry[]> e : ENTRIES.entrySet()) { + super.createLdapEntry(e.getValue()[0]); + } + + softLimitPool.initialize(); + blockingPool.initialize(); + blockingTimeoutPool.initialize(); + connStrategyPool.initialize(); + } + // CheckStyle:ParameterNumber ON + + + /** + * @param ldifFile2 to load. + * @param ldifFile3 to load. + * @param ldifFile4 to load. + * @param ldifFile5 to load. + * @param ldifFile6 to load. + * @param ldifFile7 to load. + * @param ldifFile8 to load. + * @param ldifFile9 to load. + * @param ldifFile10 to load. + * + * @throws Exception On test failure. + */ + @Parameters( + { + "searchResults2", + "searchResults3", + "searchResults4", + "searchResults5", + "searchResults6", + "searchResults7", + "searchResults8", + "searchResults9", + "searchResults10" + }) + @BeforeClass( + groups = { + "softlimitpool", + "blockingpool", + "blockingtimeoutpool", + "connstrategypool"}) + // CheckStyle:ParameterNumber OFF + public void loadPoolSearchResults( + final String ldifFile2, + final String ldifFile3, + final String ldifFile4, + final String ldifFile5, + final String ldifFile6, + final String ldifFile7, + final String ldifFile8, + final String ldifFile9, + final String ldifFile10) + throws Exception + { + // CheckStyle:Indentation OFF + ENTRIES.get("2")[1] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile2)).getEntry(); + ENTRIES.get("3")[1] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile3)).getEntry(); + ENTRIES.get("4")[1] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile4)).getEntry(); + ENTRIES.get("5")[1] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile5)).getEntry(); + ENTRIES.get("6")[1] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile6)).getEntry(); + ENTRIES.get("7")[1] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile7)).getEntry(); + ENTRIES.get("8")[1] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile8)).getEntry(); + ENTRIES.get("9")[1] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile9)).getEntry(); + ENTRIES.get("10")[1] = TestUtils.convertLdifToResult(TestUtils.readFileIntoString(ldifFile10)).getEntry(); + // CheckStyle:Indentation ON + } + // CheckStyle:ParameterNumber ON + + + /** @throws Exception On test failure. */ + @AfterClass( + groups = { + "softlimitpool", + "blockingpool", + "blockingtimeoutpool", + "connstrategypool"}) + public void deletePoolEntry() + throws Exception + { + super.deleteLdapEntry(ENTRIES.get("2")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("3")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("4")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("5")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("6")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("7")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("8")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("9")[0].getDn()); + super.deleteLdapEntry(ENTRIES.get("10")[0].getDn()); + + softLimitPool.close(); + AssertJUnit.assertEquals(softLimitPool.availableCount(), 0); + AssertJUnit.assertEquals(softLimitPool.activeCount(), 0); + blockingPool.close(); + AssertJUnit.assertEquals(blockingPool.availableCount(), 0); + AssertJUnit.assertEquals(blockingPool.activeCount(), 0); + blockingTimeoutPool.close(); + AssertJUnit.assertEquals(blockingTimeoutPool.availableCount(), 0); + AssertJUnit.assertEquals(blockingTimeoutPool.activeCount(), 0); + connStrategyPool.close(); + AssertJUnit.assertEquals(connStrategyPool.availableCount(), 0); + AssertJUnit.assertEquals(connStrategyPool.activeCount(), 0); + } + + + /** + * Sample user data. + * + * @return user data + */ + @DataProvider(name = "pool-data") + public Object[][] createPoolData() + { + return + new Object[][] { + { + new SearchRequest( + searchBaseDn, + new SearchFilter("(mail=jadams@ldaptive.org)"), + "departmentNumber", + "givenName", + "sn"), + ENTRIES.get("2")[1], + }, + { + new SearchRequest( + searchBaseDn, + new SearchFilter("(mail=tjefferson@ldaptive.org)"), + "departmentNumber", + "givenName", + "sn"), + ENTRIES.get("3")[1], + }, + { + new SearchRequest( + searchBaseDn, + new SearchFilter("(mail=jmadison@ldaptive.org)"), + "departmentNumber", + "givenName", + "sn"), + ENTRIES.get("4")[1], + }, + { + new SearchRequest( + searchBaseDn, + new SearchFilter("(mail=jmonroe@ldaptive.org)"), + "departmentNumber", + "givenName", + "sn"), + ENTRIES.get("5")[1], + }, + { + new SearchRequest( + searchBaseDn, + new SearchFilter("(mail=jqadams@ldaptive.org)"), + "departmentNumber", + "givenName", + "sn"), + ENTRIES.get("6")[1], + }, + { + new SearchRequest( + searchBaseDn, + new SearchFilter("(mail=ajackson@ldaptive.org)"), + "departmentNumber", + "givenName", + "sn"), + ENTRIES.get("7")[1], + }, + { + new SearchRequest( + searchBaseDn, + new SearchFilter("(mail=mvburen@ldaptive.org)"), + "departmentNumber", + "givenName", + "sn", + "jpegPhoto"), + ENTRIES.get("8")[1], + }, + { + new SearchRequest( + searchBaseDn, + new SearchFilter("(mail=whharrison@ldaptive.org)"), + "departmentNumber", + "givenName", + "sn"), + ENTRIES.get("9")[1], + }, + { + new SearchRequest( + searchBaseDn, + new SearchFilter("(mail=jtyler@ldaptive.org)"), + "departmentNumber", + "givenName", + "sn"), + ENTRIES.get("10")[1], + }, + }; + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"softlimitpool"}) + public void checkSoftLimitPoolImmutable() + throws Exception + { + try { + softLimitPool.getPoolConfig().setMinPoolSize(8); + AssertJUnit.fail("Expected illegalstateexception to be thrown"); + } catch (IllegalStateException e) { + AssertJUnit.assertEquals(IllegalStateException.class, e.getClass()); + } + + try { + softLimitPool.getConnectionFactory().getConnectionConfig().setConnectTimeout(Duration.ofSeconds(10)); + AssertJUnit.fail("Expected illegalstateexception to be thrown"); + } catch (IllegalStateException e) { + AssertJUnit.assertEquals(IllegalStateException.class, e.getClass()); + } + } + + + /** + * @param request to search with + * @param results to expect from the search. + * + * @throws Exception On test failure. + */ + @Test( + groups = {"softlimitpool"}, dataProvider = "pool-data", threadPoolSize = 3, invocationCount = 50, timeOut = 60000) + public void softLimitSmallSearch(final SearchRequest request, final LdapEntry results) + throws Exception + { + softLimitRuntime += search(softLimitPool, request, results); + } + + + /** + * @param request to search with + * @param results to expect from the search. + * + * @throws Exception On test failure. + */ + @Test( + groups = {"softlimitpool"}, dataProvider = "pool-data", threadPoolSize = 10, invocationCount = 100, timeOut = 60000, + dependsOnMethods = {"softLimitSmallSearch"}) + public void softLimitMediumSearch(final SearchRequest request, final LdapEntry results) + throws Exception + { + softLimitRuntime += search(softLimitPool, request, results); + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"softlimitpool"}, dependsOnMethods = {"softLimitMediumSearch"}) + public void softLimitMaxClean() + throws Exception + { + Thread.sleep(10000); + AssertJUnit.assertEquals(0, softLimitPool.activeCount()); + AssertJUnit.assertEquals(PoolConfig.DEFAULT_MIN_POOL_SIZE, softLimitPool.availableCount()); + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"blockingpool"}) + public void checkBlockingPoolImmutable() + throws Exception + { + try { + blockingPool.getPoolConfig().setMinPoolSize(8); + AssertJUnit.fail("Expected illegalstateexception to be thrown"); + } catch (IllegalStateException e) { + AssertJUnit.assertEquals(IllegalStateException.class, e.getClass()); + } + + try { + blockingPool.getConnectionFactory().getConnectionConfig().setConnectTimeout(Duration.ofSeconds(10)); + AssertJUnit.fail("Expected illegalstateexception to be thrown"); + } catch (IllegalStateException e) { + AssertJUnit.assertEquals(IllegalStateException.class, e.getClass()); + } + } + + + /** + * @param request to search with + * @param results to expect from the search. + * + * @throws Exception On test failure. + */ + @Test( + groups = {"blockingpool"}, dataProvider = "pool-data", threadPoolSize = 3, invocationCount = 50, timeOut = 60000) + public void blockingSmallSearch(final SearchRequest request, final LdapEntry results) + throws Exception + { + blockingRuntime += search(blockingPool, request, results); + } + + + /** + * @param request to search with + * @param results to expect from the search. + * + * @throws Exception On test failure. + */ + @Test( + groups = {"blockingpool"}, dataProvider = "pool-data", threadPoolSize = 10, invocationCount = 100, timeOut = 60000, + dependsOnMethods = {"blockingSmallSearch"}) + public void blockingMediumSearch(final SearchRequest request, final LdapEntry results) + throws Exception + { + blockingRuntime += search(blockingPool, request, results); + } + + + /** + * @param request to search with + * @param results to expect from the search. + * + * @throws Exception On test failure. + */ + @Test( + groups = {"blockingpool"}, dataProvider = "pool-data", threadPoolSize = 50, invocationCount = 1000, timeOut = 60000, + dependsOnMethods = {"blockingMediumSearch"}) + public void blockingLargeSearch(final SearchRequest request, final LdapEntry results) + throws Exception + { + blockingRuntime += search(blockingPool, request, results); + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"blockingpool"}, dependsOnMethods = {"blockingLargeSearch"}) + public void blockingMaxClean() + throws Exception + { + Thread.sleep(10000); + AssertJUnit.assertEquals(0, blockingPool.activeCount()); + AssertJUnit.assertEquals(PoolConfig.DEFAULT_MIN_POOL_SIZE, blockingPool.availableCount()); + } + + + /** + * @param request to search with + * @param results to expect from the search. + * + * @throws Exception On test failure. + */ + @Test( + groups = {"blockingtimeoutpool"}, dataProvider = "pool-data", threadPoolSize = 3, invocationCount = 50, + timeOut = 60000) + public void blockingTimeoutSmallSearch(final SearchRequest request, final LdapEntry results) + throws Exception + { + try { + blockingTimeoutRuntime += search(blockingTimeoutPool, request, results); + } catch (BlockingTimeoutException e) { + logger.warn("block timeout exceeded for small search", e); + } + } + + + /** + * @param request to search with + * @param results to expect from the search. + * + * @throws Exception On test failure. + */ + @Test( + groups = {"blockingtimeoutpool"}, dataProvider = "pool-data", threadPoolSize = 10, invocationCount = 100, + timeOut = 60000, dependsOnMethods = {"blockingTimeoutSmallSearch"}) + public void blockingTimeoutMediumSearch(final SearchRequest request, final LdapEntry results) + throws Exception + { + try { + blockingTimeoutRuntime += search(blockingTimeoutPool, request, results); + } catch (BlockingTimeoutException e) { + logger.warn("block timeout exceeded for medium search", e); + } + } + + + /** + * @param request to search with + * @param results to expect from the search. + * + * @throws Exception On test failure. + */ + @Test( + groups = {"blockingtimeoutpool"}, dataProvider = "pool-data", threadPoolSize = 50, invocationCount = 1000, + timeOut = 60000, dependsOnMethods = {"blockingTimeoutMediumSearch"}) + public void blockingTimeoutLargeSearch(final SearchRequest request, final LdapEntry results) + throws Exception + { + try { + blockingTimeoutRuntime += search(blockingTimeoutPool, request, results); + } catch (BlockingTimeoutException e) { + logger.warn("block timeout exceeded for large search", e); + } + } + + + /** @throws Exception On test failure. */ + @Test(groups = {"blockingtimeoutpool"}, dependsOnMethods = {"blockingTimeoutLargeSearch"}) + public void blockingTimeoutMaxClean() + throws Exception + { + Thread.sleep(10000); + AssertJUnit.assertEquals(0, blockingTimeoutPool.activeCount()); + AssertJUnit.assertEquals(PoolConfig.DEFAULT_MIN_POOL_SIZE, blockingTimeoutPool.availableCount()); + } + + + /** + * @param request to search with + * @param results to expect from the search. + * + * @throws Exception On test failure. + */ + @Test( + groups = {"connstrategypool"}, dataProvider = "pool-data", threadPoolSize = 10, invocationCount = 100, + timeOut = 60000) + public void connStrategySearch(final SearchRequest request, final LdapEntry results) + throws Exception + { + search(connStrategyPool, request, results); + } + + + /** + * @param pool to get ldap object from. + * @param request to search with + * @param results to expect from the search. + * + * @return time it takes to checkout/search/checkin from the pool + * + * @throws Exception On test failure. + */ + private long search(final ConnectionPool pool, final SearchRequest request, final LdapEntry results) + throws Exception + { + final long startTime = System.currentTimeMillis(); + Connection conn = null; + SearchResult result = null; + try { + logger.trace("waiting for pool checkout"); + conn = pool.getConnection(); + logger.trace("performing search: {}", request); + + final SearchOperation search = new SearchOperation(conn); + result = search.execute(request).getResult(); + logger.trace("search completed: {}", result); + } finally { + logger.trace("returning connection to pool"); + if (conn != null) { + conn.close(); + } + } + + final StringWriter sw = new StringWriter(); + final LdifWriter lw = new LdifWriter(sw); + lw.write(result); + AssertJUnit.assertEquals(results, TestUtils.convertLdifToResult(sw.toString()).getEntry()); + return System.currentTimeMillis() - startTime; + } +}
diff --git a/integration/src/test/java/org/ldaptive/pool/SearchValidatorTest.java b/integration/src/test/java/org/ldaptive/pool/SearchValidatorTest.java new file mode 100644 index 0000000..d5cf79b --- /dev/null +++ b/integration/src/test/java/org/ldaptive/pool/SearchValidatorTest.java
@@ -0,0 +1,61 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.pool; + +import org.ldaptive.AbstractTest; +import org.ldaptive.Connection; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchRequest; +import org.ldaptive.TestUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Test for {@link SearchValidator}. + * + * @author Middleware Services + */ +public class SearchValidatorTest extends AbstractTest +{ + + + /** @throws Exception On test failure. */ + @Test(groups = {"validator"}) + public void defaultSettings() + throws Exception + { + final Connection c = TestUtils.createConnection(); + final SearchValidator sv = new SearchValidator(); + try { + c.open(); + AssertJUnit.assertTrue(sv.validate(c)); + } finally { + c.close(); + } + AssertJUnit.assertFalse(sv.validate(c)); + } + + + /** + * @param searchDn to test with + * + * @throws Exception On test failure. + */ + @Test(groups = {"validator"}) + @Parameters("ldapBaseDn") + public void customSettings(final String searchDn) + throws Exception + { + final Connection c = TestUtils.createConnection(); + final SearchValidator sv = new SearchValidator(new SearchRequest(searchDn, new SearchFilter("(cn=*)"))); + try { + c.open(); + AssertJUnit.assertTrue(sv.validate(c)); + sv.getSearchRequest().setSearchFilter(new SearchFilter("(dne=*)")); + AssertJUnit.assertFalse(sv.validate(c)); + } finally { + c.close(); + } + AssertJUnit.assertFalse(sv.validate(c)); + } +}
diff --git a/integration/src/test/java/org/ldaptive/provider/TestControlProcessor.java b/integration/src/test/java/org/ldaptive/provider/TestControlProcessor.java new file mode 100644 index 0000000..b3f9c27 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/provider/TestControlProcessor.java
@@ -0,0 +1,20 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider; + +import javax.naming.ldap.Control; +import org.ldaptive.provider.jndi.JndiControlHandler; + +/** + * Control processor for testing. + * + * @author Middleware Services + */ +public class TestControlProcessor extends ControlProcessor<Control> +{ + + /** Default constructor. */ + public TestControlProcessor() + { + super(new JndiControlHandler()); + } +}
diff --git a/integration/src/test/java/org/ldaptive/servlets/AttributeValueServletSearchExecutorTest.java b/integration/src/test/java/org/ldaptive/servlets/AttributeValueServletSearchExecutorTest.java new file mode 100644 index 0000000..e3b65f1 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/servlets/AttributeValueServletSearchExecutorTest.java
@@ -0,0 +1,111 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.servlets; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.InputStream; +import com.meterware.httpunit.PostMethodWebRequest; +import com.meterware.httpunit.WebRequest; +import com.meterware.httpunit.WebResponse; +import com.meterware.servletunit.ServletRunner; +import com.meterware.servletunit.ServletUnitClient; +import org.ldaptive.AbstractTest; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapUtils; +import org.ldaptive.TestUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link AttributeValueServletSearchExecutor}. + * + * @author Middleware Services + */ +public class AttributeValueServletSearchExecutorTest extends AbstractTest +{ + + /** Entry created for tests. */ + private static LdapEntry testLdapEntry; + + /** To test servlets with. */ + private ServletRunner servletRunner; + + + /** + * @param ldifFile to create. + * @param webXml web.xml for queries + * + * @throws Exception On test failure. + */ + @Parameters({ "createEntry12", "webXml" }) + @BeforeClass(groups = {"servlet"}) + public void createLdapEntry(final String ldifFile, final String webXml) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + + servletRunner = new ServletRunner(new File(webXml)); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"servlet"}) + public void deleteLdapEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + servletRunner.shutDown(); + } + + + /** + * @param query to search for. + * @param attr attribute to return from search + * @param attributeValue to compare + * + * @throws Exception On test failure. + */ + @Parameters( + { + "attributeServletQuery", + "attributeServletAttr", + "attributeServletValue" + }) + @Test(groups = {"servlet"}) + public void attributeServlet(final String query, final String attr, final String attributeValue) + throws Exception + { + final ServletUnitClient sc = servletRunner.newClient(); + final WebRequest request = new PostMethodWebRequest("http://servlets.ldaptive.org/AttributeSearch"); + request.setParameter("query", query); + request.setParameter("attrs", attr); + + final WebResponse response = sc.getResponse(request); + + AssertJUnit.assertNotNull(response); + AssertJUnit.assertEquals("application/octet-stream", response.getContentType()); + AssertJUnit.assertEquals( + "attachment; filename=\"" + attr + ".bin\"", + response.getHeaderField("Content-Disposition")); + + final InputStream input = response.getInputStream(); + final ByteArrayOutputStream data = new ByteArrayOutputStream(); + if (input != null) { + try { + final byte[] buffer = new byte[128]; + int length; + while ((length = input.read(buffer)) != -1) { + data.write(buffer, 0, length); + } + } finally { + data.close(); + } + } + AssertJUnit.assertEquals(attributeValue, LdapUtils.base64Encode(data.toByteArray())); + } +}
diff --git a/integration/src/test/java/org/ldaptive/servlets/ServletSearchExecutorTest.java b/integration/src/test/java/org/ldaptive/servlets/ServletSearchExecutorTest.java new file mode 100644 index 0000000..ecb52eb --- /dev/null +++ b/integration/src/test/java/org/ldaptive/servlets/ServletSearchExecutorTest.java
@@ -0,0 +1,346 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.servlets; + +import java.io.File; +import java.io.StringWriter; +import com.meterware.httpunit.PostMethodWebRequest; +import com.meterware.httpunit.WebRequest; +import com.meterware.httpunit.WebResponse; +import com.meterware.servletunit.ServletRunner; +import com.meterware.servletunit.ServletUnitClient; +import org.ldaptive.AbstractTest; +import org.ldaptive.LdapEntry; +import org.ldaptive.SearchResult; +import org.ldaptive.TestUtils; +import org.ldaptive.io.Dsmlv1Writer; +import org.ldaptive.io.JsonWriter; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SearchServlet}. + * + * @author Middleware Services + */ +public class ServletSearchExecutorTest extends AbstractTest +{ + + /** Entry created for tests. */ + private static LdapEntry testLdapEntry; + + /** To test servlets with. */ + private ServletRunner servletRunner; + + + /** + * @param ldifFile to create. + * @param webXml web.xml for queries + * + * @throws Exception On test failure. + */ + @Parameters({ "createEntry11", "webXml" }) + @BeforeClass(groups = {"servlet"}) + public void createLdapEntry(final String ldifFile, final String webXml) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + + servletRunner = new ServletRunner(new File(webXml)); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"servlet"}) + public void deleteLdapEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + servletRunner.shutDown(); + } + + + /** + * @param query to search for. + * @param attrs attributes to return from search + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "ldifSearchServletQuery", + "ldifSearchServletAttrs", + "ldifSearchServletLdif" + }) + @Test(groups = {"servlet"}) + public void ldifSearchServlet(final String query, final String attrs, final String ldifFile) + throws Exception + { + final String expected = TestUtils.readFileIntoString(ldifFile); + + final ServletUnitClient sc = servletRunner.newClient(); + final WebRequest request = new PostMethodWebRequest("http://servlets.ldaptive.org/LdifSearch"); + request.setParameter("query", query); + request.setParameter("attrs", attrs.split("\\|")); + + final WebResponse response = sc.getResponse(request); + + AssertJUnit.assertNotNull(response); + AssertJUnit.assertEquals("text/plain", response.getContentType()); + + final SearchResult result = TestUtils.convertLdifToResult(response.getText()); + AssertJUnit.assertEquals(TestUtils.convertLdifToResult(expected), result); + } + + + /** + * @param query to search for. + * @param attrs attributes to return from search + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "dsmlSearchServletQuery", + "dsmlSearchServletAttrs", + "dsmlSearchServletLdif" + }) + @Test(groups = {"servlet"}) + public void dsmlSearchServlet(final String query, final String attrs, final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + final SearchResult result = TestUtils.convertLdifToResult(ldif); + // convert ldif into dsmlv1 + final StringWriter s1w = new StringWriter(); + final Dsmlv1Writer d1w = new Dsmlv1Writer(s1w); + d1w.write(result); + + final String dsmlv1 = s1w.toString(); + + final ServletUnitClient sc = servletRunner.newClient(); + // test basic dsml query + final WebRequest request = new PostMethodWebRequest("http://servlets.ldaptive.org/DsmlSearch"); + request.setParameter("query", query); + request.setParameter("attrs", attrs.split("\\|")); + + final WebResponse response = sc.getResponse(request); + + AssertJUnit.assertNotNull(response); + AssertJUnit.assertEquals("text/xml", response.getContentType()); + // active directory uppercases CN in the DN + AssertJUnit.assertEquals( + dsmlv1, + response.getText().replaceAll("CN=", "cn=").replaceAll("OU=Test", "ou=test").replaceAll("DC=", "dc=")); + } + + + /** + * @param query to search for. + * @param attrs attributes to return from search + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "jsonSearchServletQuery", + "jsonSearchServletAttrs", + "jsonSearchServletLdif" + }) + @Test(groups = {"servlet"}) + public void jsonSearchServlet(final String query, final String attrs, final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + final SearchResult result = TestUtils.convertLdifToResult(ldif); + // convert ldif into json + final StringWriter s1w = new StringWriter(); + final JsonWriter j1w = new JsonWriter(s1w); + j1w.write(result); + + final String json = s1w.toString(); + + final ServletUnitClient sc = servletRunner.newClient(); + // test basic json query + final WebRequest request = new PostMethodWebRequest("http://servlets.ldaptive.org/JsonSearch"); + request.setParameter("query", query); + request.setParameter("attrs", attrs.split("\\|")); + + final WebResponse response = sc.getResponse(request); + + AssertJUnit.assertNotNull(response); + AssertJUnit.assertEquals("application/json", response.getContentType()); + // active directory uppercases CN in the DN + AssertJUnit.assertEquals( + json, + response.getText().replaceAll("CN=", "cn=").replaceAll("OU=Test", "ou=test").replaceAll("DC=", "dc=")); + } + + + /** + * @param query to search for. + * @param attrs attributes to return from search + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "ldifTemplateSearchQuery", + "ldifTemplateSearchAttrs", + "ldifTemplateSearchLdif" + }) + @Test(groups = {"servlet"}) + public void templatesLdifSearchServlet(final String query, final String attrs, final String ldifFile) + throws Exception + { + final String expected = TestUtils.readFileIntoString(ldifFile); + + final ServletUnitClient sc = servletRunner.newClient(); + final WebRequest request = new PostMethodWebRequest("http://servlets.ldaptive.org/TemplatesLdifSearch"); + request.setParameter("query", query); + request.setParameter("attrs", attrs.split("\\|")); + + final WebResponse response = sc.getResponse(request); + + AssertJUnit.assertNotNull(response); + AssertJUnit.assertEquals("text/plain", response.getContentType()); + + final SearchResult result = TestUtils.convertLdifToResult(response.getText()); + AssertJUnit.assertEquals(TestUtils.convertLdifToResult(expected), result); + } + + + /** + * @param query to search for. + * @param attrs attributes to return from search + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "dsmlTemplateSearchQuery", + "dsmlTemplateSearchAttrs", + "dsmlTemplateSearchLdif" + }) + @Test(groups = {"servlet"}) + public void templatesDsmlSearchServlet(final String query, final String attrs, final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + final SearchResult result = TestUtils.convertLdifToResult(ldif); + // convert ldif into dsmlv1 + final StringWriter s1w = new StringWriter(); + final Dsmlv1Writer d1w = new Dsmlv1Writer(s1w); + d1w.write(result); + + final String dsmlv1 = s1w.toString(); + + final ServletUnitClient sc = servletRunner.newClient(); + final WebRequest request = new PostMethodWebRequest("http://servlets.ldaptive.org/TemplatesDsmlSearch"); + request.setParameter("query", query); + request.setParameter("attrs", attrs.split("\\|")); + + final WebResponse response = sc.getResponse(request); + + AssertJUnit.assertNotNull(response); + AssertJUnit.assertEquals("text/xml", response.getContentType()); + // active directory uppercases CN in the DN + AssertJUnit.assertEquals( + dsmlv1, + response.getText().replaceAll("CN=", "cn=").replaceAll("OU=Test", "ou=test").replaceAll("DC=", "dc=")); + } + + + /** + * @param query to search for. + * @param attrs attributes to return from search + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "jsonTemplateSearchQuery", + "jsonTemplateSearchAttrs", + "jsonTemplateSearchLdif" + }) + @Test(groups = {"servlet"}) + public void templatesJsonSearchServlet(final String query, final String attrs, final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + final SearchResult result = TestUtils.convertLdifToResult(ldif); + // convert ldif into json + final StringWriter s1w = new StringWriter(); + final JsonWriter j1w = new JsonWriter(s1w); + j1w.write(result); + + final String json = s1w.toString(); + + final ServletUnitClient sc = servletRunner.newClient(); + final WebRequest request = new PostMethodWebRequest("http://servlets.ldaptive.org/TemplatesJsonSearch"); + request.setParameter("query", query); + request.setParameter("attrs", attrs.split("\\|")); + + final WebResponse response = sc.getResponse(request); + + AssertJUnit.assertNotNull(response); + AssertJUnit.assertEquals("application/json", response.getContentType()); + // active directory uppercases CN in the DN + AssertJUnit.assertEquals( + json, + response.getText().replaceAll("CN=", "cn=").replaceAll("OU=Test", "ou=test").replaceAll("DC=", "dc=")); + } + + + /** + * @param query to search for. + * @param attrs attributes to return from search + * @param ldifFile to compare with + * + * @throws Exception On test failure. + */ + @Parameters( + { + "ldifTemplateSearchQuery", + "ldifTemplateSearchAttrs", + "ldifTemplateSearchLdif" + }) + @Test(groups = {"servlet"}) + public void templatesLdifIgnoreSearchServlet(final String query, final String attrs, final String ldifFile) + throws Exception + { + final String expected = TestUtils.readFileIntoString(ldifFile); + + final ServletUnitClient sc = servletRunner.newClient(); + WebRequest request = new PostMethodWebRequest("http://servlets.ldaptive.org/TemplatesLdifIgnoreSearch"); + request.setParameter("query", query); + request.setParameter("attrs", attrs.split("\\|")); + + WebResponse response = sc.getResponse(request); + + AssertJUnit.assertNotNull(response); + AssertJUnit.assertEquals("text/plain", response.getContentType()); + + final SearchResult result = TestUtils.convertLdifToResult(response.getText()); + AssertJUnit.assertEquals(TestUtils.convertLdifToResult(expected), result); + + request = new PostMethodWebRequest("http://servlets.ldaptive.org/TemplatesLdifIgnoreSearch"); + request.setParameter("query", "df"); + + response = sc.getResponse(request); + + AssertJUnit.assertNotNull(response); + AssertJUnit.assertEquals("text/plain", response.getContentType()); + AssertJUnit.assertEquals("", response.getText()); + } +}
diff --git a/integration/src/test/java/org/ldaptive/ssl/AnyHostnameVerifier.java b/integration/src/test/java/org/ldaptive/ssl/AnyHostnameVerifier.java new file mode 100644 index 0000000..8e62a5a --- /dev/null +++ b/integration/src/test/java/org/ldaptive/ssl/AnyHostnameVerifier.java
@@ -0,0 +1,21 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSession; + +/** + * Returns true for any host it is asked to verify. + * + * @author Middleware Services + */ +public class AnyHostnameVerifier implements HostnameVerifier +{ + + + @Override + public boolean verify(final String hostname, final SSLSession session) + { + return true; + } +}
diff --git a/integration/src/test/java/org/ldaptive/ssl/ClassLoaderTest.java b/integration/src/test/java/org/ldaptive/ssl/ClassLoaderTest.java new file mode 100644 index 0000000..5ff8b66 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/ssl/ClassLoaderTest.java
@@ -0,0 +1,100 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import org.ldaptive.Connection; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.Response; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.TestControl; +import org.testng.AssertJUnit; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for class loader issues related to custom SSL socket factories. + * + * @author Middleware Services + */ +public class ClassLoaderTest +{ + + + /** + * @return ssl config + * + * @throws Exception On configuration error. + */ + public SslConfig createSslConfig() + throws Exception + { + final X509CredentialConfig config = new X509CredentialConfig(); + config.setTrustCertificates("file:target/test-classes/ldaptive.trust.crt"); + return new SslConfig(config); + } + + + /** + * @param host to connect to + * + * @throws Exception On test failure. + */ + @Parameters("ldapSslTestHost") + @Test(groups = {"ssl"}) + public void connectSSL(final String host) + throws Exception + { + if (!TestControl.isJndiProvider()) { + return; + } + + // remove ldaptive classes from the classloader + final TestClassLoader cl = new TestClassLoader(Thread.currentThread().getContextClassLoader()); + Thread.currentThread().setContextClassLoader(cl); + + final ConnectionConfig cc = new ConnectionConfig(host); + cc.setUseSSL(true); + cc.setSslConfig(createSslConfig()); + final Connection conn = DefaultConnectionFactory.getConnection(cc); + try { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + final Response<SearchResult> response = op.execute(SearchRequest.newObjectScopeSearchRequest("")); + AssertJUnit.assertFalse(response.getResult().getEntries().isEmpty()); + } finally { + conn.close(); + } + } + + + /** + * Class loader that cannot find ldaptive classes. + */ + public class TestClassLoader extends ClassLoader + { + + + /** + * Creates a new test class loader. + * + * @param cl class loader delegate + */ + public TestClassLoader(final ClassLoader cl) + { + super(cl); + } + + + @Override + public Class<?> loadClass(final String name) + throws ClassNotFoundException + { + if (name.startsWith("org.ldaptive")) { + throw new ClassNotFoundException("Use a different class loader for ldaptive"); + } + return loadClass(name, false); + } + } +}
diff --git a/integration/src/test/java/org/ldaptive/ssl/HostnameVerifierConnectionTest.java b/integration/src/test/java/org/ldaptive/ssl/HostnameVerifierConnectionTest.java new file mode 100644 index 0000000..1df20a9 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/ssl/HostnameVerifierConnectionTest.java
@@ -0,0 +1,152 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.net.InetAddress; +import org.ldaptive.CompareOperation; +import org.ldaptive.CompareRequest; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.LdapAttribute; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for default hostname verification behavior. + * + * @author Middleware Services + */ +public class HostnameVerifierConnectionTest +{ + + + /** @throws Exception On test failure. */ + @BeforeClass(groups = {"ssl-hostname"}) + public void setProperties() + throws Exception + { + System.setProperty("javax.net.ssl.trustStore", "target/test-classes/ldaptive.truststore"); + System.setProperty("javax.net.ssl.trustStoreType", "BKS"); + System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"ssl-hostname"}) + public void clearProperties() + throws Exception + { + System.clearProperty("javax.net.ssl.trustStore"); + System.clearProperty("javax.net.ssl.trustStoreType"); + System.clearProperty("javax.net.ssl.trustStorePassword"); + } + + + /** + * @param host to connect to + * + * @throws Exception On test failure. + */ + @Parameters("ldapTestHost") + @Test(groups = {"ssl-hostname"}) + public void connectStartTLS(final String host) + throws Exception + { + // attempting to use startTLS by IP address should fail + ConnectionConfig cc = new ConnectionConfig(convertUrlToIp(host)); + cc.setUseStartTLS(true); + + Connection conn = DefaultConnectionFactory.getConnection(cc); + try { + conn.open(); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } finally { + conn.close(); + } + + // attempting to use startTLS by hostname address should succeed + cc = new ConnectionConfig(host); + cc.setUseStartTLS(true); + conn = DefaultConnectionFactory.getConnection(cc); + try { + conn.open(); + } finally { + conn.close(); + } + } + + + /** + * @param host to connect to + * + * @throws Exception On test failure. + */ + @Parameters("ldapSslTestHost") + @Test(groups = {"ssl-hostname"}) + public void connectSSL(final String host) + throws Exception + { + // attempting to use LDAPS by IP address should fail + ConnectionConfig cc = new ConnectionConfig(convertUrlToIp(host)); + cc.setUseSSL(true); + + Connection conn = DefaultConnectionFactory.getConnection(cc); + try { + conn.open(); + + // some providers won't perform the handshake until an operation is + // executed + final CompareOperation op = new CompareOperation(conn); + op.execute(new CompareRequest("", new LdapAttribute("objectClass", "top"))); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } finally { + conn.close(); + } + + // attempting to use LDAPS by hostname address should succeed + cc = new ConnectionConfig(host); + cc.setUseSSL(true); + conn = DefaultConnectionFactory.getConnection(cc); + try { + conn.open(); + } finally { + conn.close(); + } + } + + + /** + * Converts a DNS based url string to an IP based string. + * + * @param host url to convert + * + * @return url with IP address + * + * @throws Exception if the ip address cannot be determined + */ + private String convertUrlToIp(final String host) + throws Exception + { + // convert the hostname into an ip address + String ipHost = null; + if (host.indexOf(":") < host.lastIndexOf(":")) { + ipHost = host.substring("ldap://".length(), host.lastIndexOf(":")); + } else { + ipHost = host.substring("ldap://".length()); + } + + final InetAddress ip = InetAddress.getByName(ipHost); + ipHost = "ldap://" + ip.getHostAddress(); + if (host.indexOf(":") < host.lastIndexOf(":")) { + ipHost = ipHost + ":" + host.substring(host.lastIndexOf(":") + 1); + } + return ipHost; + } +}
diff --git a/integration/src/test/java/org/ldaptive/ssl/NoHostnameVerifier.java b/integration/src/test/java/org/ldaptive/ssl/NoHostnameVerifier.java new file mode 100644 index 0000000..13161d2 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/ssl/NoHostnameVerifier.java
@@ -0,0 +1,29 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.security.cert.X509Certificate; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSession; + +/** + * Returns false for any host it is asked to verify. + * + * @author Middleware Services + */ +public class NoHostnameVerifier implements HostnameVerifier, CertificateHostnameVerifier +{ + + + @Override + public boolean verify(final String hostname, final SSLSession session) + { + return false; + } + + + @Override + public boolean verify(final String hostname, final X509Certificate cert) + { + return false; + } +}
diff --git a/integration/src/test/java/org/ldaptive/ssl/TLSSocketFactoryTest.java b/integration/src/test/java/org/ldaptive/ssl/TLSSocketFactoryTest.java new file mode 100644 index 0000000..3313476 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/ssl/TLSSocketFactoryTest.java
@@ -0,0 +1,672 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ssl; + +import java.net.Socket; +import java.util.Arrays; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.TrustManager; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.LdapURL; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.provider.Provider; +import org.testng.AssertJUnit; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link TLSSocketFactory}. + * + * @author Middleware Services + */ +public class TLSSocketFactoryTest +{ + + /** List of ciphers. */ + public static final String[] CIPHERS = new String[] { + "SSL_RSA_WITH_3DES_EDE_CBC_SHA", + "TLS_RSA_WITH_AES_128_CBC_SHA", + "TLS_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + /* GCM ciphers only supported in Java 8 + "TLS_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384", + */ + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + /* GCM ciphers only supported in Java 8 + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + */ + "TLS_RSA_WITH_AES_128_CBC_SHA256", + "TLS_RSA_WITH_AES_256_CBC_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", + /* GCM ciphers only supported in Java 8 + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + */ + }; + + /** List of ciphers. */ + public static final String[] UNKNOWN_CIPHERS = new String[] { + /* one valid cipher, three invalid */ + "TLS_DH_anon_WITH_AES_128_CBC_SHA", + "TLS_DH_anon_WITH_3DES_256_CBC_SHA", + "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", + "SSL_DH_anon_WITH_RC4_128_MD5", + }; + + /** List of protocols. */ + public static final String[] ALL_PROTOCOLS = new String[] { + "SSLv2Hello", + "SSLv3", + "TLSv1", + "TLSv1.1", + "TLSv1.2", + }; + + /** List of protocols. */ + public static final String[] PROTOCOLS = new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"}; + + /** List of protocols. */ + public static final String[] FAIL_PROTOCOLS = new String[] {"SSLv2Hello", }; + + /** List of protocols. */ + public static final String[] UNKNOWN_PROTOCOLS = new String[] { + /* one invalid protocol, two valid */ + "SSLv3Hello", + "SSLv2Hello", + "TLSv1", + }; + + + /** + * @return ssl config + * + * @throws Exception On configuration error. + */ + public SslConfig createSslConfig() + throws Exception + { + final X509CredentialConfig config = new X509CredentialConfig(); + config.setTrustCertificates("file:target/test-classes/ldaptive.trust.crt"); + return new SslConfig(config); + } + + + /** + * @param url to connect to + * + * @return connection configuration + * + * @throws Exception On connection failure. + */ + public ConnectionConfig createTLSConnectionConfig(final String url) + throws Exception + { + final ConnectionConfig cc = new ConnectionConfig(url); + cc.setUseStartTLS(true); + cc.setSslConfig(createSslConfig()); + return cc; + } + + + /** + * @param url to connect to + * + * @return connection configuration + * + * @throws Exception On connection failure. + */ + public ConnectionConfig createSSLConnectionConfig(final String url) + throws Exception + { + final ConnectionConfig cc = new ConnectionConfig(url); + cc.setUseSSL(true); + cc.setSslConfig(createSslConfig()); + return cc; + } + + + /** + * @param url to connect to + * + * @throws Exception On test failure. + */ + @Parameters("ldapTestHost") + @Test(groups = {"ssl"}) + public void connectTLS(final String url) + throws Exception + { + final Provider<?> p = DefaultConnectionFactory.getDefaultProvider(); + + // no trusted certificates + ConnectionConfig cc = createTLSConnectionConfig(url); + cc.setSslConfig(null); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } + + // no trusted certificates + cc = createTLSConnectionConfig(url); + cc.setSslConfig(new SslConfig()); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } + + // no trusted certificates with hostname verification + cc = createTLSConnectionConfig(url); + cc.setSslConfig(new SslConfig()); + cc.getSslConfig().setHostnameVerifier(new DefaultHostnameVerifier()); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } + + // trust any + cc = createTLSConnectionConfig(url); + cc.setSslConfig(new SslConfig()); + cc.getSslConfig().setTrustManagers(new AllowAnyTrustManager()); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + } + + // trust any with hostname verification failure + if ("org.ldaptive.provider.jndi.JndiProvider".equals(p.getClass().getName())) { + // JNDI startTLS always executes default hostname verification + AssertJUnit.assertTrue(true); + } else { + cc = createTLSConnectionConfig(url); + cc.setSslConfig(new SslConfig()); + cc.getSslConfig().setTrustManagers(new AllowAnyTrustManager()); + cc.getSslConfig().setHostnameVerifier(new NoHostnameVerifier()); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } + } + + // trust any with hostname verification + cc = createTLSConnectionConfig(url); + cc.setSslConfig(new SslConfig()); + cc.getSslConfig().setTrustManagers(new AllowAnyTrustManager()); + // note that this verifier does not run with JNDI startTLS + cc.getSslConfig().setHostnameVerifier(new DefaultHostnameVerifier()); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + } + } + + + /** + * @param url to connect to + * + * @throws Exception On test failure. + */ + @Parameters("ldapSslTestHost") + @Test(groups = {"ssl"}) + public void connectSSL(final String url) + throws Exception + { + // no trusted certificates + ConnectionConfig cc = createSSLConnectionConfig(url); + cc.setSslConfig(null); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } + + // no trusted certificates + cc = createSSLConnectionConfig(url); + cc.setSslConfig(new SslConfig()); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } + + // no trusted certificates with hostname verification + cc = createSSLConnectionConfig(url); + cc.setSslConfig(new SslConfig()); + cc.getSslConfig().setHostnameVerifier(new DefaultHostnameVerifier()); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } + + // trust any + cc = createSSLConnectionConfig(url); + cc.setSslConfig(new SslConfig()); + cc.getSslConfig().setTrustManagers(new AllowAnyTrustManager()); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + } + + // trust any with hostname verification failure + cc = createSSLConnectionConfig(url); + cc.setSslConfig(new SslConfig()); + cc.getSslConfig().setTrustManagers(new AllowAnyTrustManager()); + cc.getSslConfig().setHostnameVerifier(new NoHostnameVerifier()); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } + + // trust any with hostname verification + cc = createSSLConnectionConfig(url); + cc.setSslConfig(new SslConfig()); + cc.getSslConfig().setTrustManagers(new AllowAnyTrustManager()); + cc.getSslConfig().setHostnameVerifier(new DefaultHostnameVerifier()); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + } + } + + + /** + * @param url to connect to + * + * @throws Exception On test failure. + */ + @Parameters("ldapSslTestHost") + @Test(groups = {"ssl"}) + public void connectLDAPS(final String url) + throws Exception + { + final String ldapsUrl = url.replace("ldap://", "ldaps://"); + // no trusted certificates + ConnectionConfig cc = new ConnectionConfig(ldapsUrl); + cc.setSslConfig(null); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } + + // no trusted certificates + cc = new ConnectionConfig(ldapsUrl); + cc.setSslConfig(new SslConfig()); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } + + // no trusted certificates with hostname verification + cc = new ConnectionConfig(ldapsUrl); + cc.setSslConfig(new SslConfig()); + cc.getSslConfig().setHostnameVerifier(new DefaultHostnameVerifier()); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } + + // trust any + cc = new ConnectionConfig(ldapsUrl); + cc.setSslConfig(new SslConfig()); + cc.getSslConfig().setTrustManagers(new AllowAnyTrustManager()); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + } + + // trust any with hostname verification failure + cc = new ConnectionConfig(ldapsUrl); + cc.setSslConfig(new SslConfig()); + cc.getSslConfig().setTrustManagers(new AllowAnyTrustManager()); + cc.getSslConfig().setHostnameVerifier(new NoHostnameVerifier()); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } + + // trust any with hostname verification + cc = new ConnectionConfig(ldapsUrl); + cc.setSslConfig(new SslConfig()); + cc.getSslConfig().setTrustManagers(new AllowAnyTrustManager()); + cc.getSslConfig().setHostnameVerifier(new DefaultHostnameVerifier()); + try (Connection conn = DefaultConnectionFactory.getConnection(cc)) { + conn.open(); + final SearchOperation op = new SearchOperation(conn); + op.execute(SearchRequest.newObjectScopeSearchRequest("")); + } + } + + + /** + * @param url to connect to + * + * @throws Exception On test failure. + */ + @Parameters("ldapTestHost") + @Test(groups = {"ssl"}) + public void setEnabledCipherSuites(final String url) + throws Exception + { + final ConnectionConfig cc = createTLSConnectionConfig(url); + final TLSSocketFactory sf = new TLSSocketFactory(); + sf.setSslConfig(cc.getSslConfig()); + sf.initialize(); + + AssertJUnit.assertEquals( + Arrays.asList(((SSLSocket) sf.createSocket()).getEnabledCipherSuites()), + Arrays.asList(sf.getDefaultCipherSuites())); + AssertJUnit.assertNotSame(Arrays.asList(sf.getDefaultCipherSuites()), Arrays.asList(CIPHERS)); + + cc.getSslConfig().setEnabledCipherSuites(UNKNOWN_CIPHERS); + + final Connection conn = DefaultConnectionFactory.getConnection(cc); + try { + conn.open(); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } + + sf.getSslConfig().setEnabledCipherSuites(CIPHERS); + sf.initialize(); + AssertJUnit.assertEquals( + Arrays.asList(((SSLSocket) sf.createSocket()).getEnabledCipherSuites()), + Arrays.asList(CIPHERS)); + } + + + /** + * @param url to connect to + * + * @throws Exception On test failure. + */ + @Parameters("ldapTestHost") + @Test(groups = {"ssl"}) + public void setEnabledProtocols(final String url) + throws Exception + { + final Provider<?> p = DefaultConnectionFactory.getDefaultProvider(); + + final ConnectionConfig cc = createTLSConnectionConfig(url); + final TLSSocketFactory sf = new TLSSocketFactory(); + sf.setSslConfig(cc.getSslConfig()); + sf.initialize(); + + AssertJUnit.assertNotSame( + Arrays.asList(((SSLSocket) sf.createSocket()).getEnabledProtocols()), + Arrays.asList(PROTOCOLS)); + + cc.getSslConfig().setEnabledProtocols(FAIL_PROTOCOLS); + + Connection conn = DefaultConnectionFactory.getConnection(cc); + try { + conn.open(); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } + + if ("org.ldaptive.provider.opendj.OpenDJProvider".equals(p.getClass().getName())) { + // grizzly ignores unknown protocols + AssertJUnit.assertTrue(true); + } else { + cc.getSslConfig().setEnabledProtocols(UNKNOWN_PROTOCOLS); + conn = DefaultConnectionFactory.getConnection(cc); + try { + conn.open(); + AssertJUnit.fail("Should have thrown Exception, no exception thrown"); + } catch (Exception e) { + AssertJUnit.assertNotNull(e); + } + } + + sf.getSslConfig().setEnabledProtocols(PROTOCOLS); + sf.initialize(); + AssertJUnit.assertEquals( + Arrays.asList(((SSLSocket) sf.createSocket()).getEnabledProtocols()), + Arrays.asList(PROTOCOLS)); + } + + + /** + * @param url to connect to + * + * @throws Exception On test failure. + */ + @Parameters("ldapSslTestHost") + @Test(groups = {"ssl"}) + public void setSocketConfig(final String url) + throws Exception + { + final SocketConfig sc = new SocketConfig(); + sc.setKeepAlive(true); + sc.setReuseAddress(true); + sc.setTcpNoDelay(true); + sc.setReceiveBufferSize(256); + sc.setSendBufferSize(256); + sc.setSoLinger(100); + sc.setSoTimeout(500); + sc.setTrafficClass(0x10); + + final LdapURL ldapUrl = new LdapURL(url); + final TLSSocketFactory sf = new TLSSocketFactory(); + sf.setSocketConfig(sc); + sf.initialize(); + + try (Socket s = sf.createSocket(ldapUrl.getEntry().getHostname(), ldapUrl.getEntry().getPort())) { + AssertJUnit.assertNotNull(s); + } + } + + + /** + * @throws Exception On test failure. + */ + @Test(groups = {"ssl"}) + public void createSSLContextInitializer() + throws Exception + { + // no ssl config + TLSSocketFactory factory = new TLSSocketFactory(); + SSLContextInitializer init = factory.createSSLContextInitializer(); + AssertJUnit.assertEquals(1, init.getTrustManagers().length); + AssertJUnit.assertTrue(init.getTrustManagers()[0] instanceof AggregateTrustManager); + TrustManager[] tm = ((AggregateTrustManager) init.getTrustManagers()[0]).getTrustManagers(); + AssertJUnit.assertEquals(1, tm.length); + AssertJUnit.assertEquals("sun.security.ssl.X509TrustManagerImpl", tm[0].getClass().getName()); + + // empty ssl config + factory = new TLSSocketFactory(); + factory.setSslConfig(new SslConfig()); + init = factory.createSSLContextInitializer(); + AssertJUnit.assertEquals(1, init.getTrustManagers().length); + AssertJUnit.assertTrue(init.getTrustManagers()[0] instanceof AggregateTrustManager); + tm = ((AggregateTrustManager) init.getTrustManagers()[0]).getTrustManagers(); + AssertJUnit.assertEquals(1, tm.length); + AssertJUnit.assertEquals("sun.security.ssl.X509TrustManagerImpl", tm[0].getClass().getName()); + + // trust managers + factory = new TLSSocketFactory(); + factory.setSslConfig(new SslConfig(new AllowAnyTrustManager())); + init = factory.createSSLContextInitializer(); + AssertJUnit.assertEquals(1, init.getTrustManagers().length); + AssertJUnit.assertTrue(init.getTrustManagers()[0] instanceof AggregateTrustManager); + tm = ((AggregateTrustManager) init.getTrustManagers()[0]).getTrustManagers(); + AssertJUnit.assertEquals(1, tm.length); + AssertJUnit.assertEquals("org.ldaptive.ssl.AllowAnyTrustManager", tm[0].getClass().getName()); + + // hostname verifier + factory = new TLSSocketFactory(); + SslConfig sslConfig = new SslConfig(); + sslConfig.setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier())); + factory.setSslConfig(sslConfig); + init = factory.createSSLContextInitializer(); + AssertJUnit.assertEquals(1, init.getTrustManagers().length); + AssertJUnit.assertTrue(init.getTrustManagers()[0] instanceof AggregateTrustManager); + tm = ((AggregateTrustManager) init.getTrustManagers()[0]).getTrustManagers(); + AssertJUnit.assertEquals(2, tm.length); + AssertJUnit.assertEquals("sun.security.ssl.X509TrustManagerImpl", tm[0].getClass().getName()); + AssertJUnit.assertEquals("org.ldaptive.ssl.HostnameVerifyingTrustManager", tm[1].getClass().getName()); + + // trust managers and hostname verifier + factory = new TLSSocketFactory(); + sslConfig = new SslConfig(); + sslConfig.setTrustManagers(new AllowAnyTrustManager()); + sslConfig.setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier())); + factory.setSslConfig(sslConfig); + init = factory.createSSLContextInitializer(); + AssertJUnit.assertEquals(1, init.getTrustManagers().length); + AssertJUnit.assertTrue(init.getTrustManagers()[0] instanceof AggregateTrustManager); + tm = ((AggregateTrustManager) init.getTrustManagers()[0]).getTrustManagers(); + AssertJUnit.assertEquals(2, tm.length); + AssertJUnit.assertEquals("org.ldaptive.ssl.AllowAnyTrustManager", tm[0].getClass().getName()); + AssertJUnit.assertEquals("org.ldaptive.ssl.HostnameVerifyingTrustManager", tm[1].getClass().getName()); + + // empty credential config + factory = new TLSSocketFactory(); + factory.setSslConfig(new SslConfig(new X509CredentialConfig())); + init = factory.createSSLContextInitializer(); + AssertJUnit.assertNull(init.getTrustManagers()); + + // empty credential config with trust + factory = new TLSSocketFactory(); + factory.setSslConfig(new SslConfig(new X509CredentialConfig(), new AllowAnyTrustManager())); + init = factory.createSSLContextInitializer(); + AssertJUnit.assertEquals(1, init.getTrustManagers().length); + AssertJUnit.assertTrue(init.getTrustManagers()[0] instanceof AggregateTrustManager); + tm = ((AggregateTrustManager) init.getTrustManagers()[0]).getTrustManagers(); + AssertJUnit.assertEquals(1, tm.length); + AssertJUnit.assertEquals("org.ldaptive.ssl.AllowAnyTrustManager", tm[0].getClass().getName()); + + // empty credential config with hostname verifier + factory = new TLSSocketFactory(); + sslConfig = new SslConfig(); + sslConfig.setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier())); + factory.setSslConfig(sslConfig); + init = factory.createSSLContextInitializer(); + AssertJUnit.assertEquals(1, init.getTrustManagers().length); + AssertJUnit.assertTrue(init.getTrustManagers()[0] instanceof AggregateTrustManager); + tm = ((AggregateTrustManager) init.getTrustManagers()[0]).getTrustManagers(); + AssertJUnit.assertEquals(2, tm.length); + AssertJUnit.assertEquals("sun.security.ssl.X509TrustManagerImpl", tm[0].getClass().getName()); + AssertJUnit.assertEquals("org.ldaptive.ssl.HostnameVerifyingTrustManager", tm[1].getClass().getName()); + + // empty credential config with trust and hostname verifier + factory = new TLSSocketFactory(); + sslConfig = new SslConfig(); + sslConfig.setTrustManagers(new AllowAnyTrustManager()); + sslConfig.setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier())); + factory.setSslConfig(sslConfig); + init = factory.createSSLContextInitializer(); + AssertJUnit.assertEquals(1, init.getTrustManagers().length); + AssertJUnit.assertTrue(init.getTrustManagers()[0] instanceof AggregateTrustManager); + tm = ((AggregateTrustManager) init.getTrustManagers()[0]).getTrustManagers(); + AssertJUnit.assertEquals(2, tm.length); + AssertJUnit.assertEquals("org.ldaptive.ssl.AllowAnyTrustManager", tm[0].getClass().getName()); + AssertJUnit.assertEquals("org.ldaptive.ssl.HostnameVerifyingTrustManager", tm[1].getClass().getName()); + + // credential config + factory = new TLSSocketFactory(); + factory.setSslConfig(createSslConfig()); + init = factory.createSSLContextInitializer(); + AssertJUnit.assertEquals(1, init.getTrustManagers().length); + AssertJUnit.assertTrue(init.getTrustManagers()[0] instanceof AggregateTrustManager); + tm = ((AggregateTrustManager) init.getTrustManagers()[0]).getTrustManagers(); + AssertJUnit.assertEquals(1, tm.length); + AssertJUnit.assertEquals("sun.security.ssl.X509TrustManagerImpl", tm[0].getClass().getName()); + + // credential config with trust + factory = new TLSSocketFactory(); + sslConfig = createSslConfig(); + sslConfig.setTrustManagers(new AllowAnyTrustManager()); + factory.setSslConfig(sslConfig); + init = factory.createSSLContextInitializer(); + AssertJUnit.assertEquals(1, init.getTrustManagers().length); + AssertJUnit.assertTrue(init.getTrustManagers()[0] instanceof AggregateTrustManager); + tm = ((AggregateTrustManager) init.getTrustManagers()[0]).getTrustManagers(); + AssertJUnit.assertEquals(2, tm.length); + AssertJUnit.assertEquals("sun.security.ssl.X509TrustManagerImpl", tm[0].getClass().getName()); + AssertJUnit.assertEquals("org.ldaptive.ssl.AllowAnyTrustManager", tm[1].getClass().getName()); + + // credential config with hostname verifier + factory = new TLSSocketFactory(); + sslConfig = createSslConfig(); + sslConfig.setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier())); + factory.setSslConfig(sslConfig); + init = factory.createSSLContextInitializer(); + AssertJUnit.assertEquals(init.getTrustManagers().length, 1); + AssertJUnit.assertTrue(init.getTrustManagers()[0] instanceof AggregateTrustManager); + tm = ((AggregateTrustManager) init.getTrustManagers()[0]).getTrustManagers(); + AssertJUnit.assertEquals(tm.length, 2); + AssertJUnit.assertEquals("sun.security.ssl.X509TrustManagerImpl", tm[0].getClass().getName()); + AssertJUnit.assertEquals("org.ldaptive.ssl.HostnameVerifyingTrustManager", tm[1].getClass().getName()); + + // credential config with trust and hostname verifier + factory = new TLSSocketFactory(); + sslConfig = createSslConfig(); + sslConfig.setTrustManagers(new AllowAnyTrustManager()); + sslConfig.setHostnameVerifierConfig(new HostnameVerifierConfig(new DefaultHostnameVerifier())); + factory.setSslConfig(sslConfig); + init = factory.createSSLContextInitializer(); + AssertJUnit.assertEquals(1, init.getTrustManagers().length); + AssertJUnit.assertTrue(init.getTrustManagers()[0] instanceof AggregateTrustManager); + tm = ((AggregateTrustManager) init.getTrustManagers()[0]).getTrustManagers(); + AssertJUnit.assertEquals(3, tm.length); + AssertJUnit.assertEquals("sun.security.ssl.X509TrustManagerImpl", tm[0].getClass().getName()); + AssertJUnit.assertEquals("org.ldaptive.ssl.AllowAnyTrustManager", tm[1].getClass().getName()); + AssertJUnit.assertEquals("org.ldaptive.ssl.HostnameVerifyingTrustManager", tm[2].getClass().getName()); + } +}
diff --git a/integration/src/test/java/org/ldaptive/templates/SearchTemplatesExecutorTest.java b/integration/src/test/java/org/ldaptive/templates/SearchTemplatesExecutorTest.java new file mode 100644 index 0000000..26d2580 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/templates/SearchTemplatesExecutorTest.java
@@ -0,0 +1,134 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.templates; + +import org.ldaptive.AbstractTest; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.LdapEntry; +import org.ldaptive.SearchResult; +import org.ldaptive.TestUtils; +import org.ldaptive.concurrent.AggregatePooledSearchExecutor; +import org.ldaptive.pool.BlockingConnectionPool; +import org.ldaptive.pool.ConnectionPool; +import org.ldaptive.pool.PooledConnectionFactory; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SearchTemplatesExecutor}. + * + * @author Middleware Services + */ +public class SearchTemplatesExecutorTest extends AbstractTest +{ + + /** Entry created for ldap tests. */ + private static LdapEntry testLdapEntry; + + /** Executor to test. */ + private SearchTemplatesExecutor executor; + + + /** + * @param ldifFile to create. + * + * @throws Exception On test failure. + */ + @Parameters("createEntry26") + @BeforeClass(groups = {"templates"}) + public void createLdapEntry(final String ldifFile) + throws Exception + { + final String ldif = TestUtils.readFileIntoString(ldifFile); + testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry(); + super.createLdapEntry(testLdapEntry); + // remove objectClass as active directory adds some additional ones + testLdapEntry.removeAttribute("objectClass"); + } + + + /** + * @param baseDn to search on + * + * @throws Exception On test failure. + */ + @Parameters("ldapBaseDn") + @BeforeClass(groups = {"templates"}) + public void createExecutor(final String baseDn) + throws Exception + { + final ConnectionConfig cc = TestUtils.readConnectionConfig(null); + final AggregatePooledSearchExecutor se = new AggregatePooledSearchExecutor(); + se.setBaseDn(baseDn); + + final ConnectionPool cp = new BlockingConnectionPool(new DefaultConnectionFactory(cc)); + cp.initialize(); + executor = new SearchTemplatesExecutor( + se, + new PooledConnectionFactory[] {new PooledConnectionFactory(cp)}, + new SearchTemplates( + "(|(givenName={term1})(sn={term1}))", + "(|(givenName={term1}*)(sn={term1}*))", + "(|(givenName=*{term1}*)(sn=*{term1}*))", + "(|(departmentNumber={term1})(mail={term1}))", + "(|(departmentNumber={term1})(mail={term1}*))", + "(|(departmentNumber={term1})(mail=*{term1}*))"), + new SearchTemplates( + "(&(givenName={term1})(sn={term2}))", + "(department={term1} {term2})", + "(department={term1}* {term2}*)", + "(department=*{term1}* *{term2}*)"), + new SearchTemplates( + "(|(&(givenName={term1})(sn={term3}))" + + "(&(givenName={term2})(sn={term3})))", + "(|(cn={term1} {term2} {term3})(cn={term2} {term1} {term3}))", + "(|(&(givenName={term1})(sn={term3}))" + + "(&(givenName={term2})(sn={term3})))")); + } + + + /** @throws Exception On test failure. */ + @AfterClass(groups = {"templates"}) + public void deleteLdapEntry() + throws Exception + { + super.deleteLdapEntry(testLdapEntry.getDn()); + executor.close(); + } + + + /** + * Sample executor data. + * + * @return executor data + */ + @DataProvider(name = "search-data") + public Object[][] createTestData() + { + return new Object[][] { + {"troosevelt", }, + {"0846", }, + {"theodore roosevelt", }, + }; + } + + + /** + * @param query to search with. + * + * @throws Exception On test failure. + */ + @Test(groups = {"templates"}, dataProvider = "search-data", threadPoolSize = 3, invocationCount = 50, timeOut = 60000) + public void search(final String query) + throws Exception + { + final Query q = new Query(query); + q.setReturnAttributes(testLdapEntry.getAttributeNames()); + + final SearchResult sr = executor.search(q); + TestUtils.assertEquals(testLdapEntry, sr.getEntry()); + } +}
diff --git a/integration/src/test/java/org/ldaptive/velocity/AbstractTemplateSearchDnResolver.java b/integration/src/test/java/org/ldaptive/velocity/AbstractTemplateSearchDnResolver.java new file mode 100644 index 0000000..80768f3 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/velocity/AbstractTemplateSearchDnResolver.java
@@ -0,0 +1,73 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.velocity; + +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.app.event.EventCartridge; +import org.apache.velocity.app.event.ReferenceInsertionEventHandler; +import org.apache.velocity.exception.VelocityException; +import org.ldaptive.SearchFilter; +import org.ldaptive.auth.AbstractSearchDnResolver; +import org.ldaptive.auth.User; + +/** + * Base class for {@link Template} based search dn resolvers. + * + * @author Middleware Services + */ +public abstract class AbstractTemplateSearchDnResolver extends AbstractSearchDnResolver +{ + + /** Template. */ + private final Template template; + + /** Event handler used for escaping. */ + private ReferenceInsertionEventHandler eventHandler = new EscapingReferenceInsertionEventHandler(); + + + /** + * Creates a new abstract template search DN resolver. + * + * @param engine velocity engine + * @param filter filter template + * + * @throws VelocityException if velocity is not configured properly or the filter template is invalid + */ + public AbstractTemplateSearchDnResolver(final VelocityEngine engine, final String filter) + throws VelocityException + { + template = new Template(engine, filter); + setUserFilter(filter); + } + + + /** + * Returns the template. + * + * @return template + */ + public Template getTemplate() + { + return template; + } + + + @Override + protected SearchFilter createSearchFilter(final User user) + { + final SearchFilter filter = new SearchFilter(); + if (user != null && user.getContext() != null) { + final VelocityContext context = (VelocityContext) user.getContext(); + final EventCartridge cartridge = new EventCartridge(); + cartridge.addEventHandler(eventHandler); + cartridge.attachToContext(context); + final String result = template.merge(context); + if (result != null) { + filter.setFilter(result.trim()); + } + } else { + logger.warn("Search filter cannot be created, user input was empty or null"); + } + return filter; + } +}
diff --git a/integration/src/test/java/org/ldaptive/velocity/EscapingReferenceInsertionEventHandler.java b/integration/src/test/java/org/ldaptive/velocity/EscapingReferenceInsertionEventHandler.java new file mode 100644 index 0000000..1dff30e --- /dev/null +++ b/integration/src/test/java/org/ldaptive/velocity/EscapingReferenceInsertionEventHandler.java
@@ -0,0 +1,65 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.velocity; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import org.apache.velocity.app.event.ReferenceInsertionEventHandler; +import org.ldaptive.SearchFilter; + +/** + * Insertion event handler that encodes the inserted value using {@link SearchFilter#encodeValue(String)} or {@link + * SearchFilter#encodeValue(byte[])} + * + * @author Middleware Services + */ +public class EscapingReferenceInsertionEventHandler implements ReferenceInsertionEventHandler +{ + + + @Override + public Object referenceInsert(final String reference, final Object value) + { + Object output = null; + if (value != null) { + if (value instanceof Object[]) { + final List<Object> encodedValues = new ArrayList<>(); + for (Object o : (Object[]) value) { + encodedValues.add(encode(o)); + } + output = encodedValues.toArray(); + } else if (value instanceof Collection<?>) { + output = ((Collection<?>) value).stream().map(this::encode).collect(Collectors.toList()); + } else { + output = encode(value); + } + } + return output; + } + + + /** + * Returns {@link SearchFilter#encodeValue} if value is a string. + * + * @param value to encode + * + * @return encoded value if value is a string + */ + private Object encode(final Object value) + { + if (value == null) { + return null; + } + + String s; + if (value instanceof String){ + s = SearchFilter.encodeValue((String) value); + } else if (value instanceof byte[]) { + s = SearchFilter.encodeValue((byte[]) value); + } else { + s = SearchFilter.encodeValue(value.toString()); + } + return s; + } +}
diff --git a/integration/src/test/java/org/ldaptive/velocity/PooledTemplateSearchDnResolver.java b/integration/src/test/java/org/ldaptive/velocity/PooledTemplateSearchDnResolver.java new file mode 100644 index 0000000..d239c6b --- /dev/null +++ b/integration/src/test/java/org/ldaptive/velocity/PooledTemplateSearchDnResolver.java
@@ -0,0 +1,101 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.velocity; + +import java.util.Arrays; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.exception.VelocityException; +import org.ldaptive.Connection; +import org.ldaptive.LdapException; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.pool.PooledConnectionFactoryManager; + +/** + * {@link Template} based pooled search dn resolver. + * + * @author Middleware Services + */ +public class PooledTemplateSearchDnResolver extends AbstractTemplateSearchDnResolver + implements PooledConnectionFactoryManager +{ + + /** Connection factory. */ + private PooledConnectionFactory factory; + + + /** + * Creates a new pooled template search DN resolver. + * + * @param engine velocity engine + * @param filter filter template + * + * @throws VelocityException if velocity is not configured properly or the filter template is invalid + */ + public PooledTemplateSearchDnResolver(final VelocityEngine engine, final String filter) + throws VelocityException + { + super(engine, filter); + } + + + /** + * Creates a new pooled template search DN resolver. + * + * @param cf connection factory + * @param engine velocity engine + * @param filter filter template + * + * @throws VelocityException if velocity is not configured properly or the filter template is invalid + */ + public PooledTemplateSearchDnResolver( + final PooledConnectionFactory cf, + final VelocityEngine engine, + final String filter) + throws VelocityException + { + super(engine, filter); + setConnectionFactory(cf); + } + + + @Override + public PooledConnectionFactory getConnectionFactory() + { + return factory; + } + + + @Override + public void setConnectionFactory(final PooledConnectionFactory cf) + { + factory = cf; + } + + + @Override + protected Connection getConnection() + throws LdapException + { + return factory.getConnection(); + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::factory=%s, templateName=%s, baseDn=%s, userFilter=%s, userFilterParameters=%s, " + + "allowMultipleDns=%s, subtreeSearch=%s, derefAliases=%s, referralHandler=%s]", + getClass().getName(), + hashCode(), + factory, + getTemplate().getTemplateName(), + getBaseDn(), + getUserFilter(), + Arrays.toString(getUserFilterParameters()), + getAllowMultipleDns(), + getSubtreeSearch(), + getDerefAliases(), + getReferralHandler()); + } +}
diff --git a/integration/src/test/java/org/ldaptive/velocity/Template.java b/integration/src/test/java/org/ldaptive/velocity/Template.java new file mode 100644 index 0000000..13f05c6 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/velocity/Template.java
@@ -0,0 +1,106 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.velocity; + +import java.io.StringWriter; +import java.nio.charset.StandardCharsets; +import java.util.UUID; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.exception.VelocityException; +import org.apache.velocity.runtime.resource.loader.StringResourceLoader; +import org.apache.velocity.runtime.resource.util.StringResourceRepository; + +/** + * Class that encapsulates the details of merging a velocity template with a context. + * + * @author Middleware Services + */ +public class Template +{ + + /** VelocityEngine. */ + private final VelocityEngine velocityEngine; + + /** Template name registered in the velocity repository. */ + private final String templateName; + + + /** + * Creates a new template search DN resolver. + * + * @param engine velocity engine + * @param template template text + * + * @throws VelocityException if velocity is not configured properly or the filter template is invalid + */ + public Template(final VelocityEngine engine, final String template) + throws VelocityException + { + // generate a template name and register it + final StringResourceRepository repository = StringResourceLoader.getRepository(); + if (repository == null) { + throw new VelocityException( + "Velocity engine is not configured to load templates from the default StringResourceRepository"); + } + templateName = generateTemplateName(repository); + repository.putStringResource(templateName, template, StandardCharsets.UTF_8.name()); + + // confirm velocity is configured + if (!engine.resourceExists(templateName)) { + throw new VelocityException( + "Velocity engine is not configured to load templates from the default StringResourceRepository"); + } else { + try { + engine.getTemplate(templateName); + } catch (VelocityException e) { + throw new VelocityException("Invalid template: " + template, e); + } + } + velocityEngine = engine; + } + + + /** + * Returns the template name. + * + * @return template name + */ + public String getTemplateName() + { + return templateName; + } + + + /** + * Returns a template name to use in the supplied repository. The name is selected by generating a random string and + * confirming that name is not in use. + * + * @param repository to store the template name + * + * @return template name + */ + protected String generateTemplateName(final StringResourceRepository repository) + { + String name; + do { + name = UUID.randomUUID().toString(); + } while(repository.getStringResource(name) != null); + return name; + } + + + /** + * Merges {@link #templateName} with the supplied context. See {@link + * VelocityEngine#mergeTemplate(String, String, Context, Writer)}. + * + * @param context to merge + * + * @return merged filter template + */ + public String merge(final VelocityContext context) + { + final StringWriter writer = new StringWriter(); + velocityEngine.mergeTemplate(templateName, StandardCharsets.UTF_8.name(), context, writer); + return writer.toString(); + } +}
diff --git a/integration/src/test/java/org/ldaptive/velocity/TemplateSearchDnResolver.java b/integration/src/test/java/org/ldaptive/velocity/TemplateSearchDnResolver.java new file mode 100644 index 0000000..d044a53 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/velocity/TemplateSearchDnResolver.java
@@ -0,0 +1,99 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.velocity; + +import java.util.Arrays; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.exception.VelocityException; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.ConnectionFactoryManager; +import org.ldaptive.LdapException; + +/** + * {@link Template} based search dn resolver. + * + * @author Middleware Services + */ +public class TemplateSearchDnResolver extends AbstractTemplateSearchDnResolver implements ConnectionFactoryManager +{ + + /** Connection factory. */ + private ConnectionFactory factory; + + + /** + * Creates a new template search DN resolver. + * + * @param engine velocity engine + * @param filter filter template + * + * @throws VelocityException if velocity is not configured properly or the filter template is invalid + */ + public TemplateSearchDnResolver(final VelocityEngine engine, final String filter) + throws VelocityException + { + super(engine, filter); + } + + + /** + * Creates a new template search DN resolver. + * + * @param cf connection factory + * @param engine velocity engine + * @param filter filter template + * + * @throws VelocityException if velocity is not configured properly or the filter template is invalid + */ + public TemplateSearchDnResolver(final ConnectionFactory cf, final VelocityEngine engine, final String filter) + throws VelocityException + { + super(engine, filter); + setConnectionFactory(cf); + } + + + @Override + public ConnectionFactory getConnectionFactory() + { + return factory; + } + + + @Override + public void setConnectionFactory(final ConnectionFactory cf) + { + factory = cf; + } + + + @Override + protected Connection getConnection() + throws LdapException + { + final Connection conn = factory.getConnection(); + conn.open(); + return conn; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::factory=%s, templateName=%s, baseDn=%s, userFilter=%s, userFilterParameters=%s, " + + "allowMultipleDns=%s, subtreeSearch=%s, derefAliases=%s, referralHandler=%s]", + getClass().getName(), + hashCode(), + factory, + getTemplate().getTemplateName(), + getBaseDn(), + getUserFilter(), + Arrays.toString(getUserFilterParameters()), + getAllowMultipleDns(), + getSubtreeSearch(), + getDerefAliases(), + getReferralHandler()); + } +}
diff --git a/integration/src/test/java/org/ldaptive/velocity/UserContext.java b/integration/src/test/java/org/ldaptive/velocity/UserContext.java new file mode 100644 index 0000000..54120f4 --- /dev/null +++ b/integration/src/test/java/org/ldaptive/velocity/UserContext.java
@@ -0,0 +1,36 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.velocity; + +/** + * Sample context for velocity testing. + * + * @author Middleware Services + */ +public class UserContext +{ + + /** principal name. */ + private final String principal; + + + /** + * Creates a new user context. + * + * @param username that is the principal + */ + public UserContext(final String username) + { + principal = username; + } + + + /** + * Returns the principal. + * + * @return principal + */ + public String getPrincipal() + { + return principal; + } +}
diff --git a/integration/src/test/resources/bind.credential b/integration/src/test/resources/bind.credential new file mode 100644 index 0000000..f8a7a6f --- /dev/null +++ b/integration/src/test/resources/bind.credential
@@ -0,0 +1 @@ +${ldapBindCredential} \ No newline at end of file
diff --git a/integration/src/test/resources/krb5.keytab b/integration/src/test/resources/krb5.keytab new file mode 100644 index 0000000..c800daa --- /dev/null +++ b/integration/src/test/resources/krb5.keytab Binary files differ
diff --git a/integration/src/test/resources/ldap_jaas.config b/integration/src/test/resources/ldap_jaas.config new file mode 100644 index 0000000..404cb28 --- /dev/null +++ b/integration/src/test/resources/ldap_jaas.config
@@ -0,0 +1,268 @@ +ldaptive { + org.ldaptive.jaas.LdapLoginModule required + ldapUrl="${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + bindDn="${ldapBindDn}" + bindCredential="${ldapBindCredential}" + userFilter="(mail={user})" + userRoleAttribute="departmentNumber" + credentialConfig="{trustCertificates=classpath:/ldaptive.trust.crt}"; +}; + +ldaptive-ssl { + org.ldaptive.jaas.LdapLoginModule required + ldapUrl="${ldapSslTestHost}" + baseDn="${ldapBaseDn}" + useSSL="true" + bindDn="${ldapBindDn}" + bindCredential="classpath:/bind.credential" + userFilter="(mail={user})" + userRoleAttribute="departmentNumber" + credentialConfig="org.ldaptive.ssl.X509CredentialConfig{{trustCertificates=file:target/test-classes/ldaptive.trust.crt}}"; +}; + +ldaptive-random { + org.ldaptive.jaas.LdapLoginModule required + ldapUrl="ldap://ed-dne.middleware.vt.edu ${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + connectionStrategy="RANDOM" + connectTimeout="PT1S" + responseTimeout="PT1S" + setLdapDnPrincipal="true" + bindDn="${ldapBindDn}" + bindCredential="${ldapBindCredential}" + userFilter="(mail={user})" + userRoleAttribute="departmentNumber" + credentialConfig="{trustCertificates=file:target/test-classes/ldaptive.trust.crt}"; +}; + +ldaptive-roles { + org.ldaptive.jaas.LdapLoginModule required + storePass="true" + ldapUrl="${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + bindDn="${ldapBindDn}" + bindCredential="${ldapBindCredential}" + userFilter="(mail={user})" + userRoleAttribute="departmentNumber" + credentialConfig="org.ldaptive.ssl.KeyStoreCredentialConfig{{trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS}}"; + org.ldaptive.jaas.LdapRoleAuthorizationModule optional + useFirstPass="true" + ldapUrl="${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + bindDn="${ldapBindDn}" + bindCredential="classpath:/bind.credential" + roleFilter="(mail={user})" + roleAttribute="cn,givenName,sn" + credentialConfig="org.ldaptive.ssl.KeyStoreCredentialConfig{{trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS}}"; +}; + +ldaptive-roles-recursive { + org.ldaptive.jaas.LdapLoginModule required + storePass="true" + ldapUrl="${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + bindDn="${ldapBindDn}" + bindCredential="${ldapBindCredential}" + userFilter="(mail={user})" + userRoleAttribute="departmentNumber" + credentialConfig="org.ldaptive.ssl.KeyStoreCredentialConfig{{trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS}}"; + org.ldaptive.jaas.LdapRoleAuthorizationModule required + useFirstPass="true" + ldapUrl="${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + bindDn="${ldapBindDn}" + bindCredential="${ldapBindCredential}" + roleFilter="(member={dn})" + roleAttribute="uugid" + searchEntryHandlers="org.ldaptive.handler.RecursiveEntryHandler{{searchAttribute=member}{mergeAttributes=uugid}}" + credentialConfig="org.ldaptive.ssl.KeyStoreCredentialConfig{{trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS}}"; +}; + +ldaptive-use-first { + org.ldaptive.jaas.TestLoginModule required; + org.ldaptive.jaas.LdapLoginModule required + useFirstPass="true" + ldapUrl="${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + bindDn="${ldapBindDn}" + bindCredential="${ldapBindCredential}" + userFilter="(mail={user})" + userRoleAttribute="departmentNumber" + defaultRole="test-role1,test-role2" + credentialConfig="org.ldaptive.ssl.KeyStoreCredentialConfig{{trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS}}"; +}; + +ldaptive-try-first { + org.ldaptive.jaas.TestLoginModule required; + org.ldaptive.jaas.LdapLoginModule required + tryFirstPass="true" + storePass="true" + ldapUrl="${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + bindDn="${ldapBindDn}" + bindCredential="classpath:/bind.credential" + userFilter="(mail={user})" + userRoleAttribute="departmentNumber" + credentialConfig="org.ldaptive.ssl.KeyStoreCredentialConfig{{trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS}}"; + org.ldaptive.jaas.LdapRoleAuthorizationModule optional + useFirstPass="true" + ldapUrl="${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + bindDn="${ldapBindDn}" + bindCredential="${ldapBindCredential}" + roleFilter="(mail={user})" + roleAttribute="cn,givenName,sn" + credentialConfig="org.ldaptive.ssl.KeyStoreCredentialConfig{{trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS}}"; +}; + +ldaptive-sufficient { + org.ldaptive.jaas.LdapLoginModule sufficient + ldapUrl="${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + bindDn="${ldapBindDn}" + bindCredential="${ldapBindCredential}" + userFilter="(mail={user})" + userRoleAttribute="departmentNumber" + credentialConfig="org.ldaptive.ssl.KeyStoreCredentialConfig{{trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS}}"; + org.ldaptive.jaas.LdapLoginModule sufficient + ldapUrl="${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + bindDn="${ldapBindDn}" + bindCredential="${ldapBindCredential}" + userFilter="(mail={user})" + userRoleAttribute="departmentNumber" + credentialConfig="org.ldaptive.ssl.KeyStoreCredentialConfig{{trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS}}"; +}; + +ldaptive-roles-only { + org.ldaptive.jaas.LdapRoleAuthorizationModule required + useFirstPass="true" + ldapUrl="${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + bindDn="${ldapBindDn}" + bindCredential="${ldapBindCredential}" + roleFilter="(uid=10)" + roleAttribute="departmentNumber,cn,givenName,sn" + principalGroupName="Principals" + roleGroupName="Roles" + credentialConfig="org.ldaptive.ssl.KeyStoreCredentialConfig{{trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS}}"; +}; + +ldaptive-dn-roles-only { + org.ldaptive.jaas.LdapDnAuthorizationModule required + storePass="true" + ldapUrl="${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + bindDn="${ldapBindDn}" + bindCredential="${ldapBindCredential}" + userFilter="(mail={user})" + credentialConfig="org.ldaptive.ssl.KeyStoreCredentialConfig{{trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS}}"; + org.ldaptive.jaas.LdapRoleAuthorizationModule required + useFirstPass="true" + ldapUrl="${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + bindDn="${ldapBindDn}" + bindCredential="${ldapBindCredential}" + roleFilter="(mail={user})" + roleAttribute="departmentNumber,cn,givenName,sn" + principalGroupName="Principals" + roleGroupName="Roles" + credentialConfig="org.ldaptive.ssl.KeyStoreCredentialConfig{{trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS}}"; +}; + +ldaptive-roles-only-pooled { + org.ldaptive.jaas.LdapRoleAuthorizationModule required + useFirstPass="true" + ldapUrl="${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + bindDn="${ldapBindDn}" + bindCredential="classpath:/bind.credential" + roleFilter="(uid=10)" + roleAttribute="departmentNumber,cn,givenName,sn" + principalGroupName="Principals" + roleGroupName="Roles" + roleResolver="org.ldaptive.jaas.PooledSearchRoleResolver" + cacheId="ldaptive-roles-only-pooled" + credentialConfig="org.ldaptive.ssl.KeyStoreCredentialConfig{{trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS}}"; +}; + +ldaptive-pooled-dnr { + org.ldaptive.jaas.LdapLoginModule required + ldapUrl="${ldapTestHost}" + baseDn="${ldapBaseDn}" + useStartTLS="true" + bindDn="${ldapBindDn}" + bindCredential="${ldapBindCredential}" + userFilter="(&(mail={user})(objectClass={0}))" + userFilterParameters="person" + dnResolver="org.ldaptive.auth.PooledSearchDnResolver" + authenticationHandler="org.ldaptive.auth.PooledBindAuthenticationHandler" + cacheId="ldaptive-pooled-dnr" + credentialConfig="org.ldaptive.ssl.KeyStoreCredentialConfig{{trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS}}"; +}; + +ldaptive-pooled-dnr-spring { + org.ldaptive.jaas.LdapLoginModule required + authenticatorFactory="org.ldaptive.jaas.SpringAuthenticatorFactory"; +}; + +ldaptive-props { + org.ldaptive.jaas.PropsLoginModule required + ldapUrl="${ldapTestHost}" + bindDn="${ldapBindDn}" + bindCredential="${ldapBindCredential}" + connectTimeout="PT8S" + useStartTLS="true" + connectionStrategy="ROUND_ROBIN" + java.naming.authoritative="true" + baseDn="${ldapBaseDn}" + searchScope="OBJECT" + timeLimit="PT5S" + binaryAttributes="jpegPhoto" + searchEntryHandlers="org.ldaptive.handler.RecursiveEntryHandler{{searchAttribute=member}{mergeAttributes=mail,department}},org.ldaptive.handler.MergeAttributeEntryHandler{ }" + authenticationHandler="org.ldaptive.auth.CompareAuthenticationHandler" + dnResolver="org.ldaptive.auth.PooledSearchDnResolver" + minPoolSize="1" + maxPoolSize="3" + validatePeriodically="true" + validator="org.ldaptive.pool.SearchValidator" + pruneStrategy="org.ldaptive.pool.IdlePruneStrategy{{prunePeriod=PT1M}{idleTime=PT2M}" + setLdapDnPrincipal="true" + userFilter="(mail={user})" + userRoleAttribute="departmentNumber" + credentialConfig="{trustCertificates=file:target/test-classes/ldaptive.trust.crt}"; +}; + +com.sun.security.jgss.initiate { + com.sun.security.auth.module.Krb5LoginModule required + doNotPrompt="true" + debug="true" + principal="test3" + useKeyTab="true" + keyTab="target/test-classes/krb5.keytab"; +}; + +GSSAPIBindRequest { + com.sun.security.auth.module.Krb5LoginModule required + doNotPrompt="true" + debug="true" + principal="test3" + useKeyTab="true" + keyTab="target/test-classes/krb5.keytab"; +};
diff --git a/integration/src/test/resources/ldaptive.keystore b/integration/src/test/resources/ldaptive.keystore new file mode 100644 index 0000000..0f47c03 --- /dev/null +++ b/integration/src/test/resources/ldaptive.keystore Binary files differ
diff --git a/integration/src/test/resources/ldaptive.trust.crt b/integration/src/test/resources/ldaptive.trust.crt new file mode 100644 index 0000000..571c8f8 --- /dev/null +++ b/integration/src/test/resources/ldaptive.trust.crt
@@ -0,0 +1,97 @@ +-----BEGIN CERTIFICATE----- +MIIDhzCCAvCgAwIBAgIJAPpeFAkJP5xgMA0GCSqGSIb3DQEBBQUAMIGKMQswCQYD +VQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWExEzARBgNVBAcTCkJsYWNrc2J1cmcx +FjAUBgNVBAoTDVZpcmdpbmlhIFRlY2gxEzARBgNVBAsTCk1pZGRsZXdhcmUxJjAk +BgNVBAMTHWxkYXAtdGVzdC0xLm1pZGRsZXdhcmUudnQuZWR1MB4XDTExMDkyNjE2 +NDczOFoXDTIxMDkyMzE2NDczOFowgYoxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhW +aXJnaW5pYTETMBEGA1UEBxMKQmxhY2tzYnVyZzEWMBQGA1UEChMNVmlyZ2luaWEg +VGVjaDETMBEGA1UECxMKTWlkZGxld2FyZTEmMCQGA1UEAxMdbGRhcC10ZXN0LTEu +bWlkZGxld2FyZS52dC5lZHUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJWf +/vBsfFn6sQo57IHrBzMlPARpDI1DJeqH7zl2UeVzeiZDjGiU4ETSjEsvvQRzLfXZ +IgJEr1IEAzjCX8wKF4svrmkPK3KN6JvdlknM7Thw5p0NzAh2Bq1R1h7+bUvQJGep +aizNM0od/mKrJnOnUCWEgcpG91mWg8b1PphGobeNAgMBAAGjgfIwge8wHQYDVR0O +BBYEFMT2Hkcp6JFq242hWfdMOeT3/hZ1MIG/BgNVHSMEgbcwgbSAFMT2Hkcp6JFq +242hWfdMOeT3/hZ1oYGQpIGNMIGKMQswCQYDVQQGEwJVUzERMA8GA1UECBMIVmly +Z2luaWExEzARBgNVBAcTCkJsYWNrc2J1cmcxFjAUBgNVBAoTDVZpcmdpbmlhIFRl +Y2gxEzARBgNVBAsTCk1pZGRsZXdhcmUxJjAkBgNVBAMTHWxkYXAtdGVzdC0xLm1p +ZGRsZXdhcmUudnQuZWR1ggkA+l4UCQk/nGAwDAYDVR0TBAUwAwEB/zANBgkqhkiG +9w0BAQUFAAOBgQBe0bV5iZyPupNh2zmdH7opuwldz1sxlkRdUQhKSlYsOqgAKDvS +DypmR4mqntAULTFGZIdcQ1W8HJcnRc8KuPfNatAV8A9OqMbtDLnmfWkl33JPiDUd +fIKCXuG4dZ6nn3RbjlKhXzHYADmJzdQNIC3M9eDQBEYmMy8+mV+ErVebBg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDYjCCAkqgAwIBAgIETwyocDANBgkqhkiG9w0BAQUFADBzMRMwEQYKCZImiZPy +LGQBGRYDZWR1MRIwEAYKCZImiZPyLGQBGRYCdnQxCzAJBgNVBAoTAnZ0MRMwEQYD +VQQLEwptaWRkbGV3YXJlMSYwJAYDVQQDEx1sZGFwLXRlc3QtMi5taWRkbGV3YXJl +LnZ0LmVkdTAeFw0xMjAxMTAyMTA2NTZaFw0xNDAxMDkyMTA2NTZaMHMxEzARBgoJ +kiaJk/IsZAEZFgNlZHUxEjAQBgoJkiaJk/IsZAEZFgJ2dDELMAkGA1UEChMCdnQx +EzARBgNVBAsTCm1pZGRsZXdhcmUxJjAkBgNVBAMTHWxkYXAtdGVzdC0yLm1pZGRs +ZXdhcmUudnQuZWR1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm5xR +Lm8+NlxUJSR/2tXZrYW8+9kQSJAR+a/xfcxcWETntbLHE4XZzCde28wDRM5QZo5z +fK91upR3uf4/O+4xmOgiBarP6x1Dtob6JeMeUh6/lSpNuNdkSEbSZ3gS0Vc/OYIr +mcwLQroqNxi3BPVy6ryzGSnd9/PhOf5R2C3mZcBunCQU9GyEexlvQ4d8UkYBNKz5 +sEHl4hcIIirDNTJ27v752rjVWkxPOtF6KUeRsarP4qK2N5nOipAGRrG5nON5ggFl +YC3UNdj3tvoDstxRSgPY9RaHgN5uNrMPmLrbwNY3q9YsiRZ7veiqIIvirGc3CXfc +4tTD5sClKhafguf6BQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQCMvZzuxAVc/G7W +4Ci/Oxa6YAH6Yq745SVuVAjBAhD9wz+Ney4cuFHeyPFnbYWNlikgeWpoglLkEBta +SGxSnVM74ZxGLwpaWOuI5d2tv7bWm318a0kDaTiXRrJ+6tg/rjyQ7xxYlI5+CqO+ +nK+rB4hawRhRvzguItNzKJhnCuydM5lZoXMZAPDxRxDy/2LfokvaCKpNjCYb+nGE +Q66oXAH7AP4OynJ2B5fu4eNgbr8JH4dRH667Y+Pkb03xWabdvp5b+YLmP2iOuq10 +DDm9bpasI5c/SfWdZfWTC3a12WdzZaGBLVxlTRJvegAaktEBXm79OtoSr4TJtNLC +QTHsT7nJ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDhzCCAvCgAwIBAgIJAJSeOqsyYatoMA0GCSqGSIb3DQEBBQUAMIGKMQswCQYD +VQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWExEzARBgNVBAcTCkJsYWNrc2J1cmcx +FjAUBgNVBAoTDVZpcmdpbmlhIFRlY2gxEzARBgNVBAsTCk1pZGRsZXdhcmUxJjAk +BgNVBAMTHWxkYXAtdGVzdC0yLm1pZGRsZXdhcmUudnQuZWR1MB4XDTExMDkzMDIw +MzkzNVoXDTIxMDkyNzIwMzkzNVowgYoxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhW +aXJnaW5pYTETMBEGA1UEBxMKQmxhY2tzYnVyZzEWMBQGA1UEChMNVmlyZ2luaWEg +VGVjaDETMBEGA1UECxMKTWlkZGxld2FyZTEmMCQGA1UEAxMdbGRhcC10ZXN0LTIu +bWlkZGxld2FyZS52dC5lZHUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPXl +XtrOZNiN8pxBZ6HzCOzRd1dsKYhzWAlcL8lhXwg0ScGoNkaEyiTWglCqFdCmiV4q +MdrA7SCTQms6w9Yxxs3jfRYAkWb7tlN2mt0gQxUPzR8cYqLDUniD+4H6DtuHtlyd +2U/d/FPxMDNvnuD0xytmTxOJrbxf6JwNom6lexJ7AgMBAAGjgfIwge8wHQYDVR0O +BBYEFA73flJViZzW7m/DnG8+kit9/bX3MIG/BgNVHSMEgbcwgbSAFA73flJViZzW +7m/DnG8+kit9/bX3oYGQpIGNMIGKMQswCQYDVQQGEwJVUzERMA8GA1UECBMIVmly +Z2luaWExEzARBgNVBAcTCkJsYWNrc2J1cmcxFjAUBgNVBAoTDVZpcmdpbmlhIFRl +Y2gxEzARBgNVBAsTCk1pZGRsZXdhcmUxJjAkBgNVBAMTHWxkYXAtdGVzdC0yLm1p +ZGRsZXdhcmUudnQuZWR1ggkAlJ46qzJhq2gwDAYDVR0TBAUwAwEB/zANBgkqhkiG +9w0BAQUFAAOBgQCEIP+/OUzjtX+obLt60TEzjRUl/+zpw+0lmiSh+4YjIW/Hg+bF +MD/64LhCDgdLgUsrDPRhySLRdedFxjfV8FyZMO7YuXQeVp9F274mxKh+IrasdN2A +a4NicL4X7TFCjZ7yzTfcolWpezBEgSo5fQJzQu6NtwBWFMWyXrMdWvtgaQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC+TCCAeGgAwIBAgIQap33EU39DI5Mq0kKqi3UqDANBgkqhkiG9w0BAQUFADAk +MSIwIAYDVQQDExltaWRkbGV3YXJlLXRlc3QuY2MudnQuZWR1MB4XDTEyMDIxNDIx +MDMxOVoXDTIyMDIxMTIxMDMxOVowJDEiMCAGA1UEAxMZbWlkZGxld2FyZS10ZXN0 +LmNjLnZ0LmVkdTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN0KHXSC +ON/ua9WkeZdPavD89fhSW2O/VP5yjPxNRFvKSvqnCDBaSlv3LmAFpk2JB2C38/8I +5jl+fNBME0cREFBm8oBVeX4d9hURyOhcQD2Avokq2TjPB3NdVSGOF9qfEyg+jd/Q +mj1htx2KbFSdi1v3g24ENLYsJlmnwDirtaI1Q1IgjIsdDV3WgsgiDj44cKnsOCeX +xKaBmyjZMxoPdkMiHe/fn6/5xRW7PxypFdsLaJksN5aLGllNZ/p6TgEgO5JLR/SH +Pq15MeNA2/nc6NEDs+0H3sYs0g661DKxgLNJstGsuJynLZ+yp6JTbmVPzuJA3Vy9 +PSxurFarFxz5R9ECAwEAAaMnMCUwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYDVR0P +BAcDBQCwAAAAMA0GCSqGSIb3DQEBBQUAA4IBAQBoj9bTke/aC5VIspIsEDN+HgKa ++orB5VP0v/RZab82eC9cXBj8y1P330f+panhu5iJJouXOYTyIx6QIxz4eHArw8RZ +l+3lNAFYEpWAIKReais4TJcQuU6sddjNBksCvo6FYU4sF8Pk4Ip22ZUO5X8YTcks +hQCOdGCyF3JCh42SWoRH6wxXc/BU13jYgBfXja2YFsADuT1UVlKJXKxtL58XiVrC +SyQXsmy4lryzNa4s9h5yfM3Hsrgyg9XTcKRyZe70IhJizs6HdqddpjPOw7wmf65m +vx/DLCgVsnlMSAkVHSScQZukcVt9LfzFz9DF5IaVze34pnVpsNi+JHaVyv71 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICjjCCAfegAwIBAgIFAJneB9AwDQYJKoZIhvcNAQEFBQAwgYoxJjAkBgNVBAMT +HWxkYXAtdGVzdC0zLm1pZGRsZXdhcmUudnQuZWR1MRMwEQYDVQQLEwpNaWRkbGV3 +YXJlMRYwFAYDVQQKEw1WaXJnaW5pYSBUZWNoMRMwEQYDVQQHEwpCbGFja3NidXJn +MREwDwYDVQQIEwhWaXJnaW5pYTELMAkGA1UEBhMCVVMwHhcNMTIxMTIwMTcwNTQz +WhcNMTQxMTIwMTcwNTQzWjCBijEmMCQGA1UEAxMdbGRhcC10ZXN0LTMubWlkZGxl +d2FyZS52dC5lZHUxEzARBgNVBAsTCk1pZGRsZXdhcmUxFjAUBgNVBAoTDVZpcmdp +bmlhIFRlY2gxEzARBgNVBAcTCkJsYWNrc2J1cmcxETAPBgNVBAgTCFZpcmdpbmlh +MQswCQYDVQQGEwJVUzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAl13KcfcN +M8OUzyyZjwzyli/DdcCDR29R4woSn8v0kiLFi/vM6OCO9VYXcJp5YqTQ7P/JtFKz +/D98RJrnDEp0uaSEv6KWXOloJ4xJvcS+snB1DALPEJrAHzBtOQbbps1iisXHqA0T +RmlS1O33AGR6J+PP+f0+THobS5Ud57Xmg5ECAwEAATANBgkqhkiG9w0BAQUFAAOB +gQBJkrCSA9/V6KwCrAetvXTqNt9dCAEwMs0gyzwigHxVxanXIVSn+171fRHeolVc +ykRT/CadTHXpJ7dr355s8UwYsbL84LdZrhBIBa/emprbHxYTOqrw5coQSCJhkVRS +Xy1fhtxTC5pZk5XTNWw3lK493neCD0CZiB8PQ/iRZiULDg== +-----END CERTIFICATE-----
diff --git a/integration/src/test/resources/ldaptive.truststore b/integration/src/test/resources/ldaptive.truststore new file mode 100644 index 0000000..9043ca0 --- /dev/null +++ b/integration/src/test/resources/ldaptive.truststore Binary files differ
diff --git a/integration/src/test/resources/log4j.xml b/integration/src/test/resources/log4j.xml new file mode 100644 index 0000000..4450834 --- /dev/null +++ b/integration/src/test/resources/log4j.xml
@@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> + +<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" + debug="false"> + + <appender name="CONSOLE" + class="org.apache.log4j.ConsoleAppender"> + <param name="Target" value="System.out"/> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%X{host} %d %-5p [%c] %m%n"/> + </layout> + </appender> + + <category name="org.ldaptive" + additivity="false"> + <priority value="INFO"/> + <appender-ref ref="CONSOLE"/> + </category> + + <category name="org.ldaptive.ad" + additivity="false"> + <priority value="INFO"/> + <appender-ref ref="CONSOLE"/> + </category> + + <category name="org.ldaptive.async" + additivity="false"> + <priority value="INFO"/> + <appender-ref ref="CONSOLE"/> + </category> + + <category name="org.ldaptive.auth" + additivity="false"> + <priority value="INFO"/> + <appender-ref ref="CONSOLE"/> + </category> + + <category name="org.ldaptive.beans" + additivity="false"> + <priority value="INFO"/> + <appender-ref ref="CONSOLE"/> + </category> + + <category name="org.ldaptive.jaas" + additivity="false"> + <priority value="INFO"/> + <appender-ref ref="CONSOLE"/> + </category> + + <category name="org.ldaptive.pool" + additivity="false"> + <priority value="INFO"/> + <appender-ref ref="CONSOLE"/> + </category> + + <category name="org.ldaptive.props" + additivity="false"> + <priority value="INFO"/> + <appender-ref ref="CONSOLE"/> + </category> + + <category name="org.ldaptive.ssl" + additivity="false"> + <priority value="INFO"/> + <appender-ref ref="CONSOLE"/> + </category> + + <category name="org.ldaptive.provider" + additivity="false"> + <priority value="INFO"/> + <appender-ref ref="CONSOLE"/> + </category> + + <category name="org.springframework" + additivity="false"> + <priority value="ERROR"/> + <appender-ref ref="CONSOLE"/> + </category> + + <root> + <priority value="INFO"/> + <appender-ref ref="CONSOLE"/> + </root> + +</log4j:configuration>
diff --git a/integration/src/test/resources/org/ldaptive/binaryResults.ldif b/integration/src/test/resources/org/ldaptive/binaryResults.ldif new file mode 100644 index 0000000..a5db964 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/binaryResults.ldif
@@ -0,0 +1,4 @@ +dn: cn=John Adams,${ldapBaseDn} +mail: jadams@ldaptive.org +uid: 2 +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/createGroupEntry-2.ldif b/integration/src/test/resources/org/ldaptive/createGroupEntry-2.ldif new file mode 100644 index 0000000..5d9c094 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createGroupEntry-2.ldif
@@ -0,0 +1,8 @@ +dn: cn=Group 2,${ldapBaseDn} +cn: Group 2 +contactPerson: cn=John Adams,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +objectClass: virginiaTechGroup +objectClass: top +uid: 2002 +uugid: group2
diff --git a/integration/src/test/resources/org/ldaptive/createGroupEntry-3.ldif b/integration/src/test/resources/org/ldaptive/createGroupEntry-3.ldif new file mode 100644 index 0000000..7e8d163 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createGroupEntry-3.ldif
@@ -0,0 +1,8 @@ +dn: cn=Group 3,${ldapBaseDn} +cn: Group 3 +contactPerson: cn=John Adams,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +objectClass: virginiaTechGroup +objectClass: top +uid: 2003 +uugid: group3
diff --git a/integration/src/test/resources/org/ldaptive/createGroupEntry-4.ldif b/integration/src/test/resources/org/ldaptive/createGroupEntry-4.ldif new file mode 100644 index 0000000..afec4cf --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createGroupEntry-4.ldif
@@ -0,0 +1,8 @@ +dn: cn=Group 4,${ldapBaseDn} +cn: Group 4 +contactPerson: cn=John Adams,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +objectClass: virginiaTechGroup +objectClass: top +uid: 2004 +uugid: group4
diff --git a/integration/src/test/resources/org/ldaptive/createGroupEntry-5.ldif b/integration/src/test/resources/org/ldaptive/createGroupEntry-5.ldif new file mode 100644 index 0000000..acd82ee --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createGroupEntry-5.ldif
@@ -0,0 +1,8 @@ +dn: cn=Group 5,${ldapBaseDn} +cn: Group 5 +contactPerson: cn=John Adams,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +objectClass: virginiaTechGroup +objectClass: top +uid: 2005 +uugid: group5
diff --git a/integration/src/test/resources/org/ldaptive/createGroupEntry-6.ldif b/integration/src/test/resources/org/ldaptive/createGroupEntry-6.ldif new file mode 100644 index 0000000..ac2e6be --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createGroupEntry-6.ldif
@@ -0,0 +1,8 @@ +dn: cn=Group 6,${ldapBaseDn} +cn: Group 6 +contactPerson: cn=John Tyler,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +objectClass: virginiaTechGroup +objectClass: top +uid: 2006 +uugid: group6
diff --git a/integration/src/test/resources/org/ldaptive/createGroupEntry-7.ldif b/integration/src/test/resources/org/ldaptive/createGroupEntry-7.ldif new file mode 100644 index 0000000..2292443 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createGroupEntry-7.ldif
@@ -0,0 +1,8 @@ +dn: cn=Group 7,${ldapBaseDn} +cn: Group 7 +contactPerson: cn=John Tyler,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +objectClass: virginiaTechGroup +objectClass: top +uid: 2007 +uugid: group7
diff --git a/integration/src/test/resources/org/ldaptive/createGroupEntry-8.ldif b/integration/src/test/resources/org/ldaptive/createGroupEntry-8.ldif new file mode 100644 index 0000000..92fc6db --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createGroupEntry-8.ldif
@@ -0,0 +1,8 @@ +dn: cn=Group 8,${ldapBaseDn} +cn: Group 8 +contactPerson: cn=John Tyler,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +objectClass: virginiaTechGroup +objectClass: top +uid: 2008 +uugid: group8
diff --git a/integration/src/test/resources/org/ldaptive/createGroupEntry-9.ldif b/integration/src/test/resources/org/ldaptive/createGroupEntry-9.ldif new file mode 100644 index 0000000..4010ca0 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createGroupEntry-9.ldif
@@ -0,0 +1,8 @@ +dn: cn=Group 9,${ldapBaseDn} +cn: Group 9 +contactPerson: cn=John Tyler,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +objectClass: virginiaTechGroup +objectClass: top +uid: 2009 +uugid: group9
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-10.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-10.ldif new file mode 100644 index 0000000..f9020ed --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-10.ldif
@@ -0,0 +1,15 @@ +dn: cn=John Tyler,${ldapBaseDn} +cn: John Tyler +departmentNumber: 0830 +displayName: John Tyler +givenName: John +initials: JT +mail: jtyler@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Tyler +uid: 10 +userPassword: {SHA}9o7EHN4W9rgG17BMcFdmtzGPux0= +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-11.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-11.ldif new file mode 100644 index 0000000..e7ae056 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-11.ldif
@@ -0,0 +1,15 @@ +dn: cn=James K Polk,${ldapBaseDn} +cn: James K Polk +departmentNumber: 0831 +displayName: James K Polk +givenName: James +initials: JKP +mail: jkpolk@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Polk +uid: 11 +userPassword: {SHA}3fbJod9NV67wQ8qGEKWg3qCXrws= +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-12.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-12.ldif new file mode 100644 index 0000000..b5eb2e3 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-12.ldif
@@ -0,0 +1,15 @@ +dn: cn=Zachary Taylor,${ldapBaseDn} +cn: Zachary Taylor +departmentNumber: 0832 +displayName: Zachary Taylor +givenName: Zachary +initials: ZT +mail: ztaylor@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Taylor +uid: 12 +userPassword: {SHA}EMKPnPBmhZXUXBCQp7Sirpjt+lg= +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-13.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-13.ldif new file mode 100644 index 0000000..58cb1f2 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-13.ldif
@@ -0,0 +1,15 @@ +dn: cn=Millard Fillmore,${ldapBaseDn} +cn: Millard Fillmore +departmentNumber: 0833 +displayName: Millard Fillmore +givenName: Millard +initials: MF +mail: mfillmore@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Fillmore +uid: 13 +userPassword: {SHA}1QWDIobiwdKDnzlN6Js6+Nw/jB8= +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-14.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-14.ldif new file mode 100644 index 0000000..9832159 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-14.ldif
@@ -0,0 +1,15 @@ +dn: cn=Franklin Pierce,${ldapBaseDn} +cn: Franklin Pierce +departmentNumber: 0834 +displayName: Franklin Pierce +givenName: Franklin +initials: FP +mail: fpierce@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Pierce +uid: 14 +userPassword: {SHA}ifdHvO03qdiu5cdC4q6jcyeOsp8= +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-15.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-15.ldif new file mode 100644 index 0000000..9d2472c --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-15.ldif
@@ -0,0 +1,15 @@ +dn: cn=James Buchanan,${ldapBaseDn} +cn: James Buchanan +departmentNumber: 0835 +displayName: James Buchanan +givenName: James +initials: JB +mail: jbuchanan@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Buchanan +uid: 15 +userPassword: {SHA}vQIeIcFGKPqpTUqqxIyGnWtdDsM= +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-16.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-16.ldif new file mode 100644 index 0000000..bb5cf59 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-16.ldif
@@ -0,0 +1,14 @@ +dn: cn=Abraham Lincoln,${ldapBaseDn} +cn: Abraham Lincoln +departmentNumber: 0836 +displayName: Abraham Lincoln +givenName: Abraham +initials: AL +mail: alincoln@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Lincoln +uid: 16 +userPassword: {SHA}Ped45RXnBxFLYi52mjCNGi+EBSs=
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-17.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-17.ldif new file mode 100644 index 0000000..2a27e1b --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-17.ldif
@@ -0,0 +1,13 @@ +dn: cn=Andrew Johnson,${ldapBaseDn} +cn: Andrew Johnson +departmentNumber: 0837 +displayName: Andrew Johnson +givenName: Andrew +initials: AJ +mail: ajohnson@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Johnson +uid: 17
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-18.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-18.ldif new file mode 100644 index 0000000..3aaa258 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-18.ldif
@@ -0,0 +1,13 @@ +dn: cn=Ulysses Grant,${ldapBaseDn} +cn: Ulysses Grant +departmentNumber: 0838 +displayName: Ulysses S. Grant +givenName: Ulysses +initials: USG +mail: usgrant@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Grant +uid: 18
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-19.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-19.ldif new file mode 100644 index 0000000..e068d4b --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-19.ldif
@@ -0,0 +1,13 @@ +dn: cn=Rutherford Hayes,${ldapBaseDn} +cn: Rutherford Hayes +departmentNumber: 0839 +displayName: Rutherford B. Hayes +givenName: Rutherford +initials: RBH +mail: rbhayes@vldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Hayes +uid: 19
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-2.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-2.ldif new file mode 100644 index 0000000..58dc4ab --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-2.ldif
@@ -0,0 +1,16 @@ +dn: cn=John Adams,${ldapBaseDn} +cn: John Adams +departmentNumber: 0822 +displayName: John Adams +givenName: John +initials: JA +mail: jadams@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Adams +uid: 2 +userPassword: {SHA}KqYKj/f81HPTIeAUav2eJt85UUc= +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k= +userCertificate;binary:: MIIC7zCCAligAwIBAgIQCBdZgzdx+yX5+jSRD50SJzANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIElzc3VpbmcgQ0EwHhcNMDkwNjI5MTg0NTQ2WhcNMTAwNjI5MTg0NTQ2WjBZMQ8wDQYDVQQEEwZGaXNoZXIxDzANBgNVBCoTBkRhbmllbDEWMBQGA1UEAxMNRGFuaWVsIEZpc2hlcjEdMBsGCSqGSIb3DQEJARYOZGZpc2hlckB2dC5lZHUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbsC0qvAkU3oWwz39oq/ur/mhHZ+KNODug+pAsg0ZZbSnxWD9EVBiMerevD5bJ0weTWR2dSVJqkxoJ2pZCHUpCt8CBE8LDsLJc+qAHOOfTuEywulc1ifSbevam3ehAvRg9wjmmKcm7Hwz9LniIZefxh3Tr9YwHTbw9YRaVC7nVkRu+eMY+T1+Uz3mLmCQI8YsOYCvZ1C+a1Dh9EA4Ms+EisH3Mn4dA+6i8L0nTbyUnz0kgKUTPDrkPhXsNRv1KbSmWBlShhRWXqd7qo0fAqKo5h+j5wppVabINtYdv73OShfzcJKf1qrmZqL0JFsT6fUWE12kgPT7tpMxMgaUR2I7lAgMBAAGjKzApMBkGA1UdEQQSMBCBDmRmaXNoZXJAdnQuZWR1MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEFBQADgYEAUhjHo5Mp4HiMooqINVEeJcijTSf8LpWgmNTBteVPRsQfXv4o0/684ccmWO46aNy23uDt+qEU6DplKJmILwievVMPB/Fkc3rqSSG+BLGRHCKE4z2ypzOiZ9TRO/Ckux4dQCVnXCQ6tDNHofeph9zTBHFEIgYtC3YfHmCdvayJKy0=
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-20.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-20.ldif new file mode 100644 index 0000000..e4c3dd4 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-20.ldif
@@ -0,0 +1,13 @@ +dn: cn=James Garfield,${ldapBaseDn} +cn: James Garfield +departmentNumber: 0840 +displayName: James Garfield +givenName: James +initials: JG +mail: jgarfield@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Garfield +uid: 20
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-21.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-21.ldif new file mode 100644 index 0000000..3baec31 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-21.ldif
@@ -0,0 +1,13 @@ +dn: cn=Chester Arthur,${ldapBaseDn} +cn: Chester Arthur +departmentNumber: 0841 +displayName: Chester A. Arthur +givenName: Chester +initials: CAA +mail: caarthur@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Arthur +uid: 21
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-22.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-22.ldif new file mode 100644 index 0000000..da791a4 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-22.ldif
@@ -0,0 +1,13 @@ +dn: cn=Grover Cleveland,${ldapBaseDn} +cn: Grover Cleveland +departmentNumber: 0842 +displayName: Grover Cleveland +givenName: Grover +initials: GC +mail: gcleveland@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Cleveland +uid: 22
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-23.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-23.ldif new file mode 100644 index 0000000..c05384d --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-23.ldif
@@ -0,0 +1,13 @@ +dn: cn=Benjamin Harrison,${ldapBaseDn} +cn: Benjamin Harrison +departmentNumber: 0843 +displayName: Benjamin Harrison +givenName: Benjamin +initials: BH +mail: bharrison@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Harrison +uid: 23
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-25.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-25.ldif new file mode 100644 index 0000000..e33bf27 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-25.ldif
@@ -0,0 +1,13 @@ +dn: cn=William McKinley,${ldapBaseDn} +cn: William McKinley +departmentNumber: 0845 +displayName: William McKinley +givenName: William +initials: WM +mail: wmckinley@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: McKinley +uid: 25
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-26.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-26.ldif new file mode 100644 index 0000000..b7b6a3f --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-26.ldif
@@ -0,0 +1,13 @@ +dn: cn=Theodore Roosevelt,${ldapBaseDn} +cn: Theodore Roosevelt +departmentNumber: 0846 +displayName: Theodore Roosevelt +givenName: Theodore +initials: TR +mail: troosevelt@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Roosevelt +uid: 26
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-27.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-27.ldif new file mode 100644 index 0000000..b082b7c --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-27.ldif
@@ -0,0 +1,13 @@ +dn: cn=William Howard Taft,${ldapBaseDn} +cn: William Howard Taft +departmentNumber: 0847 +displayName: William Taft +givenName: William +initials: WHT +mail: whtaft@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Taft +uid: 27
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-28.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-28.ldif new file mode 100644 index 0000000..f5868ac --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-28.ldif
@@ -0,0 +1,13 @@ +dn: cn=Woodrow Wilson,${ldapBaseDn} +cn: Woodrow Wilson +departmentNumber: 0848 +displayName: Woodrow Wilson +givenName: Woodrow +initials: WW +mail: wwilson@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Wilson +uid: 28
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-29.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-29.ldif new file mode 100644 index 0000000..00da886 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-29.ldif
@@ -0,0 +1,13 @@ +dn: cn=Warren Harding,${ldapBaseDn} +cn: Warren Harding +departmentNumber: 0849 +displayName: Warren G. Harding +givenName: Warren +initials: WGH +mail: wgharding@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Harding +uid: 29
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-3.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-3.ldif new file mode 100644 index 0000000..0890d0d --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-3.ldif
@@ -0,0 +1,15 @@ +dn: cn=Thomas Jefferson,${ldapBaseDn} +cn: Thomas Jefferson +departmentNumber: 0823 +displayName: Thomas Jefferson +givenName: Thomas +initials: TJ +mail: tjefferson@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Jefferson +uid: 3 +userPassword: {SHA}ERnP037iRzV+A0oI2ETuol9v0g8= +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-30.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-30.ldif new file mode 100644 index 0000000..7fbc00e --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-30.ldif
@@ -0,0 +1,13 @@ +dn: cn=Calvin Coolidge,${ldapBaseDn} +cn: Calvin Coolidge +departmentNumber: 0850 +displayName: Calvin Coolidge +givenName: Calvin +initials: CC +mail: ccoolidge@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Coolidge +uid: 30
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-31.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-31.ldif new file mode 100644 index 0000000..26a3a1b --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-31.ldif
@@ -0,0 +1,13 @@ +dn: cn=Herbert Hoover,${ldapBaseDn} +cn: Herbert Hoover +departmentNumber: 0851 +displayName: Herbert Hoover +givenName: Herbert +initials: HH +mail: hhoover@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Hoover +uid: 31
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-32.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-32.ldif new file mode 100644 index 0000000..b38c1f4 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-32.ldif
@@ -0,0 +1,14 @@ +dn: cn=Franklin Roosevelt,${ldapBaseDn} +cn: Franklin Roosevelt +departmentNumber: 0852 +displayName: Franklin Roosevelt +givenName: Franklin +initials: FR +mail: froosevelt@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Roosevelt +uid: 32 +userPassword: {SHA}Tg9EGzPtWfabIHVgTPdPC03F+Pc=
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-4.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-4.ldif new file mode 100644 index 0000000..d787373 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-4.ldif
@@ -0,0 +1,15 @@ +dn: cn=James Madison,${ldapBaseDn} +cn: James Madison +departmentNumber: 0824 +displayName: James Madison +givenName: James +initials: JM +mail: jmadison@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Madison +uid: 4 +userPassword: {SHA}oddYTarKRzjUma1wgohrARFyddg= +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-5.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-5.ldif new file mode 100644 index 0000000..b32992f --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-5.ldif
@@ -0,0 +1,15 @@ +dn: cn=James Monroe,${ldapBaseDn} +cn: James Monroe +departmentNumber: 0825 +displayName: James Monroe +givenName: James +initials: JM +mail: jmonroe@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Monroe +uid: 5 +userPassword: {SHA}7bqVXQ6hX9709hcm75flr1B0MMA= +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-6.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-6.ldif new file mode 100644 index 0000000..6868331 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-6.ldif
@@ -0,0 +1,15 @@ +dn: cn=John Quincy Adams,${ldapBaseDn} +cn: John Quincy Adams +departmentNumber: 0826 +displayName: John Q Adams +givenName: John +initials: JQA +mail: jqadams@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Adams +uid: 6 +userPassword: {SHA}bXSeijeKNM8ZtMAveVX1f9uhMKU= +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-7.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-7.ldif new file mode 100644 index 0000000..ddab344 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-7.ldif
@@ -0,0 +1,15 @@ +dn: cn=Andrew Jackson,${ldapBaseDn} +cn: Andrew Jackson +departmentNumber: 0827 +displayName: Andrew Jackson +givenName: Andrew +initials: AJ +mail: ajackson@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Jackson +uid: 7 +userPassword: {SHA}MwumDiQxhun6JY+Zkth2bqboi8E= +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-8.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-8.ldif new file mode 100644 index 0000000..53441f4 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-8.ldif
@@ -0,0 +1,15 @@ +dn: cn=Martin Van Buren,${ldapBaseDn} +cn: Martin Van Buren +departmentNumber: 0828 +displayName: Martin V Buren +givenName: Martin +initials: MVB +mail: mvburen@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Buren +uid: 8 +userPassword: {SHA}qNu/pBzsgz+N1Cvk0fqaExQshcI= +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/createLdapEntry-9.ldif b/integration/src/test/resources/org/ldaptive/createLdapEntry-9.ldif new file mode 100644 index 0000000..c6106ff --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/createLdapEntry-9.ldif
@@ -0,0 +1,15 @@ +dn: cn=William Henry Harrison,${ldapBaseDn} +cn: William Henry Harrison +departmentNumber: 0829 +displayName: William H Harrison +givenName: William +initials: WHH +mail: whharrison@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Harrison +uid: 9 +userPassword: {SHA}AksBkW4+rsZqLEtvxYexcF8ab8g= +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/dfisher.dsmlv1 b/integration/src/test/resources/org/ldaptive/dfisher.dsmlv1 new file mode 100644 index 0000000..25f408a --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/dfisher.dsmlv1
@@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="UTF-8"?> +<dsml:dsml xmlns:dsml="http://www.dsml.org/DSML"> + <dsml:directory-entries> + <dsml:entry dn="uid=818037,ou=People,dc=vt,dc=edu"> + <dsml:objectclass> + <dsml:oc-value>virginiaTechPerson</dsml:oc-value> + </dsml:objectclass> + <dsml:attr name="title"> + <dsml:value>Project Manager, Middleware</dsml:value> + </dsml:attr> + <dsml:attr name="uid"> + <dsml:value>818037</dsml:value> + </dsml:attr> + <dsml:attr name="authId"> + <dsml:value>dfisher</dsml:value> + </dsml:attr> + <dsml:attr name="mail"> + <dsml:value>dfisher@vt.edu</dsml:value> + </dsml:attr> + <dsml:attr name="instantMessagingID"> + <dsml:value>Yahoo!:dfish3r</dsml:value> + <dsml:value>Google:dfisher@gmail.com</dsml:value> + <dsml:value>Virginia Tech:dfisher@im.vt.edu</dsml:value> + <dsml:value>ICQ:8168282</dsml:value> + </dsml:attr> + <dsml:attr name="department"> + <dsml:value>MiddleWare</dsml:value> + </dsml:attr> + <dsml:attr name="sn"> + <dsml:value>Fisher</dsml:value> + </dsml:attr> + <dsml:attr name="userCertificate;binary"> + <dsml:value encoding="base64">MIIC7zCCAligAwIBAgIQCBdZgzdx+yX5+jSRD50SJzANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIElzc3VpbmcgQ0EwHhcNMDkwNjI5MTg0NTQ2WhcNMTAwNjI5MTg0NTQ2WjBZMQ8wDQYDVQQEEwZGaXNoZXIxDzANBgNVBCoTBkRhbmllbDEWMBQGA1UEAxMNRGFuaWVsIEZpc2hlcjEdMBsGCSqGSIb3DQEJARYOZGZpc2hlckB2dC5lZHUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbsC0qvAkU3oWwz39oq/ur/mhHZ+KNODug+pAsg0ZZbSnxWD9EVBiMerevD5bJ0weTWR2dSVJqkxoJ2pZCHUpCt8CBE8LDsLJc+qAHOOfTuEywulc1ifSbevam3ehAvRg9wjmmKcm7Hwz9LniIZefxh3Tr9YwHTbw9YRaVC7nVkRu+eMY+T1+Uz3mLmCQI8YsOYCvZ1C+a1Dh9EA4Ms+EisH3Mn4dA+6i8L0nTbyUnz0kgKUTPDrkPhXsNRv1KbSmWBlShhRWXqd7qo0fAqKo5h+j5wppVabINtYdv73OShfzcJKf1qrmZqL0JFsT6fUWE12kgPT7tpMxMgaUR2I7lAgMBAAGjKzApMBkGA1UdEQQSMBCBDmRmaXNoZXJAdnQuZWR1MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEFBQADgYEAUhjHo5Mp4HiMooqINVEeJcijTSf8LpWgmNTBteVPRsQfXv4o0/684ccmWO46aNy23uDt+qEU6DplKJmILwievVMPB/Fkc3rqSSG+BLGRHCKE4z2ypzOiZ9TRO/Ckux4dQCVnXCQ6tDNHofeph9zTBHFEIgYtC3YfHmCdvayJKy0=</dsml:value> + </dsml:attr> + <dsml:attr name="cn"> + <dsml:value>Daniel W Fisher</dsml:value> + </dsml:attr> + <dsml:attr name="mailStop"> + <dsml:value>0479</dsml:value> + </dsml:attr> + <dsml:attr name="suppressDisplay"> + <dsml:value>false</dsml:value> + </dsml:attr> + <dsml:attr name="suppressedAttribute"> + <dsml:value>localPostalAddress</dsml:value> + <dsml:value>homePostalAddress</dsml:value> + <dsml:value>homePhone</dsml:value> + <dsml:value>localPhone</dsml:value> + </dsml:attr> + <dsml:attr name="postalAddress"> + <dsml:value>SETI-Middleware$1700 Pratt Drive$Blacksburg, VA 24060</dsml:value> + </dsml:attr> + <dsml:attr name="departmentNumber"> + <dsml:value>066103</dsml:value> + </dsml:attr> + <dsml:attr name="uupid"> + <dsml:value>dfisher</dsml:value> + </dsml:attr> + <dsml:attr name="middleName"> + <dsml:value>W</dsml:value> + </dsml:attr> + <dsml:attr name="givenName"> + <dsml:value>Daniel</dsml:value> + </dsml:attr> + <dsml:attr name="telephoneNumber"> + <dsml:value>5402312096</dsml:value> + </dsml:attr> + <dsml:attr name="displayName"> + <dsml:value>Daniel W Fisher</dsml:value> + </dsml:attr> + </dsml:entry> + </dsml:directory-entries> +</dsml:dsml>
diff --git a/integration/src/test/resources/org/ldaptive/dfisher.ldif b/integration/src/test/resources/org/ldaptive/dfisher.ldif new file mode 100644 index 0000000..8d020bb --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/dfisher.ldif
@@ -0,0 +1,28 @@ +dn: uid=818037,ou=People,dc=vt,dc=edu +middleName: W +uid: 818037 +mail: dfisher@vt.edu +sn: Fisher +instantMessagingID: Yahoo!:dfish3r +instantMessagingID: Google:dfisher@gmail.com +instantMessagingID: Virginia Tech:dfisher@im.vt.edu +instantMessagingID: ICQ:8168282 +department: MiddleWare +objectClass: virginiaTechPerson +suppressedAttribute: localPostalAddress +suppressedAttribute: homePostalAddress +suppressedAttribute: homePhone +suppressedAttribute: localPhone +givenName: Daniel +title: Project Manager, Middleware +mailStop: 0479 +departmentNumber: 066103 +cn: Daniel W Fisher +authId: dfisher +telephoneNumber: 5402312096 +userCertificate;binary:: MIIC7zCCAligAwIBAgIQCBdZgzdx+yX5+jSRD50SJzANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIElzc3VpbmcgQ0EwHhcNMDkwNjI5MTg0NTQ2WhcNMTAwNjI5MTg0NTQ2WjBZMQ8wDQYDVQQEEwZGaXNoZXIxDzANBgNVBCoTBkRhbmllbDEWMBQGA1UEAxMNRGFuaWVsIEZpc2hlcjEdMBsGCSqGSIb3DQEJARYOZGZpc2hlckB2dC5lZHUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbsC0qvAkU3oWwz39oq/ur/mhHZ+KNODug+pAsg0ZZbSnxWD9EVBiMerevD5bJ0weTWR2dSVJqkxoJ2pZCHUpCt8CBE8LDsLJc+qAHOOfTuEywulc1ifSbevam3ehAvRg9wjmmKcm7Hwz9LniIZefxh3Tr9YwHTbw9YRaVC7nVkRu+eMY+T1+Uz3mLmCQI8YsOYCvZ1C+a1Dh9EA4Ms+EisH3Mn4dA+6i8L0nTbyUnz0kgKUTPDrkPhXsNRv1KbSmWBlShhRWXqd7qo0fAqKo5h+j5wppVabINtYdv73OShfzcJKf1qrmZqL0JFsT6fUWE12kgPT7tpMxMgaUR2I7lAgMBAAGjKzApMBkGA1UdEQQSMBCBDmRmaXNoZXJAdnQuZWR1MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEFBQADgYEAUhjHo5Mp4HiMooqINVEeJcijTSf8LpWgmNTBteVPRsQfXv4o0/684ccmWO46aNy23uDt+qEU6DplKJmILwievVMPB/Fkc3rqSSG+BLGRHCKE4z2ypzOiZ9TRO/Ckux4dQCVnXCQ6tDNHofeph9zTBHFEIgYtC3YfHmCdvayJKy0= +postalAddress: SETI-Middleware$1700 Pratt Drive$Blacksburg, VA 24060 +displayName: Daniel W Fisher +suppressDisplay: false +uupid: dfisher +
diff --git a/integration/src/test/resources/org/ldaptive/dfisher.sorted.dsmlv1 b/integration/src/test/resources/org/ldaptive/dfisher.sorted.dsmlv1 new file mode 100644 index 0000000..83c7e95 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/dfisher.sorted.dsmlv1
@@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="UTF-8"?> +<dsml:dsml xmlns:dsml="http://www.dsml.org/DSML"> + <dsml:directory-entries> + <dsml:entry dn="uid=818037,ou=People,dc=vt,dc=edu"> + <dsml:objectclass> + <dsml:oc-value>virginiaTechPerson</dsml:oc-value> + </dsml:objectclass> + <dsml:attr name="authId"> + <dsml:value>dfisher</dsml:value> + </dsml:attr> + <dsml:attr name="cn"> + <dsml:value>Daniel W Fisher</dsml:value> + </dsml:attr> + <dsml:attr name="department"> + <dsml:value>MiddleWare</dsml:value> + </dsml:attr> + <dsml:attr name="departmentNumber"> + <dsml:value>066103</dsml:value> + </dsml:attr> + <dsml:attr name="displayName"> + <dsml:value>Daniel W Fisher</dsml:value> + </dsml:attr> + <dsml:attr name="givenName"> + <dsml:value>Daniel</dsml:value> + </dsml:attr> + <dsml:attr name="instantMessagingID"> + <dsml:value>Google:dfisher@gmail.com</dsml:value> + <dsml:value>ICQ:8168282</dsml:value> + <dsml:value>Virginia Tech:dfisher@im.vt.edu</dsml:value> + <dsml:value>Yahoo!:dfish3r</dsml:value> + </dsml:attr> + <dsml:attr name="mail"> + <dsml:value>dfisher@vt.edu</dsml:value> + </dsml:attr> + <dsml:attr name="mailStop"> + <dsml:value>0479</dsml:value> + </dsml:attr> + <dsml:attr name="middleName"> + <dsml:value>W</dsml:value> + </dsml:attr> + <dsml:attr name="postalAddress"> + <dsml:value>SETI-Middleware$1700 Pratt Drive$Blacksburg, VA 24060</dsml:value> + </dsml:attr> + <dsml:attr name="sn"> + <dsml:value>Fisher</dsml:value> + </dsml:attr> + <dsml:attr name="suppressDisplay"> + <dsml:value>false</dsml:value> + </dsml:attr> + <dsml:attr name="suppressedAttribute"> + <dsml:value>homePhone</dsml:value> + <dsml:value>homePostalAddress</dsml:value> + <dsml:value>localPhone</dsml:value> + <dsml:value>localPostalAddress</dsml:value> + </dsml:attr> + <dsml:attr name="telephoneNumber"> + <dsml:value>5402312096</dsml:value> + </dsml:attr> + <dsml:attr name="title"> + <dsml:value>Project Manager, Middleware</dsml:value> + </dsml:attr> + <dsml:attr name="uid"> + <dsml:value>818037</dsml:value> + </dsml:attr> + <dsml:attr name="userCertificate;binary"> + <dsml:value encoding="base64">MIIC7zCCAligAwIBAgIQCBdZgzdx+yX5+jSRD50SJzANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIElzc3VpbmcgQ0EwHhcNMDkwNjI5MTg0NTQ2WhcNMTAwNjI5MTg0NTQ2WjBZMQ8wDQYDVQQEEwZGaXNoZXIxDzANBgNVBCoTBkRhbmllbDEWMBQGA1UEAxMNRGFuaWVsIEZpc2hlcjEdMBsGCSqGSIb3DQEJARYOZGZpc2hlckB2dC5lZHUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbsC0qvAkU3oWwz39oq/ur/mhHZ+KNODug+pAsg0ZZbSnxWD9EVBiMerevD5bJ0weTWR2dSVJqkxoJ2pZCHUpCt8CBE8LDsLJc+qAHOOfTuEywulc1ifSbevam3ehAvRg9wjmmKcm7Hwz9LniIZefxh3Tr9YwHTbw9YRaVC7nVkRu+eMY+T1+Uz3mLmCQI8YsOYCvZ1C+a1Dh9EA4Ms+EisH3Mn4dA+6i8L0nTbyUnz0kgKUTPDrkPhXsNRv1KbSmWBlShhRWXqd7qo0fAqKo5h+j5wppVabINtYdv73OShfzcJKf1qrmZqL0JFsT6fUWE12kgPT7tpMxMgaUR2I7lAgMBAAGjKzApMBkGA1UdEQQSMBCBDmRmaXNoZXJAdnQuZWR1MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEFBQADgYEAUhjHo5Mp4HiMooqINVEeJcijTSf8LpWgmNTBteVPRsQfXv4o0/684ccmWO46aNy23uDt+qEU6DplKJmILwievVMPB/Fkc3rqSSG+BLGRHCKE4z2ypzOiZ9TRO/Ckux4dQCVnXCQ6tDNHofeph9zTBHFEIgYtC3YfHmCdvayJKy0=</dsml:value> + </dsml:attr> + <dsml:attr name="uupid"> + <dsml:value>dfisher</dsml:value> + </dsml:attr> + </dsml:entry> + </dsml:directory-entries> +</dsml:dsml>
diff --git a/integration/src/test/resources/org/ldaptive/dfisher.sorted.ldif b/integration/src/test/resources/org/ldaptive/dfisher.sorted.ldif new file mode 100644 index 0000000..352d117 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/dfisher.sorted.ldif
@@ -0,0 +1,28 @@ +dn: uid=818037,ou=People,dc=vt,dc=edu +authId: dfisher +cn: Daniel W Fisher +department: MiddleWare +departmentNumber: 066103 +displayName: Daniel W Fisher +givenName: Daniel +instantMessagingID: Google:dfisher@gmail.com +instantMessagingID: ICQ:8168282 +instantMessagingID: Virginia Tech:dfisher@im.vt.edu +instantMessagingID: Yahoo!:dfish3r +mail: dfisher@vt.edu +mailStop: 0479 +middleName: W +objectClass: virginiaTechPerson +postalAddress: SETI-Middleware$1700 Pratt Drive$Blacksburg, VA 24060 +sn: Fisher +suppressDisplay: false +suppressedAttribute: homePhone +suppressedAttribute: homePostalAddress +suppressedAttribute: localPhone +suppressedAttribute: localPostalAddress +telephoneNumber: 5402312096 +title: Project Manager, Middleware +uid: 818037 +userCertificate;binary:: MIIC7zCCAligAwIBAgIQCBdZgzdx+yX5+jSRD50SJzANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIElzc3VpbmcgQ0EwHhcNMDkwNjI5MTg0NTQ2WhcNMTAwNjI5MTg0NTQ2WjBZMQ8wDQYDVQQEEwZGaXNoZXIxDzANBgNVBCoTBkRhbmllbDEWMBQGA1UEAxMNRGFuaWVsIEZpc2hlcjEdMBsGCSqGSIb3DQEJARYOZGZpc2hlckB2dC5lZHUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbsC0qvAkU3oWwz39oq/ur/mhHZ+KNODug+pAsg0ZZbSnxWD9EVBiMerevD5bJ0weTWR2dSVJqkxoJ2pZCHUpCt8CBE8LDsLJc+qAHOOfTuEywulc1ifSbevam3ehAvRg9wjmmKcm7Hwz9LniIZefxh3Tr9YwHTbw9YRaVC7nVkRu+eMY+T1+Uz3mLmCQI8YsOYCvZ1C+a1Dh9EA4Ms+EisH3Mn4dA+6i8L0nTbyUnz0kgKUTPDrkPhXsNRv1KbSmWBlShhRWXqd7qo0fAqKo5h+j5wppVabINtYdv73OShfzcJKf1qrmZqL0JFsT6fUWE12kgPT7tpMxMgaUR2I7lAgMBAAGjKzApMBkGA1UdEQQSMBCBDmRmaXNoZXJAdnQuZWR1MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEFBQADgYEAUhjHo5Mp4HiMooqINVEeJcijTSf8LpWgmNTBteVPRsQfXv4o0/684ccmWO46aNy23uDt+qEU6DplKJmILwievVMPB/Fkc3rqSSG+BLGRHCKE4z2ypzOiZ9TRO/Ckux4dQCVnXCQ6tDNHofeph9zTBHFEIgYtC3YfHmCdvayJKy0= +uupid: dfisher +
diff --git a/integration/src/test/resources/org/ldaptive/getSchemaResults.ldif b/integration/src/test/resources/org/ldaptive/getSchemaResults.ldif new file mode 100644 index 0000000..6495090 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/getSchemaResults.ldif
@@ -0,0 +1,11 @@ +dn: AttributeDefinition +objectclass: AttributeDefinition + +dn: ClassDefinition +objectclass: ClassDefinition + +dn: MatchingRule +objectclass: MatchingRule + +dn: SyntaxDefinition +objectclass: SyntaxDefinition
diff --git a/integration/src/test/resources/org/ldaptive/image.jpg b/integration/src/test/resources/org/ldaptive/image.jpg new file mode 100644 index 0000000..08404f1 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/image.jpg Binary files differ
diff --git a/integration/src/test/resources/org/ldaptive/ldap.conn.properties b/integration/src/test/resources/org/ldaptive/ldap.conn.properties new file mode 100644 index 0000000..6af3629 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/ldap.conn.properties
@@ -0,0 +1,17 @@ +# Configuration variables for ldap operation +# Comments must be on separate lines +# Format is 'name=value' + +## LDAP CONFIG ## + +# hostname of the LDAP +org.ldaptive.ldapUrl=ldap://dne.middleware.vt.edu ${ldapTestHost} + +# bind DN if one is required to bind before searching +org.ldaptive.bindDn=${ldapBindDn} + +# credential for the bind DN +org.ldaptive.bindCredential=${ldapBindCredential} + +# set socket timeout low for testing +org.ldaptive.connectTimeout=PT2S
diff --git a/integration/src/test/resources/org/ldaptive/ldap.cram-md5.properties b/integration/src/test/resources/org/ldaptive/ldap.cram-md5.properties new file mode 100644 index 0000000..832a261 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/ldap.cram-md5.properties
@@ -0,0 +1,26 @@ +# Configuration variables for ldap operation +# Comments must be on separate lines +# Format is 'name=value' + +## LDAP CONFIG ## + +# hostname of the LDAP +org.ldaptive.ldapUrl=${ldapTestHost} + +# base dn for performing user lookups +org.ldaptive.baseDn=${ldapBaseDn} + +# bind DN if one is required to bind before searching +org.ldaptive.bindDn=test3 + +# credential for the bind DN +org.ldaptive.bindCredential=password + +# set socket timeout low for testing +org.ldaptive.connectTimeout=PT2S + +# LDAP SASL configuration +org.ldaptive.bindSaslConfig=org.ldaptive.sasl.CramMd5Config{{securityStrength=LOW}{qualityOfProtection=AUTH}} + +# Authentication SASL configuration +org.ldaptive.auth.authenticationSaslConfig=org.ldaptive.sasl.CramMd5Config{{securityStrength=LOW}{qualityOfProtection=AUTH}}
diff --git a/integration/src/test/resources/org/ldaptive/ldap.digest-md5.properties b/integration/src/test/resources/org/ldaptive/ldap.digest-md5.properties new file mode 100644 index 0000000..3e75638 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/ldap.digest-md5.properties
@@ -0,0 +1,26 @@ +# Configuration variables for ldap operation +# Comments must be on separate lines +# Format is 'name=value' + +## LDAP CONFIG ## + +# hostname of the LDAP +org.ldaptive.ldapUrl=${ldapTestHost} + +# base dn for performing user lookups +org.ldaptive.baseDn=${ldapBaseDn} + +# bind DN if one is required to bind before searching +org.ldaptive.bindDn=test3@vt.edu + +# credential for the bind DN +org.ldaptive.bindCredential=password + +# set socket timeout low for testing +org.ldaptive.connectTimeout=PT5S + +# LDAP SASL configuration +org.ldaptive.bindSaslConfig={{mechanism=DIGEST_MD5}{authorizationId=dn:uid=test4,${ldapBaseDn}}} + +# Authentication SASL configuration +org.ldaptive.auth.authenticationSaslConfig={{mechanism=DIGEST_MD5}}
diff --git a/integration/src/test/resources/org/ldaptive/ldap.external.properties b/integration/src/test/resources/org/ldaptive/ldap.external.properties new file mode 100644 index 0000000..8897526 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/ldap.external.properties
@@ -0,0 +1,21 @@ +# Configuration variables for ldap operation +# Comments must be on separate lines +# Format is 'name=value' + +## LDAP CONFIG ## + +# fully qualified class name which implements javax.net.ssl.SSLSocketFactory +org.ldaptive.credentialConfig=org.ldaptive.ssl.KeyStoreCredentialConfig{ {trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS} {trustStoreAliases=ldap-test-ss,ldap-test-3,ldap-test-2,middleware-test} {keyStore=classpath:/ldaptive.keystore} {keyStoreType=BKS} {keyStorePassword=changeit} {keyStoreAliases=vt-ldap-test} } + +# hostname of the LDAP +org.ldaptive.ldapUrl=${ldapTestHost} + +# LDAP SASL configuration +org.ldaptive.bindSaslConfig={mechanism=EXTERNAL} + +# whether startTLS should be used for LDAP connections +# default value is 'false' +org.ldaptive.useStartTLS=true + +# set socket timeout low for testing +org.ldaptive.connectTimeout=PT5S
diff --git a/integration/src/test/resources/org/ldaptive/ldap.gssapi.properties b/integration/src/test/resources/org/ldaptive/ldap.gssapi.properties new file mode 100644 index 0000000..2a30934 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/ldap.gssapi.properties
@@ -0,0 +1,15 @@ +# Configuration variables for ldap operation +# Comments must be on separate lines +# Format is 'name=value' + +## LDAP CONFIG ## + +# hostname of the LDAP +org.ldaptive.ldapUrl=${ldapTestHost} + +# LDAP SASL configuration +org.ldaptive.bindSaslConfig={mechanism=GSSAPI} + +# whether TLS should be used for LDAP connections +# default value is 'false' +org.ldaptive.tls=false
diff --git a/integration/src/test/resources/org/ldaptive/ldap.null.properties b/integration/src/test/resources/org/ldaptive/ldap.null.properties new file mode 100644 index 0000000..70404ee --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/ldap.null.properties
@@ -0,0 +1,41 @@ +# Configuration variables for ldap operation +# Comments must be on separate lines +# Format is 'name=value' + +## LDAP CONFIG ## + +# hostname of the LDAP +org.ldaptive.ldapUrl=ldap://directory.vt.edu + +# base dn for performing user lookups +org.ldaptive.baseDn=${ldapBaseDn} + +# bind DN if one is required to bind before searching +org.ldaptive.bindDn=${ldapBindDn} + +# credential for the bind DN +org.ldaptive.bindCredential=${ldapBindCredential} + +# sets the search scope +# default value is 'SUBTREE' +org.ldaptive.searchScope=SUBTREE + +# sets the length of time that search operations will block +# default value is 0, block forever +org.ldaptive.timeLimit=PT5S + +# set socket timeout low for testing +org.ldaptive.connectTimeout=PT8S + +# specifies additional attributes which should be treated as binary +# attribute names should be space delimited +org.ldaptive.binaryAttributes=jpegPhoto + +# whether startTLS should be used for LDAP connections +# default value is 'false' +org.ldaptive.useStartTLS=false + +# nullable properties +org.ldaptive.bindSaslConfig=null +org.ldaptive.searchEntryHandlers=null +
diff --git a/integration/src/test/resources/org/ldaptive/ldap.parser.properties b/integration/src/test/resources/org/ldaptive/ldap.parser.properties new file mode 100644 index 0000000..b9630a8 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/ldap.parser.properties
@@ -0,0 +1,80 @@ +# Configuration variables for ldap operation +# Comments must be on separate lines +# Format is 'name=value' + +## LDAP CONFIG ## + +# hostname of the LDAP +org.ldaptive.ldapUrl=${ldapTestHost} + +# base dn for performing user lookups +org.ldaptive.baseDn=${ldapBaseDn} + +# bind DN if one is required to bind before searching +org.ldaptive.bindDn=${ldapBindDn} + +# credential for the bind DN +org.ldaptive.bindCredential=${ldapBindCredential} + +# sets the search scope +# default value is 'SUBTREE' +org.ldaptive.searchScope=OBJECT + +# sets the length of time that search operations will block +# default value is 0, block forever +org.ldaptive.timeLimit=PT5S + +# set socket timeout low for testing +org.ldaptive.connectTimeout=PT8S + +# specifies additional attributes which should be treated as binary +# attribute names should be space delimited +org.ldaptive.binaryAttributes=jpegPhoto + +# whether startTLS should be used for LDAP connections +# default value is 'false' +org.ldaptive.useStartTLS=false + +# connection strategy +org.ldaptive.connectionStrategy=ROUND_ROBIN + +# page search results +org.ldaptive.controls=org.ldaptive.control.PagedResultsControl{{size=5}} + +# search result handlers +org.ldaptive.searchEntryHandlers=org.ldaptive.handler.RecursiveEntryHandler{{searchAttribute=member}{mergeAttributes=mail,department}},org.ldaptive.handler.MergeAttributeEntryHandler{ } + +# provider control processor +org.ldaptive.controlProcessor=org.ldaptive.provider.TestControlProcessor + +# provider specific property +java.naming.authoritative=true + +# hostname of the authentication LDAP +org.ldaptive.auth.ldapUrl=ldap://ed-auth.middleware.vt.edu:14389 + +# whether startTLS should be used for authentication connections +# default value is 'false' +org.ldaptive.auth.useStartTLS=true + +# DN resolver +org.ldaptive.auth.dnResolver=org.ldaptive.auth.PooledSearchDnResolver + +# don't connect on create, url data is invalid +org.ldaptive.auth.connectOnCreate=false + +# configure pool size +org.ldaptive.auth.minPoolSize=1 +org.ldaptive.auth.maxPoolSize=3 +org.ldaptive.auth.validatePeriodically=true +org.ldaptive.auth.validator=org.ldaptive.pool.SearchValidator + +# prune strategy for the dn resolver pool +org.ldaptive.auth.pruneStrategy=org.ldaptive.pool.IdlePruneStrategy{{prunePeriod=PT1M}{idleTime=PT2M} + +# pool activator +org.ldaptive.auth.activator=org.ldaptive.pool.ConnectActivator + +# pool passivator +org.ldaptive.auth.passivator=org.ldaptive.pool.ClosePassivator +
diff --git a/integration/src/test/resources/org/ldaptive/ldap.properties b/integration/src/test/resources/org/ldaptive/ldap.properties new file mode 100644 index 0000000..86478a5 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/ldap.properties
@@ -0,0 +1,24 @@ +# Configuration variables for ldap operation +# Comments must be on separate lines +# Format is 'name=value' + +## LDAP CONFIG ## + +# hostname of the LDAP +org.ldaptive.ldapUrl=${ldapTestHost} + +# base dn for performing user lookups +org.ldaptive.baseDn=${ldapBaseDn} + +# bind DN if one is required to bind before searching +org.ldaptive.bindDn=${ldapBindDn} + +# credential for the bind DN +org.ldaptive.bindCredential=${ldapBindCredential} + +# set socket timeout low for testing +org.ldaptive.connectTimeout=PT8S + +# whether startTLS should be used for LDAP connections +# default value is 'false' +org.ldaptive.useStartTLS=false
diff --git a/integration/src/test/resources/org/ldaptive/ldap.setup.properties b/integration/src/test/resources/org/ldaptive/ldap.setup.properties new file mode 100644 index 0000000..c1f58c6 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/ldap.setup.properties
@@ -0,0 +1,26 @@ +# Configuration variables for ldap operation +# Comments must be on separate lines +# Format is 'name=value' + +## LDAP CONFIG ## + +# hostname of the LDAP +org.ldaptive.ldapUrl=${ldapSslTestHost} + +# bind DN if one is required to bind before searching +org.ldaptive.bindDn=${ldapBindDn} + +# credential for the bind DN +org.ldaptive.bindCredential=${ldapBindCredential} + +# whether LDAPS should be used for LDAP connections +org.ldaptive.useSSL=true + +# connection timeout +org.ldaptive.connectTimeout=PT10S + +# response timeout +org.ldaptive.responseTimeout=PT10S + +# trust material for startTLS connections +org.ldaptive.credentialConfig={ trustCertificates=file:target/test-classes/ldaptive.trust.crt }
diff --git a/integration/src/test/resources/org/ldaptive/ldap.ssl.properties b/integration/src/test/resources/org/ldaptive/ldap.ssl.properties new file mode 100644 index 0000000..d2279dc --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/ldap.ssl.properties
@@ -0,0 +1,27 @@ +# Configuration variables for ldap operation +# Comments must be on separate lines +# Format is 'name=value' + +## LDAP CONFIG ## + +# trust material for SSL connections +org.ldaptive.credentialConfig=org.ldaptive.ssl.X509CredentialConfig{{trustCertificates=file:target/test-classes/ldaptive.trust.crt}} + +# hostname of the LDAP +org.ldaptive.ldapUrl=${ldapSslTestHost} + +# base dn for performing user lookups +org.ldaptive.baseDn=${ldapBaseDn} + +# bind DN if one is required to bind before searching +org.ldaptive.bindDn=${ldapBindDn} + +# credential for the bind DN +org.ldaptive.bindCredential=${ldapBindCredential} + +# whether SSL should be used for LDAP connections +# default value is 'false' +org.ldaptive.useSSL=true + +# LDAP field which contains user identifier +org.ldaptive.auth.userFilter=(|(uid={user})(mail={user}))
diff --git a/integration/src/test/resources/org/ldaptive/ldap.tls.load.properties b/integration/src/test/resources/org/ldaptive/ldap.tls.load.properties new file mode 100644 index 0000000..79a5836 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/ldap.tls.load.properties
@@ -0,0 +1,27 @@ +# Configuration variables for ldap operation +# Comments must be on separate lines +# Format is 'name=value' + +## LDAP CONFIG ## + +# trust and key material for startTLS connections +org.ldaptive.credentialConfig=org.ldaptive.ssl.KeyStoreCredentialConfig{ {trustStore=classpath:/ldaptive.truststore} {trustStoreType=BKS} } + +# hostname of the LDAP +org.ldaptive.ldapUrl=${ldapTestHost} + +# base dn for performing user lookups +org.ldaptive.baseDn=${ldapBaseDn} + +# bind DN if one is required to bind before searching +org.ldaptive.bindDn=${ldapBindDn} + +# credential for the bind DN +org.ldaptive.bindCredential=${ldapBindCredential} + +# whether startTLS should be used for LDAP connections +# default value is 'false' +org.ldaptive.useStartTLS=true + +# LDAP field which contains user identifier +org.ldaptive.auth.userFilter=(|(uid={user})(mail={user}))
diff --git a/integration/src/test/resources/org/ldaptive/ldap.tls.properties b/integration/src/test/resources/org/ldaptive/ldap.tls.properties new file mode 100644 index 0000000..0eee8f9 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/ldap.tls.properties
@@ -0,0 +1,36 @@ +# Configuration variables for ldap operation +# Comments must be on separate lines +# Format is 'name=value' + +## LDAP CONFIG ## + +# trust material for startTLS connections +org.ldaptive.credentialConfig={ trustCertificates=file:target/test-classes/ldaptive.trust.crt } + +# hostname of the LDAP +org.ldaptive.ldapUrl=ldap://dne.middleware.vt.edu:389 + +# hostname of the LDAP +org.ldaptive.auth.ldapUrl=${ldapTestHost} + +# base dn for performing user lookups +org.ldaptive.auth.baseDn=${ldapBaseDn} + +# base dn for performing user lookups +org.ldaptive.baseDn=dc=vt,dc=edu + +# bind DN if one is required to bind before searching +org.ldaptive.bindDn=${ldapBindDn} + +# credential for the bind DN +org.ldaptive.bindCredential=${ldapBindCredential} + +# whether startTLS should be used for LDAP connections +# default value is 'false' +org.ldaptive.useStartTLS=true + +# set socket timeout low for testing +org.ldaptive.connectTimeout=PT2S + +# LDAP field which contains user identifier +org.ldaptive.auth.userFilter=(|(uid={user})(mail={user}))
diff --git a/integration/src/test/resources/org/ldaptive/mergeAttributeResults.ldif b/integration/src/test/resources/org/ldaptive/mergeAttributeResults.ldif new file mode 100644 index 0000000..1a4a40c --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/mergeAttributeResults.ldif
@@ -0,0 +1,10 @@ +dn: cn=John Adams,${ldapBaseDn} +cn: John Adams +cn: John Adams +cn: John +cn: Adams +departmentNumber: 0822 +displayName: John Adams +givenName: John +sn: Adams +uid: 2
diff --git a/integration/src/test/resources/org/ldaptive/mergeDuplicateResults.ldif b/integration/src/test/resources/org/ldaptive/mergeDuplicateResults.ldif new file mode 100644 index 0000000..50bf211 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/mergeDuplicateResults.ldif
@@ -0,0 +1,26 @@ +dn: cn=Group 3,${ldapBaseDn} +cn: Group 3 +cn: Group 4 +cn: Group 5 +contactPerson: cn=John Adams,${ldapBaseDn} +contactPerson: cn=John Adams,${ldapBaseDn} +contactPerson: cn=John Adams,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +creationDate: 2010-06-06T12:00:00 +creationDate: 2010-06-06T12:00:00 +member: cn=Group 2,${ldapBaseDn} +member: cn=Group 3,${ldapBaseDn} +member: cn=Group 4,${ldapBaseDn} +member: cn=Group 5,${ldapBaseDn} +objectClass: virginiaTechGroup +objectClass: virginiaTechGroup +objectClass: virginiaTechGroup +objectClass: top +objectClass: top +objectClass: top +uid: 2003 +uid: 2004 +uid: 2005 +uugid: group3 +uugid: group4 +uugid: group5
diff --git a/integration/src/test/resources/org/ldaptive/mergeResults.ldif b/integration/src/test/resources/org/ldaptive/mergeResults.ldif new file mode 100644 index 0000000..b4ed54c --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/mergeResults.ldif
@@ -0,0 +1,18 @@ +dn: cn=Group 3,${ldapBaseDn} +cn: Group 3 +cn: Group 4 +cn: Group 5 +contactPerson: cn=John Adams,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +member: cn=Group 2,${ldapBaseDn} +member: cn=Group 3,${ldapBaseDn} +member: cn=Group 4,${ldapBaseDn} +member: cn=Group 5,${ldapBaseDn} +objectClass: virginiaTechGroup +objectClass: top +uid: 2003 +uid: 2004 +uid: 2005 +uugid: group3 +uugid: group4 +uugid: group5
diff --git a/integration/src/test/resources/org/ldaptive/multipleEntriesIn.ldif b/integration/src/test/resources/org/ldaptive/multipleEntriesIn.ldif new file mode 100644 index 0000000..de1f5d0 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/multipleEntriesIn.ldif
@@ -0,0 +1,102 @@ +version: 1 +dn: uid=818037,ou=People,dc=vt,dc=edu +middleName: W +uid: 818037 +mail: dfisher@vt.edu +sn: Fisher +instantMessagingID: Yahoo!:dfish3r +instantMessagingID: Google:dfisher@gmail.com +instantMessagingID: Virginia Tech:dfisher@im.vt.edu +instantMessagingID: ICQ:8168282 +department: MiddleWare +objectClass: virginiaTechPerson +# random comment +suppressedAttribute: localPostalAddress +suppressedAttribute: homePostalAddress +# random comment +suppressedAttribute: homePhone +suppressedAttribute: localPhone +givenName: Daniel +title: Project Manager, Middleware +mailStop: 0479 +departmentNumber: 066103 +cn: Daniel W Fisher +authId: dfisher +telephoneNumber: 5402312096 +userCertificate;binary:: MIIC7zCCAligAwIBAgIQCBdZgzdx+yX5+jSRD50SJzANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIElzc3VpbmcgQ0EwHhcNMDkwNjI5MTg0NTQ2WhcNMTAwNjI5MTg0NTQ2WjBZMQ8wDQYDVQQEEwZGaXNoZXIxDzANBgNVBCoTBkRhbmllbDEWMBQGA1UEAxMNRGFuaWVsIEZpc2hlcjEdMBsGCSqGSIb3DQEJARYOZGZpc2hlckB2dC5lZHUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbsC0qvAkU3oWwz39oq/ur/mhHZ+KNODug+pAsg0ZZbSnxWD9EVBiMerevD5bJ0weTWR2dSVJqkxoJ2pZCHUpCt8CBE8LDsLJc+qAHOOfTuEywulc1ifSbevam3ehAvRg9wjmmKcm7Hwz9LniIZefxh3Tr9YwHTbw9YRaVC7nVkRu+eMY+T1+Uz3mLmCQI8YsOYCvZ1C+a1Dh9EA4Ms+EisH3Mn4dA+6i8L0nTbyUnz0kgKUTPDrkPhXsNRv1KbSmWBlShhRWXqd7qo0fAqKo5h+j5wppVabINtYdv73OShfzcJKf1qrmZqL0JFsT6fUWE12kgPT7tpMxMgaUR2I7lAgMBAAGjKzApMBkGA1UdEQQSMBCBDmRmaXNoZXJAdnQuZWR1MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEFBQADgYEAUhjHo5Mp4HiMooqINVEeJcijTSf8LpWgmNTBteVPRsQfXv4o0/684ccmWO46aNy23uDt+qEU6DplKJmILwievVMPB/Fkc3rqSSG+BLGRHCKE4z2ypzOiZ9TRO/Ckux4dQCVnXCQ6tDNHofeph9zTBHFEIgYtC3YfHmCdvayJKy0= +postalAddress: SETI-Middleware + 1700 Pratt Drive + Blacksburg, VA 24060 +displayName: Daniel W Fisher +suppressDisplay: false +jpegPhoto:< file:///${basedir}/target/test-classes/org/ldaptive/image.jpg +uupid: dfisher + +# random comment + +dn:uid=1152120,ou=People,dc=vt,dc=edu +middleName:H +uid:1152120 +mail:dhawes@vt.edu +sn:Hawes +instantMessagingID:Google:dhawes@gmail.com +instantMessagingID:Virginia Tech:dhawes@im.iad.vt.edu +department:MiddleWare +objectClass:virginiaTechPerson +suppressedAttribute:localPostalAddress +# random comment +givenName:David +labeledURI:Homepage:http://filebox.vt.edu/users/dhawes +title:Middleware Application Developer +mailStop:0479 +localPhone:5405529055 +departmentNumber:066103 +cn:David H Hawes +authId:dhawes +telephoneNumber:5402316978 +# random comment +postalAddress:SETI-Middleware$1700 Pratt Dr.$Blacksburg, VA 24061 +displayName:David H Hawes +suppressDisplay:false +uupid:dhawes + +dn: uid=1145718,ou=People,dc=vt,dc=edu +middleName: S +uid: 1145718 +mail: serac@vt.edu +sn: Addison +instantMessagingID: Virginia Tech:serac@im.vt.edu +department: MiddleWare +objectClass: virginiaTechPerson +suppressedAttribute: localPostalAddress +givenName: Marvin +labeledURI: Homepage:http://www.middleware.vt.edu/doku.php?id=middleware:serac +title: IT Specialist +mailStop: 0479 +departmentNumber: 066103 +cn: Marvin S Addison +authId: serac +telephoneNumber: 5402317050 +# random comment +userCertificate;binary:: MIIC/TCCAmagAwIBAgIQKQxJ2CQ0bujrfVdU9505nzANB + gkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHR + pbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIElzc + 3VpbmcgQ0EwHhcNMDkwODI3MjAwNzExWhcNMTAwODI3MjAwNzExWjBZMRAwDgYDVQQEEwd + BZGRpc29uMQ8wDQYDVQQqEwZNYXJ2aW4xFzAVBgNVBAMTDk1hcnZpbiBBZGRpc29uMRswG + QYJKoZIhvcNAQkBFgxzZXJhY0B2dC5lZHUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggE + KAoIBAQCYU7i0HPyrjhLdm09uprGeIJQnkdxU+HCu1oT0SPVg6I0/KYw64bbKSc36cHE5d + 03RpqkU5HCSJ5m4OaluDYezaOz6TcSUhAAmYnkF8lCXI7zBS1VGlPe2w3ronZoBb6bZ0Po + bBpD+1AdRRfV+6FNqhnqG+ZAOlEsAwyUkEd/lTPjYsS7Te0GXOyhPTDUiKixBdPSuMSuAJ + JZKrAIBTRe62dpDSOvBYJSVVpuGdiCSaG1YQWI3DkvjzLT4+0zvDPjb7dvePnbkbpwyFfK + +e1wYpK2yShHiJeOPAdVUZ+PjeBFnD2TkDgk/Tf8j6QJLMw0Apt7rATxW9NAUEPLoPeCFA + gMBAAGjOTA3MA4GA1UdDwEB/wQEAwID+DAXBgNVHREEEDAOgQxzZXJhY0B2dC5lZHUwDAY + DVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOBgQC5V1Kb0q7ajm7OZjbjv8xosxblvt9Qh + l5yBhnX4xL9QomntH60LZc2pf20hnJ6Pl6Onxk4LejTtemyL0Bm0i3DJbqCCBFaOsEdX2G + 3D3HPNhdphYckn7fjzuvUudMEkfvrPDj0evdJIgwOXDEvsh8y8LggO1Bp6xj63H0oPePHB + w== +postalAddress: SETI-Middleware 1700 Pratt Drive + Room 111A Blacksburg, VA 24060 +displayName: Marvin S Addison +suppressDisplay: false +uupid: serac +
diff --git a/integration/src/test/resources/org/ldaptive/multipleEntriesOut.ldif b/integration/src/test/resources/org/ldaptive/multipleEntriesOut.ldif new file mode 100644 index 0000000..da35895 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/multipleEntriesOut.ldif
@@ -0,0 +1,76 @@ +dn: uid=818037,ou=People,dc=vt,dc=edu +middleName: W +uid: 818037 +mail: dfisher@vt.edu +sn: Fisher +instantMessagingID: Yahoo!:dfish3r +instantMessagingID: Google:dfisher@gmail.com +instantMessagingID: Virginia Tech:dfisher@im.vt.edu +instantMessagingID: ICQ:8168282 +department: MiddleWare +objectClass: virginiaTechPerson +suppressedAttribute: localPostalAddress +suppressedAttribute: homePostalAddress +suppressedAttribute: homePhone +suppressedAttribute: localPhone +givenName: Daniel +title: Project Manager, Middleware +mailStop: 0479 +departmentNumber: 066103 +cn: Daniel W Fisher +authId: dfisher +telephoneNumber: 5402312096 +userCertificate;binary:: MIIC7zCCAligAwIBAgIQCBdZgzdx+yX5+jSRD50SJzANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIElzc3VpbmcgQ0EwHhcNMDkwNjI5MTg0NTQ2WhcNMTAwNjI5MTg0NTQ2WjBZMQ8wDQYDVQQEEwZGaXNoZXIxDzANBgNVBCoTBkRhbmllbDEWMBQGA1UEAxMNRGFuaWVsIEZpc2hlcjEdMBsGCSqGSIb3DQEJARYOZGZpc2hlckB2dC5lZHUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbsC0qvAkU3oWwz39oq/ur/mhHZ+KNODug+pAsg0ZZbSnxWD9EVBiMerevD5bJ0weTWR2dSVJqkxoJ2pZCHUpCt8CBE8LDsLJc+qAHOOfTuEywulc1ifSbevam3ehAvRg9wjmmKcm7Hwz9LniIZefxh3Tr9YwHTbw9YRaVC7nVkRu+eMY+T1+Uz3mLmCQI8YsOYCvZ1C+a1Dh9EA4Ms+EisH3Mn4dA+6i8L0nTbyUnz0kgKUTPDrkPhXsNRv1KbSmWBlShhRWXqd7qo0fAqKo5h+j5wppVabINtYdv73OShfzcJKf1qrmZqL0JFsT6fUWE12kgPT7tpMxMgaUR2I7lAgMBAAGjKzApMBkGA1UdEQQSMBCBDmRmaXNoZXJAdnQuZWR1MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEFBQADgYEAUhjHo5Mp4HiMooqINVEeJcijTSf8LpWgmNTBteVPRsQfXv4o0/684ccmWO46aNy23uDt+qEU6DplKJmILwievVMPB/Fkc3rqSSG+BLGRHCKE4z2ypzOiZ9TRO/Ckux4dQCVnXCQ6tDNHofeph9zTBHFEIgYtC3YfHmCdvayJKy0= +postalAddress: SETI-Middleware 1700 Pratt Drive Blacksburg, VA 24060 +displayName: Daniel W Fisher +suppressDisplay: false +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k= +uupid: dfisher + +dn: uid=1152120,ou=People,dc=vt,dc=edu +middleName: H +uid: 1152120 +mail: dhawes@vt.edu +sn: Hawes +instantMessagingID: Google:dhawes@gmail.com +instantMessagingID: Virginia Tech:dhawes@im.iad.vt.edu +department: MiddleWare +objectClass: virginiaTechPerson +suppressedAttribute: localPostalAddress +givenName: David +labeledURI: Homepage:http://filebox.vt.edu/users/dhawes +title: Middleware Application Developer +mailStop: 0479 +localPhone: 5405529055 +departmentNumber: 066103 +cn: David H Hawes +authId: dhawes +telephoneNumber: 5402316978 +postalAddress: SETI-Middleware$1700 Pratt Dr.$Blacksburg, VA 24061 +displayName: David H Hawes +suppressDisplay: false +uupid: dhawes + +dn: uid=1145718,ou=People,dc=vt,dc=edu +middleName: S +uid: 1145718 +mail: serac@vt.edu +sn: Addison +instantMessagingID: Virginia Tech:serac@im.vt.edu +department: MiddleWare +objectClass: virginiaTechPerson +suppressedAttribute: localPostalAddress +givenName: Marvin +labeledURI: Homepage:http://www.middleware.vt.edu/doku.php?id=middleware:serac +title: IT Specialist +mailStop: 0479 +departmentNumber: 066103 +cn: Marvin S Addison +authId: serac +telephoneNumber: 5402317050 +userCertificate;binary:: MIIC/TCCAmagAwIBAgIQKQxJ2CQ0bujrfVdU9505nzANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIElzc3VpbmcgQ0EwHhcNMDkwODI3MjAwNzExWhcNMTAwODI3MjAwNzExWjBZMRAwDgYDVQQEEwdBZGRpc29uMQ8wDQYDVQQqEwZNYXJ2aW4xFzAVBgNVBAMTDk1hcnZpbiBBZGRpc29uMRswGQYJKoZIhvcNAQkBFgxzZXJhY0B2dC5lZHUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYU7i0HPyrjhLdm09uprGeIJQnkdxU+HCu1oT0SPVg6I0/KYw64bbKSc36cHE5d03RpqkU5HCSJ5m4OaluDYezaOz6TcSUhAAmYnkF8lCXI7zBS1VGlPe2w3ronZoBb6bZ0PobBpD+1AdRRfV+6FNqhnqG+ZAOlEsAwyUkEd/lTPjYsS7Te0GXOyhPTDUiKixBdPSuMSuAJJZKrAIBTRe62dpDSOvBYJSVVpuGdiCSaG1YQWI3DkvjzLT4+0zvDPjb7dvePnbkbpwyFfK+e1wYpK2yShHiJeOPAdVUZ+PjeBFnD2TkDgk/Tf8j6QJLMw0Apt7rATxW9NAUEPLoPeCFAgMBAAGjOTA3MA4GA1UdDwEB/wQEAwID+DAXBgNVHREEEDAOgQxzZXJhY0B2dC5lZHUwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOBgQC5V1Kb0q7ajm7OZjbjv8xosxblvt9Qhl5yBhnX4xL9QomntH60LZc2pf20hnJ6Pl6Onxk4LejTtemyL0Bm0i3DJbqCCBFaOsEdX2G3D3HPNhdphYckn7fjzuvUudMEkfvrPDj0evdJIgwOXDEvsh8y8LggO1Bp6xj63H0oPePHBw== +postalAddress: SETI-Middleware 1700 Pratt Drive Room 111A Blacksburg, VA 24060 +displayName: Marvin S Addison +suppressDisplay: false +uupid: serac +
diff --git a/integration/src/test/resources/org/ldaptive/pagedResults.ldif b/integration/src/test/resources/org/ldaptive/pagedResults.ldif new file mode 100644 index 0000000..99e56e0 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/pagedResults.ldif
@@ -0,0 +1,41 @@ +dn: cn=Group 2,${ldapBaseDn} +cn: Group 2 +contactPerson: cn=John Adams,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +objectClass: virginiaTechGroup +objectClass: top +member: cn=Group 3,${ldapBaseDn} +uid: 2002 +uugid: group2 + +dn: cn=Group 3,${ldapBaseDn} +cn: Group 3 +contactPerson: cn=John Adams,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +objectClass: virginiaTechGroup +objectClass: top +member: cn=Group 4,${ldapBaseDn} +member: cn=Group 5,${ldapBaseDn} +uid: 2003 +uugid: group3 + +dn: cn=Group 4,${ldapBaseDn} +cn: Group 4 +contactPerson: cn=John Adams,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +objectClass: virginiaTechGroup +objectClass: top +member: cn=Group 2,${ldapBaseDn} +member: cn=Group 3,${ldapBaseDn} +uid: 2004 +uugid: group4 + +dn: cn=Group 5,${ldapBaseDn} +cn: Group 5 +contactPerson: cn=John Adams,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +objectClass: virginiaTechGroup +objectClass: top +uid: 2005 +uugid: group5 +
diff --git a/integration/src/test/resources/org/ldaptive/persistentSearchResults.ldif b/integration/src/test/resources/org/ldaptive/persistentSearchResults.ldif new file mode 100644 index 0000000..67f7f9e --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/persistentSearchResults.ldif
@@ -0,0 +1,9 @@ +dn: cn=Herbert Hoover,${ldapBaseDn} +cn: Herbert Hoover +mail: hhoover@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Hoover +uid: 31
diff --git a/integration/src/test/resources/org/ldaptive/rangeHandlerResults.ldif b/integration/src/test/resources/org/ldaptive/rangeHandlerResults.ldif new file mode 100644 index 0000000..4aa77ec --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/rangeHandlerResults.ldif
@@ -0,0 +1,5003 @@ +dn: cn=Group 550000,${ldapBaseDn} +cn: Group 550000 +member: cn=Group 550001,${ldapBaseDn} +member: cn=Group 550002,${ldapBaseDn} +member: cn=Group 550003,${ldapBaseDn} +member: cn=Group 550004,${ldapBaseDn} +member: cn=Group 550005,${ldapBaseDn} +member: cn=Group 550006,${ldapBaseDn} +member: cn=Group 550007,${ldapBaseDn} +member: cn=Group 550008,${ldapBaseDn} +member: cn=Group 550009,${ldapBaseDn} +member: cn=Group 550010,${ldapBaseDn} +member: cn=Group 550011,${ldapBaseDn} +member: cn=Group 550012,${ldapBaseDn} +member: cn=Group 550013,${ldapBaseDn} +member: cn=Group 550014,${ldapBaseDn} +member: cn=Group 550015,${ldapBaseDn} +member: cn=Group 550016,${ldapBaseDn} +member: cn=Group 550017,${ldapBaseDn} +member: cn=Group 550018,${ldapBaseDn} +member: cn=Group 550019,${ldapBaseDn} +member: cn=Group 550020,${ldapBaseDn} +member: cn=Group 550021,${ldapBaseDn} +member: cn=Group 550022,${ldapBaseDn} +member: cn=Group 550023,${ldapBaseDn} +member: cn=Group 550024,${ldapBaseDn} +member: cn=Group 550025,${ldapBaseDn} +member: cn=Group 550026,${ldapBaseDn} +member: cn=Group 550027,${ldapBaseDn} +member: cn=Group 550028,${ldapBaseDn} +member: cn=Group 550029,${ldapBaseDn} +member: cn=Group 550030,${ldapBaseDn} +member: cn=Group 550031,${ldapBaseDn} +member: cn=Group 550032,${ldapBaseDn} +member: cn=Group 550033,${ldapBaseDn} +member: cn=Group 550034,${ldapBaseDn} +member: cn=Group 550035,${ldapBaseDn} +member: cn=Group 550036,${ldapBaseDn} +member: cn=Group 550037,${ldapBaseDn} +member: cn=Group 550038,${ldapBaseDn} +member: cn=Group 550039,${ldapBaseDn} +member: cn=Group 550040,${ldapBaseDn} +member: cn=Group 550041,${ldapBaseDn} +member: cn=Group 550042,${ldapBaseDn} +member: cn=Group 550043,${ldapBaseDn} +member: cn=Group 550044,${ldapBaseDn} +member: cn=Group 550045,${ldapBaseDn} +member: cn=Group 550046,${ldapBaseDn} +member: cn=Group 550047,${ldapBaseDn} +member: cn=Group 550048,${ldapBaseDn} +member: cn=Group 550049,${ldapBaseDn} +member: cn=Group 550050,${ldapBaseDn} +member: cn=Group 550051,${ldapBaseDn} +member: cn=Group 550052,${ldapBaseDn} +member: cn=Group 550053,${ldapBaseDn} +member: cn=Group 550054,${ldapBaseDn} +member: cn=Group 550055,${ldapBaseDn} +member: cn=Group 550056,${ldapBaseDn} +member: cn=Group 550057,${ldapBaseDn} +member: cn=Group 550058,${ldapBaseDn} +member: cn=Group 550059,${ldapBaseDn} +member: cn=Group 550060,${ldapBaseDn} +member: cn=Group 550061,${ldapBaseDn} +member: cn=Group 550062,${ldapBaseDn} +member: cn=Group 550063,${ldapBaseDn} +member: cn=Group 550064,${ldapBaseDn} +member: cn=Group 550065,${ldapBaseDn} +member: cn=Group 550066,${ldapBaseDn} +member: cn=Group 550067,${ldapBaseDn} +member: cn=Group 550068,${ldapBaseDn} +member: cn=Group 550069,${ldapBaseDn} +member: cn=Group 550070,${ldapBaseDn} +member: cn=Group 550071,${ldapBaseDn} +member: cn=Group 550072,${ldapBaseDn} +member: cn=Group 550073,${ldapBaseDn} +member: cn=Group 550074,${ldapBaseDn} +member: cn=Group 550075,${ldapBaseDn} +member: cn=Group 550076,${ldapBaseDn} +member: cn=Group 550077,${ldapBaseDn} +member: cn=Group 550078,${ldapBaseDn} +member: cn=Group 550079,${ldapBaseDn} +member: cn=Group 550080,${ldapBaseDn} +member: cn=Group 550081,${ldapBaseDn} +member: cn=Group 550082,${ldapBaseDn} +member: cn=Group 550083,${ldapBaseDn} +member: cn=Group 550084,${ldapBaseDn} +member: cn=Group 550085,${ldapBaseDn} +member: cn=Group 550086,${ldapBaseDn} +member: cn=Group 550087,${ldapBaseDn} +member: cn=Group 550088,${ldapBaseDn} +member: cn=Group 550089,${ldapBaseDn} +member: cn=Group 550090,${ldapBaseDn} +member: cn=Group 550091,${ldapBaseDn} +member: cn=Group 550092,${ldapBaseDn} +member: cn=Group 550093,${ldapBaseDn} +member: cn=Group 550094,${ldapBaseDn} +member: cn=Group 550095,${ldapBaseDn} +member: cn=Group 550096,${ldapBaseDn} +member: cn=Group 550097,${ldapBaseDn} +member: cn=Group 550098,${ldapBaseDn} +member: cn=Group 550099,${ldapBaseDn} +member: cn=Group 550100,${ldapBaseDn} +member: cn=Group 550101,${ldapBaseDn} +member: cn=Group 550102,${ldapBaseDn} +member: cn=Group 550103,${ldapBaseDn} +member: cn=Group 550104,${ldapBaseDn} +member: cn=Group 550105,${ldapBaseDn} +member: cn=Group 550106,${ldapBaseDn} +member: cn=Group 550107,${ldapBaseDn} +member: cn=Group 550108,${ldapBaseDn} +member: cn=Group 550109,${ldapBaseDn} +member: cn=Group 550110,${ldapBaseDn} +member: cn=Group 550111,${ldapBaseDn} +member: cn=Group 550112,${ldapBaseDn} +member: cn=Group 550113,${ldapBaseDn} +member: cn=Group 550114,${ldapBaseDn} +member: cn=Group 550115,${ldapBaseDn} +member: cn=Group 550116,${ldapBaseDn} +member: cn=Group 550117,${ldapBaseDn} +member: cn=Group 550118,${ldapBaseDn} +member: cn=Group 550119,${ldapBaseDn} +member: cn=Group 550120,${ldapBaseDn} +member: cn=Group 550121,${ldapBaseDn} +member: cn=Group 550122,${ldapBaseDn} +member: cn=Group 550123,${ldapBaseDn} +member: cn=Group 550124,${ldapBaseDn} +member: cn=Group 550125,${ldapBaseDn} +member: cn=Group 550126,${ldapBaseDn} +member: cn=Group 550127,${ldapBaseDn} +member: cn=Group 550128,${ldapBaseDn} +member: cn=Group 550129,${ldapBaseDn} +member: cn=Group 550130,${ldapBaseDn} +member: cn=Group 550131,${ldapBaseDn} +member: cn=Group 550132,${ldapBaseDn} +member: cn=Group 550133,${ldapBaseDn} +member: cn=Group 550134,${ldapBaseDn} +member: cn=Group 550135,${ldapBaseDn} +member: cn=Group 550136,${ldapBaseDn} +member: cn=Group 550137,${ldapBaseDn} +member: cn=Group 550138,${ldapBaseDn} +member: cn=Group 550139,${ldapBaseDn} +member: cn=Group 550140,${ldapBaseDn} +member: cn=Group 550141,${ldapBaseDn} +member: cn=Group 550142,${ldapBaseDn} +member: cn=Group 550143,${ldapBaseDn} +member: cn=Group 550144,${ldapBaseDn} +member: cn=Group 550145,${ldapBaseDn} +member: cn=Group 550146,${ldapBaseDn} +member: cn=Group 550147,${ldapBaseDn} +member: cn=Group 550148,${ldapBaseDn} +member: cn=Group 550149,${ldapBaseDn} +member: cn=Group 550150,${ldapBaseDn} +member: cn=Group 550151,${ldapBaseDn} +member: cn=Group 550152,${ldapBaseDn} +member: cn=Group 550153,${ldapBaseDn} +member: cn=Group 550154,${ldapBaseDn} +member: cn=Group 550155,${ldapBaseDn} +member: cn=Group 550156,${ldapBaseDn} +member: cn=Group 550157,${ldapBaseDn} +member: cn=Group 550158,${ldapBaseDn} +member: cn=Group 550159,${ldapBaseDn} +member: cn=Group 550160,${ldapBaseDn} +member: cn=Group 550161,${ldapBaseDn} +member: cn=Group 550162,${ldapBaseDn} +member: cn=Group 550163,${ldapBaseDn} +member: cn=Group 550164,${ldapBaseDn} +member: cn=Group 550165,${ldapBaseDn} +member: cn=Group 550166,${ldapBaseDn} +member: cn=Group 550167,${ldapBaseDn} +member: cn=Group 550168,${ldapBaseDn} +member: cn=Group 550169,${ldapBaseDn} +member: cn=Group 550170,${ldapBaseDn} +member: cn=Group 550171,${ldapBaseDn} +member: cn=Group 550172,${ldapBaseDn} +member: cn=Group 550173,${ldapBaseDn} +member: cn=Group 550174,${ldapBaseDn} +member: cn=Group 550175,${ldapBaseDn} +member: cn=Group 550176,${ldapBaseDn} +member: cn=Group 550177,${ldapBaseDn} +member: cn=Group 550178,${ldapBaseDn} +member: cn=Group 550179,${ldapBaseDn} +member: cn=Group 550180,${ldapBaseDn} +member: cn=Group 550181,${ldapBaseDn} +member: cn=Group 550182,${ldapBaseDn} +member: cn=Group 550183,${ldapBaseDn} +member: cn=Group 550184,${ldapBaseDn} +member: cn=Group 550185,${ldapBaseDn} +member: cn=Group 550186,${ldapBaseDn} +member: cn=Group 550187,${ldapBaseDn} +member: cn=Group 550188,${ldapBaseDn} +member: cn=Group 550189,${ldapBaseDn} +member: cn=Group 550190,${ldapBaseDn} +member: cn=Group 550191,${ldapBaseDn} +member: cn=Group 550192,${ldapBaseDn} +member: cn=Group 550193,${ldapBaseDn} +member: cn=Group 550194,${ldapBaseDn} +member: cn=Group 550195,${ldapBaseDn} +member: cn=Group 550196,${ldapBaseDn} +member: cn=Group 550197,${ldapBaseDn} +member: cn=Group 550198,${ldapBaseDn} +member: cn=Group 550199,${ldapBaseDn} +member: cn=Group 550200,${ldapBaseDn} +member: cn=Group 550201,${ldapBaseDn} +member: cn=Group 550202,${ldapBaseDn} +member: cn=Group 550203,${ldapBaseDn} +member: cn=Group 550204,${ldapBaseDn} +member: cn=Group 550205,${ldapBaseDn} +member: cn=Group 550206,${ldapBaseDn} +member: cn=Group 550207,${ldapBaseDn} +member: cn=Group 550208,${ldapBaseDn} +member: cn=Group 550209,${ldapBaseDn} +member: cn=Group 550210,${ldapBaseDn} +member: cn=Group 550211,${ldapBaseDn} +member: cn=Group 550212,${ldapBaseDn} +member: cn=Group 550213,${ldapBaseDn} +member: cn=Group 550214,${ldapBaseDn} +member: cn=Group 550215,${ldapBaseDn} +member: cn=Group 550216,${ldapBaseDn} +member: cn=Group 550217,${ldapBaseDn} +member: cn=Group 550218,${ldapBaseDn} +member: cn=Group 550219,${ldapBaseDn} +member: cn=Group 550220,${ldapBaseDn} +member: cn=Group 550221,${ldapBaseDn} +member: cn=Group 550222,${ldapBaseDn} +member: cn=Group 550223,${ldapBaseDn} +member: cn=Group 550224,${ldapBaseDn} +member: cn=Group 550225,${ldapBaseDn} +member: cn=Group 550226,${ldapBaseDn} +member: cn=Group 550227,${ldapBaseDn} +member: cn=Group 550228,${ldapBaseDn} +member: cn=Group 550229,${ldapBaseDn} +member: cn=Group 550230,${ldapBaseDn} +member: cn=Group 550231,${ldapBaseDn} +member: cn=Group 550232,${ldapBaseDn} +member: cn=Group 550233,${ldapBaseDn} +member: cn=Group 550234,${ldapBaseDn} +member: cn=Group 550235,${ldapBaseDn} +member: cn=Group 550236,${ldapBaseDn} +member: cn=Group 550237,${ldapBaseDn} +member: cn=Group 550238,${ldapBaseDn} +member: cn=Group 550239,${ldapBaseDn} +member: cn=Group 550240,${ldapBaseDn} +member: cn=Group 550241,${ldapBaseDn} +member: cn=Group 550242,${ldapBaseDn} +member: cn=Group 550243,${ldapBaseDn} +member: cn=Group 550244,${ldapBaseDn} +member: cn=Group 550245,${ldapBaseDn} +member: cn=Group 550246,${ldapBaseDn} +member: cn=Group 550247,${ldapBaseDn} +member: cn=Group 550248,${ldapBaseDn} +member: cn=Group 550249,${ldapBaseDn} +member: cn=Group 550250,${ldapBaseDn} +member: cn=Group 550251,${ldapBaseDn} +member: cn=Group 550252,${ldapBaseDn} +member: cn=Group 550253,${ldapBaseDn} +member: cn=Group 550254,${ldapBaseDn} +member: cn=Group 550255,${ldapBaseDn} +member: cn=Group 550256,${ldapBaseDn} +member: cn=Group 550257,${ldapBaseDn} +member: cn=Group 550258,${ldapBaseDn} +member: cn=Group 550259,${ldapBaseDn} +member: cn=Group 550260,${ldapBaseDn} +member: cn=Group 550261,${ldapBaseDn} +member: cn=Group 550262,${ldapBaseDn} +member: cn=Group 550263,${ldapBaseDn} +member: cn=Group 550264,${ldapBaseDn} +member: cn=Group 550265,${ldapBaseDn} +member: cn=Group 550266,${ldapBaseDn} +member: cn=Group 550267,${ldapBaseDn} +member: cn=Group 550268,${ldapBaseDn} +member: cn=Group 550269,${ldapBaseDn} +member: cn=Group 550270,${ldapBaseDn} +member: cn=Group 550271,${ldapBaseDn} +member: cn=Group 550272,${ldapBaseDn} +member: cn=Group 550273,${ldapBaseDn} +member: cn=Group 550274,${ldapBaseDn} +member: cn=Group 550275,${ldapBaseDn} +member: cn=Group 550276,${ldapBaseDn} +member: cn=Group 550277,${ldapBaseDn} +member: cn=Group 550278,${ldapBaseDn} +member: cn=Group 550279,${ldapBaseDn} +member: cn=Group 550280,${ldapBaseDn} +member: cn=Group 550281,${ldapBaseDn} +member: cn=Group 550282,${ldapBaseDn} +member: cn=Group 550283,${ldapBaseDn} +member: cn=Group 550284,${ldapBaseDn} +member: cn=Group 550285,${ldapBaseDn} +member: cn=Group 550286,${ldapBaseDn} +member: cn=Group 550287,${ldapBaseDn} +member: cn=Group 550288,${ldapBaseDn} +member: cn=Group 550289,${ldapBaseDn} +member: cn=Group 550290,${ldapBaseDn} +member: cn=Group 550291,${ldapBaseDn} +member: cn=Group 550292,${ldapBaseDn} +member: cn=Group 550293,${ldapBaseDn} +member: cn=Group 550294,${ldapBaseDn} +member: cn=Group 550295,${ldapBaseDn} +member: cn=Group 550296,${ldapBaseDn} +member: cn=Group 550297,${ldapBaseDn} +member: cn=Group 550298,${ldapBaseDn} +member: cn=Group 550299,${ldapBaseDn} +member: cn=Group 550300,${ldapBaseDn} +member: cn=Group 550301,${ldapBaseDn} +member: cn=Group 550302,${ldapBaseDn} +member: cn=Group 550303,${ldapBaseDn} +member: cn=Group 550304,${ldapBaseDn} +member: cn=Group 550305,${ldapBaseDn} +member: cn=Group 550306,${ldapBaseDn} +member: cn=Group 550307,${ldapBaseDn} +member: cn=Group 550308,${ldapBaseDn} +member: cn=Group 550309,${ldapBaseDn} +member: cn=Group 550310,${ldapBaseDn} +member: cn=Group 550311,${ldapBaseDn} +member: cn=Group 550312,${ldapBaseDn} +member: cn=Group 550313,${ldapBaseDn} +member: cn=Group 550314,${ldapBaseDn} +member: cn=Group 550315,${ldapBaseDn} +member: cn=Group 550316,${ldapBaseDn} +member: cn=Group 550317,${ldapBaseDn} +member: cn=Group 550318,${ldapBaseDn} +member: cn=Group 550319,${ldapBaseDn} +member: cn=Group 550320,${ldapBaseDn} +member: cn=Group 550321,${ldapBaseDn} +member: cn=Group 550322,${ldapBaseDn} +member: cn=Group 550323,${ldapBaseDn} +member: cn=Group 550324,${ldapBaseDn} +member: cn=Group 550325,${ldapBaseDn} +member: cn=Group 550326,${ldapBaseDn} +member: cn=Group 550327,${ldapBaseDn} +member: cn=Group 550328,${ldapBaseDn} +member: cn=Group 550329,${ldapBaseDn} +member: cn=Group 550330,${ldapBaseDn} +member: cn=Group 550331,${ldapBaseDn} +member: cn=Group 550332,${ldapBaseDn} +member: cn=Group 550333,${ldapBaseDn} +member: cn=Group 550334,${ldapBaseDn} +member: cn=Group 550335,${ldapBaseDn} +member: cn=Group 550336,${ldapBaseDn} +member: cn=Group 550337,${ldapBaseDn} +member: cn=Group 550338,${ldapBaseDn} +member: cn=Group 550339,${ldapBaseDn} +member: cn=Group 550340,${ldapBaseDn} +member: cn=Group 550341,${ldapBaseDn} +member: cn=Group 550342,${ldapBaseDn} +member: cn=Group 550343,${ldapBaseDn} +member: cn=Group 550344,${ldapBaseDn} +member: cn=Group 550345,${ldapBaseDn} +member: cn=Group 550346,${ldapBaseDn} +member: cn=Group 550347,${ldapBaseDn} +member: cn=Group 550348,${ldapBaseDn} +member: cn=Group 550349,${ldapBaseDn} +member: cn=Group 550350,${ldapBaseDn} +member: cn=Group 550351,${ldapBaseDn} +member: cn=Group 550352,${ldapBaseDn} +member: cn=Group 550353,${ldapBaseDn} +member: cn=Group 550354,${ldapBaseDn} +member: cn=Group 550355,${ldapBaseDn} +member: cn=Group 550356,${ldapBaseDn} +member: cn=Group 550357,${ldapBaseDn} +member: cn=Group 550358,${ldapBaseDn} +member: cn=Group 550359,${ldapBaseDn} +member: cn=Group 550360,${ldapBaseDn} +member: cn=Group 550361,${ldapBaseDn} +member: cn=Group 550362,${ldapBaseDn} +member: cn=Group 550363,${ldapBaseDn} +member: cn=Group 550364,${ldapBaseDn} +member: cn=Group 550365,${ldapBaseDn} +member: cn=Group 550366,${ldapBaseDn} +member: cn=Group 550367,${ldapBaseDn} +member: cn=Group 550368,${ldapBaseDn} +member: cn=Group 550369,${ldapBaseDn} +member: cn=Group 550370,${ldapBaseDn} +member: cn=Group 550371,${ldapBaseDn} +member: cn=Group 550372,${ldapBaseDn} +member: cn=Group 550373,${ldapBaseDn} +member: cn=Group 550374,${ldapBaseDn} +member: cn=Group 550375,${ldapBaseDn} +member: cn=Group 550376,${ldapBaseDn} +member: cn=Group 550377,${ldapBaseDn} +member: cn=Group 550378,${ldapBaseDn} +member: cn=Group 550379,${ldapBaseDn} +member: cn=Group 550380,${ldapBaseDn} +member: cn=Group 550381,${ldapBaseDn} +member: cn=Group 550382,${ldapBaseDn} +member: cn=Group 550383,${ldapBaseDn} +member: cn=Group 550384,${ldapBaseDn} +member: cn=Group 550385,${ldapBaseDn} +member: cn=Group 550386,${ldapBaseDn} +member: cn=Group 550387,${ldapBaseDn} +member: cn=Group 550388,${ldapBaseDn} +member: cn=Group 550389,${ldapBaseDn} +member: cn=Group 550390,${ldapBaseDn} +member: cn=Group 550391,${ldapBaseDn} +member: cn=Group 550392,${ldapBaseDn} +member: cn=Group 550393,${ldapBaseDn} +member: cn=Group 550394,${ldapBaseDn} +member: cn=Group 550395,${ldapBaseDn} +member: cn=Group 550396,${ldapBaseDn} +member: cn=Group 550397,${ldapBaseDn} +member: cn=Group 550398,${ldapBaseDn} +member: cn=Group 550399,${ldapBaseDn} +member: cn=Group 550400,${ldapBaseDn} +member: cn=Group 550401,${ldapBaseDn} +member: cn=Group 550402,${ldapBaseDn} +member: cn=Group 550403,${ldapBaseDn} +member: cn=Group 550404,${ldapBaseDn} +member: cn=Group 550405,${ldapBaseDn} +member: cn=Group 550406,${ldapBaseDn} +member: cn=Group 550407,${ldapBaseDn} +member: cn=Group 550408,${ldapBaseDn} +member: cn=Group 550409,${ldapBaseDn} +member: cn=Group 550410,${ldapBaseDn} +member: cn=Group 550411,${ldapBaseDn} +member: cn=Group 550412,${ldapBaseDn} +member: cn=Group 550413,${ldapBaseDn} +member: cn=Group 550414,${ldapBaseDn} +member: cn=Group 550415,${ldapBaseDn} +member: cn=Group 550416,${ldapBaseDn} +member: cn=Group 550417,${ldapBaseDn} +member: cn=Group 550418,${ldapBaseDn} +member: cn=Group 550419,${ldapBaseDn} +member: cn=Group 550420,${ldapBaseDn} +member: cn=Group 550421,${ldapBaseDn} +member: cn=Group 550422,${ldapBaseDn} +member: cn=Group 550423,${ldapBaseDn} +member: cn=Group 550424,${ldapBaseDn} +member: cn=Group 550425,${ldapBaseDn} +member: cn=Group 550426,${ldapBaseDn} +member: cn=Group 550427,${ldapBaseDn} +member: cn=Group 550428,${ldapBaseDn} +member: cn=Group 550429,${ldapBaseDn} +member: cn=Group 550430,${ldapBaseDn} +member: cn=Group 550431,${ldapBaseDn} +member: cn=Group 550432,${ldapBaseDn} +member: cn=Group 550433,${ldapBaseDn} +member: cn=Group 550434,${ldapBaseDn} +member: cn=Group 550435,${ldapBaseDn} +member: cn=Group 550436,${ldapBaseDn} +member: cn=Group 550437,${ldapBaseDn} +member: cn=Group 550438,${ldapBaseDn} +member: cn=Group 550439,${ldapBaseDn} +member: cn=Group 550440,${ldapBaseDn} +member: cn=Group 550441,${ldapBaseDn} +member: cn=Group 550442,${ldapBaseDn} +member: cn=Group 550443,${ldapBaseDn} +member: cn=Group 550444,${ldapBaseDn} +member: cn=Group 550445,${ldapBaseDn} +member: cn=Group 550446,${ldapBaseDn} +member: cn=Group 550447,${ldapBaseDn} +member: cn=Group 550448,${ldapBaseDn} +member: cn=Group 550449,${ldapBaseDn} +member: cn=Group 550450,${ldapBaseDn} +member: cn=Group 550451,${ldapBaseDn} +member: cn=Group 550452,${ldapBaseDn} +member: cn=Group 550453,${ldapBaseDn} +member: cn=Group 550454,${ldapBaseDn} +member: cn=Group 550455,${ldapBaseDn} +member: cn=Group 550456,${ldapBaseDn} +member: cn=Group 550457,${ldapBaseDn} +member: cn=Group 550458,${ldapBaseDn} +member: cn=Group 550459,${ldapBaseDn} +member: cn=Group 550460,${ldapBaseDn} +member: cn=Group 550461,${ldapBaseDn} +member: cn=Group 550462,${ldapBaseDn} +member: cn=Group 550463,${ldapBaseDn} +member: cn=Group 550464,${ldapBaseDn} +member: cn=Group 550465,${ldapBaseDn} +member: cn=Group 550466,${ldapBaseDn} +member: cn=Group 550467,${ldapBaseDn} +member: cn=Group 550468,${ldapBaseDn} +member: cn=Group 550469,${ldapBaseDn} +member: cn=Group 550470,${ldapBaseDn} +member: cn=Group 550471,${ldapBaseDn} +member: cn=Group 550472,${ldapBaseDn} +member: cn=Group 550473,${ldapBaseDn} +member: cn=Group 550474,${ldapBaseDn} +member: cn=Group 550475,${ldapBaseDn} +member: cn=Group 550476,${ldapBaseDn} +member: cn=Group 550477,${ldapBaseDn} +member: cn=Group 550478,${ldapBaseDn} +member: cn=Group 550479,${ldapBaseDn} +member: cn=Group 550480,${ldapBaseDn} +member: cn=Group 550481,${ldapBaseDn} +member: cn=Group 550482,${ldapBaseDn} +member: cn=Group 550483,${ldapBaseDn} +member: cn=Group 550484,${ldapBaseDn} +member: cn=Group 550485,${ldapBaseDn} +member: cn=Group 550486,${ldapBaseDn} +member: cn=Group 550487,${ldapBaseDn} +member: cn=Group 550488,${ldapBaseDn} +member: cn=Group 550489,${ldapBaseDn} +member: cn=Group 550490,${ldapBaseDn} +member: cn=Group 550491,${ldapBaseDn} +member: cn=Group 550492,${ldapBaseDn} +member: cn=Group 550493,${ldapBaseDn} +member: cn=Group 550494,${ldapBaseDn} +member: cn=Group 550495,${ldapBaseDn} +member: cn=Group 550496,${ldapBaseDn} +member: cn=Group 550497,${ldapBaseDn} +member: cn=Group 550498,${ldapBaseDn} +member: cn=Group 550499,${ldapBaseDn} +member: cn=Group 550500,${ldapBaseDn} +member: cn=Group 550501,${ldapBaseDn} +member: cn=Group 550502,${ldapBaseDn} +member: cn=Group 550503,${ldapBaseDn} +member: cn=Group 550504,${ldapBaseDn} +member: cn=Group 550505,${ldapBaseDn} +member: cn=Group 550506,${ldapBaseDn} +member: cn=Group 550507,${ldapBaseDn} +member: cn=Group 550508,${ldapBaseDn} +member: cn=Group 550509,${ldapBaseDn} +member: cn=Group 550510,${ldapBaseDn} +member: cn=Group 550511,${ldapBaseDn} +member: cn=Group 550512,${ldapBaseDn} +member: cn=Group 550513,${ldapBaseDn} +member: cn=Group 550514,${ldapBaseDn} +member: cn=Group 550515,${ldapBaseDn} +member: cn=Group 550516,${ldapBaseDn} +member: cn=Group 550517,${ldapBaseDn} +member: cn=Group 550518,${ldapBaseDn} +member: cn=Group 550519,${ldapBaseDn} +member: cn=Group 550520,${ldapBaseDn} +member: cn=Group 550521,${ldapBaseDn} +member: cn=Group 550522,${ldapBaseDn} +member: cn=Group 550523,${ldapBaseDn} +member: cn=Group 550524,${ldapBaseDn} +member: cn=Group 550525,${ldapBaseDn} +member: cn=Group 550526,${ldapBaseDn} +member: cn=Group 550527,${ldapBaseDn} +member: cn=Group 550528,${ldapBaseDn} +member: cn=Group 550529,${ldapBaseDn} +member: cn=Group 550530,${ldapBaseDn} +member: cn=Group 550531,${ldapBaseDn} +member: cn=Group 550532,${ldapBaseDn} +member: cn=Group 550533,${ldapBaseDn} +member: cn=Group 550534,${ldapBaseDn} +member: cn=Group 550535,${ldapBaseDn} +member: cn=Group 550536,${ldapBaseDn} +member: cn=Group 550537,${ldapBaseDn} +member: cn=Group 550538,${ldapBaseDn} +member: cn=Group 550539,${ldapBaseDn} +member: cn=Group 550540,${ldapBaseDn} +member: cn=Group 550541,${ldapBaseDn} +member: cn=Group 550542,${ldapBaseDn} +member: cn=Group 550543,${ldapBaseDn} +member: cn=Group 550544,${ldapBaseDn} +member: cn=Group 550545,${ldapBaseDn} +member: cn=Group 550546,${ldapBaseDn} +member: cn=Group 550547,${ldapBaseDn} +member: cn=Group 550548,${ldapBaseDn} +member: cn=Group 550549,${ldapBaseDn} +member: cn=Group 550550,${ldapBaseDn} +member: cn=Group 550551,${ldapBaseDn} +member: cn=Group 550552,${ldapBaseDn} +member: cn=Group 550553,${ldapBaseDn} +member: cn=Group 550554,${ldapBaseDn} +member: cn=Group 550555,${ldapBaseDn} +member: cn=Group 550556,${ldapBaseDn} +member: cn=Group 550557,${ldapBaseDn} +member: cn=Group 550558,${ldapBaseDn} +member: cn=Group 550559,${ldapBaseDn} +member: cn=Group 550560,${ldapBaseDn} +member: cn=Group 550561,${ldapBaseDn} +member: cn=Group 550562,${ldapBaseDn} +member: cn=Group 550563,${ldapBaseDn} +member: cn=Group 550564,${ldapBaseDn} +member: cn=Group 550565,${ldapBaseDn} +member: cn=Group 550566,${ldapBaseDn} +member: cn=Group 550567,${ldapBaseDn} +member: cn=Group 550568,${ldapBaseDn} +member: cn=Group 550569,${ldapBaseDn} +member: cn=Group 550570,${ldapBaseDn} +member: cn=Group 550571,${ldapBaseDn} +member: cn=Group 550572,${ldapBaseDn} +member: cn=Group 550573,${ldapBaseDn} +member: cn=Group 550574,${ldapBaseDn} +member: cn=Group 550575,${ldapBaseDn} +member: cn=Group 550576,${ldapBaseDn} +member: cn=Group 550577,${ldapBaseDn} +member: cn=Group 550578,${ldapBaseDn} +member: cn=Group 550579,${ldapBaseDn} +member: cn=Group 550580,${ldapBaseDn} +member: cn=Group 550581,${ldapBaseDn} +member: cn=Group 550582,${ldapBaseDn} +member: cn=Group 550583,${ldapBaseDn} +member: cn=Group 550584,${ldapBaseDn} +member: cn=Group 550585,${ldapBaseDn} +member: cn=Group 550586,${ldapBaseDn} +member: cn=Group 550587,${ldapBaseDn} +member: cn=Group 550588,${ldapBaseDn} +member: cn=Group 550589,${ldapBaseDn} +member: cn=Group 550590,${ldapBaseDn} +member: cn=Group 550591,${ldapBaseDn} +member: cn=Group 550592,${ldapBaseDn} +member: cn=Group 550593,${ldapBaseDn} +member: cn=Group 550594,${ldapBaseDn} +member: cn=Group 550595,${ldapBaseDn} +member: cn=Group 550596,${ldapBaseDn} +member: cn=Group 550597,${ldapBaseDn} +member: cn=Group 550598,${ldapBaseDn} +member: cn=Group 550599,${ldapBaseDn} +member: cn=Group 550600,${ldapBaseDn} +member: cn=Group 550601,${ldapBaseDn} +member: cn=Group 550602,${ldapBaseDn} +member: cn=Group 550603,${ldapBaseDn} +member: cn=Group 550604,${ldapBaseDn} +member: cn=Group 550605,${ldapBaseDn} +member: cn=Group 550606,${ldapBaseDn} +member: cn=Group 550607,${ldapBaseDn} +member: cn=Group 550608,${ldapBaseDn} +member: cn=Group 550609,${ldapBaseDn} +member: cn=Group 550610,${ldapBaseDn} +member: cn=Group 550611,${ldapBaseDn} +member: cn=Group 550612,${ldapBaseDn} +member: cn=Group 550613,${ldapBaseDn} +member: cn=Group 550614,${ldapBaseDn} +member: cn=Group 550615,${ldapBaseDn} +member: cn=Group 550616,${ldapBaseDn} +member: cn=Group 550617,${ldapBaseDn} +member: cn=Group 550618,${ldapBaseDn} +member: cn=Group 550619,${ldapBaseDn} +member: cn=Group 550620,${ldapBaseDn} +member: cn=Group 550621,${ldapBaseDn} +member: cn=Group 550622,${ldapBaseDn} +member: cn=Group 550623,${ldapBaseDn} +member: cn=Group 550624,${ldapBaseDn} +member: cn=Group 550625,${ldapBaseDn} +member: cn=Group 550626,${ldapBaseDn} +member: cn=Group 550627,${ldapBaseDn} +member: cn=Group 550628,${ldapBaseDn} +member: cn=Group 550629,${ldapBaseDn} +member: cn=Group 550630,${ldapBaseDn} +member: cn=Group 550631,${ldapBaseDn} +member: cn=Group 550632,${ldapBaseDn} +member: cn=Group 550633,${ldapBaseDn} +member: cn=Group 550634,${ldapBaseDn} +member: cn=Group 550635,${ldapBaseDn} +member: cn=Group 550636,${ldapBaseDn} +member: cn=Group 550637,${ldapBaseDn} +member: cn=Group 550638,${ldapBaseDn} +member: cn=Group 550639,${ldapBaseDn} +member: cn=Group 550640,${ldapBaseDn} +member: cn=Group 550641,${ldapBaseDn} +member: cn=Group 550642,${ldapBaseDn} +member: cn=Group 550643,${ldapBaseDn} +member: cn=Group 550644,${ldapBaseDn} +member: cn=Group 550645,${ldapBaseDn} +member: cn=Group 550646,${ldapBaseDn} +member: cn=Group 550647,${ldapBaseDn} +member: cn=Group 550648,${ldapBaseDn} +member: cn=Group 550649,${ldapBaseDn} +member: cn=Group 550650,${ldapBaseDn} +member: cn=Group 550651,${ldapBaseDn} +member: cn=Group 550652,${ldapBaseDn} +member: cn=Group 550653,${ldapBaseDn} +member: cn=Group 550654,${ldapBaseDn} +member: cn=Group 550655,${ldapBaseDn} +member: cn=Group 550656,${ldapBaseDn} +member: cn=Group 550657,${ldapBaseDn} +member: cn=Group 550658,${ldapBaseDn} +member: cn=Group 550659,${ldapBaseDn} +member: cn=Group 550660,${ldapBaseDn} +member: cn=Group 550661,${ldapBaseDn} +member: cn=Group 550662,${ldapBaseDn} +member: cn=Group 550663,${ldapBaseDn} +member: cn=Group 550664,${ldapBaseDn} +member: cn=Group 550665,${ldapBaseDn} +member: cn=Group 550666,${ldapBaseDn} +member: cn=Group 550667,${ldapBaseDn} +member: cn=Group 550668,${ldapBaseDn} +member: cn=Group 550669,${ldapBaseDn} +member: cn=Group 550670,${ldapBaseDn} +member: cn=Group 550671,${ldapBaseDn} +member: cn=Group 550672,${ldapBaseDn} +member: cn=Group 550673,${ldapBaseDn} +member: cn=Group 550674,${ldapBaseDn} +member: cn=Group 550675,${ldapBaseDn} +member: cn=Group 550676,${ldapBaseDn} +member: cn=Group 550677,${ldapBaseDn} +member: cn=Group 550678,${ldapBaseDn} +member: cn=Group 550679,${ldapBaseDn} +member: cn=Group 550680,${ldapBaseDn} +member: cn=Group 550681,${ldapBaseDn} +member: cn=Group 550682,${ldapBaseDn} +member: cn=Group 550683,${ldapBaseDn} +member: cn=Group 550684,${ldapBaseDn} +member: cn=Group 550685,${ldapBaseDn} +member: cn=Group 550686,${ldapBaseDn} +member: cn=Group 550687,${ldapBaseDn} +member: cn=Group 550688,${ldapBaseDn} +member: cn=Group 550689,${ldapBaseDn} +member: cn=Group 550690,${ldapBaseDn} +member: cn=Group 550691,${ldapBaseDn} +member: cn=Group 550692,${ldapBaseDn} +member: cn=Group 550693,${ldapBaseDn} +member: cn=Group 550694,${ldapBaseDn} +member: cn=Group 550695,${ldapBaseDn} +member: cn=Group 550696,${ldapBaseDn} +member: cn=Group 550697,${ldapBaseDn} +member: cn=Group 550698,${ldapBaseDn} +member: cn=Group 550699,${ldapBaseDn} +member: cn=Group 550700,${ldapBaseDn} +member: cn=Group 550701,${ldapBaseDn} +member: cn=Group 550702,${ldapBaseDn} +member: cn=Group 550703,${ldapBaseDn} +member: cn=Group 550704,${ldapBaseDn} +member: cn=Group 550705,${ldapBaseDn} +member: cn=Group 550706,${ldapBaseDn} +member: cn=Group 550707,${ldapBaseDn} +member: cn=Group 550708,${ldapBaseDn} +member: cn=Group 550709,${ldapBaseDn} +member: cn=Group 550710,${ldapBaseDn} +member: cn=Group 550711,${ldapBaseDn} +member: cn=Group 550712,${ldapBaseDn} +member: cn=Group 550713,${ldapBaseDn} +member: cn=Group 550714,${ldapBaseDn} +member: cn=Group 550715,${ldapBaseDn} +member: cn=Group 550716,${ldapBaseDn} +member: cn=Group 550717,${ldapBaseDn} +member: cn=Group 550718,${ldapBaseDn} +member: cn=Group 550719,${ldapBaseDn} +member: cn=Group 550720,${ldapBaseDn} +member: cn=Group 550721,${ldapBaseDn} +member: cn=Group 550722,${ldapBaseDn} +member: cn=Group 550723,${ldapBaseDn} +member: cn=Group 550724,${ldapBaseDn} +member: cn=Group 550725,${ldapBaseDn} +member: cn=Group 550726,${ldapBaseDn} +member: cn=Group 550727,${ldapBaseDn} +member: cn=Group 550728,${ldapBaseDn} +member: cn=Group 550729,${ldapBaseDn} +member: cn=Group 550730,${ldapBaseDn} +member: cn=Group 550731,${ldapBaseDn} +member: cn=Group 550732,${ldapBaseDn} +member: cn=Group 550733,${ldapBaseDn} +member: cn=Group 550734,${ldapBaseDn} +member: cn=Group 550735,${ldapBaseDn} +member: cn=Group 550736,${ldapBaseDn} +member: cn=Group 550737,${ldapBaseDn} +member: cn=Group 550738,${ldapBaseDn} +member: cn=Group 550739,${ldapBaseDn} +member: cn=Group 550740,${ldapBaseDn} +member: cn=Group 550741,${ldapBaseDn} +member: cn=Group 550742,${ldapBaseDn} +member: cn=Group 550743,${ldapBaseDn} +member: cn=Group 550744,${ldapBaseDn} +member: cn=Group 550745,${ldapBaseDn} +member: cn=Group 550746,${ldapBaseDn} +member: cn=Group 550747,${ldapBaseDn} +member: cn=Group 550748,${ldapBaseDn} +member: cn=Group 550749,${ldapBaseDn} +member: cn=Group 550750,${ldapBaseDn} +member: cn=Group 550751,${ldapBaseDn} +member: cn=Group 550752,${ldapBaseDn} +member: cn=Group 550753,${ldapBaseDn} +member: cn=Group 550754,${ldapBaseDn} +member: cn=Group 550755,${ldapBaseDn} +member: cn=Group 550756,${ldapBaseDn} +member: cn=Group 550757,${ldapBaseDn} +member: cn=Group 550758,${ldapBaseDn} +member: cn=Group 550759,${ldapBaseDn} +member: cn=Group 550760,${ldapBaseDn} +member: cn=Group 550761,${ldapBaseDn} +member: cn=Group 550762,${ldapBaseDn} +member: cn=Group 550763,${ldapBaseDn} +member: cn=Group 550764,${ldapBaseDn} +member: cn=Group 550765,${ldapBaseDn} +member: cn=Group 550766,${ldapBaseDn} +member: cn=Group 550767,${ldapBaseDn} +member: cn=Group 550768,${ldapBaseDn} +member: cn=Group 550769,${ldapBaseDn} +member: cn=Group 550770,${ldapBaseDn} +member: cn=Group 550771,${ldapBaseDn} +member: cn=Group 550772,${ldapBaseDn} +member: cn=Group 550773,${ldapBaseDn} +member: cn=Group 550774,${ldapBaseDn} +member: cn=Group 550775,${ldapBaseDn} +member: cn=Group 550776,${ldapBaseDn} +member: cn=Group 550777,${ldapBaseDn} +member: cn=Group 550778,${ldapBaseDn} +member: cn=Group 550779,${ldapBaseDn} +member: cn=Group 550780,${ldapBaseDn} +member: cn=Group 550781,${ldapBaseDn} +member: cn=Group 550782,${ldapBaseDn} +member: cn=Group 550783,${ldapBaseDn} +member: cn=Group 550784,${ldapBaseDn} +member: cn=Group 550785,${ldapBaseDn} +member: cn=Group 550786,${ldapBaseDn} +member: cn=Group 550787,${ldapBaseDn} +member: cn=Group 550788,${ldapBaseDn} +member: cn=Group 550789,${ldapBaseDn} +member: cn=Group 550790,${ldapBaseDn} +member: cn=Group 550791,${ldapBaseDn} +member: cn=Group 550792,${ldapBaseDn} +member: cn=Group 550793,${ldapBaseDn} +member: cn=Group 550794,${ldapBaseDn} +member: cn=Group 550795,${ldapBaseDn} +member: cn=Group 550796,${ldapBaseDn} +member: cn=Group 550797,${ldapBaseDn} +member: cn=Group 550798,${ldapBaseDn} +member: cn=Group 550799,${ldapBaseDn} +member: cn=Group 550800,${ldapBaseDn} +member: cn=Group 550801,${ldapBaseDn} +member: cn=Group 550802,${ldapBaseDn} +member: cn=Group 550803,${ldapBaseDn} +member: cn=Group 550804,${ldapBaseDn} +member: cn=Group 550805,${ldapBaseDn} +member: cn=Group 550806,${ldapBaseDn} +member: cn=Group 550807,${ldapBaseDn} +member: cn=Group 550808,${ldapBaseDn} +member: cn=Group 550809,${ldapBaseDn} +member: cn=Group 550810,${ldapBaseDn} +member: cn=Group 550811,${ldapBaseDn} +member: cn=Group 550812,${ldapBaseDn} +member: cn=Group 550813,${ldapBaseDn} +member: cn=Group 550814,${ldapBaseDn} +member: cn=Group 550815,${ldapBaseDn} +member: cn=Group 550816,${ldapBaseDn} +member: cn=Group 550817,${ldapBaseDn} +member: cn=Group 550818,${ldapBaseDn} +member: cn=Group 550819,${ldapBaseDn} +member: cn=Group 550820,${ldapBaseDn} +member: cn=Group 550821,${ldapBaseDn} +member: cn=Group 550822,${ldapBaseDn} +member: cn=Group 550823,${ldapBaseDn} +member: cn=Group 550824,${ldapBaseDn} +member: cn=Group 550825,${ldapBaseDn} +member: cn=Group 550826,${ldapBaseDn} +member: cn=Group 550827,${ldapBaseDn} +member: cn=Group 550828,${ldapBaseDn} +member: cn=Group 550829,${ldapBaseDn} +member: cn=Group 550830,${ldapBaseDn} +member: cn=Group 550831,${ldapBaseDn} +member: cn=Group 550832,${ldapBaseDn} +member: cn=Group 550833,${ldapBaseDn} +member: cn=Group 550834,${ldapBaseDn} +member: cn=Group 550835,${ldapBaseDn} +member: cn=Group 550836,${ldapBaseDn} +member: cn=Group 550837,${ldapBaseDn} +member: cn=Group 550838,${ldapBaseDn} +member: cn=Group 550839,${ldapBaseDn} +member: cn=Group 550840,${ldapBaseDn} +member: cn=Group 550841,${ldapBaseDn} +member: cn=Group 550842,${ldapBaseDn} +member: cn=Group 550843,${ldapBaseDn} +member: cn=Group 550844,${ldapBaseDn} +member: cn=Group 550845,${ldapBaseDn} +member: cn=Group 550846,${ldapBaseDn} +member: cn=Group 550847,${ldapBaseDn} +member: cn=Group 550848,${ldapBaseDn} +member: cn=Group 550849,${ldapBaseDn} +member: cn=Group 550850,${ldapBaseDn} +member: cn=Group 550851,${ldapBaseDn} +member: cn=Group 550852,${ldapBaseDn} +member: cn=Group 550853,${ldapBaseDn} +member: cn=Group 550854,${ldapBaseDn} +member: cn=Group 550855,${ldapBaseDn} +member: cn=Group 550856,${ldapBaseDn} +member: cn=Group 550857,${ldapBaseDn} +member: cn=Group 550858,${ldapBaseDn} +member: cn=Group 550859,${ldapBaseDn} +member: cn=Group 550860,${ldapBaseDn} +member: cn=Group 550861,${ldapBaseDn} +member: cn=Group 550862,${ldapBaseDn} +member: cn=Group 550863,${ldapBaseDn} +member: cn=Group 550864,${ldapBaseDn} +member: cn=Group 550865,${ldapBaseDn} +member: cn=Group 550866,${ldapBaseDn} +member: cn=Group 550867,${ldapBaseDn} +member: cn=Group 550868,${ldapBaseDn} +member: cn=Group 550869,${ldapBaseDn} +member: cn=Group 550870,${ldapBaseDn} +member: cn=Group 550871,${ldapBaseDn} +member: cn=Group 550872,${ldapBaseDn} +member: cn=Group 550873,${ldapBaseDn} +member: cn=Group 550874,${ldapBaseDn} +member: cn=Group 550875,${ldapBaseDn} +member: cn=Group 550876,${ldapBaseDn} +member: cn=Group 550877,${ldapBaseDn} +member: cn=Group 550878,${ldapBaseDn} +member: cn=Group 550879,${ldapBaseDn} +member: cn=Group 550880,${ldapBaseDn} +member: cn=Group 550881,${ldapBaseDn} +member: cn=Group 550882,${ldapBaseDn} +member: cn=Group 550883,${ldapBaseDn} +member: cn=Group 550884,${ldapBaseDn} +member: cn=Group 550885,${ldapBaseDn} +member: cn=Group 550886,${ldapBaseDn} +member: cn=Group 550887,${ldapBaseDn} +member: cn=Group 550888,${ldapBaseDn} +member: cn=Group 550889,${ldapBaseDn} +member: cn=Group 550890,${ldapBaseDn} +member: cn=Group 550891,${ldapBaseDn} +member: cn=Group 550892,${ldapBaseDn} +member: cn=Group 550893,${ldapBaseDn} +member: cn=Group 550894,${ldapBaseDn} +member: cn=Group 550895,${ldapBaseDn} +member: cn=Group 550896,${ldapBaseDn} +member: cn=Group 550897,${ldapBaseDn} +member: cn=Group 550898,${ldapBaseDn} +member: cn=Group 550899,${ldapBaseDn} +member: cn=Group 550900,${ldapBaseDn} +member: cn=Group 550901,${ldapBaseDn} +member: cn=Group 550902,${ldapBaseDn} +member: cn=Group 550903,${ldapBaseDn} +member: cn=Group 550904,${ldapBaseDn} +member: cn=Group 550905,${ldapBaseDn} +member: cn=Group 550906,${ldapBaseDn} +member: cn=Group 550907,${ldapBaseDn} +member: cn=Group 550908,${ldapBaseDn} +member: cn=Group 550909,${ldapBaseDn} +member: cn=Group 550910,${ldapBaseDn} +member: cn=Group 550911,${ldapBaseDn} +member: cn=Group 550912,${ldapBaseDn} +member: cn=Group 550913,${ldapBaseDn} +member: cn=Group 550914,${ldapBaseDn} +member: cn=Group 550915,${ldapBaseDn} +member: cn=Group 550916,${ldapBaseDn} +member: cn=Group 550917,${ldapBaseDn} +member: cn=Group 550918,${ldapBaseDn} +member: cn=Group 550919,${ldapBaseDn} +member: cn=Group 550920,${ldapBaseDn} +member: cn=Group 550921,${ldapBaseDn} +member: cn=Group 550922,${ldapBaseDn} +member: cn=Group 550923,${ldapBaseDn} +member: cn=Group 550924,${ldapBaseDn} +member: cn=Group 550925,${ldapBaseDn} +member: cn=Group 550926,${ldapBaseDn} +member: cn=Group 550927,${ldapBaseDn} +member: cn=Group 550928,${ldapBaseDn} +member: cn=Group 550929,${ldapBaseDn} +member: cn=Group 550930,${ldapBaseDn} +member: cn=Group 550931,${ldapBaseDn} +member: cn=Group 550932,${ldapBaseDn} +member: cn=Group 550933,${ldapBaseDn} +member: cn=Group 550934,${ldapBaseDn} +member: cn=Group 550935,${ldapBaseDn} +member: cn=Group 550936,${ldapBaseDn} +member: cn=Group 550937,${ldapBaseDn} +member: cn=Group 550938,${ldapBaseDn} +member: cn=Group 550939,${ldapBaseDn} +member: cn=Group 550940,${ldapBaseDn} +member: cn=Group 550941,${ldapBaseDn} +member: cn=Group 550942,${ldapBaseDn} +member: cn=Group 550943,${ldapBaseDn} +member: cn=Group 550944,${ldapBaseDn} +member: cn=Group 550945,${ldapBaseDn} +member: cn=Group 550946,${ldapBaseDn} +member: cn=Group 550947,${ldapBaseDn} +member: cn=Group 550948,${ldapBaseDn} +member: cn=Group 550949,${ldapBaseDn} +member: cn=Group 550950,${ldapBaseDn} +member: cn=Group 550951,${ldapBaseDn} +member: cn=Group 550952,${ldapBaseDn} +member: cn=Group 550953,${ldapBaseDn} +member: cn=Group 550954,${ldapBaseDn} +member: cn=Group 550955,${ldapBaseDn} +member: cn=Group 550956,${ldapBaseDn} +member: cn=Group 550957,${ldapBaseDn} +member: cn=Group 550958,${ldapBaseDn} +member: cn=Group 550959,${ldapBaseDn} +member: cn=Group 550960,${ldapBaseDn} +member: cn=Group 550961,${ldapBaseDn} +member: cn=Group 550962,${ldapBaseDn} +member: cn=Group 550963,${ldapBaseDn} +member: cn=Group 550964,${ldapBaseDn} +member: cn=Group 550965,${ldapBaseDn} +member: cn=Group 550966,${ldapBaseDn} +member: cn=Group 550967,${ldapBaseDn} +member: cn=Group 550968,${ldapBaseDn} +member: cn=Group 550969,${ldapBaseDn} +member: cn=Group 550970,${ldapBaseDn} +member: cn=Group 550971,${ldapBaseDn} +member: cn=Group 550972,${ldapBaseDn} +member: cn=Group 550973,${ldapBaseDn} +member: cn=Group 550974,${ldapBaseDn} +member: cn=Group 550975,${ldapBaseDn} +member: cn=Group 550976,${ldapBaseDn} +member: cn=Group 550977,${ldapBaseDn} +member: cn=Group 550978,${ldapBaseDn} +member: cn=Group 550979,${ldapBaseDn} +member: cn=Group 550980,${ldapBaseDn} +member: cn=Group 550981,${ldapBaseDn} +member: cn=Group 550982,${ldapBaseDn} +member: cn=Group 550983,${ldapBaseDn} +member: cn=Group 550984,${ldapBaseDn} +member: cn=Group 550985,${ldapBaseDn} +member: cn=Group 550986,${ldapBaseDn} +member: cn=Group 550987,${ldapBaseDn} +member: cn=Group 550988,${ldapBaseDn} +member: cn=Group 550989,${ldapBaseDn} +member: cn=Group 550990,${ldapBaseDn} +member: cn=Group 550991,${ldapBaseDn} +member: cn=Group 550992,${ldapBaseDn} +member: cn=Group 550993,${ldapBaseDn} +member: cn=Group 550994,${ldapBaseDn} +member: cn=Group 550995,${ldapBaseDn} +member: cn=Group 550996,${ldapBaseDn} +member: cn=Group 550997,${ldapBaseDn} +member: cn=Group 550998,${ldapBaseDn} +member: cn=Group 550999,${ldapBaseDn} +member: cn=Group 551000,${ldapBaseDn} +member: cn=Group 551001,${ldapBaseDn} +member: cn=Group 551002,${ldapBaseDn} +member: cn=Group 551003,${ldapBaseDn} +member: cn=Group 551004,${ldapBaseDn} +member: cn=Group 551005,${ldapBaseDn} +member: cn=Group 551006,${ldapBaseDn} +member: cn=Group 551007,${ldapBaseDn} +member: cn=Group 551008,${ldapBaseDn} +member: cn=Group 551009,${ldapBaseDn} +member: cn=Group 551010,${ldapBaseDn} +member: cn=Group 551011,${ldapBaseDn} +member: cn=Group 551012,${ldapBaseDn} +member: cn=Group 551013,${ldapBaseDn} +member: cn=Group 551014,${ldapBaseDn} +member: cn=Group 551015,${ldapBaseDn} +member: cn=Group 551016,${ldapBaseDn} +member: cn=Group 551017,${ldapBaseDn} +member: cn=Group 551018,${ldapBaseDn} +member: cn=Group 551019,${ldapBaseDn} +member: cn=Group 551020,${ldapBaseDn} +member: cn=Group 551021,${ldapBaseDn} +member: cn=Group 551022,${ldapBaseDn} +member: cn=Group 551023,${ldapBaseDn} +member: cn=Group 551024,${ldapBaseDn} +member: cn=Group 551025,${ldapBaseDn} +member: cn=Group 551026,${ldapBaseDn} +member: cn=Group 551027,${ldapBaseDn} +member: cn=Group 551028,${ldapBaseDn} +member: cn=Group 551029,${ldapBaseDn} +member: cn=Group 551030,${ldapBaseDn} +member: cn=Group 551031,${ldapBaseDn} +member: cn=Group 551032,${ldapBaseDn} +member: cn=Group 551033,${ldapBaseDn} +member: cn=Group 551034,${ldapBaseDn} +member: cn=Group 551035,${ldapBaseDn} +member: cn=Group 551036,${ldapBaseDn} +member: cn=Group 551037,${ldapBaseDn} +member: cn=Group 551038,${ldapBaseDn} +member: cn=Group 551039,${ldapBaseDn} +member: cn=Group 551040,${ldapBaseDn} +member: cn=Group 551041,${ldapBaseDn} +member: cn=Group 551042,${ldapBaseDn} +member: cn=Group 551043,${ldapBaseDn} +member: cn=Group 551044,${ldapBaseDn} +member: cn=Group 551045,${ldapBaseDn} +member: cn=Group 551046,${ldapBaseDn} +member: cn=Group 551047,${ldapBaseDn} +member: cn=Group 551048,${ldapBaseDn} +member: cn=Group 551049,${ldapBaseDn} +member: cn=Group 551050,${ldapBaseDn} +member: cn=Group 551051,${ldapBaseDn} +member: cn=Group 551052,${ldapBaseDn} +member: cn=Group 551053,${ldapBaseDn} +member: cn=Group 551054,${ldapBaseDn} +member: cn=Group 551055,${ldapBaseDn} +member: cn=Group 551056,${ldapBaseDn} +member: cn=Group 551057,${ldapBaseDn} +member: cn=Group 551058,${ldapBaseDn} +member: cn=Group 551059,${ldapBaseDn} +member: cn=Group 551060,${ldapBaseDn} +member: cn=Group 551061,${ldapBaseDn} +member: cn=Group 551062,${ldapBaseDn} +member: cn=Group 551063,${ldapBaseDn} +member: cn=Group 551064,${ldapBaseDn} +member: cn=Group 551065,${ldapBaseDn} +member: cn=Group 551066,${ldapBaseDn} +member: cn=Group 551067,${ldapBaseDn} +member: cn=Group 551068,${ldapBaseDn} +member: cn=Group 551069,${ldapBaseDn} +member: cn=Group 551070,${ldapBaseDn} +member: cn=Group 551071,${ldapBaseDn} +member: cn=Group 551072,${ldapBaseDn} +member: cn=Group 551073,${ldapBaseDn} +member: cn=Group 551074,${ldapBaseDn} +member: cn=Group 551075,${ldapBaseDn} +member: cn=Group 551076,${ldapBaseDn} +member: cn=Group 551077,${ldapBaseDn} +member: cn=Group 551078,${ldapBaseDn} +member: cn=Group 551079,${ldapBaseDn} +member: cn=Group 551080,${ldapBaseDn} +member: cn=Group 551081,${ldapBaseDn} +member: cn=Group 551082,${ldapBaseDn} +member: cn=Group 551083,${ldapBaseDn} +member: cn=Group 551084,${ldapBaseDn} +member: cn=Group 551085,${ldapBaseDn} +member: cn=Group 551086,${ldapBaseDn} +member: cn=Group 551087,${ldapBaseDn} +member: cn=Group 551088,${ldapBaseDn} +member: cn=Group 551089,${ldapBaseDn} +member: cn=Group 551090,${ldapBaseDn} +member: cn=Group 551091,${ldapBaseDn} +member: cn=Group 551092,${ldapBaseDn} +member: cn=Group 551093,${ldapBaseDn} +member: cn=Group 551094,${ldapBaseDn} +member: cn=Group 551095,${ldapBaseDn} +member: cn=Group 551096,${ldapBaseDn} +member: cn=Group 551097,${ldapBaseDn} +member: cn=Group 551098,${ldapBaseDn} +member: cn=Group 551099,${ldapBaseDn} +member: cn=Group 551100,${ldapBaseDn} +member: cn=Group 551101,${ldapBaseDn} +member: cn=Group 551102,${ldapBaseDn} +member: cn=Group 551103,${ldapBaseDn} +member: cn=Group 551104,${ldapBaseDn} +member: cn=Group 551105,${ldapBaseDn} +member: cn=Group 551106,${ldapBaseDn} +member: cn=Group 551107,${ldapBaseDn} +member: cn=Group 551108,${ldapBaseDn} +member: cn=Group 551109,${ldapBaseDn} +member: cn=Group 551110,${ldapBaseDn} +member: cn=Group 551111,${ldapBaseDn} +member: cn=Group 551112,${ldapBaseDn} +member: cn=Group 551113,${ldapBaseDn} +member: cn=Group 551114,${ldapBaseDn} +member: cn=Group 551115,${ldapBaseDn} +member: cn=Group 551116,${ldapBaseDn} +member: cn=Group 551117,${ldapBaseDn} +member: cn=Group 551118,${ldapBaseDn} +member: cn=Group 551119,${ldapBaseDn} +member: cn=Group 551120,${ldapBaseDn} +member: cn=Group 551121,${ldapBaseDn} +member: cn=Group 551122,${ldapBaseDn} +member: cn=Group 551123,${ldapBaseDn} +member: cn=Group 551124,${ldapBaseDn} +member: cn=Group 551125,${ldapBaseDn} +member: cn=Group 551126,${ldapBaseDn} +member: cn=Group 551127,${ldapBaseDn} +member: cn=Group 551128,${ldapBaseDn} +member: cn=Group 551129,${ldapBaseDn} +member: cn=Group 551130,${ldapBaseDn} +member: cn=Group 551131,${ldapBaseDn} +member: cn=Group 551132,${ldapBaseDn} +member: cn=Group 551133,${ldapBaseDn} +member: cn=Group 551134,${ldapBaseDn} +member: cn=Group 551135,${ldapBaseDn} +member: cn=Group 551136,${ldapBaseDn} +member: cn=Group 551137,${ldapBaseDn} +member: cn=Group 551138,${ldapBaseDn} +member: cn=Group 551139,${ldapBaseDn} +member: cn=Group 551140,${ldapBaseDn} +member: cn=Group 551141,${ldapBaseDn} +member: cn=Group 551142,${ldapBaseDn} +member: cn=Group 551143,${ldapBaseDn} +member: cn=Group 551144,${ldapBaseDn} +member: cn=Group 551145,${ldapBaseDn} +member: cn=Group 551146,${ldapBaseDn} +member: cn=Group 551147,${ldapBaseDn} +member: cn=Group 551148,${ldapBaseDn} +member: cn=Group 551149,${ldapBaseDn} +member: cn=Group 551150,${ldapBaseDn} +member: cn=Group 551151,${ldapBaseDn} +member: cn=Group 551152,${ldapBaseDn} +member: cn=Group 551153,${ldapBaseDn} +member: cn=Group 551154,${ldapBaseDn} +member: cn=Group 551155,${ldapBaseDn} +member: cn=Group 551156,${ldapBaseDn} +member: cn=Group 551157,${ldapBaseDn} +member: cn=Group 551158,${ldapBaseDn} +member: cn=Group 551159,${ldapBaseDn} +member: cn=Group 551160,${ldapBaseDn} +member: cn=Group 551161,${ldapBaseDn} +member: cn=Group 551162,${ldapBaseDn} +member: cn=Group 551163,${ldapBaseDn} +member: cn=Group 551164,${ldapBaseDn} +member: cn=Group 551165,${ldapBaseDn} +member: cn=Group 551166,${ldapBaseDn} +member: cn=Group 551167,${ldapBaseDn} +member: cn=Group 551168,${ldapBaseDn} +member: cn=Group 551169,${ldapBaseDn} +member: cn=Group 551170,${ldapBaseDn} +member: cn=Group 551171,${ldapBaseDn} +member: cn=Group 551172,${ldapBaseDn} +member: cn=Group 551173,${ldapBaseDn} +member: cn=Group 551174,${ldapBaseDn} +member: cn=Group 551175,${ldapBaseDn} +member: cn=Group 551176,${ldapBaseDn} +member: cn=Group 551177,${ldapBaseDn} +member: cn=Group 551178,${ldapBaseDn} +member: cn=Group 551179,${ldapBaseDn} +member: cn=Group 551180,${ldapBaseDn} +member: cn=Group 551181,${ldapBaseDn} +member: cn=Group 551182,${ldapBaseDn} +member: cn=Group 551183,${ldapBaseDn} +member: cn=Group 551184,${ldapBaseDn} +member: cn=Group 551185,${ldapBaseDn} +member: cn=Group 551186,${ldapBaseDn} +member: cn=Group 551187,${ldapBaseDn} +member: cn=Group 551188,${ldapBaseDn} +member: cn=Group 551189,${ldapBaseDn} +member: cn=Group 551190,${ldapBaseDn} +member: cn=Group 551191,${ldapBaseDn} +member: cn=Group 551192,${ldapBaseDn} +member: cn=Group 551193,${ldapBaseDn} +member: cn=Group 551194,${ldapBaseDn} +member: cn=Group 551195,${ldapBaseDn} +member: cn=Group 551196,${ldapBaseDn} +member: cn=Group 551197,${ldapBaseDn} +member: cn=Group 551198,${ldapBaseDn} +member: cn=Group 551199,${ldapBaseDn} +member: cn=Group 551200,${ldapBaseDn} +member: cn=Group 551201,${ldapBaseDn} +member: cn=Group 551202,${ldapBaseDn} +member: cn=Group 551203,${ldapBaseDn} +member: cn=Group 551204,${ldapBaseDn} +member: cn=Group 551205,${ldapBaseDn} +member: cn=Group 551206,${ldapBaseDn} +member: cn=Group 551207,${ldapBaseDn} +member: cn=Group 551208,${ldapBaseDn} +member: cn=Group 551209,${ldapBaseDn} +member: cn=Group 551210,${ldapBaseDn} +member: cn=Group 551211,${ldapBaseDn} +member: cn=Group 551212,${ldapBaseDn} +member: cn=Group 551213,${ldapBaseDn} +member: cn=Group 551214,${ldapBaseDn} +member: cn=Group 551215,${ldapBaseDn} +member: cn=Group 551216,${ldapBaseDn} +member: cn=Group 551217,${ldapBaseDn} +member: cn=Group 551218,${ldapBaseDn} +member: cn=Group 551219,${ldapBaseDn} +member: cn=Group 551220,${ldapBaseDn} +member: cn=Group 551221,${ldapBaseDn} +member: cn=Group 551222,${ldapBaseDn} +member: cn=Group 551223,${ldapBaseDn} +member: cn=Group 551224,${ldapBaseDn} +member: cn=Group 551225,${ldapBaseDn} +member: cn=Group 551226,${ldapBaseDn} +member: cn=Group 551227,${ldapBaseDn} +member: cn=Group 551228,${ldapBaseDn} +member: cn=Group 551229,${ldapBaseDn} +member: cn=Group 551230,${ldapBaseDn} +member: cn=Group 551231,${ldapBaseDn} +member: cn=Group 551232,${ldapBaseDn} +member: cn=Group 551233,${ldapBaseDn} +member: cn=Group 551234,${ldapBaseDn} +member: cn=Group 551235,${ldapBaseDn} +member: cn=Group 551236,${ldapBaseDn} +member: cn=Group 551237,${ldapBaseDn} +member: cn=Group 551238,${ldapBaseDn} +member: cn=Group 551239,${ldapBaseDn} +member: cn=Group 551240,${ldapBaseDn} +member: cn=Group 551241,${ldapBaseDn} +member: cn=Group 551242,${ldapBaseDn} +member: cn=Group 551243,${ldapBaseDn} +member: cn=Group 551244,${ldapBaseDn} +member: cn=Group 551245,${ldapBaseDn} +member: cn=Group 551246,${ldapBaseDn} +member: cn=Group 551247,${ldapBaseDn} +member: cn=Group 551248,${ldapBaseDn} +member: cn=Group 551249,${ldapBaseDn} +member: cn=Group 551250,${ldapBaseDn} +member: cn=Group 551251,${ldapBaseDn} +member: cn=Group 551252,${ldapBaseDn} +member: cn=Group 551253,${ldapBaseDn} +member: cn=Group 551254,${ldapBaseDn} +member: cn=Group 551255,${ldapBaseDn} +member: cn=Group 551256,${ldapBaseDn} +member: cn=Group 551257,${ldapBaseDn} +member: cn=Group 551258,${ldapBaseDn} +member: cn=Group 551259,${ldapBaseDn} +member: cn=Group 551260,${ldapBaseDn} +member: cn=Group 551261,${ldapBaseDn} +member: cn=Group 551262,${ldapBaseDn} +member: cn=Group 551263,${ldapBaseDn} +member: cn=Group 551264,${ldapBaseDn} +member: cn=Group 551265,${ldapBaseDn} +member: cn=Group 551266,${ldapBaseDn} +member: cn=Group 551267,${ldapBaseDn} +member: cn=Group 551268,${ldapBaseDn} +member: cn=Group 551269,${ldapBaseDn} +member: cn=Group 551270,${ldapBaseDn} +member: cn=Group 551271,${ldapBaseDn} +member: cn=Group 551272,${ldapBaseDn} +member: cn=Group 551273,${ldapBaseDn} +member: cn=Group 551274,${ldapBaseDn} +member: cn=Group 551275,${ldapBaseDn} +member: cn=Group 551276,${ldapBaseDn} +member: cn=Group 551277,${ldapBaseDn} +member: cn=Group 551278,${ldapBaseDn} +member: cn=Group 551279,${ldapBaseDn} +member: cn=Group 551280,${ldapBaseDn} +member: cn=Group 551281,${ldapBaseDn} +member: cn=Group 551282,${ldapBaseDn} +member: cn=Group 551283,${ldapBaseDn} +member: cn=Group 551284,${ldapBaseDn} +member: cn=Group 551285,${ldapBaseDn} +member: cn=Group 551286,${ldapBaseDn} +member: cn=Group 551287,${ldapBaseDn} +member: cn=Group 551288,${ldapBaseDn} +member: cn=Group 551289,${ldapBaseDn} +member: cn=Group 551290,${ldapBaseDn} +member: cn=Group 551291,${ldapBaseDn} +member: cn=Group 551292,${ldapBaseDn} +member: cn=Group 551293,${ldapBaseDn} +member: cn=Group 551294,${ldapBaseDn} +member: cn=Group 551295,${ldapBaseDn} +member: cn=Group 551296,${ldapBaseDn} +member: cn=Group 551297,${ldapBaseDn} +member: cn=Group 551298,${ldapBaseDn} +member: cn=Group 551299,${ldapBaseDn} +member: cn=Group 551300,${ldapBaseDn} +member: cn=Group 551301,${ldapBaseDn} +member: cn=Group 551302,${ldapBaseDn} +member: cn=Group 551303,${ldapBaseDn} +member: cn=Group 551304,${ldapBaseDn} +member: cn=Group 551305,${ldapBaseDn} +member: cn=Group 551306,${ldapBaseDn} +member: cn=Group 551307,${ldapBaseDn} +member: cn=Group 551308,${ldapBaseDn} +member: cn=Group 551309,${ldapBaseDn} +member: cn=Group 551310,${ldapBaseDn} +member: cn=Group 551311,${ldapBaseDn} +member: cn=Group 551312,${ldapBaseDn} +member: cn=Group 551313,${ldapBaseDn} +member: cn=Group 551314,${ldapBaseDn} +member: cn=Group 551315,${ldapBaseDn} +member: cn=Group 551316,${ldapBaseDn} +member: cn=Group 551317,${ldapBaseDn} +member: cn=Group 551318,${ldapBaseDn} +member: cn=Group 551319,${ldapBaseDn} +member: cn=Group 551320,${ldapBaseDn} +member: cn=Group 551321,${ldapBaseDn} +member: cn=Group 551322,${ldapBaseDn} +member: cn=Group 551323,${ldapBaseDn} +member: cn=Group 551324,${ldapBaseDn} +member: cn=Group 551325,${ldapBaseDn} +member: cn=Group 551326,${ldapBaseDn} +member: cn=Group 551327,${ldapBaseDn} +member: cn=Group 551328,${ldapBaseDn} +member: cn=Group 551329,${ldapBaseDn} +member: cn=Group 551330,${ldapBaseDn} +member: cn=Group 551331,${ldapBaseDn} +member: cn=Group 551332,${ldapBaseDn} +member: cn=Group 551333,${ldapBaseDn} +member: cn=Group 551334,${ldapBaseDn} +member: cn=Group 551335,${ldapBaseDn} +member: cn=Group 551336,${ldapBaseDn} +member: cn=Group 551337,${ldapBaseDn} +member: cn=Group 551338,${ldapBaseDn} +member: cn=Group 551339,${ldapBaseDn} +member: cn=Group 551340,${ldapBaseDn} +member: cn=Group 551341,${ldapBaseDn} +member: cn=Group 551342,${ldapBaseDn} +member: cn=Group 551343,${ldapBaseDn} +member: cn=Group 551344,${ldapBaseDn} +member: cn=Group 551345,${ldapBaseDn} +member: cn=Group 551346,${ldapBaseDn} +member: cn=Group 551347,${ldapBaseDn} +member: cn=Group 551348,${ldapBaseDn} +member: cn=Group 551349,${ldapBaseDn} +member: cn=Group 551350,${ldapBaseDn} +member: cn=Group 551351,${ldapBaseDn} +member: cn=Group 551352,${ldapBaseDn} +member: cn=Group 551353,${ldapBaseDn} +member: cn=Group 551354,${ldapBaseDn} +member: cn=Group 551355,${ldapBaseDn} +member: cn=Group 551356,${ldapBaseDn} +member: cn=Group 551357,${ldapBaseDn} +member: cn=Group 551358,${ldapBaseDn} +member: cn=Group 551359,${ldapBaseDn} +member: cn=Group 551360,${ldapBaseDn} +member: cn=Group 551361,${ldapBaseDn} +member: cn=Group 551362,${ldapBaseDn} +member: cn=Group 551363,${ldapBaseDn} +member: cn=Group 551364,${ldapBaseDn} +member: cn=Group 551365,${ldapBaseDn} +member: cn=Group 551366,${ldapBaseDn} +member: cn=Group 551367,${ldapBaseDn} +member: cn=Group 551368,${ldapBaseDn} +member: cn=Group 551369,${ldapBaseDn} +member: cn=Group 551370,${ldapBaseDn} +member: cn=Group 551371,${ldapBaseDn} +member: cn=Group 551372,${ldapBaseDn} +member: cn=Group 551373,${ldapBaseDn} +member: cn=Group 551374,${ldapBaseDn} +member: cn=Group 551375,${ldapBaseDn} +member: cn=Group 551376,${ldapBaseDn} +member: cn=Group 551377,${ldapBaseDn} +member: cn=Group 551378,${ldapBaseDn} +member: cn=Group 551379,${ldapBaseDn} +member: cn=Group 551380,${ldapBaseDn} +member: cn=Group 551381,${ldapBaseDn} +member: cn=Group 551382,${ldapBaseDn} +member: cn=Group 551383,${ldapBaseDn} +member: cn=Group 551384,${ldapBaseDn} +member: cn=Group 551385,${ldapBaseDn} +member: cn=Group 551386,${ldapBaseDn} +member: cn=Group 551387,${ldapBaseDn} +member: cn=Group 551388,${ldapBaseDn} +member: cn=Group 551389,${ldapBaseDn} +member: cn=Group 551390,${ldapBaseDn} +member: cn=Group 551391,${ldapBaseDn} +member: cn=Group 551392,${ldapBaseDn} +member: cn=Group 551393,${ldapBaseDn} +member: cn=Group 551394,${ldapBaseDn} +member: cn=Group 551395,${ldapBaseDn} +member: cn=Group 551396,${ldapBaseDn} +member: cn=Group 551397,${ldapBaseDn} +member: cn=Group 551398,${ldapBaseDn} +member: cn=Group 551399,${ldapBaseDn} +member: cn=Group 551400,${ldapBaseDn} +member: cn=Group 551401,${ldapBaseDn} +member: cn=Group 551402,${ldapBaseDn} +member: cn=Group 551403,${ldapBaseDn} +member: cn=Group 551404,${ldapBaseDn} +member: cn=Group 551405,${ldapBaseDn} +member: cn=Group 551406,${ldapBaseDn} +member: cn=Group 551407,${ldapBaseDn} +member: cn=Group 551408,${ldapBaseDn} +member: cn=Group 551409,${ldapBaseDn} +member: cn=Group 551410,${ldapBaseDn} +member: cn=Group 551411,${ldapBaseDn} +member: cn=Group 551412,${ldapBaseDn} +member: cn=Group 551413,${ldapBaseDn} +member: cn=Group 551414,${ldapBaseDn} +member: cn=Group 551415,${ldapBaseDn} +member: cn=Group 551416,${ldapBaseDn} +member: cn=Group 551417,${ldapBaseDn} +member: cn=Group 551418,${ldapBaseDn} +member: cn=Group 551419,${ldapBaseDn} +member: cn=Group 551420,${ldapBaseDn} +member: cn=Group 551421,${ldapBaseDn} +member: cn=Group 551422,${ldapBaseDn} +member: cn=Group 551423,${ldapBaseDn} +member: cn=Group 551424,${ldapBaseDn} +member: cn=Group 551425,${ldapBaseDn} +member: cn=Group 551426,${ldapBaseDn} +member: cn=Group 551427,${ldapBaseDn} +member: cn=Group 551428,${ldapBaseDn} +member: cn=Group 551429,${ldapBaseDn} +member: cn=Group 551430,${ldapBaseDn} +member: cn=Group 551431,${ldapBaseDn} +member: cn=Group 551432,${ldapBaseDn} +member: cn=Group 551433,${ldapBaseDn} +member: cn=Group 551434,${ldapBaseDn} +member: cn=Group 551435,${ldapBaseDn} +member: cn=Group 551436,${ldapBaseDn} +member: cn=Group 551437,${ldapBaseDn} +member: cn=Group 551438,${ldapBaseDn} +member: cn=Group 551439,${ldapBaseDn} +member: cn=Group 551440,${ldapBaseDn} +member: cn=Group 551441,${ldapBaseDn} +member: cn=Group 551442,${ldapBaseDn} +member: cn=Group 551443,${ldapBaseDn} +member: cn=Group 551444,${ldapBaseDn} +member: cn=Group 551445,${ldapBaseDn} +member: cn=Group 551446,${ldapBaseDn} +member: cn=Group 551447,${ldapBaseDn} +member: cn=Group 551448,${ldapBaseDn} +member: cn=Group 551449,${ldapBaseDn} +member: cn=Group 551450,${ldapBaseDn} +member: cn=Group 551451,${ldapBaseDn} +member: cn=Group 551452,${ldapBaseDn} +member: cn=Group 551453,${ldapBaseDn} +member: cn=Group 551454,${ldapBaseDn} +member: cn=Group 551455,${ldapBaseDn} +member: cn=Group 551456,${ldapBaseDn} +member: cn=Group 551457,${ldapBaseDn} +member: cn=Group 551458,${ldapBaseDn} +member: cn=Group 551459,${ldapBaseDn} +member: cn=Group 551460,${ldapBaseDn} +member: cn=Group 551461,${ldapBaseDn} +member: cn=Group 551462,${ldapBaseDn} +member: cn=Group 551463,${ldapBaseDn} +member: cn=Group 551464,${ldapBaseDn} +member: cn=Group 551465,${ldapBaseDn} +member: cn=Group 551466,${ldapBaseDn} +member: cn=Group 551467,${ldapBaseDn} +member: cn=Group 551468,${ldapBaseDn} +member: cn=Group 551469,${ldapBaseDn} +member: cn=Group 551470,${ldapBaseDn} +member: cn=Group 551471,${ldapBaseDn} +member: cn=Group 551472,${ldapBaseDn} +member: cn=Group 551473,${ldapBaseDn} +member: cn=Group 551474,${ldapBaseDn} +member: cn=Group 551475,${ldapBaseDn} +member: cn=Group 551476,${ldapBaseDn} +member: cn=Group 551477,${ldapBaseDn} +member: cn=Group 551478,${ldapBaseDn} +member: cn=Group 551479,${ldapBaseDn} +member: cn=Group 551480,${ldapBaseDn} +member: cn=Group 551481,${ldapBaseDn} +member: cn=Group 551482,${ldapBaseDn} +member: cn=Group 551483,${ldapBaseDn} +member: cn=Group 551484,${ldapBaseDn} +member: cn=Group 551485,${ldapBaseDn} +member: cn=Group 551486,${ldapBaseDn} +member: cn=Group 551487,${ldapBaseDn} +member: cn=Group 551488,${ldapBaseDn} +member: cn=Group 551489,${ldapBaseDn} +member: cn=Group 551490,${ldapBaseDn} +member: cn=Group 551491,${ldapBaseDn} +member: cn=Group 551492,${ldapBaseDn} +member: cn=Group 551493,${ldapBaseDn} +member: cn=Group 551494,${ldapBaseDn} +member: cn=Group 551495,${ldapBaseDn} +member: cn=Group 551496,${ldapBaseDn} +member: cn=Group 551497,${ldapBaseDn} +member: cn=Group 551498,${ldapBaseDn} +member: cn=Group 551499,${ldapBaseDn} +member: cn=Group 551500,${ldapBaseDn} +member: cn=Group 551501,${ldapBaseDn} +member: cn=Group 551502,${ldapBaseDn} +member: cn=Group 551503,${ldapBaseDn} +member: cn=Group 551504,${ldapBaseDn} +member: cn=Group 551505,${ldapBaseDn} +member: cn=Group 551506,${ldapBaseDn} +member: cn=Group 551507,${ldapBaseDn} +member: cn=Group 551508,${ldapBaseDn} +member: cn=Group 551509,${ldapBaseDn} +member: cn=Group 551510,${ldapBaseDn} +member: cn=Group 551511,${ldapBaseDn} +member: cn=Group 551512,${ldapBaseDn} +member: cn=Group 551513,${ldapBaseDn} +member: cn=Group 551514,${ldapBaseDn} +member: cn=Group 551515,${ldapBaseDn} +member: cn=Group 551516,${ldapBaseDn} +member: cn=Group 551517,${ldapBaseDn} +member: cn=Group 551518,${ldapBaseDn} +member: cn=Group 551519,${ldapBaseDn} +member: cn=Group 551520,${ldapBaseDn} +member: cn=Group 551521,${ldapBaseDn} +member: cn=Group 551522,${ldapBaseDn} +member: cn=Group 551523,${ldapBaseDn} +member: cn=Group 551524,${ldapBaseDn} +member: cn=Group 551525,${ldapBaseDn} +member: cn=Group 551526,${ldapBaseDn} +member: cn=Group 551527,${ldapBaseDn} +member: cn=Group 551528,${ldapBaseDn} +member: cn=Group 551529,${ldapBaseDn} +member: cn=Group 551530,${ldapBaseDn} +member: cn=Group 551531,${ldapBaseDn} +member: cn=Group 551532,${ldapBaseDn} +member: cn=Group 551533,${ldapBaseDn} +member: cn=Group 551534,${ldapBaseDn} +member: cn=Group 551535,${ldapBaseDn} +member: cn=Group 551536,${ldapBaseDn} +member: cn=Group 551537,${ldapBaseDn} +member: cn=Group 551538,${ldapBaseDn} +member: cn=Group 551539,${ldapBaseDn} +member: cn=Group 551540,${ldapBaseDn} +member: cn=Group 551541,${ldapBaseDn} +member: cn=Group 551542,${ldapBaseDn} +member: cn=Group 551543,${ldapBaseDn} +member: cn=Group 551544,${ldapBaseDn} +member: cn=Group 551545,${ldapBaseDn} +member: cn=Group 551546,${ldapBaseDn} +member: cn=Group 551547,${ldapBaseDn} +member: cn=Group 551548,${ldapBaseDn} +member: cn=Group 551549,${ldapBaseDn} +member: cn=Group 551550,${ldapBaseDn} +member: cn=Group 551551,${ldapBaseDn} +member: cn=Group 551552,${ldapBaseDn} +member: cn=Group 551553,${ldapBaseDn} +member: cn=Group 551554,${ldapBaseDn} +member: cn=Group 551555,${ldapBaseDn} +member: cn=Group 551556,${ldapBaseDn} +member: cn=Group 551557,${ldapBaseDn} +member: cn=Group 551558,${ldapBaseDn} +member: cn=Group 551559,${ldapBaseDn} +member: cn=Group 551560,${ldapBaseDn} +member: cn=Group 551561,${ldapBaseDn} +member: cn=Group 551562,${ldapBaseDn} +member: cn=Group 551563,${ldapBaseDn} +member: cn=Group 551564,${ldapBaseDn} +member: cn=Group 551565,${ldapBaseDn} +member: cn=Group 551566,${ldapBaseDn} +member: cn=Group 551567,${ldapBaseDn} +member: cn=Group 551568,${ldapBaseDn} +member: cn=Group 551569,${ldapBaseDn} +member: cn=Group 551570,${ldapBaseDn} +member: cn=Group 551571,${ldapBaseDn} +member: cn=Group 551572,${ldapBaseDn} +member: cn=Group 551573,${ldapBaseDn} +member: cn=Group 551574,${ldapBaseDn} +member: cn=Group 551575,${ldapBaseDn} +member: cn=Group 551576,${ldapBaseDn} +member: cn=Group 551577,${ldapBaseDn} +member: cn=Group 551578,${ldapBaseDn} +member: cn=Group 551579,${ldapBaseDn} +member: cn=Group 551580,${ldapBaseDn} +member: cn=Group 551581,${ldapBaseDn} +member: cn=Group 551582,${ldapBaseDn} +member: cn=Group 551583,${ldapBaseDn} +member: cn=Group 551584,${ldapBaseDn} +member: cn=Group 551585,${ldapBaseDn} +member: cn=Group 551586,${ldapBaseDn} +member: cn=Group 551587,${ldapBaseDn} +member: cn=Group 551588,${ldapBaseDn} +member: cn=Group 551589,${ldapBaseDn} +member: cn=Group 551590,${ldapBaseDn} +member: cn=Group 551591,${ldapBaseDn} +member: cn=Group 551592,${ldapBaseDn} +member: cn=Group 551593,${ldapBaseDn} +member: cn=Group 551594,${ldapBaseDn} +member: cn=Group 551595,${ldapBaseDn} +member: cn=Group 551596,${ldapBaseDn} +member: cn=Group 551597,${ldapBaseDn} +member: cn=Group 551598,${ldapBaseDn} +member: cn=Group 551599,${ldapBaseDn} +member: cn=Group 551600,${ldapBaseDn} +member: cn=Group 551601,${ldapBaseDn} +member: cn=Group 551602,${ldapBaseDn} +member: cn=Group 551603,${ldapBaseDn} +member: cn=Group 551604,${ldapBaseDn} +member: cn=Group 551605,${ldapBaseDn} +member: cn=Group 551606,${ldapBaseDn} +member: cn=Group 551607,${ldapBaseDn} +member: cn=Group 551608,${ldapBaseDn} +member: cn=Group 551609,${ldapBaseDn} +member: cn=Group 551610,${ldapBaseDn} +member: cn=Group 551611,${ldapBaseDn} +member: cn=Group 551612,${ldapBaseDn} +member: cn=Group 551613,${ldapBaseDn} +member: cn=Group 551614,${ldapBaseDn} +member: cn=Group 551615,${ldapBaseDn} +member: cn=Group 551616,${ldapBaseDn} +member: cn=Group 551617,${ldapBaseDn} +member: cn=Group 551618,${ldapBaseDn} +member: cn=Group 551619,${ldapBaseDn} +member: cn=Group 551620,${ldapBaseDn} +member: cn=Group 551621,${ldapBaseDn} +member: cn=Group 551622,${ldapBaseDn} +member: cn=Group 551623,${ldapBaseDn} +member: cn=Group 551624,${ldapBaseDn} +member: cn=Group 551625,${ldapBaseDn} +member: cn=Group 551626,${ldapBaseDn} +member: cn=Group 551627,${ldapBaseDn} +member: cn=Group 551628,${ldapBaseDn} +member: cn=Group 551629,${ldapBaseDn} +member: cn=Group 551630,${ldapBaseDn} +member: cn=Group 551631,${ldapBaseDn} +member: cn=Group 551632,${ldapBaseDn} +member: cn=Group 551633,${ldapBaseDn} +member: cn=Group 551634,${ldapBaseDn} +member: cn=Group 551635,${ldapBaseDn} +member: cn=Group 551636,${ldapBaseDn} +member: cn=Group 551637,${ldapBaseDn} +member: cn=Group 551638,${ldapBaseDn} +member: cn=Group 551639,${ldapBaseDn} +member: cn=Group 551640,${ldapBaseDn} +member: cn=Group 551641,${ldapBaseDn} +member: cn=Group 551642,${ldapBaseDn} +member: cn=Group 551643,${ldapBaseDn} +member: cn=Group 551644,${ldapBaseDn} +member: cn=Group 551645,${ldapBaseDn} +member: cn=Group 551646,${ldapBaseDn} +member: cn=Group 551647,${ldapBaseDn} +member: cn=Group 551648,${ldapBaseDn} +member: cn=Group 551649,${ldapBaseDn} +member: cn=Group 551650,${ldapBaseDn} +member: cn=Group 551651,${ldapBaseDn} +member: cn=Group 551652,${ldapBaseDn} +member: cn=Group 551653,${ldapBaseDn} +member: cn=Group 551654,${ldapBaseDn} +member: cn=Group 551655,${ldapBaseDn} +member: cn=Group 551656,${ldapBaseDn} +member: cn=Group 551657,${ldapBaseDn} +member: cn=Group 551658,${ldapBaseDn} +member: cn=Group 551659,${ldapBaseDn} +member: cn=Group 551660,${ldapBaseDn} +member: cn=Group 551661,${ldapBaseDn} +member: cn=Group 551662,${ldapBaseDn} +member: cn=Group 551663,${ldapBaseDn} +member: cn=Group 551664,${ldapBaseDn} +member: cn=Group 551665,${ldapBaseDn} +member: cn=Group 551666,${ldapBaseDn} +member: cn=Group 551667,${ldapBaseDn} +member: cn=Group 551668,${ldapBaseDn} +member: cn=Group 551669,${ldapBaseDn} +member: cn=Group 551670,${ldapBaseDn} +member: cn=Group 551671,${ldapBaseDn} +member: cn=Group 551672,${ldapBaseDn} +member: cn=Group 551673,${ldapBaseDn} +member: cn=Group 551674,${ldapBaseDn} +member: cn=Group 551675,${ldapBaseDn} +member: cn=Group 551676,${ldapBaseDn} +member: cn=Group 551677,${ldapBaseDn} +member: cn=Group 551678,${ldapBaseDn} +member: cn=Group 551679,${ldapBaseDn} +member: cn=Group 551680,${ldapBaseDn} +member: cn=Group 551681,${ldapBaseDn} +member: cn=Group 551682,${ldapBaseDn} +member: cn=Group 551683,${ldapBaseDn} +member: cn=Group 551684,${ldapBaseDn} +member: cn=Group 551685,${ldapBaseDn} +member: cn=Group 551686,${ldapBaseDn} +member: cn=Group 551687,${ldapBaseDn} +member: cn=Group 551688,${ldapBaseDn} +member: cn=Group 551689,${ldapBaseDn} +member: cn=Group 551690,${ldapBaseDn} +member: cn=Group 551691,${ldapBaseDn} +member: cn=Group 551692,${ldapBaseDn} +member: cn=Group 551693,${ldapBaseDn} +member: cn=Group 551694,${ldapBaseDn} +member: cn=Group 551695,${ldapBaseDn} +member: cn=Group 551696,${ldapBaseDn} +member: cn=Group 551697,${ldapBaseDn} +member: cn=Group 551698,${ldapBaseDn} +member: cn=Group 551699,${ldapBaseDn} +member: cn=Group 551700,${ldapBaseDn} +member: cn=Group 551701,${ldapBaseDn} +member: cn=Group 551702,${ldapBaseDn} +member: cn=Group 551703,${ldapBaseDn} +member: cn=Group 551704,${ldapBaseDn} +member: cn=Group 551705,${ldapBaseDn} +member: cn=Group 551706,${ldapBaseDn} +member: cn=Group 551707,${ldapBaseDn} +member: cn=Group 551708,${ldapBaseDn} +member: cn=Group 551709,${ldapBaseDn} +member: cn=Group 551710,${ldapBaseDn} +member: cn=Group 551711,${ldapBaseDn} +member: cn=Group 551712,${ldapBaseDn} +member: cn=Group 551713,${ldapBaseDn} +member: cn=Group 551714,${ldapBaseDn} +member: cn=Group 551715,${ldapBaseDn} +member: cn=Group 551716,${ldapBaseDn} +member: cn=Group 551717,${ldapBaseDn} +member: cn=Group 551718,${ldapBaseDn} +member: cn=Group 551719,${ldapBaseDn} +member: cn=Group 551720,${ldapBaseDn} +member: cn=Group 551721,${ldapBaseDn} +member: cn=Group 551722,${ldapBaseDn} +member: cn=Group 551723,${ldapBaseDn} +member: cn=Group 551724,${ldapBaseDn} +member: cn=Group 551725,${ldapBaseDn} +member: cn=Group 551726,${ldapBaseDn} +member: cn=Group 551727,${ldapBaseDn} +member: cn=Group 551728,${ldapBaseDn} +member: cn=Group 551729,${ldapBaseDn} +member: cn=Group 551730,${ldapBaseDn} +member: cn=Group 551731,${ldapBaseDn} +member: cn=Group 551732,${ldapBaseDn} +member: cn=Group 551733,${ldapBaseDn} +member: cn=Group 551734,${ldapBaseDn} +member: cn=Group 551735,${ldapBaseDn} +member: cn=Group 551736,${ldapBaseDn} +member: cn=Group 551737,${ldapBaseDn} +member: cn=Group 551738,${ldapBaseDn} +member: cn=Group 551739,${ldapBaseDn} +member: cn=Group 551740,${ldapBaseDn} +member: cn=Group 551741,${ldapBaseDn} +member: cn=Group 551742,${ldapBaseDn} +member: cn=Group 551743,${ldapBaseDn} +member: cn=Group 551744,${ldapBaseDn} +member: cn=Group 551745,${ldapBaseDn} +member: cn=Group 551746,${ldapBaseDn} +member: cn=Group 551747,${ldapBaseDn} +member: cn=Group 551748,${ldapBaseDn} +member: cn=Group 551749,${ldapBaseDn} +member: cn=Group 551750,${ldapBaseDn} +member: cn=Group 551751,${ldapBaseDn} +member: cn=Group 551752,${ldapBaseDn} +member: cn=Group 551753,${ldapBaseDn} +member: cn=Group 551754,${ldapBaseDn} +member: cn=Group 551755,${ldapBaseDn} +member: cn=Group 551756,${ldapBaseDn} +member: cn=Group 551757,${ldapBaseDn} +member: cn=Group 551758,${ldapBaseDn} +member: cn=Group 551759,${ldapBaseDn} +member: cn=Group 551760,${ldapBaseDn} +member: cn=Group 551761,${ldapBaseDn} +member: cn=Group 551762,${ldapBaseDn} +member: cn=Group 551763,${ldapBaseDn} +member: cn=Group 551764,${ldapBaseDn} +member: cn=Group 551765,${ldapBaseDn} +member: cn=Group 551766,${ldapBaseDn} +member: cn=Group 551767,${ldapBaseDn} +member: cn=Group 551768,${ldapBaseDn} +member: cn=Group 551769,${ldapBaseDn} +member: cn=Group 551770,${ldapBaseDn} +member: cn=Group 551771,${ldapBaseDn} +member: cn=Group 551772,${ldapBaseDn} +member: cn=Group 551773,${ldapBaseDn} +member: cn=Group 551774,${ldapBaseDn} +member: cn=Group 551775,${ldapBaseDn} +member: cn=Group 551776,${ldapBaseDn} +member: cn=Group 551777,${ldapBaseDn} +member: cn=Group 551778,${ldapBaseDn} +member: cn=Group 551779,${ldapBaseDn} +member: cn=Group 551780,${ldapBaseDn} +member: cn=Group 551781,${ldapBaseDn} +member: cn=Group 551782,${ldapBaseDn} +member: cn=Group 551783,${ldapBaseDn} +member: cn=Group 551784,${ldapBaseDn} +member: cn=Group 551785,${ldapBaseDn} +member: cn=Group 551786,${ldapBaseDn} +member: cn=Group 551787,${ldapBaseDn} +member: cn=Group 551788,${ldapBaseDn} +member: cn=Group 551789,${ldapBaseDn} +member: cn=Group 551790,${ldapBaseDn} +member: cn=Group 551791,${ldapBaseDn} +member: cn=Group 551792,${ldapBaseDn} +member: cn=Group 551793,${ldapBaseDn} +member: cn=Group 551794,${ldapBaseDn} +member: cn=Group 551795,${ldapBaseDn} +member: cn=Group 551796,${ldapBaseDn} +member: cn=Group 551797,${ldapBaseDn} +member: cn=Group 551798,${ldapBaseDn} +member: cn=Group 551799,${ldapBaseDn} +member: cn=Group 551800,${ldapBaseDn} +member: cn=Group 551801,${ldapBaseDn} +member: cn=Group 551802,${ldapBaseDn} +member: cn=Group 551803,${ldapBaseDn} +member: cn=Group 551804,${ldapBaseDn} +member: cn=Group 551805,${ldapBaseDn} +member: cn=Group 551806,${ldapBaseDn} +member: cn=Group 551807,${ldapBaseDn} +member: cn=Group 551808,${ldapBaseDn} +member: cn=Group 551809,${ldapBaseDn} +member: cn=Group 551810,${ldapBaseDn} +member: cn=Group 551811,${ldapBaseDn} +member: cn=Group 551812,${ldapBaseDn} +member: cn=Group 551813,${ldapBaseDn} +member: cn=Group 551814,${ldapBaseDn} +member: cn=Group 551815,${ldapBaseDn} +member: cn=Group 551816,${ldapBaseDn} +member: cn=Group 551817,${ldapBaseDn} +member: cn=Group 551818,${ldapBaseDn} +member: cn=Group 551819,${ldapBaseDn} +member: cn=Group 551820,${ldapBaseDn} +member: cn=Group 551821,${ldapBaseDn} +member: cn=Group 551822,${ldapBaseDn} +member: cn=Group 551823,${ldapBaseDn} +member: cn=Group 551824,${ldapBaseDn} +member: cn=Group 551825,${ldapBaseDn} +member: cn=Group 551826,${ldapBaseDn} +member: cn=Group 551827,${ldapBaseDn} +member: cn=Group 551828,${ldapBaseDn} +member: cn=Group 551829,${ldapBaseDn} +member: cn=Group 551830,${ldapBaseDn} +member: cn=Group 551831,${ldapBaseDn} +member: cn=Group 551832,${ldapBaseDn} +member: cn=Group 551833,${ldapBaseDn} +member: cn=Group 551834,${ldapBaseDn} +member: cn=Group 551835,${ldapBaseDn} +member: cn=Group 551836,${ldapBaseDn} +member: cn=Group 551837,${ldapBaseDn} +member: cn=Group 551838,${ldapBaseDn} +member: cn=Group 551839,${ldapBaseDn} +member: cn=Group 551840,${ldapBaseDn} +member: cn=Group 551841,${ldapBaseDn} +member: cn=Group 551842,${ldapBaseDn} +member: cn=Group 551843,${ldapBaseDn} +member: cn=Group 551844,${ldapBaseDn} +member: cn=Group 551845,${ldapBaseDn} +member: cn=Group 551846,${ldapBaseDn} +member: cn=Group 551847,${ldapBaseDn} +member: cn=Group 551848,${ldapBaseDn} +member: cn=Group 551849,${ldapBaseDn} +member: cn=Group 551850,${ldapBaseDn} +member: cn=Group 551851,${ldapBaseDn} +member: cn=Group 551852,${ldapBaseDn} +member: cn=Group 551853,${ldapBaseDn} +member: cn=Group 551854,${ldapBaseDn} +member: cn=Group 551855,${ldapBaseDn} +member: cn=Group 551856,${ldapBaseDn} +member: cn=Group 551857,${ldapBaseDn} +member: cn=Group 551858,${ldapBaseDn} +member: cn=Group 551859,${ldapBaseDn} +member: cn=Group 551860,${ldapBaseDn} +member: cn=Group 551861,${ldapBaseDn} +member: cn=Group 551862,${ldapBaseDn} +member: cn=Group 551863,${ldapBaseDn} +member: cn=Group 551864,${ldapBaseDn} +member: cn=Group 551865,${ldapBaseDn} +member: cn=Group 551866,${ldapBaseDn} +member: cn=Group 551867,${ldapBaseDn} +member: cn=Group 551868,${ldapBaseDn} +member: cn=Group 551869,${ldapBaseDn} +member: cn=Group 551870,${ldapBaseDn} +member: cn=Group 551871,${ldapBaseDn} +member: cn=Group 551872,${ldapBaseDn} +member: cn=Group 551873,${ldapBaseDn} +member: cn=Group 551874,${ldapBaseDn} +member: cn=Group 551875,${ldapBaseDn} +member: cn=Group 551876,${ldapBaseDn} +member: cn=Group 551877,${ldapBaseDn} +member: cn=Group 551878,${ldapBaseDn} +member: cn=Group 551879,${ldapBaseDn} +member: cn=Group 551880,${ldapBaseDn} +member: cn=Group 551881,${ldapBaseDn} +member: cn=Group 551882,${ldapBaseDn} +member: cn=Group 551883,${ldapBaseDn} +member: cn=Group 551884,${ldapBaseDn} +member: cn=Group 551885,${ldapBaseDn} +member: cn=Group 551886,${ldapBaseDn} +member: cn=Group 551887,${ldapBaseDn} +member: cn=Group 551888,${ldapBaseDn} +member: cn=Group 551889,${ldapBaseDn} +member: cn=Group 551890,${ldapBaseDn} +member: cn=Group 551891,${ldapBaseDn} +member: cn=Group 551892,${ldapBaseDn} +member: cn=Group 551893,${ldapBaseDn} +member: cn=Group 551894,${ldapBaseDn} +member: cn=Group 551895,${ldapBaseDn} +member: cn=Group 551896,${ldapBaseDn} +member: cn=Group 551897,${ldapBaseDn} +member: cn=Group 551898,${ldapBaseDn} +member: cn=Group 551899,${ldapBaseDn} +member: cn=Group 551900,${ldapBaseDn} +member: cn=Group 551901,${ldapBaseDn} +member: cn=Group 551902,${ldapBaseDn} +member: cn=Group 551903,${ldapBaseDn} +member: cn=Group 551904,${ldapBaseDn} +member: cn=Group 551905,${ldapBaseDn} +member: cn=Group 551906,${ldapBaseDn} +member: cn=Group 551907,${ldapBaseDn} +member: cn=Group 551908,${ldapBaseDn} +member: cn=Group 551909,${ldapBaseDn} +member: cn=Group 551910,${ldapBaseDn} +member: cn=Group 551911,${ldapBaseDn} +member: cn=Group 551912,${ldapBaseDn} +member: cn=Group 551913,${ldapBaseDn} +member: cn=Group 551914,${ldapBaseDn} +member: cn=Group 551915,${ldapBaseDn} +member: cn=Group 551916,${ldapBaseDn} +member: cn=Group 551917,${ldapBaseDn} +member: cn=Group 551918,${ldapBaseDn} +member: cn=Group 551919,${ldapBaseDn} +member: cn=Group 551920,${ldapBaseDn} +member: cn=Group 551921,${ldapBaseDn} +member: cn=Group 551922,${ldapBaseDn} +member: cn=Group 551923,${ldapBaseDn} +member: cn=Group 551924,${ldapBaseDn} +member: cn=Group 551925,${ldapBaseDn} +member: cn=Group 551926,${ldapBaseDn} +member: cn=Group 551927,${ldapBaseDn} +member: cn=Group 551928,${ldapBaseDn} +member: cn=Group 551929,${ldapBaseDn} +member: cn=Group 551930,${ldapBaseDn} +member: cn=Group 551931,${ldapBaseDn} +member: cn=Group 551932,${ldapBaseDn} +member: cn=Group 551933,${ldapBaseDn} +member: cn=Group 551934,${ldapBaseDn} +member: cn=Group 551935,${ldapBaseDn} +member: cn=Group 551936,${ldapBaseDn} +member: cn=Group 551937,${ldapBaseDn} +member: cn=Group 551938,${ldapBaseDn} +member: cn=Group 551939,${ldapBaseDn} +member: cn=Group 551940,${ldapBaseDn} +member: cn=Group 551941,${ldapBaseDn} +member: cn=Group 551942,${ldapBaseDn} +member: cn=Group 551943,${ldapBaseDn} +member: cn=Group 551944,${ldapBaseDn} +member: cn=Group 551945,${ldapBaseDn} +member: cn=Group 551946,${ldapBaseDn} +member: cn=Group 551947,${ldapBaseDn} +member: cn=Group 551948,${ldapBaseDn} +member: cn=Group 551949,${ldapBaseDn} +member: cn=Group 551950,${ldapBaseDn} +member: cn=Group 551951,${ldapBaseDn} +member: cn=Group 551952,${ldapBaseDn} +member: cn=Group 551953,${ldapBaseDn} +member: cn=Group 551954,${ldapBaseDn} +member: cn=Group 551955,${ldapBaseDn} +member: cn=Group 551956,${ldapBaseDn} +member: cn=Group 551957,${ldapBaseDn} +member: cn=Group 551958,${ldapBaseDn} +member: cn=Group 551959,${ldapBaseDn} +member: cn=Group 551960,${ldapBaseDn} +member: cn=Group 551961,${ldapBaseDn} +member: cn=Group 551962,${ldapBaseDn} +member: cn=Group 551963,${ldapBaseDn} +member: cn=Group 551964,${ldapBaseDn} +member: cn=Group 551965,${ldapBaseDn} +member: cn=Group 551966,${ldapBaseDn} +member: cn=Group 551967,${ldapBaseDn} +member: cn=Group 551968,${ldapBaseDn} +member: cn=Group 551969,${ldapBaseDn} +member: cn=Group 551970,${ldapBaseDn} +member: cn=Group 551971,${ldapBaseDn} +member: cn=Group 551972,${ldapBaseDn} +member: cn=Group 551973,${ldapBaseDn} +member: cn=Group 551974,${ldapBaseDn} +member: cn=Group 551975,${ldapBaseDn} +member: cn=Group 551976,${ldapBaseDn} +member: cn=Group 551977,${ldapBaseDn} +member: cn=Group 551978,${ldapBaseDn} +member: cn=Group 551979,${ldapBaseDn} +member: cn=Group 551980,${ldapBaseDn} +member: cn=Group 551981,${ldapBaseDn} +member: cn=Group 551982,${ldapBaseDn} +member: cn=Group 551983,${ldapBaseDn} +member: cn=Group 551984,${ldapBaseDn} +member: cn=Group 551985,${ldapBaseDn} +member: cn=Group 551986,${ldapBaseDn} +member: cn=Group 551987,${ldapBaseDn} +member: cn=Group 551988,${ldapBaseDn} +member: cn=Group 551989,${ldapBaseDn} +member: cn=Group 551990,${ldapBaseDn} +member: cn=Group 551991,${ldapBaseDn} +member: cn=Group 551992,${ldapBaseDn} +member: cn=Group 551993,${ldapBaseDn} +member: cn=Group 551994,${ldapBaseDn} +member: cn=Group 551995,${ldapBaseDn} +member: cn=Group 551996,${ldapBaseDn} +member: cn=Group 551997,${ldapBaseDn} +member: cn=Group 551998,${ldapBaseDn} +member: cn=Group 551999,${ldapBaseDn} +member: cn=Group 552000,${ldapBaseDn} +member: cn=Group 552001,${ldapBaseDn} +member: cn=Group 552002,${ldapBaseDn} +member: cn=Group 552003,${ldapBaseDn} +member: cn=Group 552004,${ldapBaseDn} +member: cn=Group 552005,${ldapBaseDn} +member: cn=Group 552006,${ldapBaseDn} +member: cn=Group 552007,${ldapBaseDn} +member: cn=Group 552008,${ldapBaseDn} +member: cn=Group 552009,${ldapBaseDn} +member: cn=Group 552010,${ldapBaseDn} +member: cn=Group 552011,${ldapBaseDn} +member: cn=Group 552012,${ldapBaseDn} +member: cn=Group 552013,${ldapBaseDn} +member: cn=Group 552014,${ldapBaseDn} +member: cn=Group 552015,${ldapBaseDn} +member: cn=Group 552016,${ldapBaseDn} +member: cn=Group 552017,${ldapBaseDn} +member: cn=Group 552018,${ldapBaseDn} +member: cn=Group 552019,${ldapBaseDn} +member: cn=Group 552020,${ldapBaseDn} +member: cn=Group 552021,${ldapBaseDn} +member: cn=Group 552022,${ldapBaseDn} +member: cn=Group 552023,${ldapBaseDn} +member: cn=Group 552024,${ldapBaseDn} +member: cn=Group 552025,${ldapBaseDn} +member: cn=Group 552026,${ldapBaseDn} +member: cn=Group 552027,${ldapBaseDn} +member: cn=Group 552028,${ldapBaseDn} +member: cn=Group 552029,${ldapBaseDn} +member: cn=Group 552030,${ldapBaseDn} +member: cn=Group 552031,${ldapBaseDn} +member: cn=Group 552032,${ldapBaseDn} +member: cn=Group 552033,${ldapBaseDn} +member: cn=Group 552034,${ldapBaseDn} +member: cn=Group 552035,${ldapBaseDn} +member: cn=Group 552036,${ldapBaseDn} +member: cn=Group 552037,${ldapBaseDn} +member: cn=Group 552038,${ldapBaseDn} +member: cn=Group 552039,${ldapBaseDn} +member: cn=Group 552040,${ldapBaseDn} +member: cn=Group 552041,${ldapBaseDn} +member: cn=Group 552042,${ldapBaseDn} +member: cn=Group 552043,${ldapBaseDn} +member: cn=Group 552044,${ldapBaseDn} +member: cn=Group 552045,${ldapBaseDn} +member: cn=Group 552046,${ldapBaseDn} +member: cn=Group 552047,${ldapBaseDn} +member: cn=Group 552048,${ldapBaseDn} +member: cn=Group 552049,${ldapBaseDn} +member: cn=Group 552050,${ldapBaseDn} +member: cn=Group 552051,${ldapBaseDn} +member: cn=Group 552052,${ldapBaseDn} +member: cn=Group 552053,${ldapBaseDn} +member: cn=Group 552054,${ldapBaseDn} +member: cn=Group 552055,${ldapBaseDn} +member: cn=Group 552056,${ldapBaseDn} +member: cn=Group 552057,${ldapBaseDn} +member: cn=Group 552058,${ldapBaseDn} +member: cn=Group 552059,${ldapBaseDn} +member: cn=Group 552060,${ldapBaseDn} +member: cn=Group 552061,${ldapBaseDn} +member: cn=Group 552062,${ldapBaseDn} +member: cn=Group 552063,${ldapBaseDn} +member: cn=Group 552064,${ldapBaseDn} +member: cn=Group 552065,${ldapBaseDn} +member: cn=Group 552066,${ldapBaseDn} +member: cn=Group 552067,${ldapBaseDn} +member: cn=Group 552068,${ldapBaseDn} +member: cn=Group 552069,${ldapBaseDn} +member: cn=Group 552070,${ldapBaseDn} +member: cn=Group 552071,${ldapBaseDn} +member: cn=Group 552072,${ldapBaseDn} +member: cn=Group 552073,${ldapBaseDn} +member: cn=Group 552074,${ldapBaseDn} +member: cn=Group 552075,${ldapBaseDn} +member: cn=Group 552076,${ldapBaseDn} +member: cn=Group 552077,${ldapBaseDn} +member: cn=Group 552078,${ldapBaseDn} +member: cn=Group 552079,${ldapBaseDn} +member: cn=Group 552080,${ldapBaseDn} +member: cn=Group 552081,${ldapBaseDn} +member: cn=Group 552082,${ldapBaseDn} +member: cn=Group 552083,${ldapBaseDn} +member: cn=Group 552084,${ldapBaseDn} +member: cn=Group 552085,${ldapBaseDn} +member: cn=Group 552086,${ldapBaseDn} +member: cn=Group 552087,${ldapBaseDn} +member: cn=Group 552088,${ldapBaseDn} +member: cn=Group 552089,${ldapBaseDn} +member: cn=Group 552090,${ldapBaseDn} +member: cn=Group 552091,${ldapBaseDn} +member: cn=Group 552092,${ldapBaseDn} +member: cn=Group 552093,${ldapBaseDn} +member: cn=Group 552094,${ldapBaseDn} +member: cn=Group 552095,${ldapBaseDn} +member: cn=Group 552096,${ldapBaseDn} +member: cn=Group 552097,${ldapBaseDn} +member: cn=Group 552098,${ldapBaseDn} +member: cn=Group 552099,${ldapBaseDn} +member: cn=Group 552100,${ldapBaseDn} +member: cn=Group 552101,${ldapBaseDn} +member: cn=Group 552102,${ldapBaseDn} +member: cn=Group 552103,${ldapBaseDn} +member: cn=Group 552104,${ldapBaseDn} +member: cn=Group 552105,${ldapBaseDn} +member: cn=Group 552106,${ldapBaseDn} +member: cn=Group 552107,${ldapBaseDn} +member: cn=Group 552108,${ldapBaseDn} +member: cn=Group 552109,${ldapBaseDn} +member: cn=Group 552110,${ldapBaseDn} +member: cn=Group 552111,${ldapBaseDn} +member: cn=Group 552112,${ldapBaseDn} +member: cn=Group 552113,${ldapBaseDn} +member: cn=Group 552114,${ldapBaseDn} +member: cn=Group 552115,${ldapBaseDn} +member: cn=Group 552116,${ldapBaseDn} +member: cn=Group 552117,${ldapBaseDn} +member: cn=Group 552118,${ldapBaseDn} +member: cn=Group 552119,${ldapBaseDn} +member: cn=Group 552120,${ldapBaseDn} +member: cn=Group 552121,${ldapBaseDn} +member: cn=Group 552122,${ldapBaseDn} +member: cn=Group 552123,${ldapBaseDn} +member: cn=Group 552124,${ldapBaseDn} +member: cn=Group 552125,${ldapBaseDn} +member: cn=Group 552126,${ldapBaseDn} +member: cn=Group 552127,${ldapBaseDn} +member: cn=Group 552128,${ldapBaseDn} +member: cn=Group 552129,${ldapBaseDn} +member: cn=Group 552130,${ldapBaseDn} +member: cn=Group 552131,${ldapBaseDn} +member: cn=Group 552132,${ldapBaseDn} +member: cn=Group 552133,${ldapBaseDn} +member: cn=Group 552134,${ldapBaseDn} +member: cn=Group 552135,${ldapBaseDn} +member: cn=Group 552136,${ldapBaseDn} +member: cn=Group 552137,${ldapBaseDn} +member: cn=Group 552138,${ldapBaseDn} +member: cn=Group 552139,${ldapBaseDn} +member: cn=Group 552140,${ldapBaseDn} +member: cn=Group 552141,${ldapBaseDn} +member: cn=Group 552142,${ldapBaseDn} +member: cn=Group 552143,${ldapBaseDn} +member: cn=Group 552144,${ldapBaseDn} +member: cn=Group 552145,${ldapBaseDn} +member: cn=Group 552146,${ldapBaseDn} +member: cn=Group 552147,${ldapBaseDn} +member: cn=Group 552148,${ldapBaseDn} +member: cn=Group 552149,${ldapBaseDn} +member: cn=Group 552150,${ldapBaseDn} +member: cn=Group 552151,${ldapBaseDn} +member: cn=Group 552152,${ldapBaseDn} +member: cn=Group 552153,${ldapBaseDn} +member: cn=Group 552154,${ldapBaseDn} +member: cn=Group 552155,${ldapBaseDn} +member: cn=Group 552156,${ldapBaseDn} +member: cn=Group 552157,${ldapBaseDn} +member: cn=Group 552158,${ldapBaseDn} +member: cn=Group 552159,${ldapBaseDn} +member: cn=Group 552160,${ldapBaseDn} +member: cn=Group 552161,${ldapBaseDn} +member: cn=Group 552162,${ldapBaseDn} +member: cn=Group 552163,${ldapBaseDn} +member: cn=Group 552164,${ldapBaseDn} +member: cn=Group 552165,${ldapBaseDn} +member: cn=Group 552166,${ldapBaseDn} +member: cn=Group 552167,${ldapBaseDn} +member: cn=Group 552168,${ldapBaseDn} +member: cn=Group 552169,${ldapBaseDn} +member: cn=Group 552170,${ldapBaseDn} +member: cn=Group 552171,${ldapBaseDn} +member: cn=Group 552172,${ldapBaseDn} +member: cn=Group 552173,${ldapBaseDn} +member: cn=Group 552174,${ldapBaseDn} +member: cn=Group 552175,${ldapBaseDn} +member: cn=Group 552176,${ldapBaseDn} +member: cn=Group 552177,${ldapBaseDn} +member: cn=Group 552178,${ldapBaseDn} +member: cn=Group 552179,${ldapBaseDn} +member: cn=Group 552180,${ldapBaseDn} +member: cn=Group 552181,${ldapBaseDn} +member: cn=Group 552182,${ldapBaseDn} +member: cn=Group 552183,${ldapBaseDn} +member: cn=Group 552184,${ldapBaseDn} +member: cn=Group 552185,${ldapBaseDn} +member: cn=Group 552186,${ldapBaseDn} +member: cn=Group 552187,${ldapBaseDn} +member: cn=Group 552188,${ldapBaseDn} +member: cn=Group 552189,${ldapBaseDn} +member: cn=Group 552190,${ldapBaseDn} +member: cn=Group 552191,${ldapBaseDn} +member: cn=Group 552192,${ldapBaseDn} +member: cn=Group 552193,${ldapBaseDn} +member: cn=Group 552194,${ldapBaseDn} +member: cn=Group 552195,${ldapBaseDn} +member: cn=Group 552196,${ldapBaseDn} +member: cn=Group 552197,${ldapBaseDn} +member: cn=Group 552198,${ldapBaseDn} +member: cn=Group 552199,${ldapBaseDn} +member: cn=Group 552200,${ldapBaseDn} +member: cn=Group 552201,${ldapBaseDn} +member: cn=Group 552202,${ldapBaseDn} +member: cn=Group 552203,${ldapBaseDn} +member: cn=Group 552204,${ldapBaseDn} +member: cn=Group 552205,${ldapBaseDn} +member: cn=Group 552206,${ldapBaseDn} +member: cn=Group 552207,${ldapBaseDn} +member: cn=Group 552208,${ldapBaseDn} +member: cn=Group 552209,${ldapBaseDn} +member: cn=Group 552210,${ldapBaseDn} +member: cn=Group 552211,${ldapBaseDn} +member: cn=Group 552212,${ldapBaseDn} +member: cn=Group 552213,${ldapBaseDn} +member: cn=Group 552214,${ldapBaseDn} +member: cn=Group 552215,${ldapBaseDn} +member: cn=Group 552216,${ldapBaseDn} +member: cn=Group 552217,${ldapBaseDn} +member: cn=Group 552218,${ldapBaseDn} +member: cn=Group 552219,${ldapBaseDn} +member: cn=Group 552220,${ldapBaseDn} +member: cn=Group 552221,${ldapBaseDn} +member: cn=Group 552222,${ldapBaseDn} +member: cn=Group 552223,${ldapBaseDn} +member: cn=Group 552224,${ldapBaseDn} +member: cn=Group 552225,${ldapBaseDn} +member: cn=Group 552226,${ldapBaseDn} +member: cn=Group 552227,${ldapBaseDn} +member: cn=Group 552228,${ldapBaseDn} +member: cn=Group 552229,${ldapBaseDn} +member: cn=Group 552230,${ldapBaseDn} +member: cn=Group 552231,${ldapBaseDn} +member: cn=Group 552232,${ldapBaseDn} +member: cn=Group 552233,${ldapBaseDn} +member: cn=Group 552234,${ldapBaseDn} +member: cn=Group 552235,${ldapBaseDn} +member: cn=Group 552236,${ldapBaseDn} +member: cn=Group 552237,${ldapBaseDn} +member: cn=Group 552238,${ldapBaseDn} +member: cn=Group 552239,${ldapBaseDn} +member: cn=Group 552240,${ldapBaseDn} +member: cn=Group 552241,${ldapBaseDn} +member: cn=Group 552242,${ldapBaseDn} +member: cn=Group 552243,${ldapBaseDn} +member: cn=Group 552244,${ldapBaseDn} +member: cn=Group 552245,${ldapBaseDn} +member: cn=Group 552246,${ldapBaseDn} +member: cn=Group 552247,${ldapBaseDn} +member: cn=Group 552248,${ldapBaseDn} +member: cn=Group 552249,${ldapBaseDn} +member: cn=Group 552250,${ldapBaseDn} +member: cn=Group 552251,${ldapBaseDn} +member: cn=Group 552252,${ldapBaseDn} +member: cn=Group 552253,${ldapBaseDn} +member: cn=Group 552254,${ldapBaseDn} +member: cn=Group 552255,${ldapBaseDn} +member: cn=Group 552256,${ldapBaseDn} +member: cn=Group 552257,${ldapBaseDn} +member: cn=Group 552258,${ldapBaseDn} +member: cn=Group 552259,${ldapBaseDn} +member: cn=Group 552260,${ldapBaseDn} +member: cn=Group 552261,${ldapBaseDn} +member: cn=Group 552262,${ldapBaseDn} +member: cn=Group 552263,${ldapBaseDn} +member: cn=Group 552264,${ldapBaseDn} +member: cn=Group 552265,${ldapBaseDn} +member: cn=Group 552266,${ldapBaseDn} +member: cn=Group 552267,${ldapBaseDn} +member: cn=Group 552268,${ldapBaseDn} +member: cn=Group 552269,${ldapBaseDn} +member: cn=Group 552270,${ldapBaseDn} +member: cn=Group 552271,${ldapBaseDn} +member: cn=Group 552272,${ldapBaseDn} +member: cn=Group 552273,${ldapBaseDn} +member: cn=Group 552274,${ldapBaseDn} +member: cn=Group 552275,${ldapBaseDn} +member: cn=Group 552276,${ldapBaseDn} +member: cn=Group 552277,${ldapBaseDn} +member: cn=Group 552278,${ldapBaseDn} +member: cn=Group 552279,${ldapBaseDn} +member: cn=Group 552280,${ldapBaseDn} +member: cn=Group 552281,${ldapBaseDn} +member: cn=Group 552282,${ldapBaseDn} +member: cn=Group 552283,${ldapBaseDn} +member: cn=Group 552284,${ldapBaseDn} +member: cn=Group 552285,${ldapBaseDn} +member: cn=Group 552286,${ldapBaseDn} +member: cn=Group 552287,${ldapBaseDn} +member: cn=Group 552288,${ldapBaseDn} +member: cn=Group 552289,${ldapBaseDn} +member: cn=Group 552290,${ldapBaseDn} +member: cn=Group 552291,${ldapBaseDn} +member: cn=Group 552292,${ldapBaseDn} +member: cn=Group 552293,${ldapBaseDn} +member: cn=Group 552294,${ldapBaseDn} +member: cn=Group 552295,${ldapBaseDn} +member: cn=Group 552296,${ldapBaseDn} +member: cn=Group 552297,${ldapBaseDn} +member: cn=Group 552298,${ldapBaseDn} +member: cn=Group 552299,${ldapBaseDn} +member: cn=Group 552300,${ldapBaseDn} +member: cn=Group 552301,${ldapBaseDn} +member: cn=Group 552302,${ldapBaseDn} +member: cn=Group 552303,${ldapBaseDn} +member: cn=Group 552304,${ldapBaseDn} +member: cn=Group 552305,${ldapBaseDn} +member: cn=Group 552306,${ldapBaseDn} +member: cn=Group 552307,${ldapBaseDn} +member: cn=Group 552308,${ldapBaseDn} +member: cn=Group 552309,${ldapBaseDn} +member: cn=Group 552310,${ldapBaseDn} +member: cn=Group 552311,${ldapBaseDn} +member: cn=Group 552312,${ldapBaseDn} +member: cn=Group 552313,${ldapBaseDn} +member: cn=Group 552314,${ldapBaseDn} +member: cn=Group 552315,${ldapBaseDn} +member: cn=Group 552316,${ldapBaseDn} +member: cn=Group 552317,${ldapBaseDn} +member: cn=Group 552318,${ldapBaseDn} +member: cn=Group 552319,${ldapBaseDn} +member: cn=Group 552320,${ldapBaseDn} +member: cn=Group 552321,${ldapBaseDn} +member: cn=Group 552322,${ldapBaseDn} +member: cn=Group 552323,${ldapBaseDn} +member: cn=Group 552324,${ldapBaseDn} +member: cn=Group 552325,${ldapBaseDn} +member: cn=Group 552326,${ldapBaseDn} +member: cn=Group 552327,${ldapBaseDn} +member: cn=Group 552328,${ldapBaseDn} +member: cn=Group 552329,${ldapBaseDn} +member: cn=Group 552330,${ldapBaseDn} +member: cn=Group 552331,${ldapBaseDn} +member: cn=Group 552332,${ldapBaseDn} +member: cn=Group 552333,${ldapBaseDn} +member: cn=Group 552334,${ldapBaseDn} +member: cn=Group 552335,${ldapBaseDn} +member: cn=Group 552336,${ldapBaseDn} +member: cn=Group 552337,${ldapBaseDn} +member: cn=Group 552338,${ldapBaseDn} +member: cn=Group 552339,${ldapBaseDn} +member: cn=Group 552340,${ldapBaseDn} +member: cn=Group 552341,${ldapBaseDn} +member: cn=Group 552342,${ldapBaseDn} +member: cn=Group 552343,${ldapBaseDn} +member: cn=Group 552344,${ldapBaseDn} +member: cn=Group 552345,${ldapBaseDn} +member: cn=Group 552346,${ldapBaseDn} +member: cn=Group 552347,${ldapBaseDn} +member: cn=Group 552348,${ldapBaseDn} +member: cn=Group 552349,${ldapBaseDn} +member: cn=Group 552350,${ldapBaseDn} +member: cn=Group 552351,${ldapBaseDn} +member: cn=Group 552352,${ldapBaseDn} +member: cn=Group 552353,${ldapBaseDn} +member: cn=Group 552354,${ldapBaseDn} +member: cn=Group 552355,${ldapBaseDn} +member: cn=Group 552356,${ldapBaseDn} +member: cn=Group 552357,${ldapBaseDn} +member: cn=Group 552358,${ldapBaseDn} +member: cn=Group 552359,${ldapBaseDn} +member: cn=Group 552360,${ldapBaseDn} +member: cn=Group 552361,${ldapBaseDn} +member: cn=Group 552362,${ldapBaseDn} +member: cn=Group 552363,${ldapBaseDn} +member: cn=Group 552364,${ldapBaseDn} +member: cn=Group 552365,${ldapBaseDn} +member: cn=Group 552366,${ldapBaseDn} +member: cn=Group 552367,${ldapBaseDn} +member: cn=Group 552368,${ldapBaseDn} +member: cn=Group 552369,${ldapBaseDn} +member: cn=Group 552370,${ldapBaseDn} +member: cn=Group 552371,${ldapBaseDn} +member: cn=Group 552372,${ldapBaseDn} +member: cn=Group 552373,${ldapBaseDn} +member: cn=Group 552374,${ldapBaseDn} +member: cn=Group 552375,${ldapBaseDn} +member: cn=Group 552376,${ldapBaseDn} +member: cn=Group 552377,${ldapBaseDn} +member: cn=Group 552378,${ldapBaseDn} +member: cn=Group 552379,${ldapBaseDn} +member: cn=Group 552380,${ldapBaseDn} +member: cn=Group 552381,${ldapBaseDn} +member: cn=Group 552382,${ldapBaseDn} +member: cn=Group 552383,${ldapBaseDn} +member: cn=Group 552384,${ldapBaseDn} +member: cn=Group 552385,${ldapBaseDn} +member: cn=Group 552386,${ldapBaseDn} +member: cn=Group 552387,${ldapBaseDn} +member: cn=Group 552388,${ldapBaseDn} +member: cn=Group 552389,${ldapBaseDn} +member: cn=Group 552390,${ldapBaseDn} +member: cn=Group 552391,${ldapBaseDn} +member: cn=Group 552392,${ldapBaseDn} +member: cn=Group 552393,${ldapBaseDn} +member: cn=Group 552394,${ldapBaseDn} +member: cn=Group 552395,${ldapBaseDn} +member: cn=Group 552396,${ldapBaseDn} +member: cn=Group 552397,${ldapBaseDn} +member: cn=Group 552398,${ldapBaseDn} +member: cn=Group 552399,${ldapBaseDn} +member: cn=Group 552400,${ldapBaseDn} +member: cn=Group 552401,${ldapBaseDn} +member: cn=Group 552402,${ldapBaseDn} +member: cn=Group 552403,${ldapBaseDn} +member: cn=Group 552404,${ldapBaseDn} +member: cn=Group 552405,${ldapBaseDn} +member: cn=Group 552406,${ldapBaseDn} +member: cn=Group 552407,${ldapBaseDn} +member: cn=Group 552408,${ldapBaseDn} +member: cn=Group 552409,${ldapBaseDn} +member: cn=Group 552410,${ldapBaseDn} +member: cn=Group 552411,${ldapBaseDn} +member: cn=Group 552412,${ldapBaseDn} +member: cn=Group 552413,${ldapBaseDn} +member: cn=Group 552414,${ldapBaseDn} +member: cn=Group 552415,${ldapBaseDn} +member: cn=Group 552416,${ldapBaseDn} +member: cn=Group 552417,${ldapBaseDn} +member: cn=Group 552418,${ldapBaseDn} +member: cn=Group 552419,${ldapBaseDn} +member: cn=Group 552420,${ldapBaseDn} +member: cn=Group 552421,${ldapBaseDn} +member: cn=Group 552422,${ldapBaseDn} +member: cn=Group 552423,${ldapBaseDn} +member: cn=Group 552424,${ldapBaseDn} +member: cn=Group 552425,${ldapBaseDn} +member: cn=Group 552426,${ldapBaseDn} +member: cn=Group 552427,${ldapBaseDn} +member: cn=Group 552428,${ldapBaseDn} +member: cn=Group 552429,${ldapBaseDn} +member: cn=Group 552430,${ldapBaseDn} +member: cn=Group 552431,${ldapBaseDn} +member: cn=Group 552432,${ldapBaseDn} +member: cn=Group 552433,${ldapBaseDn} +member: cn=Group 552434,${ldapBaseDn} +member: cn=Group 552435,${ldapBaseDn} +member: cn=Group 552436,${ldapBaseDn} +member: cn=Group 552437,${ldapBaseDn} +member: cn=Group 552438,${ldapBaseDn} +member: cn=Group 552439,${ldapBaseDn} +member: cn=Group 552440,${ldapBaseDn} +member: cn=Group 552441,${ldapBaseDn} +member: cn=Group 552442,${ldapBaseDn} +member: cn=Group 552443,${ldapBaseDn} +member: cn=Group 552444,${ldapBaseDn} +member: cn=Group 552445,${ldapBaseDn} +member: cn=Group 552446,${ldapBaseDn} +member: cn=Group 552447,${ldapBaseDn} +member: cn=Group 552448,${ldapBaseDn} +member: cn=Group 552449,${ldapBaseDn} +member: cn=Group 552450,${ldapBaseDn} +member: cn=Group 552451,${ldapBaseDn} +member: cn=Group 552452,${ldapBaseDn} +member: cn=Group 552453,${ldapBaseDn} +member: cn=Group 552454,${ldapBaseDn} +member: cn=Group 552455,${ldapBaseDn} +member: cn=Group 552456,${ldapBaseDn} +member: cn=Group 552457,${ldapBaseDn} +member: cn=Group 552458,${ldapBaseDn} +member: cn=Group 552459,${ldapBaseDn} +member: cn=Group 552460,${ldapBaseDn} +member: cn=Group 552461,${ldapBaseDn} +member: cn=Group 552462,${ldapBaseDn} +member: cn=Group 552463,${ldapBaseDn} +member: cn=Group 552464,${ldapBaseDn} +member: cn=Group 552465,${ldapBaseDn} +member: cn=Group 552466,${ldapBaseDn} +member: cn=Group 552467,${ldapBaseDn} +member: cn=Group 552468,${ldapBaseDn} +member: cn=Group 552469,${ldapBaseDn} +member: cn=Group 552470,${ldapBaseDn} +member: cn=Group 552471,${ldapBaseDn} +member: cn=Group 552472,${ldapBaseDn} +member: cn=Group 552473,${ldapBaseDn} +member: cn=Group 552474,${ldapBaseDn} +member: cn=Group 552475,${ldapBaseDn} +member: cn=Group 552476,${ldapBaseDn} +member: cn=Group 552477,${ldapBaseDn} +member: cn=Group 552478,${ldapBaseDn} +member: cn=Group 552479,${ldapBaseDn} +member: cn=Group 552480,${ldapBaseDn} +member: cn=Group 552481,${ldapBaseDn} +member: cn=Group 552482,${ldapBaseDn} +member: cn=Group 552483,${ldapBaseDn} +member: cn=Group 552484,${ldapBaseDn} +member: cn=Group 552485,${ldapBaseDn} +member: cn=Group 552486,${ldapBaseDn} +member: cn=Group 552487,${ldapBaseDn} +member: cn=Group 552488,${ldapBaseDn} +member: cn=Group 552489,${ldapBaseDn} +member: cn=Group 552490,${ldapBaseDn} +member: cn=Group 552491,${ldapBaseDn} +member: cn=Group 552492,${ldapBaseDn} +member: cn=Group 552493,${ldapBaseDn} +member: cn=Group 552494,${ldapBaseDn} +member: cn=Group 552495,${ldapBaseDn} +member: cn=Group 552496,${ldapBaseDn} +member: cn=Group 552497,${ldapBaseDn} +member: cn=Group 552498,${ldapBaseDn} +member: cn=Group 552499,${ldapBaseDn} +member: cn=Group 552500,${ldapBaseDn} +member: cn=Group 552501,${ldapBaseDn} +member: cn=Group 552502,${ldapBaseDn} +member: cn=Group 552503,${ldapBaseDn} +member: cn=Group 552504,${ldapBaseDn} +member: cn=Group 552505,${ldapBaseDn} +member: cn=Group 552506,${ldapBaseDn} +member: cn=Group 552507,${ldapBaseDn} +member: cn=Group 552508,${ldapBaseDn} +member: cn=Group 552509,${ldapBaseDn} +member: cn=Group 552510,${ldapBaseDn} +member: cn=Group 552511,${ldapBaseDn} +member: cn=Group 552512,${ldapBaseDn} +member: cn=Group 552513,${ldapBaseDn} +member: cn=Group 552514,${ldapBaseDn} +member: cn=Group 552515,${ldapBaseDn} +member: cn=Group 552516,${ldapBaseDn} +member: cn=Group 552517,${ldapBaseDn} +member: cn=Group 552518,${ldapBaseDn} +member: cn=Group 552519,${ldapBaseDn} +member: cn=Group 552520,${ldapBaseDn} +member: cn=Group 552521,${ldapBaseDn} +member: cn=Group 552522,${ldapBaseDn} +member: cn=Group 552523,${ldapBaseDn} +member: cn=Group 552524,${ldapBaseDn} +member: cn=Group 552525,${ldapBaseDn} +member: cn=Group 552526,${ldapBaseDn} +member: cn=Group 552527,${ldapBaseDn} +member: cn=Group 552528,${ldapBaseDn} +member: cn=Group 552529,${ldapBaseDn} +member: cn=Group 552530,${ldapBaseDn} +member: cn=Group 552531,${ldapBaseDn} +member: cn=Group 552532,${ldapBaseDn} +member: cn=Group 552533,${ldapBaseDn} +member: cn=Group 552534,${ldapBaseDn} +member: cn=Group 552535,${ldapBaseDn} +member: cn=Group 552536,${ldapBaseDn} +member: cn=Group 552537,${ldapBaseDn} +member: cn=Group 552538,${ldapBaseDn} +member: cn=Group 552539,${ldapBaseDn} +member: cn=Group 552540,${ldapBaseDn} +member: cn=Group 552541,${ldapBaseDn} +member: cn=Group 552542,${ldapBaseDn} +member: cn=Group 552543,${ldapBaseDn} +member: cn=Group 552544,${ldapBaseDn} +member: cn=Group 552545,${ldapBaseDn} +member: cn=Group 552546,${ldapBaseDn} +member: cn=Group 552547,${ldapBaseDn} +member: cn=Group 552548,${ldapBaseDn} +member: cn=Group 552549,${ldapBaseDn} +member: cn=Group 552550,${ldapBaseDn} +member: cn=Group 552551,${ldapBaseDn} +member: cn=Group 552552,${ldapBaseDn} +member: cn=Group 552553,${ldapBaseDn} +member: cn=Group 552554,${ldapBaseDn} +member: cn=Group 552555,${ldapBaseDn} +member: cn=Group 552556,${ldapBaseDn} +member: cn=Group 552557,${ldapBaseDn} +member: cn=Group 552558,${ldapBaseDn} +member: cn=Group 552559,${ldapBaseDn} +member: cn=Group 552560,${ldapBaseDn} +member: cn=Group 552561,${ldapBaseDn} +member: cn=Group 552562,${ldapBaseDn} +member: cn=Group 552563,${ldapBaseDn} +member: cn=Group 552564,${ldapBaseDn} +member: cn=Group 552565,${ldapBaseDn} +member: cn=Group 552566,${ldapBaseDn} +member: cn=Group 552567,${ldapBaseDn} +member: cn=Group 552568,${ldapBaseDn} +member: cn=Group 552569,${ldapBaseDn} +member: cn=Group 552570,${ldapBaseDn} +member: cn=Group 552571,${ldapBaseDn} +member: cn=Group 552572,${ldapBaseDn} +member: cn=Group 552573,${ldapBaseDn} +member: cn=Group 552574,${ldapBaseDn} +member: cn=Group 552575,${ldapBaseDn} +member: cn=Group 552576,${ldapBaseDn} +member: cn=Group 552577,${ldapBaseDn} +member: cn=Group 552578,${ldapBaseDn} +member: cn=Group 552579,${ldapBaseDn} +member: cn=Group 552580,${ldapBaseDn} +member: cn=Group 552581,${ldapBaseDn} +member: cn=Group 552582,${ldapBaseDn} +member: cn=Group 552583,${ldapBaseDn} +member: cn=Group 552584,${ldapBaseDn} +member: cn=Group 552585,${ldapBaseDn} +member: cn=Group 552586,${ldapBaseDn} +member: cn=Group 552587,${ldapBaseDn} +member: cn=Group 552588,${ldapBaseDn} +member: cn=Group 552589,${ldapBaseDn} +member: cn=Group 552590,${ldapBaseDn} +member: cn=Group 552591,${ldapBaseDn} +member: cn=Group 552592,${ldapBaseDn} +member: cn=Group 552593,${ldapBaseDn} +member: cn=Group 552594,${ldapBaseDn} +member: cn=Group 552595,${ldapBaseDn} +member: cn=Group 552596,${ldapBaseDn} +member: cn=Group 552597,${ldapBaseDn} +member: cn=Group 552598,${ldapBaseDn} +member: cn=Group 552599,${ldapBaseDn} +member: cn=Group 552600,${ldapBaseDn} +member: cn=Group 552601,${ldapBaseDn} +member: cn=Group 552602,${ldapBaseDn} +member: cn=Group 552603,${ldapBaseDn} +member: cn=Group 552604,${ldapBaseDn} +member: cn=Group 552605,${ldapBaseDn} +member: cn=Group 552606,${ldapBaseDn} +member: cn=Group 552607,${ldapBaseDn} +member: cn=Group 552608,${ldapBaseDn} +member: cn=Group 552609,${ldapBaseDn} +member: cn=Group 552610,${ldapBaseDn} +member: cn=Group 552611,${ldapBaseDn} +member: cn=Group 552612,${ldapBaseDn} +member: cn=Group 552613,${ldapBaseDn} +member: cn=Group 552614,${ldapBaseDn} +member: cn=Group 552615,${ldapBaseDn} +member: cn=Group 552616,${ldapBaseDn} +member: cn=Group 552617,${ldapBaseDn} +member: cn=Group 552618,${ldapBaseDn} +member: cn=Group 552619,${ldapBaseDn} +member: cn=Group 552620,${ldapBaseDn} +member: cn=Group 552621,${ldapBaseDn} +member: cn=Group 552622,${ldapBaseDn} +member: cn=Group 552623,${ldapBaseDn} +member: cn=Group 552624,${ldapBaseDn} +member: cn=Group 552625,${ldapBaseDn} +member: cn=Group 552626,${ldapBaseDn} +member: cn=Group 552627,${ldapBaseDn} +member: cn=Group 552628,${ldapBaseDn} +member: cn=Group 552629,${ldapBaseDn} +member: cn=Group 552630,${ldapBaseDn} +member: cn=Group 552631,${ldapBaseDn} +member: cn=Group 552632,${ldapBaseDn} +member: cn=Group 552633,${ldapBaseDn} +member: cn=Group 552634,${ldapBaseDn} +member: cn=Group 552635,${ldapBaseDn} +member: cn=Group 552636,${ldapBaseDn} +member: cn=Group 552637,${ldapBaseDn} +member: cn=Group 552638,${ldapBaseDn} +member: cn=Group 552639,${ldapBaseDn} +member: cn=Group 552640,${ldapBaseDn} +member: cn=Group 552641,${ldapBaseDn} +member: cn=Group 552642,${ldapBaseDn} +member: cn=Group 552643,${ldapBaseDn} +member: cn=Group 552644,${ldapBaseDn} +member: cn=Group 552645,${ldapBaseDn} +member: cn=Group 552646,${ldapBaseDn} +member: cn=Group 552647,${ldapBaseDn} +member: cn=Group 552648,${ldapBaseDn} +member: cn=Group 552649,${ldapBaseDn} +member: cn=Group 552650,${ldapBaseDn} +member: cn=Group 552651,${ldapBaseDn} +member: cn=Group 552652,${ldapBaseDn} +member: cn=Group 552653,${ldapBaseDn} +member: cn=Group 552654,${ldapBaseDn} +member: cn=Group 552655,${ldapBaseDn} +member: cn=Group 552656,${ldapBaseDn} +member: cn=Group 552657,${ldapBaseDn} +member: cn=Group 552658,${ldapBaseDn} +member: cn=Group 552659,${ldapBaseDn} +member: cn=Group 552660,${ldapBaseDn} +member: cn=Group 552661,${ldapBaseDn} +member: cn=Group 552662,${ldapBaseDn} +member: cn=Group 552663,${ldapBaseDn} +member: cn=Group 552664,${ldapBaseDn} +member: cn=Group 552665,${ldapBaseDn} +member: cn=Group 552666,${ldapBaseDn} +member: cn=Group 552667,${ldapBaseDn} +member: cn=Group 552668,${ldapBaseDn} +member: cn=Group 552669,${ldapBaseDn} +member: cn=Group 552670,${ldapBaseDn} +member: cn=Group 552671,${ldapBaseDn} +member: cn=Group 552672,${ldapBaseDn} +member: cn=Group 552673,${ldapBaseDn} +member: cn=Group 552674,${ldapBaseDn} +member: cn=Group 552675,${ldapBaseDn} +member: cn=Group 552676,${ldapBaseDn} +member: cn=Group 552677,${ldapBaseDn} +member: cn=Group 552678,${ldapBaseDn} +member: cn=Group 552679,${ldapBaseDn} +member: cn=Group 552680,${ldapBaseDn} +member: cn=Group 552681,${ldapBaseDn} +member: cn=Group 552682,${ldapBaseDn} +member: cn=Group 552683,${ldapBaseDn} +member: cn=Group 552684,${ldapBaseDn} +member: cn=Group 552685,${ldapBaseDn} +member: cn=Group 552686,${ldapBaseDn} +member: cn=Group 552687,${ldapBaseDn} +member: cn=Group 552688,${ldapBaseDn} +member: cn=Group 552689,${ldapBaseDn} +member: cn=Group 552690,${ldapBaseDn} +member: cn=Group 552691,${ldapBaseDn} +member: cn=Group 552692,${ldapBaseDn} +member: cn=Group 552693,${ldapBaseDn} +member: cn=Group 552694,${ldapBaseDn} +member: cn=Group 552695,${ldapBaseDn} +member: cn=Group 552696,${ldapBaseDn} +member: cn=Group 552697,${ldapBaseDn} +member: cn=Group 552698,${ldapBaseDn} +member: cn=Group 552699,${ldapBaseDn} +member: cn=Group 552700,${ldapBaseDn} +member: cn=Group 552701,${ldapBaseDn} +member: cn=Group 552702,${ldapBaseDn} +member: cn=Group 552703,${ldapBaseDn} +member: cn=Group 552704,${ldapBaseDn} +member: cn=Group 552705,${ldapBaseDn} +member: cn=Group 552706,${ldapBaseDn} +member: cn=Group 552707,${ldapBaseDn} +member: cn=Group 552708,${ldapBaseDn} +member: cn=Group 552709,${ldapBaseDn} +member: cn=Group 552710,${ldapBaseDn} +member: cn=Group 552711,${ldapBaseDn} +member: cn=Group 552712,${ldapBaseDn} +member: cn=Group 552713,${ldapBaseDn} +member: cn=Group 552714,${ldapBaseDn} +member: cn=Group 552715,${ldapBaseDn} +member: cn=Group 552716,${ldapBaseDn} +member: cn=Group 552717,${ldapBaseDn} +member: cn=Group 552718,${ldapBaseDn} +member: cn=Group 552719,${ldapBaseDn} +member: cn=Group 552720,${ldapBaseDn} +member: cn=Group 552721,${ldapBaseDn} +member: cn=Group 552722,${ldapBaseDn} +member: cn=Group 552723,${ldapBaseDn} +member: cn=Group 552724,${ldapBaseDn} +member: cn=Group 552725,${ldapBaseDn} +member: cn=Group 552726,${ldapBaseDn} +member: cn=Group 552727,${ldapBaseDn} +member: cn=Group 552728,${ldapBaseDn} +member: cn=Group 552729,${ldapBaseDn} +member: cn=Group 552730,${ldapBaseDn} +member: cn=Group 552731,${ldapBaseDn} +member: cn=Group 552732,${ldapBaseDn} +member: cn=Group 552733,${ldapBaseDn} +member: cn=Group 552734,${ldapBaseDn} +member: cn=Group 552735,${ldapBaseDn} +member: cn=Group 552736,${ldapBaseDn} +member: cn=Group 552737,${ldapBaseDn} +member: cn=Group 552738,${ldapBaseDn} +member: cn=Group 552739,${ldapBaseDn} +member: cn=Group 552740,${ldapBaseDn} +member: cn=Group 552741,${ldapBaseDn} +member: cn=Group 552742,${ldapBaseDn} +member: cn=Group 552743,${ldapBaseDn} +member: cn=Group 552744,${ldapBaseDn} +member: cn=Group 552745,${ldapBaseDn} +member: cn=Group 552746,${ldapBaseDn} +member: cn=Group 552747,${ldapBaseDn} +member: cn=Group 552748,${ldapBaseDn} +member: cn=Group 552749,${ldapBaseDn} +member: cn=Group 552750,${ldapBaseDn} +member: cn=Group 552751,${ldapBaseDn} +member: cn=Group 552752,${ldapBaseDn} +member: cn=Group 552753,${ldapBaseDn} +member: cn=Group 552754,${ldapBaseDn} +member: cn=Group 552755,${ldapBaseDn} +member: cn=Group 552756,${ldapBaseDn} +member: cn=Group 552757,${ldapBaseDn} +member: cn=Group 552758,${ldapBaseDn} +member: cn=Group 552759,${ldapBaseDn} +member: cn=Group 552760,${ldapBaseDn} +member: cn=Group 552761,${ldapBaseDn} +member: cn=Group 552762,${ldapBaseDn} +member: cn=Group 552763,${ldapBaseDn} +member: cn=Group 552764,${ldapBaseDn} +member: cn=Group 552765,${ldapBaseDn} +member: cn=Group 552766,${ldapBaseDn} +member: cn=Group 552767,${ldapBaseDn} +member: cn=Group 552768,${ldapBaseDn} +member: cn=Group 552769,${ldapBaseDn} +member: cn=Group 552770,${ldapBaseDn} +member: cn=Group 552771,${ldapBaseDn} +member: cn=Group 552772,${ldapBaseDn} +member: cn=Group 552773,${ldapBaseDn} +member: cn=Group 552774,${ldapBaseDn} +member: cn=Group 552775,${ldapBaseDn} +member: cn=Group 552776,${ldapBaseDn} +member: cn=Group 552777,${ldapBaseDn} +member: cn=Group 552778,${ldapBaseDn} +member: cn=Group 552779,${ldapBaseDn} +member: cn=Group 552780,${ldapBaseDn} +member: cn=Group 552781,${ldapBaseDn} +member: cn=Group 552782,${ldapBaseDn} +member: cn=Group 552783,${ldapBaseDn} +member: cn=Group 552784,${ldapBaseDn} +member: cn=Group 552785,${ldapBaseDn} +member: cn=Group 552786,${ldapBaseDn} +member: cn=Group 552787,${ldapBaseDn} +member: cn=Group 552788,${ldapBaseDn} +member: cn=Group 552789,${ldapBaseDn} +member: cn=Group 552790,${ldapBaseDn} +member: cn=Group 552791,${ldapBaseDn} +member: cn=Group 552792,${ldapBaseDn} +member: cn=Group 552793,${ldapBaseDn} +member: cn=Group 552794,${ldapBaseDn} +member: cn=Group 552795,${ldapBaseDn} +member: cn=Group 552796,${ldapBaseDn} +member: cn=Group 552797,${ldapBaseDn} +member: cn=Group 552798,${ldapBaseDn} +member: cn=Group 552799,${ldapBaseDn} +member: cn=Group 552800,${ldapBaseDn} +member: cn=Group 552801,${ldapBaseDn} +member: cn=Group 552802,${ldapBaseDn} +member: cn=Group 552803,${ldapBaseDn} +member: cn=Group 552804,${ldapBaseDn} +member: cn=Group 552805,${ldapBaseDn} +member: cn=Group 552806,${ldapBaseDn} +member: cn=Group 552807,${ldapBaseDn} +member: cn=Group 552808,${ldapBaseDn} +member: cn=Group 552809,${ldapBaseDn} +member: cn=Group 552810,${ldapBaseDn} +member: cn=Group 552811,${ldapBaseDn} +member: cn=Group 552812,${ldapBaseDn} +member: cn=Group 552813,${ldapBaseDn} +member: cn=Group 552814,${ldapBaseDn} +member: cn=Group 552815,${ldapBaseDn} +member: cn=Group 552816,${ldapBaseDn} +member: cn=Group 552817,${ldapBaseDn} +member: cn=Group 552818,${ldapBaseDn} +member: cn=Group 552819,${ldapBaseDn} +member: cn=Group 552820,${ldapBaseDn} +member: cn=Group 552821,${ldapBaseDn} +member: cn=Group 552822,${ldapBaseDn} +member: cn=Group 552823,${ldapBaseDn} +member: cn=Group 552824,${ldapBaseDn} +member: cn=Group 552825,${ldapBaseDn} +member: cn=Group 552826,${ldapBaseDn} +member: cn=Group 552827,${ldapBaseDn} +member: cn=Group 552828,${ldapBaseDn} +member: cn=Group 552829,${ldapBaseDn} +member: cn=Group 552830,${ldapBaseDn} +member: cn=Group 552831,${ldapBaseDn} +member: cn=Group 552832,${ldapBaseDn} +member: cn=Group 552833,${ldapBaseDn} +member: cn=Group 552834,${ldapBaseDn} +member: cn=Group 552835,${ldapBaseDn} +member: cn=Group 552836,${ldapBaseDn} +member: cn=Group 552837,${ldapBaseDn} +member: cn=Group 552838,${ldapBaseDn} +member: cn=Group 552839,${ldapBaseDn} +member: cn=Group 552840,${ldapBaseDn} +member: cn=Group 552841,${ldapBaseDn} +member: cn=Group 552842,${ldapBaseDn} +member: cn=Group 552843,${ldapBaseDn} +member: cn=Group 552844,${ldapBaseDn} +member: cn=Group 552845,${ldapBaseDn} +member: cn=Group 552846,${ldapBaseDn} +member: cn=Group 552847,${ldapBaseDn} +member: cn=Group 552848,${ldapBaseDn} +member: cn=Group 552849,${ldapBaseDn} +member: cn=Group 552850,${ldapBaseDn} +member: cn=Group 552851,${ldapBaseDn} +member: cn=Group 552852,${ldapBaseDn} +member: cn=Group 552853,${ldapBaseDn} +member: cn=Group 552854,${ldapBaseDn} +member: cn=Group 552855,${ldapBaseDn} +member: cn=Group 552856,${ldapBaseDn} +member: cn=Group 552857,${ldapBaseDn} +member: cn=Group 552858,${ldapBaseDn} +member: cn=Group 552859,${ldapBaseDn} +member: cn=Group 552860,${ldapBaseDn} +member: cn=Group 552861,${ldapBaseDn} +member: cn=Group 552862,${ldapBaseDn} +member: cn=Group 552863,${ldapBaseDn} +member: cn=Group 552864,${ldapBaseDn} +member: cn=Group 552865,${ldapBaseDn} +member: cn=Group 552866,${ldapBaseDn} +member: cn=Group 552867,${ldapBaseDn} +member: cn=Group 552868,${ldapBaseDn} +member: cn=Group 552869,${ldapBaseDn} +member: cn=Group 552870,${ldapBaseDn} +member: cn=Group 552871,${ldapBaseDn} +member: cn=Group 552872,${ldapBaseDn} +member: cn=Group 552873,${ldapBaseDn} +member: cn=Group 552874,${ldapBaseDn} +member: cn=Group 552875,${ldapBaseDn} +member: cn=Group 552876,${ldapBaseDn} +member: cn=Group 552877,${ldapBaseDn} +member: cn=Group 552878,${ldapBaseDn} +member: cn=Group 552879,${ldapBaseDn} +member: cn=Group 552880,${ldapBaseDn} +member: cn=Group 552881,${ldapBaseDn} +member: cn=Group 552882,${ldapBaseDn} +member: cn=Group 552883,${ldapBaseDn} +member: cn=Group 552884,${ldapBaseDn} +member: cn=Group 552885,${ldapBaseDn} +member: cn=Group 552886,${ldapBaseDn} +member: cn=Group 552887,${ldapBaseDn} +member: cn=Group 552888,${ldapBaseDn} +member: cn=Group 552889,${ldapBaseDn} +member: cn=Group 552890,${ldapBaseDn} +member: cn=Group 552891,${ldapBaseDn} +member: cn=Group 552892,${ldapBaseDn} +member: cn=Group 552893,${ldapBaseDn} +member: cn=Group 552894,${ldapBaseDn} +member: cn=Group 552895,${ldapBaseDn} +member: cn=Group 552896,${ldapBaseDn} +member: cn=Group 552897,${ldapBaseDn} +member: cn=Group 552898,${ldapBaseDn} +member: cn=Group 552899,${ldapBaseDn} +member: cn=Group 552900,${ldapBaseDn} +member: cn=Group 552901,${ldapBaseDn} +member: cn=Group 552902,${ldapBaseDn} +member: cn=Group 552903,${ldapBaseDn} +member: cn=Group 552904,${ldapBaseDn} +member: cn=Group 552905,${ldapBaseDn} +member: cn=Group 552906,${ldapBaseDn} +member: cn=Group 552907,${ldapBaseDn} +member: cn=Group 552908,${ldapBaseDn} +member: cn=Group 552909,${ldapBaseDn} +member: cn=Group 552910,${ldapBaseDn} +member: cn=Group 552911,${ldapBaseDn} +member: cn=Group 552912,${ldapBaseDn} +member: cn=Group 552913,${ldapBaseDn} +member: cn=Group 552914,${ldapBaseDn} +member: cn=Group 552915,${ldapBaseDn} +member: cn=Group 552916,${ldapBaseDn} +member: cn=Group 552917,${ldapBaseDn} +member: cn=Group 552918,${ldapBaseDn} +member: cn=Group 552919,${ldapBaseDn} +member: cn=Group 552920,${ldapBaseDn} +member: cn=Group 552921,${ldapBaseDn} +member: cn=Group 552922,${ldapBaseDn} +member: cn=Group 552923,${ldapBaseDn} +member: cn=Group 552924,${ldapBaseDn} +member: cn=Group 552925,${ldapBaseDn} +member: cn=Group 552926,${ldapBaseDn} +member: cn=Group 552927,${ldapBaseDn} +member: cn=Group 552928,${ldapBaseDn} +member: cn=Group 552929,${ldapBaseDn} +member: cn=Group 552930,${ldapBaseDn} +member: cn=Group 552931,${ldapBaseDn} +member: cn=Group 552932,${ldapBaseDn} +member: cn=Group 552933,${ldapBaseDn} +member: cn=Group 552934,${ldapBaseDn} +member: cn=Group 552935,${ldapBaseDn} +member: cn=Group 552936,${ldapBaseDn} +member: cn=Group 552937,${ldapBaseDn} +member: cn=Group 552938,${ldapBaseDn} +member: cn=Group 552939,${ldapBaseDn} +member: cn=Group 552940,${ldapBaseDn} +member: cn=Group 552941,${ldapBaseDn} +member: cn=Group 552942,${ldapBaseDn} +member: cn=Group 552943,${ldapBaseDn} +member: cn=Group 552944,${ldapBaseDn} +member: cn=Group 552945,${ldapBaseDn} +member: cn=Group 552946,${ldapBaseDn} +member: cn=Group 552947,${ldapBaseDn} +member: cn=Group 552948,${ldapBaseDn} +member: cn=Group 552949,${ldapBaseDn} +member: cn=Group 552950,${ldapBaseDn} +member: cn=Group 552951,${ldapBaseDn} +member: cn=Group 552952,${ldapBaseDn} +member: cn=Group 552953,${ldapBaseDn} +member: cn=Group 552954,${ldapBaseDn} +member: cn=Group 552955,${ldapBaseDn} +member: cn=Group 552956,${ldapBaseDn} +member: cn=Group 552957,${ldapBaseDn} +member: cn=Group 552958,${ldapBaseDn} +member: cn=Group 552959,${ldapBaseDn} +member: cn=Group 552960,${ldapBaseDn} +member: cn=Group 552961,${ldapBaseDn} +member: cn=Group 552962,${ldapBaseDn} +member: cn=Group 552963,${ldapBaseDn} +member: cn=Group 552964,${ldapBaseDn} +member: cn=Group 552965,${ldapBaseDn} +member: cn=Group 552966,${ldapBaseDn} +member: cn=Group 552967,${ldapBaseDn} +member: cn=Group 552968,${ldapBaseDn} +member: cn=Group 552969,${ldapBaseDn} +member: cn=Group 552970,${ldapBaseDn} +member: cn=Group 552971,${ldapBaseDn} +member: cn=Group 552972,${ldapBaseDn} +member: cn=Group 552973,${ldapBaseDn} +member: cn=Group 552974,${ldapBaseDn} +member: cn=Group 552975,${ldapBaseDn} +member: cn=Group 552976,${ldapBaseDn} +member: cn=Group 552977,${ldapBaseDn} +member: cn=Group 552978,${ldapBaseDn} +member: cn=Group 552979,${ldapBaseDn} +member: cn=Group 552980,${ldapBaseDn} +member: cn=Group 552981,${ldapBaseDn} +member: cn=Group 552982,${ldapBaseDn} +member: cn=Group 552983,${ldapBaseDn} +member: cn=Group 552984,${ldapBaseDn} +member: cn=Group 552985,${ldapBaseDn} +member: cn=Group 552986,${ldapBaseDn} +member: cn=Group 552987,${ldapBaseDn} +member: cn=Group 552988,${ldapBaseDn} +member: cn=Group 552989,${ldapBaseDn} +member: cn=Group 552990,${ldapBaseDn} +member: cn=Group 552991,${ldapBaseDn} +member: cn=Group 552992,${ldapBaseDn} +member: cn=Group 552993,${ldapBaseDn} +member: cn=Group 552994,${ldapBaseDn} +member: cn=Group 552995,${ldapBaseDn} +member: cn=Group 552996,${ldapBaseDn} +member: cn=Group 552997,${ldapBaseDn} +member: cn=Group 552998,${ldapBaseDn} +member: cn=Group 552999,${ldapBaseDn} +member: cn=Group 553000,${ldapBaseDn} +member: cn=Group 553001,${ldapBaseDn} +member: cn=Group 553002,${ldapBaseDn} +member: cn=Group 553003,${ldapBaseDn} +member: cn=Group 553004,${ldapBaseDn} +member: cn=Group 553005,${ldapBaseDn} +member: cn=Group 553006,${ldapBaseDn} +member: cn=Group 553007,${ldapBaseDn} +member: cn=Group 553008,${ldapBaseDn} +member: cn=Group 553009,${ldapBaseDn} +member: cn=Group 553010,${ldapBaseDn} +member: cn=Group 553011,${ldapBaseDn} +member: cn=Group 553012,${ldapBaseDn} +member: cn=Group 553013,${ldapBaseDn} +member: cn=Group 553014,${ldapBaseDn} +member: cn=Group 553015,${ldapBaseDn} +member: cn=Group 553016,${ldapBaseDn} +member: cn=Group 553017,${ldapBaseDn} +member: cn=Group 553018,${ldapBaseDn} +member: cn=Group 553019,${ldapBaseDn} +member: cn=Group 553020,${ldapBaseDn} +member: cn=Group 553021,${ldapBaseDn} +member: cn=Group 553022,${ldapBaseDn} +member: cn=Group 553023,${ldapBaseDn} +member: cn=Group 553024,${ldapBaseDn} +member: cn=Group 553025,${ldapBaseDn} +member: cn=Group 553026,${ldapBaseDn} +member: cn=Group 553027,${ldapBaseDn} +member: cn=Group 553028,${ldapBaseDn} +member: cn=Group 553029,${ldapBaseDn} +member: cn=Group 553030,${ldapBaseDn} +member: cn=Group 553031,${ldapBaseDn} +member: cn=Group 553032,${ldapBaseDn} +member: cn=Group 553033,${ldapBaseDn} +member: cn=Group 553034,${ldapBaseDn} +member: cn=Group 553035,${ldapBaseDn} +member: cn=Group 553036,${ldapBaseDn} +member: cn=Group 553037,${ldapBaseDn} +member: cn=Group 553038,${ldapBaseDn} +member: cn=Group 553039,${ldapBaseDn} +member: cn=Group 553040,${ldapBaseDn} +member: cn=Group 553041,${ldapBaseDn} +member: cn=Group 553042,${ldapBaseDn} +member: cn=Group 553043,${ldapBaseDn} +member: cn=Group 553044,${ldapBaseDn} +member: cn=Group 553045,${ldapBaseDn} +member: cn=Group 553046,${ldapBaseDn} +member: cn=Group 553047,${ldapBaseDn} +member: cn=Group 553048,${ldapBaseDn} +member: cn=Group 553049,${ldapBaseDn} +member: cn=Group 553050,${ldapBaseDn} +member: cn=Group 553051,${ldapBaseDn} +member: cn=Group 553052,${ldapBaseDn} +member: cn=Group 553053,${ldapBaseDn} +member: cn=Group 553054,${ldapBaseDn} +member: cn=Group 553055,${ldapBaseDn} +member: cn=Group 553056,${ldapBaseDn} +member: cn=Group 553057,${ldapBaseDn} +member: cn=Group 553058,${ldapBaseDn} +member: cn=Group 553059,${ldapBaseDn} +member: cn=Group 553060,${ldapBaseDn} +member: cn=Group 553061,${ldapBaseDn} +member: cn=Group 553062,${ldapBaseDn} +member: cn=Group 553063,${ldapBaseDn} +member: cn=Group 553064,${ldapBaseDn} +member: cn=Group 553065,${ldapBaseDn} +member: cn=Group 553066,${ldapBaseDn} +member: cn=Group 553067,${ldapBaseDn} +member: cn=Group 553068,${ldapBaseDn} +member: cn=Group 553069,${ldapBaseDn} +member: cn=Group 553070,${ldapBaseDn} +member: cn=Group 553071,${ldapBaseDn} +member: cn=Group 553072,${ldapBaseDn} +member: cn=Group 553073,${ldapBaseDn} +member: cn=Group 553074,${ldapBaseDn} +member: cn=Group 553075,${ldapBaseDn} +member: cn=Group 553076,${ldapBaseDn} +member: cn=Group 553077,${ldapBaseDn} +member: cn=Group 553078,${ldapBaseDn} +member: cn=Group 553079,${ldapBaseDn} +member: cn=Group 553080,${ldapBaseDn} +member: cn=Group 553081,${ldapBaseDn} +member: cn=Group 553082,${ldapBaseDn} +member: cn=Group 553083,${ldapBaseDn} +member: cn=Group 553084,${ldapBaseDn} +member: cn=Group 553085,${ldapBaseDn} +member: cn=Group 553086,${ldapBaseDn} +member: cn=Group 553087,${ldapBaseDn} +member: cn=Group 553088,${ldapBaseDn} +member: cn=Group 553089,${ldapBaseDn} +member: cn=Group 553090,${ldapBaseDn} +member: cn=Group 553091,${ldapBaseDn} +member: cn=Group 553092,${ldapBaseDn} +member: cn=Group 553093,${ldapBaseDn} +member: cn=Group 553094,${ldapBaseDn} +member: cn=Group 553095,${ldapBaseDn} +member: cn=Group 553096,${ldapBaseDn} +member: cn=Group 553097,${ldapBaseDn} +member: cn=Group 553098,${ldapBaseDn} +member: cn=Group 553099,${ldapBaseDn} +member: cn=Group 553100,${ldapBaseDn} +member: cn=Group 553101,${ldapBaseDn} +member: cn=Group 553102,${ldapBaseDn} +member: cn=Group 553103,${ldapBaseDn} +member: cn=Group 553104,${ldapBaseDn} +member: cn=Group 553105,${ldapBaseDn} +member: cn=Group 553106,${ldapBaseDn} +member: cn=Group 553107,${ldapBaseDn} +member: cn=Group 553108,${ldapBaseDn} +member: cn=Group 553109,${ldapBaseDn} +member: cn=Group 553110,${ldapBaseDn} +member: cn=Group 553111,${ldapBaseDn} +member: cn=Group 553112,${ldapBaseDn} +member: cn=Group 553113,${ldapBaseDn} +member: cn=Group 553114,${ldapBaseDn} +member: cn=Group 553115,${ldapBaseDn} +member: cn=Group 553116,${ldapBaseDn} +member: cn=Group 553117,${ldapBaseDn} +member: cn=Group 553118,${ldapBaseDn} +member: cn=Group 553119,${ldapBaseDn} +member: cn=Group 553120,${ldapBaseDn} +member: cn=Group 553121,${ldapBaseDn} +member: cn=Group 553122,${ldapBaseDn} +member: cn=Group 553123,${ldapBaseDn} +member: cn=Group 553124,${ldapBaseDn} +member: cn=Group 553125,${ldapBaseDn} +member: cn=Group 553126,${ldapBaseDn} +member: cn=Group 553127,${ldapBaseDn} +member: cn=Group 553128,${ldapBaseDn} +member: cn=Group 553129,${ldapBaseDn} +member: cn=Group 553130,${ldapBaseDn} +member: cn=Group 553131,${ldapBaseDn} +member: cn=Group 553132,${ldapBaseDn} +member: cn=Group 553133,${ldapBaseDn} +member: cn=Group 553134,${ldapBaseDn} +member: cn=Group 553135,${ldapBaseDn} +member: cn=Group 553136,${ldapBaseDn} +member: cn=Group 553137,${ldapBaseDn} +member: cn=Group 553138,${ldapBaseDn} +member: cn=Group 553139,${ldapBaseDn} +member: cn=Group 553140,${ldapBaseDn} +member: cn=Group 553141,${ldapBaseDn} +member: cn=Group 553142,${ldapBaseDn} +member: cn=Group 553143,${ldapBaseDn} +member: cn=Group 553144,${ldapBaseDn} +member: cn=Group 553145,${ldapBaseDn} +member: cn=Group 553146,${ldapBaseDn} +member: cn=Group 553147,${ldapBaseDn} +member: cn=Group 553148,${ldapBaseDn} +member: cn=Group 553149,${ldapBaseDn} +member: cn=Group 553150,${ldapBaseDn} +member: cn=Group 553151,${ldapBaseDn} +member: cn=Group 553152,${ldapBaseDn} +member: cn=Group 553153,${ldapBaseDn} +member: cn=Group 553154,${ldapBaseDn} +member: cn=Group 553155,${ldapBaseDn} +member: cn=Group 553156,${ldapBaseDn} +member: cn=Group 553157,${ldapBaseDn} +member: cn=Group 553158,${ldapBaseDn} +member: cn=Group 553159,${ldapBaseDn} +member: cn=Group 553160,${ldapBaseDn} +member: cn=Group 553161,${ldapBaseDn} +member: cn=Group 553162,${ldapBaseDn} +member: cn=Group 553163,${ldapBaseDn} +member: cn=Group 553164,${ldapBaseDn} +member: cn=Group 553165,${ldapBaseDn} +member: cn=Group 553166,${ldapBaseDn} +member: cn=Group 553167,${ldapBaseDn} +member: cn=Group 553168,${ldapBaseDn} +member: cn=Group 553169,${ldapBaseDn} +member: cn=Group 553170,${ldapBaseDn} +member: cn=Group 553171,${ldapBaseDn} +member: cn=Group 553172,${ldapBaseDn} +member: cn=Group 553173,${ldapBaseDn} +member: cn=Group 553174,${ldapBaseDn} +member: cn=Group 553175,${ldapBaseDn} +member: cn=Group 553176,${ldapBaseDn} +member: cn=Group 553177,${ldapBaseDn} +member: cn=Group 553178,${ldapBaseDn} +member: cn=Group 553179,${ldapBaseDn} +member: cn=Group 553180,${ldapBaseDn} +member: cn=Group 553181,${ldapBaseDn} +member: cn=Group 553182,${ldapBaseDn} +member: cn=Group 553183,${ldapBaseDn} +member: cn=Group 553184,${ldapBaseDn} +member: cn=Group 553185,${ldapBaseDn} +member: cn=Group 553186,${ldapBaseDn} +member: cn=Group 553187,${ldapBaseDn} +member: cn=Group 553188,${ldapBaseDn} +member: cn=Group 553189,${ldapBaseDn} +member: cn=Group 553190,${ldapBaseDn} +member: cn=Group 553191,${ldapBaseDn} +member: cn=Group 553192,${ldapBaseDn} +member: cn=Group 553193,${ldapBaseDn} +member: cn=Group 553194,${ldapBaseDn} +member: cn=Group 553195,${ldapBaseDn} +member: cn=Group 553196,${ldapBaseDn} +member: cn=Group 553197,${ldapBaseDn} +member: cn=Group 553198,${ldapBaseDn} +member: cn=Group 553199,${ldapBaseDn} +member: cn=Group 553200,${ldapBaseDn} +member: cn=Group 553201,${ldapBaseDn} +member: cn=Group 553202,${ldapBaseDn} +member: cn=Group 553203,${ldapBaseDn} +member: cn=Group 553204,${ldapBaseDn} +member: cn=Group 553205,${ldapBaseDn} +member: cn=Group 553206,${ldapBaseDn} +member: cn=Group 553207,${ldapBaseDn} +member: cn=Group 553208,${ldapBaseDn} +member: cn=Group 553209,${ldapBaseDn} +member: cn=Group 553210,${ldapBaseDn} +member: cn=Group 553211,${ldapBaseDn} +member: cn=Group 553212,${ldapBaseDn} +member: cn=Group 553213,${ldapBaseDn} +member: cn=Group 553214,${ldapBaseDn} +member: cn=Group 553215,${ldapBaseDn} +member: cn=Group 553216,${ldapBaseDn} +member: cn=Group 553217,${ldapBaseDn} +member: cn=Group 553218,${ldapBaseDn} +member: cn=Group 553219,${ldapBaseDn} +member: cn=Group 553220,${ldapBaseDn} +member: cn=Group 553221,${ldapBaseDn} +member: cn=Group 553222,${ldapBaseDn} +member: cn=Group 553223,${ldapBaseDn} +member: cn=Group 553224,${ldapBaseDn} +member: cn=Group 553225,${ldapBaseDn} +member: cn=Group 553226,${ldapBaseDn} +member: cn=Group 553227,${ldapBaseDn} +member: cn=Group 553228,${ldapBaseDn} +member: cn=Group 553229,${ldapBaseDn} +member: cn=Group 553230,${ldapBaseDn} +member: cn=Group 553231,${ldapBaseDn} +member: cn=Group 553232,${ldapBaseDn} +member: cn=Group 553233,${ldapBaseDn} +member: cn=Group 553234,${ldapBaseDn} +member: cn=Group 553235,${ldapBaseDn} +member: cn=Group 553236,${ldapBaseDn} +member: cn=Group 553237,${ldapBaseDn} +member: cn=Group 553238,${ldapBaseDn} +member: cn=Group 553239,${ldapBaseDn} +member: cn=Group 553240,${ldapBaseDn} +member: cn=Group 553241,${ldapBaseDn} +member: cn=Group 553242,${ldapBaseDn} +member: cn=Group 553243,${ldapBaseDn} +member: cn=Group 553244,${ldapBaseDn} +member: cn=Group 553245,${ldapBaseDn} +member: cn=Group 553246,${ldapBaseDn} +member: cn=Group 553247,${ldapBaseDn} +member: cn=Group 553248,${ldapBaseDn} +member: cn=Group 553249,${ldapBaseDn} +member: cn=Group 553250,${ldapBaseDn} +member: cn=Group 553251,${ldapBaseDn} +member: cn=Group 553252,${ldapBaseDn} +member: cn=Group 553253,${ldapBaseDn} +member: cn=Group 553254,${ldapBaseDn} +member: cn=Group 553255,${ldapBaseDn} +member: cn=Group 553256,${ldapBaseDn} +member: cn=Group 553257,${ldapBaseDn} +member: cn=Group 553258,${ldapBaseDn} +member: cn=Group 553259,${ldapBaseDn} +member: cn=Group 553260,${ldapBaseDn} +member: cn=Group 553261,${ldapBaseDn} +member: cn=Group 553262,${ldapBaseDn} +member: cn=Group 553263,${ldapBaseDn} +member: cn=Group 553264,${ldapBaseDn} +member: cn=Group 553265,${ldapBaseDn} +member: cn=Group 553266,${ldapBaseDn} +member: cn=Group 553267,${ldapBaseDn} +member: cn=Group 553268,${ldapBaseDn} +member: cn=Group 553269,${ldapBaseDn} +member: cn=Group 553270,${ldapBaseDn} +member: cn=Group 553271,${ldapBaseDn} +member: cn=Group 553272,${ldapBaseDn} +member: cn=Group 553273,${ldapBaseDn} +member: cn=Group 553274,${ldapBaseDn} +member: cn=Group 553275,${ldapBaseDn} +member: cn=Group 553276,${ldapBaseDn} +member: cn=Group 553277,${ldapBaseDn} +member: cn=Group 553278,${ldapBaseDn} +member: cn=Group 553279,${ldapBaseDn} +member: cn=Group 553280,${ldapBaseDn} +member: cn=Group 553281,${ldapBaseDn} +member: cn=Group 553282,${ldapBaseDn} +member: cn=Group 553283,${ldapBaseDn} +member: cn=Group 553284,${ldapBaseDn} +member: cn=Group 553285,${ldapBaseDn} +member: cn=Group 553286,${ldapBaseDn} +member: cn=Group 553287,${ldapBaseDn} +member: cn=Group 553288,${ldapBaseDn} +member: cn=Group 553289,${ldapBaseDn} +member: cn=Group 553290,${ldapBaseDn} +member: cn=Group 553291,${ldapBaseDn} +member: cn=Group 553292,${ldapBaseDn} +member: cn=Group 553293,${ldapBaseDn} +member: cn=Group 553294,${ldapBaseDn} +member: cn=Group 553295,${ldapBaseDn} +member: cn=Group 553296,${ldapBaseDn} +member: cn=Group 553297,${ldapBaseDn} +member: cn=Group 553298,${ldapBaseDn} +member: cn=Group 553299,${ldapBaseDn} +member: cn=Group 553300,${ldapBaseDn} +member: cn=Group 553301,${ldapBaseDn} +member: cn=Group 553302,${ldapBaseDn} +member: cn=Group 553303,${ldapBaseDn} +member: cn=Group 553304,${ldapBaseDn} +member: cn=Group 553305,${ldapBaseDn} +member: cn=Group 553306,${ldapBaseDn} +member: cn=Group 553307,${ldapBaseDn} +member: cn=Group 553308,${ldapBaseDn} +member: cn=Group 553309,${ldapBaseDn} +member: cn=Group 553310,${ldapBaseDn} +member: cn=Group 553311,${ldapBaseDn} +member: cn=Group 553312,${ldapBaseDn} +member: cn=Group 553313,${ldapBaseDn} +member: cn=Group 553314,${ldapBaseDn} +member: cn=Group 553315,${ldapBaseDn} +member: cn=Group 553316,${ldapBaseDn} +member: cn=Group 553317,${ldapBaseDn} +member: cn=Group 553318,${ldapBaseDn} +member: cn=Group 553319,${ldapBaseDn} +member: cn=Group 553320,${ldapBaseDn} +member: cn=Group 553321,${ldapBaseDn} +member: cn=Group 553322,${ldapBaseDn} +member: cn=Group 553323,${ldapBaseDn} +member: cn=Group 553324,${ldapBaseDn} +member: cn=Group 553325,${ldapBaseDn} +member: cn=Group 553326,${ldapBaseDn} +member: cn=Group 553327,${ldapBaseDn} +member: cn=Group 553328,${ldapBaseDn} +member: cn=Group 553329,${ldapBaseDn} +member: cn=Group 553330,${ldapBaseDn} +member: cn=Group 553331,${ldapBaseDn} +member: cn=Group 553332,${ldapBaseDn} +member: cn=Group 553333,${ldapBaseDn} +member: cn=Group 553334,${ldapBaseDn} +member: cn=Group 553335,${ldapBaseDn} +member: cn=Group 553336,${ldapBaseDn} +member: cn=Group 553337,${ldapBaseDn} +member: cn=Group 553338,${ldapBaseDn} +member: cn=Group 553339,${ldapBaseDn} +member: cn=Group 553340,${ldapBaseDn} +member: cn=Group 553341,${ldapBaseDn} +member: cn=Group 553342,${ldapBaseDn} +member: cn=Group 553343,${ldapBaseDn} +member: cn=Group 553344,${ldapBaseDn} +member: cn=Group 553345,${ldapBaseDn} +member: cn=Group 553346,${ldapBaseDn} +member: cn=Group 553347,${ldapBaseDn} +member: cn=Group 553348,${ldapBaseDn} +member: cn=Group 553349,${ldapBaseDn} +member: cn=Group 553350,${ldapBaseDn} +member: cn=Group 553351,${ldapBaseDn} +member: cn=Group 553352,${ldapBaseDn} +member: cn=Group 553353,${ldapBaseDn} +member: cn=Group 553354,${ldapBaseDn} +member: cn=Group 553355,${ldapBaseDn} +member: cn=Group 553356,${ldapBaseDn} +member: cn=Group 553357,${ldapBaseDn} +member: cn=Group 553358,${ldapBaseDn} +member: cn=Group 553359,${ldapBaseDn} +member: cn=Group 553360,${ldapBaseDn} +member: cn=Group 553361,${ldapBaseDn} +member: cn=Group 553362,${ldapBaseDn} +member: cn=Group 553363,${ldapBaseDn} +member: cn=Group 553364,${ldapBaseDn} +member: cn=Group 553365,${ldapBaseDn} +member: cn=Group 553366,${ldapBaseDn} +member: cn=Group 553367,${ldapBaseDn} +member: cn=Group 553368,${ldapBaseDn} +member: cn=Group 553369,${ldapBaseDn} +member: cn=Group 553370,${ldapBaseDn} +member: cn=Group 553371,${ldapBaseDn} +member: cn=Group 553372,${ldapBaseDn} +member: cn=Group 553373,${ldapBaseDn} +member: cn=Group 553374,${ldapBaseDn} +member: cn=Group 553375,${ldapBaseDn} +member: cn=Group 553376,${ldapBaseDn} +member: cn=Group 553377,${ldapBaseDn} +member: cn=Group 553378,${ldapBaseDn} +member: cn=Group 553379,${ldapBaseDn} +member: cn=Group 553380,${ldapBaseDn} +member: cn=Group 553381,${ldapBaseDn} +member: cn=Group 553382,${ldapBaseDn} +member: cn=Group 553383,${ldapBaseDn} +member: cn=Group 553384,${ldapBaseDn} +member: cn=Group 553385,${ldapBaseDn} +member: cn=Group 553386,${ldapBaseDn} +member: cn=Group 553387,${ldapBaseDn} +member: cn=Group 553388,${ldapBaseDn} +member: cn=Group 553389,${ldapBaseDn} +member: cn=Group 553390,${ldapBaseDn} +member: cn=Group 553391,${ldapBaseDn} +member: cn=Group 553392,${ldapBaseDn} +member: cn=Group 553393,${ldapBaseDn} +member: cn=Group 553394,${ldapBaseDn} +member: cn=Group 553395,${ldapBaseDn} +member: cn=Group 553396,${ldapBaseDn} +member: cn=Group 553397,${ldapBaseDn} +member: cn=Group 553398,${ldapBaseDn} +member: cn=Group 553399,${ldapBaseDn} +member: cn=Group 553400,${ldapBaseDn} +member: cn=Group 553401,${ldapBaseDn} +member: cn=Group 553402,${ldapBaseDn} +member: cn=Group 553403,${ldapBaseDn} +member: cn=Group 553404,${ldapBaseDn} +member: cn=Group 553405,${ldapBaseDn} +member: cn=Group 553406,${ldapBaseDn} +member: cn=Group 553407,${ldapBaseDn} +member: cn=Group 553408,${ldapBaseDn} +member: cn=Group 553409,${ldapBaseDn} +member: cn=Group 553410,${ldapBaseDn} +member: cn=Group 553411,${ldapBaseDn} +member: cn=Group 553412,${ldapBaseDn} +member: cn=Group 553413,${ldapBaseDn} +member: cn=Group 553414,${ldapBaseDn} +member: cn=Group 553415,${ldapBaseDn} +member: cn=Group 553416,${ldapBaseDn} +member: cn=Group 553417,${ldapBaseDn} +member: cn=Group 553418,${ldapBaseDn} +member: cn=Group 553419,${ldapBaseDn} +member: cn=Group 553420,${ldapBaseDn} +member: cn=Group 553421,${ldapBaseDn} +member: cn=Group 553422,${ldapBaseDn} +member: cn=Group 553423,${ldapBaseDn} +member: cn=Group 553424,${ldapBaseDn} +member: cn=Group 553425,${ldapBaseDn} +member: cn=Group 553426,${ldapBaseDn} +member: cn=Group 553427,${ldapBaseDn} +member: cn=Group 553428,${ldapBaseDn} +member: cn=Group 553429,${ldapBaseDn} +member: cn=Group 553430,${ldapBaseDn} +member: cn=Group 553431,${ldapBaseDn} +member: cn=Group 553432,${ldapBaseDn} +member: cn=Group 553433,${ldapBaseDn} +member: cn=Group 553434,${ldapBaseDn} +member: cn=Group 553435,${ldapBaseDn} +member: cn=Group 553436,${ldapBaseDn} +member: cn=Group 553437,${ldapBaseDn} +member: cn=Group 553438,${ldapBaseDn} +member: cn=Group 553439,${ldapBaseDn} +member: cn=Group 553440,${ldapBaseDn} +member: cn=Group 553441,${ldapBaseDn} +member: cn=Group 553442,${ldapBaseDn} +member: cn=Group 553443,${ldapBaseDn} +member: cn=Group 553444,${ldapBaseDn} +member: cn=Group 553445,${ldapBaseDn} +member: cn=Group 553446,${ldapBaseDn} +member: cn=Group 553447,${ldapBaseDn} +member: cn=Group 553448,${ldapBaseDn} +member: cn=Group 553449,${ldapBaseDn} +member: cn=Group 553450,${ldapBaseDn} +member: cn=Group 553451,${ldapBaseDn} +member: cn=Group 553452,${ldapBaseDn} +member: cn=Group 553453,${ldapBaseDn} +member: cn=Group 553454,${ldapBaseDn} +member: cn=Group 553455,${ldapBaseDn} +member: cn=Group 553456,${ldapBaseDn} +member: cn=Group 553457,${ldapBaseDn} +member: cn=Group 553458,${ldapBaseDn} +member: cn=Group 553459,${ldapBaseDn} +member: cn=Group 553460,${ldapBaseDn} +member: cn=Group 553461,${ldapBaseDn} +member: cn=Group 553462,${ldapBaseDn} +member: cn=Group 553463,${ldapBaseDn} +member: cn=Group 553464,${ldapBaseDn} +member: cn=Group 553465,${ldapBaseDn} +member: cn=Group 553466,${ldapBaseDn} +member: cn=Group 553467,${ldapBaseDn} +member: cn=Group 553468,${ldapBaseDn} +member: cn=Group 553469,${ldapBaseDn} +member: cn=Group 553470,${ldapBaseDn} +member: cn=Group 553471,${ldapBaseDn} +member: cn=Group 553472,${ldapBaseDn} +member: cn=Group 553473,${ldapBaseDn} +member: cn=Group 553474,${ldapBaseDn} +member: cn=Group 553475,${ldapBaseDn} +member: cn=Group 553476,${ldapBaseDn} +member: cn=Group 553477,${ldapBaseDn} +member: cn=Group 553478,${ldapBaseDn} +member: cn=Group 553479,${ldapBaseDn} +member: cn=Group 553480,${ldapBaseDn} +member: cn=Group 553481,${ldapBaseDn} +member: cn=Group 553482,${ldapBaseDn} +member: cn=Group 553483,${ldapBaseDn} +member: cn=Group 553484,${ldapBaseDn} +member: cn=Group 553485,${ldapBaseDn} +member: cn=Group 553486,${ldapBaseDn} +member: cn=Group 553487,${ldapBaseDn} +member: cn=Group 553488,${ldapBaseDn} +member: cn=Group 553489,${ldapBaseDn} +member: cn=Group 553490,${ldapBaseDn} +member: cn=Group 553491,${ldapBaseDn} +member: cn=Group 553492,${ldapBaseDn} +member: cn=Group 553493,${ldapBaseDn} +member: cn=Group 553494,${ldapBaseDn} +member: cn=Group 553495,${ldapBaseDn} +member: cn=Group 553496,${ldapBaseDn} +member: cn=Group 553497,${ldapBaseDn} +member: cn=Group 553498,${ldapBaseDn} +member: cn=Group 553499,${ldapBaseDn} +member: cn=Group 553500,${ldapBaseDn} +member: cn=Group 553501,${ldapBaseDn} +member: cn=Group 553502,${ldapBaseDn} +member: cn=Group 553503,${ldapBaseDn} +member: cn=Group 553504,${ldapBaseDn} +member: cn=Group 553505,${ldapBaseDn} +member: cn=Group 553506,${ldapBaseDn} +member: cn=Group 553507,${ldapBaseDn} +member: cn=Group 553508,${ldapBaseDn} +member: cn=Group 553509,${ldapBaseDn} +member: cn=Group 553510,${ldapBaseDn} +member: cn=Group 553511,${ldapBaseDn} +member: cn=Group 553512,${ldapBaseDn} +member: cn=Group 553513,${ldapBaseDn} +member: cn=Group 553514,${ldapBaseDn} +member: cn=Group 553515,${ldapBaseDn} +member: cn=Group 553516,${ldapBaseDn} +member: cn=Group 553517,${ldapBaseDn} +member: cn=Group 553518,${ldapBaseDn} +member: cn=Group 553519,${ldapBaseDn} +member: cn=Group 553520,${ldapBaseDn} +member: cn=Group 553521,${ldapBaseDn} +member: cn=Group 553522,${ldapBaseDn} +member: cn=Group 553523,${ldapBaseDn} +member: cn=Group 553524,${ldapBaseDn} +member: cn=Group 553525,${ldapBaseDn} +member: cn=Group 553526,${ldapBaseDn} +member: cn=Group 553527,${ldapBaseDn} +member: cn=Group 553528,${ldapBaseDn} +member: cn=Group 553529,${ldapBaseDn} +member: cn=Group 553530,${ldapBaseDn} +member: cn=Group 553531,${ldapBaseDn} +member: cn=Group 553532,${ldapBaseDn} +member: cn=Group 553533,${ldapBaseDn} +member: cn=Group 553534,${ldapBaseDn} +member: cn=Group 553535,${ldapBaseDn} +member: cn=Group 553536,${ldapBaseDn} +member: cn=Group 553537,${ldapBaseDn} +member: cn=Group 553538,${ldapBaseDn} +member: cn=Group 553539,${ldapBaseDn} +member: cn=Group 553540,${ldapBaseDn} +member: cn=Group 553541,${ldapBaseDn} +member: cn=Group 553542,${ldapBaseDn} +member: cn=Group 553543,${ldapBaseDn} +member: cn=Group 553544,${ldapBaseDn} +member: cn=Group 553545,${ldapBaseDn} +member: cn=Group 553546,${ldapBaseDn} +member: cn=Group 553547,${ldapBaseDn} +member: cn=Group 553548,${ldapBaseDn} +member: cn=Group 553549,${ldapBaseDn} +member: cn=Group 553550,${ldapBaseDn} +member: cn=Group 553551,${ldapBaseDn} +member: cn=Group 553552,${ldapBaseDn} +member: cn=Group 553553,${ldapBaseDn} +member: cn=Group 553554,${ldapBaseDn} +member: cn=Group 553555,${ldapBaseDn} +member: cn=Group 553556,${ldapBaseDn} +member: cn=Group 553557,${ldapBaseDn} +member: cn=Group 553558,${ldapBaseDn} +member: cn=Group 553559,${ldapBaseDn} +member: cn=Group 553560,${ldapBaseDn} +member: cn=Group 553561,${ldapBaseDn} +member: cn=Group 553562,${ldapBaseDn} +member: cn=Group 553563,${ldapBaseDn} +member: cn=Group 553564,${ldapBaseDn} +member: cn=Group 553565,${ldapBaseDn} +member: cn=Group 553566,${ldapBaseDn} +member: cn=Group 553567,${ldapBaseDn} +member: cn=Group 553568,${ldapBaseDn} +member: cn=Group 553569,${ldapBaseDn} +member: cn=Group 553570,${ldapBaseDn} +member: cn=Group 553571,${ldapBaseDn} +member: cn=Group 553572,${ldapBaseDn} +member: cn=Group 553573,${ldapBaseDn} +member: cn=Group 553574,${ldapBaseDn} +member: cn=Group 553575,${ldapBaseDn} +member: cn=Group 553576,${ldapBaseDn} +member: cn=Group 553577,${ldapBaseDn} +member: cn=Group 553578,${ldapBaseDn} +member: cn=Group 553579,${ldapBaseDn} +member: cn=Group 553580,${ldapBaseDn} +member: cn=Group 553581,${ldapBaseDn} +member: cn=Group 553582,${ldapBaseDn} +member: cn=Group 553583,${ldapBaseDn} +member: cn=Group 553584,${ldapBaseDn} +member: cn=Group 553585,${ldapBaseDn} +member: cn=Group 553586,${ldapBaseDn} +member: cn=Group 553587,${ldapBaseDn} +member: cn=Group 553588,${ldapBaseDn} +member: cn=Group 553589,${ldapBaseDn} +member: cn=Group 553590,${ldapBaseDn} +member: cn=Group 553591,${ldapBaseDn} +member: cn=Group 553592,${ldapBaseDn} +member: cn=Group 553593,${ldapBaseDn} +member: cn=Group 553594,${ldapBaseDn} +member: cn=Group 553595,${ldapBaseDn} +member: cn=Group 553596,${ldapBaseDn} +member: cn=Group 553597,${ldapBaseDn} +member: cn=Group 553598,${ldapBaseDn} +member: cn=Group 553599,${ldapBaseDn} +member: cn=Group 553600,${ldapBaseDn} +member: cn=Group 553601,${ldapBaseDn} +member: cn=Group 553602,${ldapBaseDn} +member: cn=Group 553603,${ldapBaseDn} +member: cn=Group 553604,${ldapBaseDn} +member: cn=Group 553605,${ldapBaseDn} +member: cn=Group 553606,${ldapBaseDn} +member: cn=Group 553607,${ldapBaseDn} +member: cn=Group 553608,${ldapBaseDn} +member: cn=Group 553609,${ldapBaseDn} +member: cn=Group 553610,${ldapBaseDn} +member: cn=Group 553611,${ldapBaseDn} +member: cn=Group 553612,${ldapBaseDn} +member: cn=Group 553613,${ldapBaseDn} +member: cn=Group 553614,${ldapBaseDn} +member: cn=Group 553615,${ldapBaseDn} +member: cn=Group 553616,${ldapBaseDn} +member: cn=Group 553617,${ldapBaseDn} +member: cn=Group 553618,${ldapBaseDn} +member: cn=Group 553619,${ldapBaseDn} +member: cn=Group 553620,${ldapBaseDn} +member: cn=Group 553621,${ldapBaseDn} +member: cn=Group 553622,${ldapBaseDn} +member: cn=Group 553623,${ldapBaseDn} +member: cn=Group 553624,${ldapBaseDn} +member: cn=Group 553625,${ldapBaseDn} +member: cn=Group 553626,${ldapBaseDn} +member: cn=Group 553627,${ldapBaseDn} +member: cn=Group 553628,${ldapBaseDn} +member: cn=Group 553629,${ldapBaseDn} +member: cn=Group 553630,${ldapBaseDn} +member: cn=Group 553631,${ldapBaseDn} +member: cn=Group 553632,${ldapBaseDn} +member: cn=Group 553633,${ldapBaseDn} +member: cn=Group 553634,${ldapBaseDn} +member: cn=Group 553635,${ldapBaseDn} +member: cn=Group 553636,${ldapBaseDn} +member: cn=Group 553637,${ldapBaseDn} +member: cn=Group 553638,${ldapBaseDn} +member: cn=Group 553639,${ldapBaseDn} +member: cn=Group 553640,${ldapBaseDn} +member: cn=Group 553641,${ldapBaseDn} +member: cn=Group 553642,${ldapBaseDn} +member: cn=Group 553643,${ldapBaseDn} +member: cn=Group 553644,${ldapBaseDn} +member: cn=Group 553645,${ldapBaseDn} +member: cn=Group 553646,${ldapBaseDn} +member: cn=Group 553647,${ldapBaseDn} +member: cn=Group 553648,${ldapBaseDn} +member: cn=Group 553649,${ldapBaseDn} +member: cn=Group 553650,${ldapBaseDn} +member: cn=Group 553651,${ldapBaseDn} +member: cn=Group 553652,${ldapBaseDn} +member: cn=Group 553653,${ldapBaseDn} +member: cn=Group 553654,${ldapBaseDn} +member: cn=Group 553655,${ldapBaseDn} +member: cn=Group 553656,${ldapBaseDn} +member: cn=Group 553657,${ldapBaseDn} +member: cn=Group 553658,${ldapBaseDn} +member: cn=Group 553659,${ldapBaseDn} +member: cn=Group 553660,${ldapBaseDn} +member: cn=Group 553661,${ldapBaseDn} +member: cn=Group 553662,${ldapBaseDn} +member: cn=Group 553663,${ldapBaseDn} +member: cn=Group 553664,${ldapBaseDn} +member: cn=Group 553665,${ldapBaseDn} +member: cn=Group 553666,${ldapBaseDn} +member: cn=Group 553667,${ldapBaseDn} +member: cn=Group 553668,${ldapBaseDn} +member: cn=Group 553669,${ldapBaseDn} +member: cn=Group 553670,${ldapBaseDn} +member: cn=Group 553671,${ldapBaseDn} +member: cn=Group 553672,${ldapBaseDn} +member: cn=Group 553673,${ldapBaseDn} +member: cn=Group 553674,${ldapBaseDn} +member: cn=Group 553675,${ldapBaseDn} +member: cn=Group 553676,${ldapBaseDn} +member: cn=Group 553677,${ldapBaseDn} +member: cn=Group 553678,${ldapBaseDn} +member: cn=Group 553679,${ldapBaseDn} +member: cn=Group 553680,${ldapBaseDn} +member: cn=Group 553681,${ldapBaseDn} +member: cn=Group 553682,${ldapBaseDn} +member: cn=Group 553683,${ldapBaseDn} +member: cn=Group 553684,${ldapBaseDn} +member: cn=Group 553685,${ldapBaseDn} +member: cn=Group 553686,${ldapBaseDn} +member: cn=Group 553687,${ldapBaseDn} +member: cn=Group 553688,${ldapBaseDn} +member: cn=Group 553689,${ldapBaseDn} +member: cn=Group 553690,${ldapBaseDn} +member: cn=Group 553691,${ldapBaseDn} +member: cn=Group 553692,${ldapBaseDn} +member: cn=Group 553693,${ldapBaseDn} +member: cn=Group 553694,${ldapBaseDn} +member: cn=Group 553695,${ldapBaseDn} +member: cn=Group 553696,${ldapBaseDn} +member: cn=Group 553697,${ldapBaseDn} +member: cn=Group 553698,${ldapBaseDn} +member: cn=Group 553699,${ldapBaseDn} +member: cn=Group 553700,${ldapBaseDn} +member: cn=Group 553701,${ldapBaseDn} +member: cn=Group 553702,${ldapBaseDn} +member: cn=Group 553703,${ldapBaseDn} +member: cn=Group 553704,${ldapBaseDn} +member: cn=Group 553705,${ldapBaseDn} +member: cn=Group 553706,${ldapBaseDn} +member: cn=Group 553707,${ldapBaseDn} +member: cn=Group 553708,${ldapBaseDn} +member: cn=Group 553709,${ldapBaseDn} +member: cn=Group 553710,${ldapBaseDn} +member: cn=Group 553711,${ldapBaseDn} +member: cn=Group 553712,${ldapBaseDn} +member: cn=Group 553713,${ldapBaseDn} +member: cn=Group 553714,${ldapBaseDn} +member: cn=Group 553715,${ldapBaseDn} +member: cn=Group 553716,${ldapBaseDn} +member: cn=Group 553717,${ldapBaseDn} +member: cn=Group 553718,${ldapBaseDn} +member: cn=Group 553719,${ldapBaseDn} +member: cn=Group 553720,${ldapBaseDn} +member: cn=Group 553721,${ldapBaseDn} +member: cn=Group 553722,${ldapBaseDn} +member: cn=Group 553723,${ldapBaseDn} +member: cn=Group 553724,${ldapBaseDn} +member: cn=Group 553725,${ldapBaseDn} +member: cn=Group 553726,${ldapBaseDn} +member: cn=Group 553727,${ldapBaseDn} +member: cn=Group 553728,${ldapBaseDn} +member: cn=Group 553729,${ldapBaseDn} +member: cn=Group 553730,${ldapBaseDn} +member: cn=Group 553731,${ldapBaseDn} +member: cn=Group 553732,${ldapBaseDn} +member: cn=Group 553733,${ldapBaseDn} +member: cn=Group 553734,${ldapBaseDn} +member: cn=Group 553735,${ldapBaseDn} +member: cn=Group 553736,${ldapBaseDn} +member: cn=Group 553737,${ldapBaseDn} +member: cn=Group 553738,${ldapBaseDn} +member: cn=Group 553739,${ldapBaseDn} +member: cn=Group 553740,${ldapBaseDn} +member: cn=Group 553741,${ldapBaseDn} +member: cn=Group 553742,${ldapBaseDn} +member: cn=Group 553743,${ldapBaseDn} +member: cn=Group 553744,${ldapBaseDn} +member: cn=Group 553745,${ldapBaseDn} +member: cn=Group 553746,${ldapBaseDn} +member: cn=Group 553747,${ldapBaseDn} +member: cn=Group 553748,${ldapBaseDn} +member: cn=Group 553749,${ldapBaseDn} +member: cn=Group 553750,${ldapBaseDn} +member: cn=Group 553751,${ldapBaseDn} +member: cn=Group 553752,${ldapBaseDn} +member: cn=Group 553753,${ldapBaseDn} +member: cn=Group 553754,${ldapBaseDn} +member: cn=Group 553755,${ldapBaseDn} +member: cn=Group 553756,${ldapBaseDn} +member: cn=Group 553757,${ldapBaseDn} +member: cn=Group 553758,${ldapBaseDn} +member: cn=Group 553759,${ldapBaseDn} +member: cn=Group 553760,${ldapBaseDn} +member: cn=Group 553761,${ldapBaseDn} +member: cn=Group 553762,${ldapBaseDn} +member: cn=Group 553763,${ldapBaseDn} +member: cn=Group 553764,${ldapBaseDn} +member: cn=Group 553765,${ldapBaseDn} +member: cn=Group 553766,${ldapBaseDn} +member: cn=Group 553767,${ldapBaseDn} +member: cn=Group 553768,${ldapBaseDn} +member: cn=Group 553769,${ldapBaseDn} +member: cn=Group 553770,${ldapBaseDn} +member: cn=Group 553771,${ldapBaseDn} +member: cn=Group 553772,${ldapBaseDn} +member: cn=Group 553773,${ldapBaseDn} +member: cn=Group 553774,${ldapBaseDn} +member: cn=Group 553775,${ldapBaseDn} +member: cn=Group 553776,${ldapBaseDn} +member: cn=Group 553777,${ldapBaseDn} +member: cn=Group 553778,${ldapBaseDn} +member: cn=Group 553779,${ldapBaseDn} +member: cn=Group 553780,${ldapBaseDn} +member: cn=Group 553781,${ldapBaseDn} +member: cn=Group 553782,${ldapBaseDn} +member: cn=Group 553783,${ldapBaseDn} +member: cn=Group 553784,${ldapBaseDn} +member: cn=Group 553785,${ldapBaseDn} +member: cn=Group 553786,${ldapBaseDn} +member: cn=Group 553787,${ldapBaseDn} +member: cn=Group 553788,${ldapBaseDn} +member: cn=Group 553789,${ldapBaseDn} +member: cn=Group 553790,${ldapBaseDn} +member: cn=Group 553791,${ldapBaseDn} +member: cn=Group 553792,${ldapBaseDn} +member: cn=Group 553793,${ldapBaseDn} +member: cn=Group 553794,${ldapBaseDn} +member: cn=Group 553795,${ldapBaseDn} +member: cn=Group 553796,${ldapBaseDn} +member: cn=Group 553797,${ldapBaseDn} +member: cn=Group 553798,${ldapBaseDn} +member: cn=Group 553799,${ldapBaseDn} +member: cn=Group 553800,${ldapBaseDn} +member: cn=Group 553801,${ldapBaseDn} +member: cn=Group 553802,${ldapBaseDn} +member: cn=Group 553803,${ldapBaseDn} +member: cn=Group 553804,${ldapBaseDn} +member: cn=Group 553805,${ldapBaseDn} +member: cn=Group 553806,${ldapBaseDn} +member: cn=Group 553807,${ldapBaseDn} +member: cn=Group 553808,${ldapBaseDn} +member: cn=Group 553809,${ldapBaseDn} +member: cn=Group 553810,${ldapBaseDn} +member: cn=Group 553811,${ldapBaseDn} +member: cn=Group 553812,${ldapBaseDn} +member: cn=Group 553813,${ldapBaseDn} +member: cn=Group 553814,${ldapBaseDn} +member: cn=Group 553815,${ldapBaseDn} +member: cn=Group 553816,${ldapBaseDn} +member: cn=Group 553817,${ldapBaseDn} +member: cn=Group 553818,${ldapBaseDn} +member: cn=Group 553819,${ldapBaseDn} +member: cn=Group 553820,${ldapBaseDn} +member: cn=Group 553821,${ldapBaseDn} +member: cn=Group 553822,${ldapBaseDn} +member: cn=Group 553823,${ldapBaseDn} +member: cn=Group 553824,${ldapBaseDn} +member: cn=Group 553825,${ldapBaseDn} +member: cn=Group 553826,${ldapBaseDn} +member: cn=Group 553827,${ldapBaseDn} +member: cn=Group 553828,${ldapBaseDn} +member: cn=Group 553829,${ldapBaseDn} +member: cn=Group 553830,${ldapBaseDn} +member: cn=Group 553831,${ldapBaseDn} +member: cn=Group 553832,${ldapBaseDn} +member: cn=Group 553833,${ldapBaseDn} +member: cn=Group 553834,${ldapBaseDn} +member: cn=Group 553835,${ldapBaseDn} +member: cn=Group 553836,${ldapBaseDn} +member: cn=Group 553837,${ldapBaseDn} +member: cn=Group 553838,${ldapBaseDn} +member: cn=Group 553839,${ldapBaseDn} +member: cn=Group 553840,${ldapBaseDn} +member: cn=Group 553841,${ldapBaseDn} +member: cn=Group 553842,${ldapBaseDn} +member: cn=Group 553843,${ldapBaseDn} +member: cn=Group 553844,${ldapBaseDn} +member: cn=Group 553845,${ldapBaseDn} +member: cn=Group 553846,${ldapBaseDn} +member: cn=Group 553847,${ldapBaseDn} +member: cn=Group 553848,${ldapBaseDn} +member: cn=Group 553849,${ldapBaseDn} +member: cn=Group 553850,${ldapBaseDn} +member: cn=Group 553851,${ldapBaseDn} +member: cn=Group 553852,${ldapBaseDn} +member: cn=Group 553853,${ldapBaseDn} +member: cn=Group 553854,${ldapBaseDn} +member: cn=Group 553855,${ldapBaseDn} +member: cn=Group 553856,${ldapBaseDn} +member: cn=Group 553857,${ldapBaseDn} +member: cn=Group 553858,${ldapBaseDn} +member: cn=Group 553859,${ldapBaseDn} +member: cn=Group 553860,${ldapBaseDn} +member: cn=Group 553861,${ldapBaseDn} +member: cn=Group 553862,${ldapBaseDn} +member: cn=Group 553863,${ldapBaseDn} +member: cn=Group 553864,${ldapBaseDn} +member: cn=Group 553865,${ldapBaseDn} +member: cn=Group 553866,${ldapBaseDn} +member: cn=Group 553867,${ldapBaseDn} +member: cn=Group 553868,${ldapBaseDn} +member: cn=Group 553869,${ldapBaseDn} +member: cn=Group 553870,${ldapBaseDn} +member: cn=Group 553871,${ldapBaseDn} +member: cn=Group 553872,${ldapBaseDn} +member: cn=Group 553873,${ldapBaseDn} +member: cn=Group 553874,${ldapBaseDn} +member: cn=Group 553875,${ldapBaseDn} +member: cn=Group 553876,${ldapBaseDn} +member: cn=Group 553877,${ldapBaseDn} +member: cn=Group 553878,${ldapBaseDn} +member: cn=Group 553879,${ldapBaseDn} +member: cn=Group 553880,${ldapBaseDn} +member: cn=Group 553881,${ldapBaseDn} +member: cn=Group 553882,${ldapBaseDn} +member: cn=Group 553883,${ldapBaseDn} +member: cn=Group 553884,${ldapBaseDn} +member: cn=Group 553885,${ldapBaseDn} +member: cn=Group 553886,${ldapBaseDn} +member: cn=Group 553887,${ldapBaseDn} +member: cn=Group 553888,${ldapBaseDn} +member: cn=Group 553889,${ldapBaseDn} +member: cn=Group 553890,${ldapBaseDn} +member: cn=Group 553891,${ldapBaseDn} +member: cn=Group 553892,${ldapBaseDn} +member: cn=Group 553893,${ldapBaseDn} +member: cn=Group 553894,${ldapBaseDn} +member: cn=Group 553895,${ldapBaseDn} +member: cn=Group 553896,${ldapBaseDn} +member: cn=Group 553897,${ldapBaseDn} +member: cn=Group 553898,${ldapBaseDn} +member: cn=Group 553899,${ldapBaseDn} +member: cn=Group 553900,${ldapBaseDn} +member: cn=Group 553901,${ldapBaseDn} +member: cn=Group 553902,${ldapBaseDn} +member: cn=Group 553903,${ldapBaseDn} +member: cn=Group 553904,${ldapBaseDn} +member: cn=Group 553905,${ldapBaseDn} +member: cn=Group 553906,${ldapBaseDn} +member: cn=Group 553907,${ldapBaseDn} +member: cn=Group 553908,${ldapBaseDn} +member: cn=Group 553909,${ldapBaseDn} +member: cn=Group 553910,${ldapBaseDn} +member: cn=Group 553911,${ldapBaseDn} +member: cn=Group 553912,${ldapBaseDn} +member: cn=Group 553913,${ldapBaseDn} +member: cn=Group 553914,${ldapBaseDn} +member: cn=Group 553915,${ldapBaseDn} +member: cn=Group 553916,${ldapBaseDn} +member: cn=Group 553917,${ldapBaseDn} +member: cn=Group 553918,${ldapBaseDn} +member: cn=Group 553919,${ldapBaseDn} +member: cn=Group 553920,${ldapBaseDn} +member: cn=Group 553921,${ldapBaseDn} +member: cn=Group 553922,${ldapBaseDn} +member: cn=Group 553923,${ldapBaseDn} +member: cn=Group 553924,${ldapBaseDn} +member: cn=Group 553925,${ldapBaseDn} +member: cn=Group 553926,${ldapBaseDn} +member: cn=Group 553927,${ldapBaseDn} +member: cn=Group 553928,${ldapBaseDn} +member: cn=Group 553929,${ldapBaseDn} +member: cn=Group 553930,${ldapBaseDn} +member: cn=Group 553931,${ldapBaseDn} +member: cn=Group 553932,${ldapBaseDn} +member: cn=Group 553933,${ldapBaseDn} +member: cn=Group 553934,${ldapBaseDn} +member: cn=Group 553935,${ldapBaseDn} +member: cn=Group 553936,${ldapBaseDn} +member: cn=Group 553937,${ldapBaseDn} +member: cn=Group 553938,${ldapBaseDn} +member: cn=Group 553939,${ldapBaseDn} +member: cn=Group 553940,${ldapBaseDn} +member: cn=Group 553941,${ldapBaseDn} +member: cn=Group 553942,${ldapBaseDn} +member: cn=Group 553943,${ldapBaseDn} +member: cn=Group 553944,${ldapBaseDn} +member: cn=Group 553945,${ldapBaseDn} +member: cn=Group 553946,${ldapBaseDn} +member: cn=Group 553947,${ldapBaseDn} +member: cn=Group 553948,${ldapBaseDn} +member: cn=Group 553949,${ldapBaseDn} +member: cn=Group 553950,${ldapBaseDn} +member: cn=Group 553951,${ldapBaseDn} +member: cn=Group 553952,${ldapBaseDn} +member: cn=Group 553953,${ldapBaseDn} +member: cn=Group 553954,${ldapBaseDn} +member: cn=Group 553955,${ldapBaseDn} +member: cn=Group 553956,${ldapBaseDn} +member: cn=Group 553957,${ldapBaseDn} +member: cn=Group 553958,${ldapBaseDn} +member: cn=Group 553959,${ldapBaseDn} +member: cn=Group 553960,${ldapBaseDn} +member: cn=Group 553961,${ldapBaseDn} +member: cn=Group 553962,${ldapBaseDn} +member: cn=Group 553963,${ldapBaseDn} +member: cn=Group 553964,${ldapBaseDn} +member: cn=Group 553965,${ldapBaseDn} +member: cn=Group 553966,${ldapBaseDn} +member: cn=Group 553967,${ldapBaseDn} +member: cn=Group 553968,${ldapBaseDn} +member: cn=Group 553969,${ldapBaseDn} +member: cn=Group 553970,${ldapBaseDn} +member: cn=Group 553971,${ldapBaseDn} +member: cn=Group 553972,${ldapBaseDn} +member: cn=Group 553973,${ldapBaseDn} +member: cn=Group 553974,${ldapBaseDn} +member: cn=Group 553975,${ldapBaseDn} +member: cn=Group 553976,${ldapBaseDn} +member: cn=Group 553977,${ldapBaseDn} +member: cn=Group 553978,${ldapBaseDn} +member: cn=Group 553979,${ldapBaseDn} +member: cn=Group 553980,${ldapBaseDn} +member: cn=Group 553981,${ldapBaseDn} +member: cn=Group 553982,${ldapBaseDn} +member: cn=Group 553983,${ldapBaseDn} +member: cn=Group 553984,${ldapBaseDn} +member: cn=Group 553985,${ldapBaseDn} +member: cn=Group 553986,${ldapBaseDn} +member: cn=Group 553987,${ldapBaseDn} +member: cn=Group 553988,${ldapBaseDn} +member: cn=Group 553989,${ldapBaseDn} +member: cn=Group 553990,${ldapBaseDn} +member: cn=Group 553991,${ldapBaseDn} +member: cn=Group 553992,${ldapBaseDn} +member: cn=Group 553993,${ldapBaseDn} +member: cn=Group 553994,${ldapBaseDn} +member: cn=Group 553995,${ldapBaseDn} +member: cn=Group 553996,${ldapBaseDn} +member: cn=Group 553997,${ldapBaseDn} +member: cn=Group 553998,${ldapBaseDn} +member: cn=Group 553999,${ldapBaseDn} +member: cn=Group 554000,${ldapBaseDn} +member: cn=Group 554001,${ldapBaseDn} +member: cn=Group 554002,${ldapBaseDn} +member: cn=Group 554003,${ldapBaseDn} +member: cn=Group 554004,${ldapBaseDn} +member: cn=Group 554005,${ldapBaseDn} +member: cn=Group 554006,${ldapBaseDn} +member: cn=Group 554007,${ldapBaseDn} +member: cn=Group 554008,${ldapBaseDn} +member: cn=Group 554009,${ldapBaseDn} +member: cn=Group 554010,${ldapBaseDn} +member: cn=Group 554011,${ldapBaseDn} +member: cn=Group 554012,${ldapBaseDn} +member: cn=Group 554013,${ldapBaseDn} +member: cn=Group 554014,${ldapBaseDn} +member: cn=Group 554015,${ldapBaseDn} +member: cn=Group 554016,${ldapBaseDn} +member: cn=Group 554017,${ldapBaseDn} +member: cn=Group 554018,${ldapBaseDn} +member: cn=Group 554019,${ldapBaseDn} +member: cn=Group 554020,${ldapBaseDn} +member: cn=Group 554021,${ldapBaseDn} +member: cn=Group 554022,${ldapBaseDn} +member: cn=Group 554023,${ldapBaseDn} +member: cn=Group 554024,${ldapBaseDn} +member: cn=Group 554025,${ldapBaseDn} +member: cn=Group 554026,${ldapBaseDn} +member: cn=Group 554027,${ldapBaseDn} +member: cn=Group 554028,${ldapBaseDn} +member: cn=Group 554029,${ldapBaseDn} +member: cn=Group 554030,${ldapBaseDn} +member: cn=Group 554031,${ldapBaseDn} +member: cn=Group 554032,${ldapBaseDn} +member: cn=Group 554033,${ldapBaseDn} +member: cn=Group 554034,${ldapBaseDn} +member: cn=Group 554035,${ldapBaseDn} +member: cn=Group 554036,${ldapBaseDn} +member: cn=Group 554037,${ldapBaseDn} +member: cn=Group 554038,${ldapBaseDn} +member: cn=Group 554039,${ldapBaseDn} +member: cn=Group 554040,${ldapBaseDn} +member: cn=Group 554041,${ldapBaseDn} +member: cn=Group 554042,${ldapBaseDn} +member: cn=Group 554043,${ldapBaseDn} +member: cn=Group 554044,${ldapBaseDn} +member: cn=Group 554045,${ldapBaseDn} +member: cn=Group 554046,${ldapBaseDn} +member: cn=Group 554047,${ldapBaseDn} +member: cn=Group 554048,${ldapBaseDn} +member: cn=Group 554049,${ldapBaseDn} +member: cn=Group 554050,${ldapBaseDn} +member: cn=Group 554051,${ldapBaseDn} +member: cn=Group 554052,${ldapBaseDn} +member: cn=Group 554053,${ldapBaseDn} +member: cn=Group 554054,${ldapBaseDn} +member: cn=Group 554055,${ldapBaseDn} +member: cn=Group 554056,${ldapBaseDn} +member: cn=Group 554057,${ldapBaseDn} +member: cn=Group 554058,${ldapBaseDn} +member: cn=Group 554059,${ldapBaseDn} +member: cn=Group 554060,${ldapBaseDn} +member: cn=Group 554061,${ldapBaseDn} +member: cn=Group 554062,${ldapBaseDn} +member: cn=Group 554063,${ldapBaseDn} +member: cn=Group 554064,${ldapBaseDn} +member: cn=Group 554065,${ldapBaseDn} +member: cn=Group 554066,${ldapBaseDn} +member: cn=Group 554067,${ldapBaseDn} +member: cn=Group 554068,${ldapBaseDn} +member: cn=Group 554069,${ldapBaseDn} +member: cn=Group 554070,${ldapBaseDn} +member: cn=Group 554071,${ldapBaseDn} +member: cn=Group 554072,${ldapBaseDn} +member: cn=Group 554073,${ldapBaseDn} +member: cn=Group 554074,${ldapBaseDn} +member: cn=Group 554075,${ldapBaseDn} +member: cn=Group 554076,${ldapBaseDn} +member: cn=Group 554077,${ldapBaseDn} +member: cn=Group 554078,${ldapBaseDn} +member: cn=Group 554079,${ldapBaseDn} +member: cn=Group 554080,${ldapBaseDn} +member: cn=Group 554081,${ldapBaseDn} +member: cn=Group 554082,${ldapBaseDn} +member: cn=Group 554083,${ldapBaseDn} +member: cn=Group 554084,${ldapBaseDn} +member: cn=Group 554085,${ldapBaseDn} +member: cn=Group 554086,${ldapBaseDn} +member: cn=Group 554087,${ldapBaseDn} +member: cn=Group 554088,${ldapBaseDn} +member: cn=Group 554089,${ldapBaseDn} +member: cn=Group 554090,${ldapBaseDn} +member: cn=Group 554091,${ldapBaseDn} +member: cn=Group 554092,${ldapBaseDn} +member: cn=Group 554093,${ldapBaseDn} +member: cn=Group 554094,${ldapBaseDn} +member: cn=Group 554095,${ldapBaseDn} +member: cn=Group 554096,${ldapBaseDn} +member: cn=Group 554097,${ldapBaseDn} +member: cn=Group 554098,${ldapBaseDn} +member: cn=Group 554099,${ldapBaseDn} +member: cn=Group 554100,${ldapBaseDn} +member: cn=Group 554101,${ldapBaseDn} +member: cn=Group 554102,${ldapBaseDn} +member: cn=Group 554103,${ldapBaseDn} +member: cn=Group 554104,${ldapBaseDn} +member: cn=Group 554105,${ldapBaseDn} +member: cn=Group 554106,${ldapBaseDn} +member: cn=Group 554107,${ldapBaseDn} +member: cn=Group 554108,${ldapBaseDn} +member: cn=Group 554109,${ldapBaseDn} +member: cn=Group 554110,${ldapBaseDn} +member: cn=Group 554111,${ldapBaseDn} +member: cn=Group 554112,${ldapBaseDn} +member: cn=Group 554113,${ldapBaseDn} +member: cn=Group 554114,${ldapBaseDn} +member: cn=Group 554115,${ldapBaseDn} +member: cn=Group 554116,${ldapBaseDn} +member: cn=Group 554117,${ldapBaseDn} +member: cn=Group 554118,${ldapBaseDn} +member: cn=Group 554119,${ldapBaseDn} +member: cn=Group 554120,${ldapBaseDn} +member: cn=Group 554121,${ldapBaseDn} +member: cn=Group 554122,${ldapBaseDn} +member: cn=Group 554123,${ldapBaseDn} +member: cn=Group 554124,${ldapBaseDn} +member: cn=Group 554125,${ldapBaseDn} +member: cn=Group 554126,${ldapBaseDn} +member: cn=Group 554127,${ldapBaseDn} +member: cn=Group 554128,${ldapBaseDn} +member: cn=Group 554129,${ldapBaseDn} +member: cn=Group 554130,${ldapBaseDn} +member: cn=Group 554131,${ldapBaseDn} +member: cn=Group 554132,${ldapBaseDn} +member: cn=Group 554133,${ldapBaseDn} +member: cn=Group 554134,${ldapBaseDn} +member: cn=Group 554135,${ldapBaseDn} +member: cn=Group 554136,${ldapBaseDn} +member: cn=Group 554137,${ldapBaseDn} +member: cn=Group 554138,${ldapBaseDn} +member: cn=Group 554139,${ldapBaseDn} +member: cn=Group 554140,${ldapBaseDn} +member: cn=Group 554141,${ldapBaseDn} +member: cn=Group 554142,${ldapBaseDn} +member: cn=Group 554143,${ldapBaseDn} +member: cn=Group 554144,${ldapBaseDn} +member: cn=Group 554145,${ldapBaseDn} +member: cn=Group 554146,${ldapBaseDn} +member: cn=Group 554147,${ldapBaseDn} +member: cn=Group 554148,${ldapBaseDn} +member: cn=Group 554149,${ldapBaseDn} +member: cn=Group 554150,${ldapBaseDn} +member: cn=Group 554151,${ldapBaseDn} +member: cn=Group 554152,${ldapBaseDn} +member: cn=Group 554153,${ldapBaseDn} +member: cn=Group 554154,${ldapBaseDn} +member: cn=Group 554155,${ldapBaseDn} +member: cn=Group 554156,${ldapBaseDn} +member: cn=Group 554157,${ldapBaseDn} +member: cn=Group 554158,${ldapBaseDn} +member: cn=Group 554159,${ldapBaseDn} +member: cn=Group 554160,${ldapBaseDn} +member: cn=Group 554161,${ldapBaseDn} +member: cn=Group 554162,${ldapBaseDn} +member: cn=Group 554163,${ldapBaseDn} +member: cn=Group 554164,${ldapBaseDn} +member: cn=Group 554165,${ldapBaseDn} +member: cn=Group 554166,${ldapBaseDn} +member: cn=Group 554167,${ldapBaseDn} +member: cn=Group 554168,${ldapBaseDn} +member: cn=Group 554169,${ldapBaseDn} +member: cn=Group 554170,${ldapBaseDn} +member: cn=Group 554171,${ldapBaseDn} +member: cn=Group 554172,${ldapBaseDn} +member: cn=Group 554173,${ldapBaseDn} +member: cn=Group 554174,${ldapBaseDn} +member: cn=Group 554175,${ldapBaseDn} +member: cn=Group 554176,${ldapBaseDn} +member: cn=Group 554177,${ldapBaseDn} +member: cn=Group 554178,${ldapBaseDn} +member: cn=Group 554179,${ldapBaseDn} +member: cn=Group 554180,${ldapBaseDn} +member: cn=Group 554181,${ldapBaseDn} +member: cn=Group 554182,${ldapBaseDn} +member: cn=Group 554183,${ldapBaseDn} +member: cn=Group 554184,${ldapBaseDn} +member: cn=Group 554185,${ldapBaseDn} +member: cn=Group 554186,${ldapBaseDn} +member: cn=Group 554187,${ldapBaseDn} +member: cn=Group 554188,${ldapBaseDn} +member: cn=Group 554189,${ldapBaseDn} +member: cn=Group 554190,${ldapBaseDn} +member: cn=Group 554191,${ldapBaseDn} +member: cn=Group 554192,${ldapBaseDn} +member: cn=Group 554193,${ldapBaseDn} +member: cn=Group 554194,${ldapBaseDn} +member: cn=Group 554195,${ldapBaseDn} +member: cn=Group 554196,${ldapBaseDn} +member: cn=Group 554197,${ldapBaseDn} +member: cn=Group 554198,${ldapBaseDn} +member: cn=Group 554199,${ldapBaseDn} +member: cn=Group 554200,${ldapBaseDn} +member: cn=Group 554201,${ldapBaseDn} +member: cn=Group 554202,${ldapBaseDn} +member: cn=Group 554203,${ldapBaseDn} +member: cn=Group 554204,${ldapBaseDn} +member: cn=Group 554205,${ldapBaseDn} +member: cn=Group 554206,${ldapBaseDn} +member: cn=Group 554207,${ldapBaseDn} +member: cn=Group 554208,${ldapBaseDn} +member: cn=Group 554209,${ldapBaseDn} +member: cn=Group 554210,${ldapBaseDn} +member: cn=Group 554211,${ldapBaseDn} +member: cn=Group 554212,${ldapBaseDn} +member: cn=Group 554213,${ldapBaseDn} +member: cn=Group 554214,${ldapBaseDn} +member: cn=Group 554215,${ldapBaseDn} +member: cn=Group 554216,${ldapBaseDn} +member: cn=Group 554217,${ldapBaseDn} +member: cn=Group 554218,${ldapBaseDn} +member: cn=Group 554219,${ldapBaseDn} +member: cn=Group 554220,${ldapBaseDn} +member: cn=Group 554221,${ldapBaseDn} +member: cn=Group 554222,${ldapBaseDn} +member: cn=Group 554223,${ldapBaseDn} +member: cn=Group 554224,${ldapBaseDn} +member: cn=Group 554225,${ldapBaseDn} +member: cn=Group 554226,${ldapBaseDn} +member: cn=Group 554227,${ldapBaseDn} +member: cn=Group 554228,${ldapBaseDn} +member: cn=Group 554229,${ldapBaseDn} +member: cn=Group 554230,${ldapBaseDn} +member: cn=Group 554231,${ldapBaseDn} +member: cn=Group 554232,${ldapBaseDn} +member: cn=Group 554233,${ldapBaseDn} +member: cn=Group 554234,${ldapBaseDn} +member: cn=Group 554235,${ldapBaseDn} +member: cn=Group 554236,${ldapBaseDn} +member: cn=Group 554237,${ldapBaseDn} +member: cn=Group 554238,${ldapBaseDn} +member: cn=Group 554239,${ldapBaseDn} +member: cn=Group 554240,${ldapBaseDn} +member: cn=Group 554241,${ldapBaseDn} +member: cn=Group 554242,${ldapBaseDn} +member: cn=Group 554243,${ldapBaseDn} +member: cn=Group 554244,${ldapBaseDn} +member: cn=Group 554245,${ldapBaseDn} +member: cn=Group 554246,${ldapBaseDn} +member: cn=Group 554247,${ldapBaseDn} +member: cn=Group 554248,${ldapBaseDn} +member: cn=Group 554249,${ldapBaseDn} +member: cn=Group 554250,${ldapBaseDn} +member: cn=Group 554251,${ldapBaseDn} +member: cn=Group 554252,${ldapBaseDn} +member: cn=Group 554253,${ldapBaseDn} +member: cn=Group 554254,${ldapBaseDn} +member: cn=Group 554255,${ldapBaseDn} +member: cn=Group 554256,${ldapBaseDn} +member: cn=Group 554257,${ldapBaseDn} +member: cn=Group 554258,${ldapBaseDn} +member: cn=Group 554259,${ldapBaseDn} +member: cn=Group 554260,${ldapBaseDn} +member: cn=Group 554261,${ldapBaseDn} +member: cn=Group 554262,${ldapBaseDn} +member: cn=Group 554263,${ldapBaseDn} +member: cn=Group 554264,${ldapBaseDn} +member: cn=Group 554265,${ldapBaseDn} +member: cn=Group 554266,${ldapBaseDn} +member: cn=Group 554267,${ldapBaseDn} +member: cn=Group 554268,${ldapBaseDn} +member: cn=Group 554269,${ldapBaseDn} +member: cn=Group 554270,${ldapBaseDn} +member: cn=Group 554271,${ldapBaseDn} +member: cn=Group 554272,${ldapBaseDn} +member: cn=Group 554273,${ldapBaseDn} +member: cn=Group 554274,${ldapBaseDn} +member: cn=Group 554275,${ldapBaseDn} +member: cn=Group 554276,${ldapBaseDn} +member: cn=Group 554277,${ldapBaseDn} +member: cn=Group 554278,${ldapBaseDn} +member: cn=Group 554279,${ldapBaseDn} +member: cn=Group 554280,${ldapBaseDn} +member: cn=Group 554281,${ldapBaseDn} +member: cn=Group 554282,${ldapBaseDn} +member: cn=Group 554283,${ldapBaseDn} +member: cn=Group 554284,${ldapBaseDn} +member: cn=Group 554285,${ldapBaseDn} +member: cn=Group 554286,${ldapBaseDn} +member: cn=Group 554287,${ldapBaseDn} +member: cn=Group 554288,${ldapBaseDn} +member: cn=Group 554289,${ldapBaseDn} +member: cn=Group 554290,${ldapBaseDn} +member: cn=Group 554291,${ldapBaseDn} +member: cn=Group 554292,${ldapBaseDn} +member: cn=Group 554293,${ldapBaseDn} +member: cn=Group 554294,${ldapBaseDn} +member: cn=Group 554295,${ldapBaseDn} +member: cn=Group 554296,${ldapBaseDn} +member: cn=Group 554297,${ldapBaseDn} +member: cn=Group 554298,${ldapBaseDn} +member: cn=Group 554299,${ldapBaseDn} +member: cn=Group 554300,${ldapBaseDn} +member: cn=Group 554301,${ldapBaseDn} +member: cn=Group 554302,${ldapBaseDn} +member: cn=Group 554303,${ldapBaseDn} +member: cn=Group 554304,${ldapBaseDn} +member: cn=Group 554305,${ldapBaseDn} +member: cn=Group 554306,${ldapBaseDn} +member: cn=Group 554307,${ldapBaseDn} +member: cn=Group 554308,${ldapBaseDn} +member: cn=Group 554309,${ldapBaseDn} +member: cn=Group 554310,${ldapBaseDn} +member: cn=Group 554311,${ldapBaseDn} +member: cn=Group 554312,${ldapBaseDn} +member: cn=Group 554313,${ldapBaseDn} +member: cn=Group 554314,${ldapBaseDn} +member: cn=Group 554315,${ldapBaseDn} +member: cn=Group 554316,${ldapBaseDn} +member: cn=Group 554317,${ldapBaseDn} +member: cn=Group 554318,${ldapBaseDn} +member: cn=Group 554319,${ldapBaseDn} +member: cn=Group 554320,${ldapBaseDn} +member: cn=Group 554321,${ldapBaseDn} +member: cn=Group 554322,${ldapBaseDn} +member: cn=Group 554323,${ldapBaseDn} +member: cn=Group 554324,${ldapBaseDn} +member: cn=Group 554325,${ldapBaseDn} +member: cn=Group 554326,${ldapBaseDn} +member: cn=Group 554327,${ldapBaseDn} +member: cn=Group 554328,${ldapBaseDn} +member: cn=Group 554329,${ldapBaseDn} +member: cn=Group 554330,${ldapBaseDn} +member: cn=Group 554331,${ldapBaseDn} +member: cn=Group 554332,${ldapBaseDn} +member: cn=Group 554333,${ldapBaseDn} +member: cn=Group 554334,${ldapBaseDn} +member: cn=Group 554335,${ldapBaseDn} +member: cn=Group 554336,${ldapBaseDn} +member: cn=Group 554337,${ldapBaseDn} +member: cn=Group 554338,${ldapBaseDn} +member: cn=Group 554339,${ldapBaseDn} +member: cn=Group 554340,${ldapBaseDn} +member: cn=Group 554341,${ldapBaseDn} +member: cn=Group 554342,${ldapBaseDn} +member: cn=Group 554343,${ldapBaseDn} +member: cn=Group 554344,${ldapBaseDn} +member: cn=Group 554345,${ldapBaseDn} +member: cn=Group 554346,${ldapBaseDn} +member: cn=Group 554347,${ldapBaseDn} +member: cn=Group 554348,${ldapBaseDn} +member: cn=Group 554349,${ldapBaseDn} +member: cn=Group 554350,${ldapBaseDn} +member: cn=Group 554351,${ldapBaseDn} +member: cn=Group 554352,${ldapBaseDn} +member: cn=Group 554353,${ldapBaseDn} +member: cn=Group 554354,${ldapBaseDn} +member: cn=Group 554355,${ldapBaseDn} +member: cn=Group 554356,${ldapBaseDn} +member: cn=Group 554357,${ldapBaseDn} +member: cn=Group 554358,${ldapBaseDn} +member: cn=Group 554359,${ldapBaseDn} +member: cn=Group 554360,${ldapBaseDn} +member: cn=Group 554361,${ldapBaseDn} +member: cn=Group 554362,${ldapBaseDn} +member: cn=Group 554363,${ldapBaseDn} +member: cn=Group 554364,${ldapBaseDn} +member: cn=Group 554365,${ldapBaseDn} +member: cn=Group 554366,${ldapBaseDn} +member: cn=Group 554367,${ldapBaseDn} +member: cn=Group 554368,${ldapBaseDn} +member: cn=Group 554369,${ldapBaseDn} +member: cn=Group 554370,${ldapBaseDn} +member: cn=Group 554371,${ldapBaseDn} +member: cn=Group 554372,${ldapBaseDn} +member: cn=Group 554373,${ldapBaseDn} +member: cn=Group 554374,${ldapBaseDn} +member: cn=Group 554375,${ldapBaseDn} +member: cn=Group 554376,${ldapBaseDn} +member: cn=Group 554377,${ldapBaseDn} +member: cn=Group 554378,${ldapBaseDn} +member: cn=Group 554379,${ldapBaseDn} +member: cn=Group 554380,${ldapBaseDn} +member: cn=Group 554381,${ldapBaseDn} +member: cn=Group 554382,${ldapBaseDn} +member: cn=Group 554383,${ldapBaseDn} +member: cn=Group 554384,${ldapBaseDn} +member: cn=Group 554385,${ldapBaseDn} +member: cn=Group 554386,${ldapBaseDn} +member: cn=Group 554387,${ldapBaseDn} +member: cn=Group 554388,${ldapBaseDn} +member: cn=Group 554389,${ldapBaseDn} +member: cn=Group 554390,${ldapBaseDn} +member: cn=Group 554391,${ldapBaseDn} +member: cn=Group 554392,${ldapBaseDn} +member: cn=Group 554393,${ldapBaseDn} +member: cn=Group 554394,${ldapBaseDn} +member: cn=Group 554395,${ldapBaseDn} +member: cn=Group 554396,${ldapBaseDn} +member: cn=Group 554397,${ldapBaseDn} +member: cn=Group 554398,${ldapBaseDn} +member: cn=Group 554399,${ldapBaseDn} +member: cn=Group 554400,${ldapBaseDn} +member: cn=Group 554401,${ldapBaseDn} +member: cn=Group 554402,${ldapBaseDn} +member: cn=Group 554403,${ldapBaseDn} +member: cn=Group 554404,${ldapBaseDn} +member: cn=Group 554405,${ldapBaseDn} +member: cn=Group 554406,${ldapBaseDn} +member: cn=Group 554407,${ldapBaseDn} +member: cn=Group 554408,${ldapBaseDn} +member: cn=Group 554409,${ldapBaseDn} +member: cn=Group 554410,${ldapBaseDn} +member: cn=Group 554411,${ldapBaseDn} +member: cn=Group 554412,${ldapBaseDn} +member: cn=Group 554413,${ldapBaseDn} +member: cn=Group 554414,${ldapBaseDn} +member: cn=Group 554415,${ldapBaseDn} +member: cn=Group 554416,${ldapBaseDn} +member: cn=Group 554417,${ldapBaseDn} +member: cn=Group 554418,${ldapBaseDn} +member: cn=Group 554419,${ldapBaseDn} +member: cn=Group 554420,${ldapBaseDn} +member: cn=Group 554421,${ldapBaseDn} +member: cn=Group 554422,${ldapBaseDn} +member: cn=Group 554423,${ldapBaseDn} +member: cn=Group 554424,${ldapBaseDn} +member: cn=Group 554425,${ldapBaseDn} +member: cn=Group 554426,${ldapBaseDn} +member: cn=Group 554427,${ldapBaseDn} +member: cn=Group 554428,${ldapBaseDn} +member: cn=Group 554429,${ldapBaseDn} +member: cn=Group 554430,${ldapBaseDn} +member: cn=Group 554431,${ldapBaseDn} +member: cn=Group 554432,${ldapBaseDn} +member: cn=Group 554433,${ldapBaseDn} +member: cn=Group 554434,${ldapBaseDn} +member: cn=Group 554435,${ldapBaseDn} +member: cn=Group 554436,${ldapBaseDn} +member: cn=Group 554437,${ldapBaseDn} +member: cn=Group 554438,${ldapBaseDn} +member: cn=Group 554439,${ldapBaseDn} +member: cn=Group 554440,${ldapBaseDn} +member: cn=Group 554441,${ldapBaseDn} +member: cn=Group 554442,${ldapBaseDn} +member: cn=Group 554443,${ldapBaseDn} +member: cn=Group 554444,${ldapBaseDn} +member: cn=Group 554445,${ldapBaseDn} +member: cn=Group 554446,${ldapBaseDn} +member: cn=Group 554447,${ldapBaseDn} +member: cn=Group 554448,${ldapBaseDn} +member: cn=Group 554449,${ldapBaseDn} +member: cn=Group 554450,${ldapBaseDn} +member: cn=Group 554451,${ldapBaseDn} +member: cn=Group 554452,${ldapBaseDn} +member: cn=Group 554453,${ldapBaseDn} +member: cn=Group 554454,${ldapBaseDn} +member: cn=Group 554455,${ldapBaseDn} +member: cn=Group 554456,${ldapBaseDn} +member: cn=Group 554457,${ldapBaseDn} +member: cn=Group 554458,${ldapBaseDn} +member: cn=Group 554459,${ldapBaseDn} +member: cn=Group 554460,${ldapBaseDn} +member: cn=Group 554461,${ldapBaseDn} +member: cn=Group 554462,${ldapBaseDn} +member: cn=Group 554463,${ldapBaseDn} +member: cn=Group 554464,${ldapBaseDn} +member: cn=Group 554465,${ldapBaseDn} +member: cn=Group 554466,${ldapBaseDn} +member: cn=Group 554467,${ldapBaseDn} +member: cn=Group 554468,${ldapBaseDn} +member: cn=Group 554469,${ldapBaseDn} +member: cn=Group 554470,${ldapBaseDn} +member: cn=Group 554471,${ldapBaseDn} +member: cn=Group 554472,${ldapBaseDn} +member: cn=Group 554473,${ldapBaseDn} +member: cn=Group 554474,${ldapBaseDn} +member: cn=Group 554475,${ldapBaseDn} +member: cn=Group 554476,${ldapBaseDn} +member: cn=Group 554477,${ldapBaseDn} +member: cn=Group 554478,${ldapBaseDn} +member: cn=Group 554479,${ldapBaseDn} +member: cn=Group 554480,${ldapBaseDn} +member: cn=Group 554481,${ldapBaseDn} +member: cn=Group 554482,${ldapBaseDn} +member: cn=Group 554483,${ldapBaseDn} +member: cn=Group 554484,${ldapBaseDn} +member: cn=Group 554485,${ldapBaseDn} +member: cn=Group 554486,${ldapBaseDn} +member: cn=Group 554487,${ldapBaseDn} +member: cn=Group 554488,${ldapBaseDn} +member: cn=Group 554489,${ldapBaseDn} +member: cn=Group 554490,${ldapBaseDn} +member: cn=Group 554491,${ldapBaseDn} +member: cn=Group 554492,${ldapBaseDn} +member: cn=Group 554493,${ldapBaseDn} +member: cn=Group 554494,${ldapBaseDn} +member: cn=Group 554495,${ldapBaseDn} +member: cn=Group 554496,${ldapBaseDn} +member: cn=Group 554497,${ldapBaseDn} +member: cn=Group 554498,${ldapBaseDn} +member: cn=Group 554499,${ldapBaseDn} +member: cn=Group 554500,${ldapBaseDn} +member: cn=Group 554501,${ldapBaseDn} +member: cn=Group 554502,${ldapBaseDn} +member: cn=Group 554503,${ldapBaseDn} +member: cn=Group 554504,${ldapBaseDn} +member: cn=Group 554505,${ldapBaseDn} +member: cn=Group 554506,${ldapBaseDn} +member: cn=Group 554507,${ldapBaseDn} +member: cn=Group 554508,${ldapBaseDn} +member: cn=Group 554509,${ldapBaseDn} +member: cn=Group 554510,${ldapBaseDn} +member: cn=Group 554511,${ldapBaseDn} +member: cn=Group 554512,${ldapBaseDn} +member: cn=Group 554513,${ldapBaseDn} +member: cn=Group 554514,${ldapBaseDn} +member: cn=Group 554515,${ldapBaseDn} +member: cn=Group 554516,${ldapBaseDn} +member: cn=Group 554517,${ldapBaseDn} +member: cn=Group 554518,${ldapBaseDn} +member: cn=Group 554519,${ldapBaseDn} +member: cn=Group 554520,${ldapBaseDn} +member: cn=Group 554521,${ldapBaseDn} +member: cn=Group 554522,${ldapBaseDn} +member: cn=Group 554523,${ldapBaseDn} +member: cn=Group 554524,${ldapBaseDn} +member: cn=Group 554525,${ldapBaseDn} +member: cn=Group 554526,${ldapBaseDn} +member: cn=Group 554527,${ldapBaseDn} +member: cn=Group 554528,${ldapBaseDn} +member: cn=Group 554529,${ldapBaseDn} +member: cn=Group 554530,${ldapBaseDn} +member: cn=Group 554531,${ldapBaseDn} +member: cn=Group 554532,${ldapBaseDn} +member: cn=Group 554533,${ldapBaseDn} +member: cn=Group 554534,${ldapBaseDn} +member: cn=Group 554535,${ldapBaseDn} +member: cn=Group 554536,${ldapBaseDn} +member: cn=Group 554537,${ldapBaseDn} +member: cn=Group 554538,${ldapBaseDn} +member: cn=Group 554539,${ldapBaseDn} +member: cn=Group 554540,${ldapBaseDn} +member: cn=Group 554541,${ldapBaseDn} +member: cn=Group 554542,${ldapBaseDn} +member: cn=Group 554543,${ldapBaseDn} +member: cn=Group 554544,${ldapBaseDn} +member: cn=Group 554545,${ldapBaseDn} +member: cn=Group 554546,${ldapBaseDn} +member: cn=Group 554547,${ldapBaseDn} +member: cn=Group 554548,${ldapBaseDn} +member: cn=Group 554549,${ldapBaseDn} +member: cn=Group 554550,${ldapBaseDn} +member: cn=Group 554551,${ldapBaseDn} +member: cn=Group 554552,${ldapBaseDn} +member: cn=Group 554553,${ldapBaseDn} +member: cn=Group 554554,${ldapBaseDn} +member: cn=Group 554555,${ldapBaseDn} +member: cn=Group 554556,${ldapBaseDn} +member: cn=Group 554557,${ldapBaseDn} +member: cn=Group 554558,${ldapBaseDn} +member: cn=Group 554559,${ldapBaseDn} +member: cn=Group 554560,${ldapBaseDn} +member: cn=Group 554561,${ldapBaseDn} +member: cn=Group 554562,${ldapBaseDn} +member: cn=Group 554563,${ldapBaseDn} +member: cn=Group 554564,${ldapBaseDn} +member: cn=Group 554565,${ldapBaseDn} +member: cn=Group 554566,${ldapBaseDn} +member: cn=Group 554567,${ldapBaseDn} +member: cn=Group 554568,${ldapBaseDn} +member: cn=Group 554569,${ldapBaseDn} +member: cn=Group 554570,${ldapBaseDn} +member: cn=Group 554571,${ldapBaseDn} +member: cn=Group 554572,${ldapBaseDn} +member: cn=Group 554573,${ldapBaseDn} +member: cn=Group 554574,${ldapBaseDn} +member: cn=Group 554575,${ldapBaseDn} +member: cn=Group 554576,${ldapBaseDn} +member: cn=Group 554577,${ldapBaseDn} +member: cn=Group 554578,${ldapBaseDn} +member: cn=Group 554579,${ldapBaseDn} +member: cn=Group 554580,${ldapBaseDn} +member: cn=Group 554581,${ldapBaseDn} +member: cn=Group 554582,${ldapBaseDn} +member: cn=Group 554583,${ldapBaseDn} +member: cn=Group 554584,${ldapBaseDn} +member: cn=Group 554585,${ldapBaseDn} +member: cn=Group 554586,${ldapBaseDn} +member: cn=Group 554587,${ldapBaseDn} +member: cn=Group 554588,${ldapBaseDn} +member: cn=Group 554589,${ldapBaseDn} +member: cn=Group 554590,${ldapBaseDn} +member: cn=Group 554591,${ldapBaseDn} +member: cn=Group 554592,${ldapBaseDn} +member: cn=Group 554593,${ldapBaseDn} +member: cn=Group 554594,${ldapBaseDn} +member: cn=Group 554595,${ldapBaseDn} +member: cn=Group 554596,${ldapBaseDn} +member: cn=Group 554597,${ldapBaseDn} +member: cn=Group 554598,${ldapBaseDn} +member: cn=Group 554599,${ldapBaseDn} +member: cn=Group 554600,${ldapBaseDn} +member: cn=Group 554601,${ldapBaseDn} +member: cn=Group 554602,${ldapBaseDn} +member: cn=Group 554603,${ldapBaseDn} +member: cn=Group 554604,${ldapBaseDn} +member: cn=Group 554605,${ldapBaseDn} +member: cn=Group 554606,${ldapBaseDn} +member: cn=Group 554607,${ldapBaseDn} +member: cn=Group 554608,${ldapBaseDn} +member: cn=Group 554609,${ldapBaseDn} +member: cn=Group 554610,${ldapBaseDn} +member: cn=Group 554611,${ldapBaseDn} +member: cn=Group 554612,${ldapBaseDn} +member: cn=Group 554613,${ldapBaseDn} +member: cn=Group 554614,${ldapBaseDn} +member: cn=Group 554615,${ldapBaseDn} +member: cn=Group 554616,${ldapBaseDn} +member: cn=Group 554617,${ldapBaseDn} +member: cn=Group 554618,${ldapBaseDn} +member: cn=Group 554619,${ldapBaseDn} +member: cn=Group 554620,${ldapBaseDn} +member: cn=Group 554621,${ldapBaseDn} +member: cn=Group 554622,${ldapBaseDn} +member: cn=Group 554623,${ldapBaseDn} +member: cn=Group 554624,${ldapBaseDn} +member: cn=Group 554625,${ldapBaseDn} +member: cn=Group 554626,${ldapBaseDn} +member: cn=Group 554627,${ldapBaseDn} +member: cn=Group 554628,${ldapBaseDn} +member: cn=Group 554629,${ldapBaseDn} +member: cn=Group 554630,${ldapBaseDn} +member: cn=Group 554631,${ldapBaseDn} +member: cn=Group 554632,${ldapBaseDn} +member: cn=Group 554633,${ldapBaseDn} +member: cn=Group 554634,${ldapBaseDn} +member: cn=Group 554635,${ldapBaseDn} +member: cn=Group 554636,${ldapBaseDn} +member: cn=Group 554637,${ldapBaseDn} +member: cn=Group 554638,${ldapBaseDn} +member: cn=Group 554639,${ldapBaseDn} +member: cn=Group 554640,${ldapBaseDn} +member: cn=Group 554641,${ldapBaseDn} +member: cn=Group 554642,${ldapBaseDn} +member: cn=Group 554643,${ldapBaseDn} +member: cn=Group 554644,${ldapBaseDn} +member: cn=Group 554645,${ldapBaseDn} +member: cn=Group 554646,${ldapBaseDn} +member: cn=Group 554647,${ldapBaseDn} +member: cn=Group 554648,${ldapBaseDn} +member: cn=Group 554649,${ldapBaseDn} +member: cn=Group 554650,${ldapBaseDn} +member: cn=Group 554651,${ldapBaseDn} +member: cn=Group 554652,${ldapBaseDn} +member: cn=Group 554653,${ldapBaseDn} +member: cn=Group 554654,${ldapBaseDn} +member: cn=Group 554655,${ldapBaseDn} +member: cn=Group 554656,${ldapBaseDn} +member: cn=Group 554657,${ldapBaseDn} +member: cn=Group 554658,${ldapBaseDn} +member: cn=Group 554659,${ldapBaseDn} +member: cn=Group 554660,${ldapBaseDn} +member: cn=Group 554661,${ldapBaseDn} +member: cn=Group 554662,${ldapBaseDn} +member: cn=Group 554663,${ldapBaseDn} +member: cn=Group 554664,${ldapBaseDn} +member: cn=Group 554665,${ldapBaseDn} +member: cn=Group 554666,${ldapBaseDn} +member: cn=Group 554667,${ldapBaseDn} +member: cn=Group 554668,${ldapBaseDn} +member: cn=Group 554669,${ldapBaseDn} +member: cn=Group 554670,${ldapBaseDn} +member: cn=Group 554671,${ldapBaseDn} +member: cn=Group 554672,${ldapBaseDn} +member: cn=Group 554673,${ldapBaseDn} +member: cn=Group 554674,${ldapBaseDn} +member: cn=Group 554675,${ldapBaseDn} +member: cn=Group 554676,${ldapBaseDn} +member: cn=Group 554677,${ldapBaseDn} +member: cn=Group 554678,${ldapBaseDn} +member: cn=Group 554679,${ldapBaseDn} +member: cn=Group 554680,${ldapBaseDn} +member: cn=Group 554681,${ldapBaseDn} +member: cn=Group 554682,${ldapBaseDn} +member: cn=Group 554683,${ldapBaseDn} +member: cn=Group 554684,${ldapBaseDn} +member: cn=Group 554685,${ldapBaseDn} +member: cn=Group 554686,${ldapBaseDn} +member: cn=Group 554687,${ldapBaseDn} +member: cn=Group 554688,${ldapBaseDn} +member: cn=Group 554689,${ldapBaseDn} +member: cn=Group 554690,${ldapBaseDn} +member: cn=Group 554691,${ldapBaseDn} +member: cn=Group 554692,${ldapBaseDn} +member: cn=Group 554693,${ldapBaseDn} +member: cn=Group 554694,${ldapBaseDn} +member: cn=Group 554695,${ldapBaseDn} +member: cn=Group 554696,${ldapBaseDn} +member: cn=Group 554697,${ldapBaseDn} +member: cn=Group 554698,${ldapBaseDn} +member: cn=Group 554699,${ldapBaseDn} +member: cn=Group 554700,${ldapBaseDn} +member: cn=Group 554701,${ldapBaseDn} +member: cn=Group 554702,${ldapBaseDn} +member: cn=Group 554703,${ldapBaseDn} +member: cn=Group 554704,${ldapBaseDn} +member: cn=Group 554705,${ldapBaseDn} +member: cn=Group 554706,${ldapBaseDn} +member: cn=Group 554707,${ldapBaseDn} +member: cn=Group 554708,${ldapBaseDn} +member: cn=Group 554709,${ldapBaseDn} +member: cn=Group 554710,${ldapBaseDn} +member: cn=Group 554711,${ldapBaseDn} +member: cn=Group 554712,${ldapBaseDn} +member: cn=Group 554713,${ldapBaseDn} +member: cn=Group 554714,${ldapBaseDn} +member: cn=Group 554715,${ldapBaseDn} +member: cn=Group 554716,${ldapBaseDn} +member: cn=Group 554717,${ldapBaseDn} +member: cn=Group 554718,${ldapBaseDn} +member: cn=Group 554719,${ldapBaseDn} +member: cn=Group 554720,${ldapBaseDn} +member: cn=Group 554721,${ldapBaseDn} +member: cn=Group 554722,${ldapBaseDn} +member: cn=Group 554723,${ldapBaseDn} +member: cn=Group 554724,${ldapBaseDn} +member: cn=Group 554725,${ldapBaseDn} +member: cn=Group 554726,${ldapBaseDn} +member: cn=Group 554727,${ldapBaseDn} +member: cn=Group 554728,${ldapBaseDn} +member: cn=Group 554729,${ldapBaseDn} +member: cn=Group 554730,${ldapBaseDn} +member: cn=Group 554731,${ldapBaseDn} +member: cn=Group 554732,${ldapBaseDn} +member: cn=Group 554733,${ldapBaseDn} +member: cn=Group 554734,${ldapBaseDn} +member: cn=Group 554735,${ldapBaseDn} +member: cn=Group 554736,${ldapBaseDn} +member: cn=Group 554737,${ldapBaseDn} +member: cn=Group 554738,${ldapBaseDn} +member: cn=Group 554739,${ldapBaseDn} +member: cn=Group 554740,${ldapBaseDn} +member: cn=Group 554741,${ldapBaseDn} +member: cn=Group 554742,${ldapBaseDn} +member: cn=Group 554743,${ldapBaseDn} +member: cn=Group 554744,${ldapBaseDn} +member: cn=Group 554745,${ldapBaseDn} +member: cn=Group 554746,${ldapBaseDn} +member: cn=Group 554747,${ldapBaseDn} +member: cn=Group 554748,${ldapBaseDn} +member: cn=Group 554749,${ldapBaseDn} +member: cn=Group 554750,${ldapBaseDn} +member: cn=Group 554751,${ldapBaseDn} +member: cn=Group 554752,${ldapBaseDn} +member: cn=Group 554753,${ldapBaseDn} +member: cn=Group 554754,${ldapBaseDn} +member: cn=Group 554755,${ldapBaseDn} +member: cn=Group 554756,${ldapBaseDn} +member: cn=Group 554757,${ldapBaseDn} +member: cn=Group 554758,${ldapBaseDn} +member: cn=Group 554759,${ldapBaseDn} +member: cn=Group 554760,${ldapBaseDn} +member: cn=Group 554761,${ldapBaseDn} +member: cn=Group 554762,${ldapBaseDn} +member: cn=Group 554763,${ldapBaseDn} +member: cn=Group 554764,${ldapBaseDn} +member: cn=Group 554765,${ldapBaseDn} +member: cn=Group 554766,${ldapBaseDn} +member: cn=Group 554767,${ldapBaseDn} +member: cn=Group 554768,${ldapBaseDn} +member: cn=Group 554769,${ldapBaseDn} +member: cn=Group 554770,${ldapBaseDn} +member: cn=Group 554771,${ldapBaseDn} +member: cn=Group 554772,${ldapBaseDn} +member: cn=Group 554773,${ldapBaseDn} +member: cn=Group 554774,${ldapBaseDn} +member: cn=Group 554775,${ldapBaseDn} +member: cn=Group 554776,${ldapBaseDn} +member: cn=Group 554777,${ldapBaseDn} +member: cn=Group 554778,${ldapBaseDn} +member: cn=Group 554779,${ldapBaseDn} +member: cn=Group 554780,${ldapBaseDn} +member: cn=Group 554781,${ldapBaseDn} +member: cn=Group 554782,${ldapBaseDn} +member: cn=Group 554783,${ldapBaseDn} +member: cn=Group 554784,${ldapBaseDn} +member: cn=Group 554785,${ldapBaseDn} +member: cn=Group 554786,${ldapBaseDn} +member: cn=Group 554787,${ldapBaseDn} +member: cn=Group 554788,${ldapBaseDn} +member: cn=Group 554789,${ldapBaseDn} +member: cn=Group 554790,${ldapBaseDn} +member: cn=Group 554791,${ldapBaseDn} +member: cn=Group 554792,${ldapBaseDn} +member: cn=Group 554793,${ldapBaseDn} +member: cn=Group 554794,${ldapBaseDn} +member: cn=Group 554795,${ldapBaseDn} +member: cn=Group 554796,${ldapBaseDn} +member: cn=Group 554797,${ldapBaseDn} +member: cn=Group 554798,${ldapBaseDn} +member: cn=Group 554799,${ldapBaseDn} +member: cn=Group 554800,${ldapBaseDn} +member: cn=Group 554801,${ldapBaseDn} +member: cn=Group 554802,${ldapBaseDn} +member: cn=Group 554803,${ldapBaseDn} +member: cn=Group 554804,${ldapBaseDn} +member: cn=Group 554805,${ldapBaseDn} +member: cn=Group 554806,${ldapBaseDn} +member: cn=Group 554807,${ldapBaseDn} +member: cn=Group 554808,${ldapBaseDn} +member: cn=Group 554809,${ldapBaseDn} +member: cn=Group 554810,${ldapBaseDn} +member: cn=Group 554811,${ldapBaseDn} +member: cn=Group 554812,${ldapBaseDn} +member: cn=Group 554813,${ldapBaseDn} +member: cn=Group 554814,${ldapBaseDn} +member: cn=Group 554815,${ldapBaseDn} +member: cn=Group 554816,${ldapBaseDn} +member: cn=Group 554817,${ldapBaseDn} +member: cn=Group 554818,${ldapBaseDn} +member: cn=Group 554819,${ldapBaseDn} +member: cn=Group 554820,${ldapBaseDn} +member: cn=Group 554821,${ldapBaseDn} +member: cn=Group 554822,${ldapBaseDn} +member: cn=Group 554823,${ldapBaseDn} +member: cn=Group 554824,${ldapBaseDn} +member: cn=Group 554825,${ldapBaseDn} +member: cn=Group 554826,${ldapBaseDn} +member: cn=Group 554827,${ldapBaseDn} +member: cn=Group 554828,${ldapBaseDn} +member: cn=Group 554829,${ldapBaseDn} +member: cn=Group 554830,${ldapBaseDn} +member: cn=Group 554831,${ldapBaseDn} +member: cn=Group 554832,${ldapBaseDn} +member: cn=Group 554833,${ldapBaseDn} +member: cn=Group 554834,${ldapBaseDn} +member: cn=Group 554835,${ldapBaseDn} +member: cn=Group 554836,${ldapBaseDn} +member: cn=Group 554837,${ldapBaseDn} +member: cn=Group 554838,${ldapBaseDn} +member: cn=Group 554839,${ldapBaseDn} +member: cn=Group 554840,${ldapBaseDn} +member: cn=Group 554841,${ldapBaseDn} +member: cn=Group 554842,${ldapBaseDn} +member: cn=Group 554843,${ldapBaseDn} +member: cn=Group 554844,${ldapBaseDn} +member: cn=Group 554845,${ldapBaseDn} +member: cn=Group 554846,${ldapBaseDn} +member: cn=Group 554847,${ldapBaseDn} +member: cn=Group 554848,${ldapBaseDn} +member: cn=Group 554849,${ldapBaseDn} +member: cn=Group 554850,${ldapBaseDn} +member: cn=Group 554851,${ldapBaseDn} +member: cn=Group 554852,${ldapBaseDn} +member: cn=Group 554853,${ldapBaseDn} +member: cn=Group 554854,${ldapBaseDn} +member: cn=Group 554855,${ldapBaseDn} +member: cn=Group 554856,${ldapBaseDn} +member: cn=Group 554857,${ldapBaseDn} +member: cn=Group 554858,${ldapBaseDn} +member: cn=Group 554859,${ldapBaseDn} +member: cn=Group 554860,${ldapBaseDn} +member: cn=Group 554861,${ldapBaseDn} +member: cn=Group 554862,${ldapBaseDn} +member: cn=Group 554863,${ldapBaseDn} +member: cn=Group 554864,${ldapBaseDn} +member: cn=Group 554865,${ldapBaseDn} +member: cn=Group 554866,${ldapBaseDn} +member: cn=Group 554867,${ldapBaseDn} +member: cn=Group 554868,${ldapBaseDn} +member: cn=Group 554869,${ldapBaseDn} +member: cn=Group 554870,${ldapBaseDn} +member: cn=Group 554871,${ldapBaseDn} +member: cn=Group 554872,${ldapBaseDn} +member: cn=Group 554873,${ldapBaseDn} +member: cn=Group 554874,${ldapBaseDn} +member: cn=Group 554875,${ldapBaseDn} +member: cn=Group 554876,${ldapBaseDn} +member: cn=Group 554877,${ldapBaseDn} +member: cn=Group 554878,${ldapBaseDn} +member: cn=Group 554879,${ldapBaseDn} +member: cn=Group 554880,${ldapBaseDn} +member: cn=Group 554881,${ldapBaseDn} +member: cn=Group 554882,${ldapBaseDn} +member: cn=Group 554883,${ldapBaseDn} +member: cn=Group 554884,${ldapBaseDn} +member: cn=Group 554885,${ldapBaseDn} +member: cn=Group 554886,${ldapBaseDn} +member: cn=Group 554887,${ldapBaseDn} +member: cn=Group 554888,${ldapBaseDn} +member: cn=Group 554889,${ldapBaseDn} +member: cn=Group 554890,${ldapBaseDn} +member: cn=Group 554891,${ldapBaseDn} +member: cn=Group 554892,${ldapBaseDn} +member: cn=Group 554893,${ldapBaseDn} +member: cn=Group 554894,${ldapBaseDn} +member: cn=Group 554895,${ldapBaseDn} +member: cn=Group 554896,${ldapBaseDn} +member: cn=Group 554897,${ldapBaseDn} +member: cn=Group 554898,${ldapBaseDn} +member: cn=Group 554899,${ldapBaseDn} +member: cn=Group 554900,${ldapBaseDn} +member: cn=Group 554901,${ldapBaseDn} +member: cn=Group 554902,${ldapBaseDn} +member: cn=Group 554903,${ldapBaseDn} +member: cn=Group 554904,${ldapBaseDn} +member: cn=Group 554905,${ldapBaseDn} +member: cn=Group 554906,${ldapBaseDn} +member: cn=Group 554907,${ldapBaseDn} +member: cn=Group 554908,${ldapBaseDn} +member: cn=Group 554909,${ldapBaseDn} +member: cn=Group 554910,${ldapBaseDn} +member: cn=Group 554911,${ldapBaseDn} +member: cn=Group 554912,${ldapBaseDn} +member: cn=Group 554913,${ldapBaseDn} +member: cn=Group 554914,${ldapBaseDn} +member: cn=Group 554915,${ldapBaseDn} +member: cn=Group 554916,${ldapBaseDn} +member: cn=Group 554917,${ldapBaseDn} +member: cn=Group 554918,${ldapBaseDn} +member: cn=Group 554919,${ldapBaseDn} +member: cn=Group 554920,${ldapBaseDn} +member: cn=Group 554921,${ldapBaseDn} +member: cn=Group 554922,${ldapBaseDn} +member: cn=Group 554923,${ldapBaseDn} +member: cn=Group 554924,${ldapBaseDn} +member: cn=Group 554925,${ldapBaseDn} +member: cn=Group 554926,${ldapBaseDn} +member: cn=Group 554927,${ldapBaseDn} +member: cn=Group 554928,${ldapBaseDn} +member: cn=Group 554929,${ldapBaseDn} +member: cn=Group 554930,${ldapBaseDn} +member: cn=Group 554931,${ldapBaseDn} +member: cn=Group 554932,${ldapBaseDn} +member: cn=Group 554933,${ldapBaseDn} +member: cn=Group 554934,${ldapBaseDn} +member: cn=Group 554935,${ldapBaseDn} +member: cn=Group 554936,${ldapBaseDn} +member: cn=Group 554937,${ldapBaseDn} +member: cn=Group 554938,${ldapBaseDn} +member: cn=Group 554939,${ldapBaseDn} +member: cn=Group 554940,${ldapBaseDn} +member: cn=Group 554941,${ldapBaseDn} +member: cn=Group 554942,${ldapBaseDn} +member: cn=Group 554943,${ldapBaseDn} +member: cn=Group 554944,${ldapBaseDn} +member: cn=Group 554945,${ldapBaseDn} +member: cn=Group 554946,${ldapBaseDn} +member: cn=Group 554947,${ldapBaseDn} +member: cn=Group 554948,${ldapBaseDn} +member: cn=Group 554949,${ldapBaseDn} +member: cn=Group 554950,${ldapBaseDn} +member: cn=Group 554951,${ldapBaseDn} +member: cn=Group 554952,${ldapBaseDn} +member: cn=Group 554953,${ldapBaseDn} +member: cn=Group 554954,${ldapBaseDn} +member: cn=Group 554955,${ldapBaseDn} +member: cn=Group 554956,${ldapBaseDn} +member: cn=Group 554957,${ldapBaseDn} +member: cn=Group 554958,${ldapBaseDn} +member: cn=Group 554959,${ldapBaseDn} +member: cn=Group 554960,${ldapBaseDn} +member: cn=Group 554961,${ldapBaseDn} +member: cn=Group 554962,${ldapBaseDn} +member: cn=Group 554963,${ldapBaseDn} +member: cn=Group 554964,${ldapBaseDn} +member: cn=Group 554965,${ldapBaseDn} +member: cn=Group 554966,${ldapBaseDn} +member: cn=Group 554967,${ldapBaseDn} +member: cn=Group 554968,${ldapBaseDn} +member: cn=Group 554969,${ldapBaseDn} +member: cn=Group 554970,${ldapBaseDn} +member: cn=Group 554971,${ldapBaseDn} +member: cn=Group 554972,${ldapBaseDn} +member: cn=Group 554973,${ldapBaseDn} +member: cn=Group 554974,${ldapBaseDn} +member: cn=Group 554975,${ldapBaseDn} +member: cn=Group 554976,${ldapBaseDn} +member: cn=Group 554977,${ldapBaseDn} +member: cn=Group 554978,${ldapBaseDn} +member: cn=Group 554979,${ldapBaseDn} +member: cn=Group 554980,${ldapBaseDn} +member: cn=Group 554981,${ldapBaseDn} +member: cn=Group 554982,${ldapBaseDn} +member: cn=Group 554983,${ldapBaseDn} +member: cn=Group 554984,${ldapBaseDn} +member: cn=Group 554985,${ldapBaseDn} +member: cn=Group 554986,${ldapBaseDn} +member: cn=Group 554987,${ldapBaseDn} +member: cn=Group 554988,${ldapBaseDn} +member: cn=Group 554989,${ldapBaseDn} +member: cn=Group 554990,${ldapBaseDn} +member: cn=Group 554991,${ldapBaseDn} +member: cn=Group 554992,${ldapBaseDn} +member: cn=Group 554993,${ldapBaseDn} +member: cn=Group 554994,${ldapBaseDn} +member: cn=Group 554995,${ldapBaseDn} +member: cn=Group 554996,${ldapBaseDn} +member: cn=Group 554997,${ldapBaseDn} +member: cn=Group 554998,${ldapBaseDn} +member: cn=Group 554999,${ldapBaseDn} +uid: 550000 +uugid: group550000
diff --git a/integration/src/test/resources/org/ldaptive/recursiveHandlerResults-2.ldif b/integration/src/test/resources/org/ldaptive/recursiveHandlerResults-2.ldif new file mode 100644 index 0000000..17e9165 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/recursiveHandlerResults-2.ldif
@@ -0,0 +1,19 @@ +dn: cn=Group 2,${ldapBaseDn} +member: cn=Group 2,${ldapBaseDn} +member: cn=Group 3,${ldapBaseDn} +member: cn=Group 4,${ldapBaseDn} +member: cn=Group 5,${ldapBaseDn} + +dn: cn=Group 3,${ldapBaseDn} +member: cn=Group 2,${ldapBaseDn} +member: cn=Group 3,${ldapBaseDn} +member: cn=Group 4,${ldapBaseDn} +member: cn=Group 5,${ldapBaseDn} + +dn: cn=Group 4,${ldapBaseDn} +member: cn=Group 2,${ldapBaseDn} +member: cn=Group 3,${ldapBaseDn} +member: cn=Group 4,${ldapBaseDn} +member: cn=Group 5,${ldapBaseDn} + +dn: cn=Group 5,${ldapBaseDn}
diff --git a/integration/src/test/resources/org/ldaptive/recursiveHandlerResults.ldif b/integration/src/test/resources/org/ldaptive/recursiveHandlerResults.ldif new file mode 100644 index 0000000..20c0912 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/recursiveHandlerResults.ldif
@@ -0,0 +1,15 @@ +dn: cn=Group 2,${ldapBaseDn} +cn: Group 2 +contactPerson: cn=John Adams,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +member: cn=Group 3,${ldapBaseDn} +objectClass: virginiaTechGroup +objectClass: top +uid: 2002 +uid: 2003 +uid: 2004 +uid: 2005 +uugid: group2 +uugid: group3 +uugid: group4 +uugid: group5
diff --git a/integration/src/test/resources/org/ldaptive/searchAttributesResults-2.ldif b/integration/src/test/resources/org/ldaptive/searchAttributesResults-2.ldif new file mode 100644 index 0000000..36cee0a --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchAttributesResults-2.ldif
@@ -0,0 +1,4 @@ +dn: cn=John Adams,${ldapBaseDn} +departmentNumber: 0822 +givenName: John +sn: Adams
diff --git a/integration/src/test/resources/org/ldaptive/searchResults-10.ldif b/integration/src/test/resources/org/ldaptive/searchResults-10.ldif new file mode 100644 index 0000000..2cfc955 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchResults-10.ldif
@@ -0,0 +1,4 @@ +dn: CN=John Tyler,${ldapBaseDn} +departmentNumber: 0830 +givenName: John +sn: Tyler
diff --git a/integration/src/test/resources/org/ldaptive/searchResults-11.ldif b/integration/src/test/resources/org/ldaptive/searchResults-11.ldif new file mode 100644 index 0000000..cd2a574 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchResults-11.ldif
@@ -0,0 +1,5 @@ +dn: cn=James K Polk,${ldapBaseDn} +departmentNumber: 0831 +givenName: James +sn: Polk +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/searchResults-12.ldif b/integration/src/test/resources/org/ldaptive/searchResults-12.ldif new file mode 100644 index 0000000..15a6560 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchResults-12.ldif
@@ -0,0 +1,14 @@ +dn: CN=Zachary Taylor,${ldapBaseDn} +cn: Zachary Taylor +departmentNumber: 0832 +displayName: Zachary Taylor +givenName: Zachary +initials: ZT +mail: ztaylor@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Taylor +uid: 12 +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/searchResults-13.ldif b/integration/src/test/resources/org/ldaptive/searchResults-13.ldif new file mode 100644 index 0000000..8fb5572 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchResults-13.ldif
@@ -0,0 +1,4 @@ +dn: CN=Millard Fillmore,${ldapBaseDn} +departmentNumber: 0833 +givenName: Millard +sn: Fillmore
diff --git a/integration/src/test/resources/org/ldaptive/searchResults-14.ldif b/integration/src/test/resources/org/ldaptive/searchResults-14.ldif new file mode 100644 index 0000000..7de173a --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchResults-14.ldif
@@ -0,0 +1,4 @@ +dn: CN=Franklin Pierce,${ldapBaseDn} +departmentNumber: 0834 +givenName: Franklin +sn: Pierce
diff --git a/integration/src/test/resources/org/ldaptive/searchResults-15.ldif b/integration/src/test/resources/org/ldaptive/searchResults-15.ldif new file mode 100644 index 0000000..31a8647 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchResults-15.ldif
@@ -0,0 +1,4 @@ +dn: CN=James Buchanan,${ldapBaseDn} +departmentNumber: 0835 +givenName: James +sn: Buchanan
diff --git a/integration/src/test/resources/org/ldaptive/searchResults-17.ldif b/integration/src/test/resources/org/ldaptive/searchResults-17.ldif new file mode 100644 index 0000000..45f0cb8 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchResults-17.ldif
@@ -0,0 +1,4 @@ +dn: cn=Andrew Johnson,${ldapBaseDn} +departmentNumber: 0837 +givenName: Andrew +sn: Johnson
diff --git a/integration/src/test/resources/org/ldaptive/searchResults-2.ldif b/integration/src/test/resources/org/ldaptive/searchResults-2.ldif new file mode 100644 index 0000000..6815f39 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchResults-2.ldif
@@ -0,0 +1,4 @@ +dn: CN=John Adams,${ldapBaseDn} +departmentNumber: 0822 +givenName: John +sn: Adams
diff --git a/integration/src/test/resources/org/ldaptive/searchResults-3.ldif b/integration/src/test/resources/org/ldaptive/searchResults-3.ldif new file mode 100644 index 0000000..afc78d2 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchResults-3.ldif
@@ -0,0 +1,4 @@ +dn: CN=Thomas Jefferson,${ldapBaseDn} +departmentNumber: 0823 +givenName: Thomas +sn: Jefferson
diff --git a/integration/src/test/resources/org/ldaptive/searchResults-4.ldif b/integration/src/test/resources/org/ldaptive/searchResults-4.ldif new file mode 100644 index 0000000..1514f86 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchResults-4.ldif
@@ -0,0 +1,4 @@ +dn: CN=James Madison,${ldapBaseDn} +departmentNumber: 0824 +givenName: James +sn: Madison
diff --git a/integration/src/test/resources/org/ldaptive/searchResults-5.ldif b/integration/src/test/resources/org/ldaptive/searchResults-5.ldif new file mode 100644 index 0000000..853b2d6 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchResults-5.ldif
@@ -0,0 +1,4 @@ +dn: CN=James Monroe,${ldapBaseDn} +departmentNumber: 0825 +givenName: James +sn: Monroe
diff --git a/integration/src/test/resources/org/ldaptive/searchResults-6.ldif b/integration/src/test/resources/org/ldaptive/searchResults-6.ldif new file mode 100644 index 0000000..2f8a112 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchResults-6.ldif
@@ -0,0 +1,4 @@ +dn: CN=John Quincy Adams,${ldapBaseDn} +departmentNumber: 0826 +givenName: John +sn: Adams
diff --git a/integration/src/test/resources/org/ldaptive/searchResults-7.ldif b/integration/src/test/resources/org/ldaptive/searchResults-7.ldif new file mode 100644 index 0000000..3f6af66 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchResults-7.ldif
@@ -0,0 +1,4 @@ +dn: CN=Andrew Jackson,${ldapBaseDn} +departmentNumber: 0827 +givenName: Andrew +sn: Jackson
diff --git a/integration/src/test/resources/org/ldaptive/searchResults-8.ldif b/integration/src/test/resources/org/ldaptive/searchResults-8.ldif new file mode 100644 index 0000000..ed17cfc --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchResults-8.ldif
@@ -0,0 +1,5 @@ +dn: CN=Martin Van Buren,${ldapBaseDn} +departmentNumber: 0828 +givenName: Martin +sn: Buren +jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k=
diff --git a/integration/src/test/resources/org/ldaptive/searchResults-9.ldif b/integration/src/test/resources/org/ldaptive/searchResults-9.ldif new file mode 100644 index 0000000..4ba00de --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/searchResults-9.ldif
@@ -0,0 +1,4 @@ +dn: CN=William Henry Harrison,${ldapBaseDn} +departmentNumber: 0829 +givenName: William +sn: Harrison
diff --git a/integration/src/test/resources/org/ldaptive/specialChars-2.ldif b/integration/src/test/resources/org/ldaptive/specialChars-2.ldif new file mode 100644 index 0000000..451966e --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/specialChars-2.ldif
@@ -0,0 +1,10 @@ +dn: cn=Test/User/ #2\,3\=4/\+5\<6\>7\;8,${ldapBaseDn} +cn: Test/User/ #2,3=4/+5<6>7;8 +givenName: Test +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: User +uid: 17894 +userPassword: {SHA}8vnY59vr9MsOYRA0q8wN3NDyGDk=
diff --git a/integration/src/test/resources/org/ldaptive/specialChars-3.ldif b/integration/src/test/resources/org/ldaptive/specialChars-3.ldif new file mode 100644 index 0000000..3985288 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/specialChars-3.ldif
@@ -0,0 +1,10 @@ +dn: cn=Test\\User,${ldapBaseDn} +cn: Test\User +givenName: Test +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: User +uid: 17895 +userPassword: {SHA}rfKc0oug83hbYSYg8IiuVsQZ8Wk=
diff --git a/integration/src/test/resources/org/ldaptive/specialChars.ldif b/integration/src/test/resources/org/ldaptive/specialChars.ldif new file mode 100644 index 0000000..46703e1 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/specialChars.ldif
@@ -0,0 +1,9 @@ +dn: cn=Test/User/ #1,${ldapBaseDn} +cn: Test/User/ #1 +givenName: Test +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: (Us\er)* +uid: 17893
diff --git a/integration/src/test/resources/org/ldaptive/specialCharsResults.ldif b/integration/src/test/resources/org/ldaptive/specialCharsResults.ldif new file mode 100644 index 0000000..dbd212b --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/specialCharsResults.ldif
@@ -0,0 +1,5 @@ +dn: cn=Test/User/ #1,${ldapBaseDn} +cn: Test/User/ #1 +givenName: Test +sn: (Us\er)* +uid: 17893
diff --git a/integration/src/test/resources/org/ldaptive/syncReplResults.ldif b/integration/src/test/resources/org/ldaptive/syncReplResults.ldif new file mode 100644 index 0000000..6bda385 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/syncReplResults.ldif
@@ -0,0 +1,9 @@ +dn: cn=Ulysses Grant,${ldapBaseDn} +cn: Ulysses Grant +mail: usgrant@ldaptive.org +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +sn: Grant +uid: 18
diff --git a/integration/src/test/resources/org/ldaptive/test3.ldif b/integration/src/test/resources/org/ldaptive/test3.ldif new file mode 100644 index 0000000..91c599e --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/test3.ldif
@@ -0,0 +1,4 @@ +dn: uid=test3,${ldapBaseDn} +cn: test3 +sn: test3 +uid: test3
diff --git a/integration/src/test/resources/org/ldaptive/virtualListViewResults.ldif b/integration/src/test/resources/org/ldaptive/virtualListViewResults.ldif new file mode 100644 index 0000000..fb30519 --- /dev/null +++ b/integration/src/test/resources/org/ldaptive/virtualListViewResults.ldif
@@ -0,0 +1,31 @@ +dn: cn=Group 3,${ldapBaseDn} +cn: Group 3 +contactPerson: cn=John Adams,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +objectClass: virginiaTechGroup +objectClass: top +member: cn=Group 4,${ldapBaseDn} +member: cn=Group 5,${ldapBaseDn} +uid: 2003 +uugid: group3 + +dn: cn=Group 4,${ldapBaseDn} +cn: Group 4 +contactPerson: cn=John Adams,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +objectClass: virginiaTechGroup +objectClass: top +member: cn=Group 2,${ldapBaseDn} +member: cn=Group 3,${ldapBaseDn} +uid: 2004 +uugid: group4 + +dn: cn=Group 5,${ldapBaseDn} +cn: Group 5 +contactPerson: cn=John Adams,${ldapBaseDn} +creationDate: 2010-06-06T12:00:00 +objectClass: virginiaTechGroup +objectClass: top +uid: 2005 +uugid: group5 +
diff --git a/integration/src/test/resources/spring-context.xml b/integration/src/test/resources/spring-context.xml new file mode 100644 index 0000000..b1789d4 --- /dev/null +++ b/integration/src/test/resources/spring-context.xml
@@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:p="http://www.springframework.org/schema/p" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> + + <bean id="connectionFactory" + class="org.ldaptive.DefaultConnectionFactory" + p:connectionConfig-ref="connectionConfig" + /> + + <bean id="connectionConfig" + class="org.ldaptive.ConnectionConfig" + p:ldapUrl="${ldapTestHost}" + p:useStartTLS="true" + p:sslConfig-ref="sslConfig" + p:connectionInitializer-ref="bindConnectionInitializer" + /> + + <bean id="bindConnectionInitializer" + class="org.ldaptive.BindConnectionInitializer" + p:bindDn="${ldapBindDn}" + p:bindCredential="${ldapBindCredential}" + /> + + <bean id="sslConfig" + class="org.ldaptive.ssl.SslConfig" + p:credentialConfig-ref="credentialConfig" + /> + + <bean id="credentialConfig" + class="org.ldaptive.ssl.KeyStoreCredentialConfig" + p:keyStore="classpath:/ldaptive.keystore" + p:keyStoreType="BKS" + p:keyStorePassword="changeit" + p:trustStore="classpath:/ldaptive.truststore" + p:trustStoreType="BKS" + p:trustStorePassword="changeit" + /> + +</beans>
diff --git a/integration/src/test/resources/spring-ext-context.xml b/integration/src/test/resources/spring-ext-context.xml new file mode 100644 index 0000000..781e42f --- /dev/null +++ b/integration/src/test/resources/spring-ext-context.xml
@@ -0,0 +1,244 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ldaptive="http://www.ldaptive.org/schema/spring-ext" + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation=" + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.ldaptive.org/schema/spring-ext http://www.ldaptive.org/schema/spring-ext-${project.version}.xsd"> + + <context:property-placeholder location="classpath:/spring-ext.properties"/> + + <ldaptive:anonymous-search-authenticator + ldapUrl="${ldap.url}" + trustCertificates="classpath:/ldaptive.trust.crt" + baseDn="${ldap.baseDn}" + userFilter="(mail={user})" + connectTimeout="${ldap.connectTimeout}" + useStartTLS="${ldap.useStartTLS}" + blockWaitTime="${ldap.pool.blockWaitTime}" + maxPoolSize="${ldap.pool.maxSize}" + minPoolSize="${ldap.pool.minSize}" + /> + + <ldaptive:bind-search-authenticator + ldapUrl="${ldap.url}" + trustStore="classpath:/ldaptive.truststore" + trustStorePassword="changeit" + trustStoreType="BKS" + baseDn="${ldap.baseDn}" + userFilter="(mail={user})" + bindDn="${ldap.bindDn}" + bindCredential="${ldap.bindCredential}" + resolveEntryWithBindCredentials="true" + connectTimeout="${ldap.connectTimeout}" + useStartTLS="${ldap.useStartTLS}" + blockWaitTime="${ldap.pool.blockWaitTime}" + maxPoolSize="${ldap.pool.maxSize}" + minPoolSize="${ldap.pool.minSize}"> + <ldaptive:authentication-response-handler> + <ldaptive:password-policy-handler/> + </ldaptive:authentication-response-handler> + </ldaptive:bind-search-authenticator> + + <ldaptive:bind-search-authenticator + id="bind-search-disable-pool" + ldapUrl="${ldap.url}" + trustStore="classpath:/ldaptive.truststore" + trustStorePassword="changeit" + trustStoreType="BKS" + baseDn="${ldap.baseDn}" + userFilter="(mail={user})" + bindDn="${ldap.bindDn}" + bindCredential="${ldap.bindCredential}" + resolveEntryWithBindCredentials="true" + disablePooling="true" + connectTimeout="${ldap.connectTimeout}" + useStartTLS="${ldap.useStartTLS}"> + <ldaptive:authentication-response-handler> + <ldaptive:password-policy-handler/> + </ldaptive:authentication-response-handler> + </ldaptive:bind-search-authenticator> + + <ldaptive:sasl-bind-search-authenticator + id="sasl-auth" + mechanism="${ldap.sasl.mechanism}" + qualityOfProtection="${ldap.sasl.qualityOfProtection}" + securityStrength="${ldap.sasl.securityStrength}" + ldapUrl="${ldap.url}" + trustCertificates="classpath:/ldaptive.trust.crt" + baseDn="${ldap.baseDn}" + userFilter="(mail={user})" + bindDn="test3@vt.edu" + bindCredential="password" + connectTimeout="${ldap.connectTimeout}" + useStartTLS="${ldap.useStartTLS}" + blockWaitTime="${ldap.pool.blockWaitTime}" + maxPoolSize="${ldap.pool.maxSize}" + allowMultipleDns="${ldap.allowMultipleDns:false}" + minPoolSize="${ldap.pool.minSize}" + validateOnCheckOut="${ldap.pool.validateOnCheckout:false}" + validatePeriodically="${ldap.pool.validatePeriodically:true}" + validatePeriod="${ldap.pool.validatePeriod:PT5M}" + idleTime="${ldap.pool.idleTime:PT10M}" + prunePeriod="${ldap.pool.prunePeriod:PT5M}" + failFastInitialize="false" + subtreeSearch="${ldap.subtreeSearch:true}" + useSSL="false"> + <ldaptive:authentication-response-handler> + <ldaptive:password-expiration-handler/> + </ldaptive:authentication-response-handler> + </ldaptive:sasl-bind-search-authenticator> + + <ldaptive:direct-authenticator + ldapUrl="${ldap.url}" + trustCertificates="${ldap.trustCertificates}" + format="${ldap.dnFormat}" + connectTimeout="${ldap.connectTimeout}" + useStartTLS="${ldap.useStartTLS}" + blockWaitTime="${ldap.pool.blockWaitTime}" + maxPoolSize="${ldap.pool.maxSize}" + minPoolSize="${ldap.pool.minSize}"> + <ldaptive:authentication-response-handler> + <ldaptive:free-ipa-handler expirationPeriod="${ldap.auth.expirationPeriod}" warningPeriod="${ldap.auth.warningPeriod}" maxLoginFailures="4"/> + </ldaptive:authentication-response-handler> + </ldaptive:direct-authenticator> + + <ldaptive:ad-authenticator + ldapUrl="${ldap.url}" + baseDn="${ldap.baseDn}" + userFilter="(mail={user})" + bindDn="${ldap.bindDn}" + provider="org.ldaptive.provider.jndi.JndiProvider" + bindCredential="${ldap.bindCredential}" + trustCertificates="classpath:/ldaptive.trust.crt" + connectTimeout="${ldap.connectTimeout}" + useStartTLS="${ldap.useStartTLS}" + blockWaitTime="${ldap.pool.blockWaitTime}" + maxPoolSize="${ldap.pool.maxSize}" + minPoolSize="${ldap.pool.minSize}"> + <ldaptive:authentication-response-handler> + <ldaptive:active-directory-handler expirationPeriod="${ldap.auth.expirationPeriod}" warningPeriod="${ldap.auth.warningPeriod}"/> + </ldaptive:authentication-response-handler> + </ldaptive:ad-authenticator> + + <ldaptive:pooled-connection-factory + ldapUrl="${ldap.url}" + trustStore="${ldap.trustStore}" + trustStoreType="${ldap.trustStoreType}" + keyStore="${ldap.keyStore}" + keyStoreType="${ldap.keyStoreType}" + keyStoreAliases="${ldap.keyStoreAliases}" + /> + + <ldaptive:connection-factory + ldapUrl="${ldap.url}" + trustCertificates="classpath:/ldaptive.trust.crt" + /> + + <ldaptive:connection-pool + ldapUrl="${ldap.url}" + trustCertificates="classpath:/ldaptive.trust.crt" + /> + + <ldaptive:search-executor + baseDn="${ldap.baseDn}" + searchFilter="(mail=*)" + returnAttributes="cn,givenName,sn" + searchScope="${ldap.searchScope}" + timeLimit="${ldap.timeLimit}" + sizeLimit="${ldap.sizeLimit}" + binaryAttributes="jpegPhoto,userCertificate" + sortBehavior="${ldap.sortBehavior}" + /> + + <ldaptive:parallel-search-executor + baseDn="${ldap.baseDn}" + searchFilter="(mail=*)" + returnAttributes="cn,givenName,sn" + searchScope="${ldap.searchScope}" + timeLimit="${ldap.timeLimit}" + sizeLimit="${ldap.sizeLimit}" + binaryAttributes="jpegPhoto,userCertificate" + sortBehavior="${ldap.sortBehavior}" + /> + + <ldaptive:parallel-pooled-search-executor + baseDn="${ldap.baseDn}" + searchFilter="(mail=*)" + returnAttributes="cn,givenName,sn" + searchScope="${ldap.searchScope}" + timeLimit="${ldap.timeLimit}" + sizeLimit="${ldap.sizeLimit}" + binaryAttributes="jpegPhoto,userCertificate" + sortBehavior="${ldap.sortBehavior}" + /> + + <ldaptive:aggregate-search-executor + baseDn="${ldap.baseDn}" + searchFilter="(mail=*)" + returnAttributes="cn,givenName,sn" + searchScope="${ldap.searchScope}" + timeLimit="${ldap.timeLimit}" + sizeLimit="${ldap.sizeLimit}" + binaryAttributes="jpegPhoto,userCertificate" + sortBehavior="${ldap.sortBehavior}" + /> + + <ldaptive:aggregate-pooled-search-executor + baseDn="${ldap.baseDn}" + searchFilter="(mail=*)" + returnAttributes="cn,givenName,sn" + searchScope="${ldap.searchScope}" + timeLimit="${ldap.timeLimit}" + sizeLimit="${ldap.sizeLimit}" + binaryAttributes="jpegPhoto,userCertificate" + sortBehavior="${ldap.sortBehavior}" + /> + + <ldaptive:connection-config + ldapUrl="${ldap.url}" + connectTimeout="PT3S" + trustStore="classpath:/ldaptive.truststore" + trustStorePassword="changeit" + trustStoreType="BKS" + keyStore="${ldap.keyStore}" + keyStorePassword="changeit" + keyStoreType="BKS" + keyStoreAliases="${ldap.keyStoreAliases}" + /> + + <ldaptive:aggregate-authenticator> + <ldaptive:anonymous-search-authenticator + ldapUrl="${ldap.url}" + trustCertificates="classpath:/ldaptive.trust.crt" + baseDn="${ldap.baseDn}" + userFilter="(mail={user})" + connectTimeout="${ldap.connectTimeout}" + useStartTLS="${ldap.useStartTLS}" + blockWaitTime="${ldap.pool.blockWaitTime}" + maxPoolSize="${ldap.pool.maxSize}" + minPoolSize="${ldap.pool.minSize}" + /> + <ldaptive:bind-search-authenticator + ldapUrl="${ldap.url}" + trustStore="classpath:/ldaptive.truststore" + trustStorePassword="changeit" + trustStoreType="BKS" + baseDn="${ldap.baseDn}" + userFilter="(mail={user})" + bindDn="${ldap.bindDn}" + bindCredential="${ldap.bindCredential}" + resolveEntryWithBindCredentials="true" + connectTimeout="${ldap.connectTimeout}" + useStartTLS="${ldap.useStartTLS}" + blockWaitTime="${ldap.pool.blockWaitTime}" + maxPoolSize="${ldap.pool.maxSize}" + minPoolSize="${ldap.pool.minSize}"> + <ldaptive:authentication-response-handler> + <ldaptive:password-policy-handler/> + </ldaptive:authentication-response-handler> + </ldaptive:bind-search-authenticator> + </ldaptive:aggregate-authenticator> +</beans>
diff --git a/integration/src/test/resources/spring-ext.properties b/integration/src/test/resources/spring-ext.properties new file mode 100644 index 0000000..258c269 --- /dev/null +++ b/integration/src/test/resources/spring-ext.properties
@@ -0,0 +1,33 @@ +ldap.url=${ldapTestHost} +ldap.sslUrl=${ldapSslTestHost} +ldap.baseDn=${ldapBaseDn} +ldap.bindDn=${ldapBindDn} +ldap.bindCredential=${ldapBindCredential} +ldap.dnFormat=cn=%1$s,${ldapBaseDn} +ldap.connectTimeout=PT3S +ldap.useStartTLS=true +ldap.pool.blockWaitTime=PT3S +ldap.pool.maxSize=10 +ldap.pool.minSize=3 +ldap.ppolicy=true +ldap.trustCertificates=classpath:/ldaptive.trust.crt +ldap.trustStore=classpath:/ldaptive.truststore +ldap.trustStorePassword=changeit +ldap.trustStoreType=BKS +ldap.keyStore=classpath:/ldaptive.keystore +ldap.keyStorePassword=changeit +ldap.keyStoreType=BKS +ldap.keyStoreAliases=vt-ldap-test + +ldap.sasl.mechanism=DIGEST_MD5 +ldap.sasl.qualityOfProtection=AUTH_INT +ldap.sasl.securityStrength=MEDIUM + +ldap.auth.expirationPeriod=P90D +ldap.auth.warningPeriod=P15D + +# search executor +ldap.timeLimit=PT5S +ldap.sizeLimit=10 +ldap.searchScope=ONELEVEL +ldap.sortBehavior=ORDERED
diff --git a/integration/src/test/resources/spring-factory-context.xml b/integration/src/test/resources/spring-factory-context.xml new file mode 100644 index 0000000..5ea6308 --- /dev/null +++ b/integration/src/test/resources/spring-factory-context.xml
@@ -0,0 +1,114 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:p="http://www.springframework.org/schema/p" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> + + <bean id="connectionFactory" + class="org.ldaptive.DefaultConnectionFactory" + p:connectionConfig-ref="connectionConfig" + /> + + <bean id="connectionConfig" + class="org.ldaptive.ConnectionConfig" + p:ldapUrl="${ldapTestHost}" + p:useStartTLS="true" + p:sslConfig-ref="sslConfig" + p:connectionInitializer-ref="bindConnectionInitializer" + /> + + <bean id="bindConnectionInitializer" + class="org.ldaptive.BindConnectionInitializer" + p:bindDn="${ldapBindDn}" + p:bindCredential="${ldapBindCredential}" + /> + + <bean id="sslConfig" + class="org.ldaptive.ssl.SslConfig" + p:credentialConfig-ref="credentialConfig" + /> + + <bean id="credentialConfig" + class="org.ldaptive.ssl.CredentialConfigFactory" + factory-method="createX509CredentialConfig"> + <constructor-arg> + <value>-----BEGIN CERTIFICATE----- +MIIDhzCCAvCgAwIBAgIJAPpeFAkJP5xgMA0GCSqGSIb3DQEBBQUAMIGKMQswCQYD +VQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWExEzARBgNVBAcTCkJsYWNrc2J1cmcx +FjAUBgNVBAoTDVZpcmdpbmlhIFRlY2gxEzARBgNVBAsTCk1pZGRsZXdhcmUxJjAk +BgNVBAMTHWxkYXAtdGVzdC0xLm1pZGRsZXdhcmUudnQuZWR1MB4XDTExMDkyNjE2 +NDczOFoXDTIxMDkyMzE2NDczOFowgYoxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhW +aXJnaW5pYTETMBEGA1UEBxMKQmxhY2tzYnVyZzEWMBQGA1UEChMNVmlyZ2luaWEg +VGVjaDETMBEGA1UECxMKTWlkZGxld2FyZTEmMCQGA1UEAxMdbGRhcC10ZXN0LTEu +bWlkZGxld2FyZS52dC5lZHUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJWf +/vBsfFn6sQo57IHrBzMlPARpDI1DJeqH7zl2UeVzeiZDjGiU4ETSjEsvvQRzLfXZ +IgJEr1IEAzjCX8wKF4svrmkPK3KN6JvdlknM7Thw5p0NzAh2Bq1R1h7+bUvQJGep +aizNM0od/mKrJnOnUCWEgcpG91mWg8b1PphGobeNAgMBAAGjgfIwge8wHQYDVR0O +BBYEFMT2Hkcp6JFq242hWfdMOeT3/hZ1MIG/BgNVHSMEgbcwgbSAFMT2Hkcp6JFq +242hWfdMOeT3/hZ1oYGQpIGNMIGKMQswCQYDVQQGEwJVUzERMA8GA1UECBMIVmly +Z2luaWExEzARBgNVBAcTCkJsYWNrc2J1cmcxFjAUBgNVBAoTDVZpcmdpbmlhIFRl +Y2gxEzARBgNVBAsTCk1pZGRsZXdhcmUxJjAkBgNVBAMTHWxkYXAtdGVzdC0xLm1p +ZGRsZXdhcmUudnQuZWR1ggkA+l4UCQk/nGAwDAYDVR0TBAUwAwEB/zANBgkqhkiG +9w0BAQUFAAOBgQBe0bV5iZyPupNh2zmdH7opuwldz1sxlkRdUQhKSlYsOqgAKDvS +DypmR4mqntAULTFGZIdcQ1W8HJcnRc8KuPfNatAV8A9OqMbtDLnmfWkl33JPiDUd +fIKCXuG4dZ6nn3RbjlKhXzHYADmJzdQNIC3M9eDQBEYmMy8+mV+ErVebBg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDYjCCAkqgAwIBAgIETwyocDANBgkqhkiG9w0BAQUFADBzMRMwEQYKCZImiZPy +LGQBGRYDZWR1MRIwEAYKCZImiZPyLGQBGRYCdnQxCzAJBgNVBAoTAnZ0MRMwEQYD +VQQLEwptaWRkbGV3YXJlMSYwJAYDVQQDEx1sZGFwLXRlc3QtMi5taWRkbGV3YXJl +LnZ0LmVkdTAeFw0xMjAxMTAyMTA2NTZaFw0xNDAxMDkyMTA2NTZaMHMxEzARBgoJ +kiaJk/IsZAEZFgNlZHUxEjAQBgoJkiaJk/IsZAEZFgJ2dDELMAkGA1UEChMCdnQx +EzARBgNVBAsTCm1pZGRsZXdhcmUxJjAkBgNVBAMTHWxkYXAtdGVzdC0yLm1pZGRs +ZXdhcmUudnQuZWR1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm5xR +Lm8+NlxUJSR/2tXZrYW8+9kQSJAR+a/xfcxcWETntbLHE4XZzCde28wDRM5QZo5z +fK91upR3uf4/O+4xmOgiBarP6x1Dtob6JeMeUh6/lSpNuNdkSEbSZ3gS0Vc/OYIr +mcwLQroqNxi3BPVy6ryzGSnd9/PhOf5R2C3mZcBunCQU9GyEexlvQ4d8UkYBNKz5 +sEHl4hcIIirDNTJ27v752rjVWkxPOtF6KUeRsarP4qK2N5nOipAGRrG5nON5ggFl +YC3UNdj3tvoDstxRSgPY9RaHgN5uNrMPmLrbwNY3q9YsiRZ7veiqIIvirGc3CXfc +4tTD5sClKhafguf6BQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQCMvZzuxAVc/G7W +4Ci/Oxa6YAH6Yq745SVuVAjBAhD9wz+Ney4cuFHeyPFnbYWNlikgeWpoglLkEBta +SGxSnVM74ZxGLwpaWOuI5d2tv7bWm318a0kDaTiXRrJ+6tg/rjyQ7xxYlI5+CqO+ +nK+rB4hawRhRvzguItNzKJhnCuydM5lZoXMZAPDxRxDy/2LfokvaCKpNjCYb+nGE +Q66oXAH7AP4OynJ2B5fu4eNgbr8JH4dRH667Y+Pkb03xWabdvp5b+YLmP2iOuq10 +DDm9bpasI5c/SfWdZfWTC3a12WdzZaGBLVxlTRJvegAaktEBXm79OtoSr4TJtNLC +QTHsT7nJ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC+TCCAeGgAwIBAgIQap33EU39DI5Mq0kKqi3UqDANBgkqhkiG9w0BAQUFADAk +MSIwIAYDVQQDExltaWRkbGV3YXJlLXRlc3QuY2MudnQuZWR1MB4XDTEyMDIxNDIx +MDMxOVoXDTIyMDIxMTIxMDMxOVowJDEiMCAGA1UEAxMZbWlkZGxld2FyZS10ZXN0 +LmNjLnZ0LmVkdTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN0KHXSC +ON/ua9WkeZdPavD89fhSW2O/VP5yjPxNRFvKSvqnCDBaSlv3LmAFpk2JB2C38/8I +5jl+fNBME0cREFBm8oBVeX4d9hURyOhcQD2Avokq2TjPB3NdVSGOF9qfEyg+jd/Q +mj1htx2KbFSdi1v3g24ENLYsJlmnwDirtaI1Q1IgjIsdDV3WgsgiDj44cKnsOCeX +xKaBmyjZMxoPdkMiHe/fn6/5xRW7PxypFdsLaJksN5aLGllNZ/p6TgEgO5JLR/SH +Pq15MeNA2/nc6NEDs+0H3sYs0g661DKxgLNJstGsuJynLZ+yp6JTbmVPzuJA3Vy9 +PSxurFarFxz5R9ECAwEAAaMnMCUwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYDVR0P +BAcDBQCwAAAAMA0GCSqGSIb3DQEBBQUAA4IBAQBoj9bTke/aC5VIspIsEDN+HgKa ++orB5VP0v/RZab82eC9cXBj8y1P330f+panhu5iJJouXOYTyIx6QIxz4eHArw8RZ +l+3lNAFYEpWAIKReais4TJcQuU6sddjNBksCvo6FYU4sF8Pk4Ip22ZUO5X8YTcks +hQCOdGCyF3JCh42SWoRH6wxXc/BU13jYgBfXja2YFsADuT1UVlKJXKxtL58XiVrC +SyQXsmy4lryzNa4s9h5yfM3Hsrgyg9XTcKRyZe70IhJizs6HdqddpjPOw7wmf65m +vx/DLCgVsnlMSAkVHSScQZukcVt9LfzFz9DF5IaVze34pnVpsNi+JHaVyv71 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICjjCCAfegAwIBAgIFAJneB9AwDQYJKoZIhvcNAQEFBQAwgYoxJjAkBgNVBAMT +HWxkYXAtdGVzdC0zLm1pZGRsZXdhcmUudnQuZWR1MRMwEQYDVQQLEwpNaWRkbGV3 +YXJlMRYwFAYDVQQKEw1WaXJnaW5pYSBUZWNoMRMwEQYDVQQHEwpCbGFja3NidXJn +MREwDwYDVQQIEwhWaXJnaW5pYTELMAkGA1UEBhMCVVMwHhcNMTIxMTIwMTcwNTQz +WhcNMTQxMTIwMTcwNTQzWjCBijEmMCQGA1UEAxMdbGRhcC10ZXN0LTMubWlkZGxl +d2FyZS52dC5lZHUxEzARBgNVBAsTCk1pZGRsZXdhcmUxFjAUBgNVBAoTDVZpcmdp +bmlhIFRlY2gxEzARBgNVBAcTCkJsYWNrc2J1cmcxETAPBgNVBAgTCFZpcmdpbmlh +MQswCQYDVQQGEwJVUzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAl13KcfcN +M8OUzyyZjwzyli/DdcCDR29R4woSn8v0kiLFi/vM6OCO9VYXcJp5YqTQ7P/JtFKz +/D98RJrnDEp0uaSEv6KWXOloJ4xJvcS+snB1DALPEJrAHzBtOQbbps1iisXHqA0T +RmlS1O33AGR6J+PP+f0+THobS5Ud57Xmg5ECAwEAATANBgkqhkiG9w0BAQUFAAOB +gQBJkrCSA9/V6KwCrAetvXTqNt9dCAEwMs0gyzwigHxVxanXIVSn+171fRHeolVc +ykRT/CadTHXpJ7dr355s8UwYsbL84LdZrhBIBa/emprbHxYTOqrw5coQSCJhkVRS +Xy1fhtxTC5pZk5XTNWw3lK493neCD0CZiB8PQ/iRZiULDg== +-----END CERTIFICATE-----</value> + </constructor-arg> + </bean> + +</beans>
diff --git a/integration/src/test/resources/spring-jaas-context.xml b/integration/src/test/resources/spring-jaas-context.xml new file mode 100644 index 0000000..292cdbf --- /dev/null +++ b/integration/src/test/resources/spring-jaas-context.xml
@@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:p="http://www.springframework.org/schema/p" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> + + <bean id="conversionService" + class="org.springframework.context.support.ConversionServiceFactoryBean"> + <property name="converters"> + <set> + <bean class="org.ldaptive.beans.spring.convert.StringToDurationConverter"/> + <bean class="org.ldaptive.beans.spring.convert.DurationToStringConverter"/> + </set> + </property> + </bean> + + <bean id="authenticator" + class="org.ldaptive.auth.Authenticator" + p:dnResolver-ref="dnResolver" + p:authenticationHandler-ref="authenticationHandler" + /> + + <bean id="dnResolver" + class="org.ldaptive.auth.PooledSearchDnResolver" + p:baseDn="${ldapBaseDn}" + p:userFilter="(&(mail={user})(objectClass={0}))" + p:userFilterParameters="person"> + <constructor-arg index="0" ref="drConnectionFactory"/> + </bean> + + <bean id="authenticationHandler" + class="org.ldaptive.auth.PooledBindAuthenticationHandler" + p:connectionFactory-ref="ahConnectionFactory" + /> + + <bean id="authenticationRequest" + class="org.ldaptive.auth.AuthenticationRequest" + scope="prototype" + /> + + <bean id="drConnectionFactory" + class="org.ldaptive.pool.PooledConnectionFactory" + p:connectionPool-ref="drPool" + /> + + <bean id="ahConnectionFactory" + class="org.ldaptive.pool.PooledConnectionFactory" + p:connectionPool-ref="ahPool" + /> + + <bean id="drPool" + class="org.ldaptive.pool.BlockingConnectionPool" + init-method="initialize"> + <constructor-arg index="0" ref="poolConfig"/> + <constructor-arg index="1" ref="connectionFactory"/> + </bean> + + <bean id="ahPool" + class="org.ldaptive.pool.BlockingConnectionPool" + init-method="initialize"> + <constructor-arg index="0" ref="poolConfig"/> + <constructor-arg index="1" ref="connectionFactory"/> + </bean> + + <bean id="poolConfig" + class="org.ldaptive.pool.PoolConfig" + p:minPoolSize="5" + p:maxPoolSize="20" + p:validatePeriod="PT30S" + /> + + <bean id="connectionFactory" + class="org.ldaptive.DefaultConnectionFactory" + p:connectionConfig-ref="connectionConfig" + /> + + <bean id="connectionConfig" + class="org.ldaptive.ConnectionConfig" + p:ldapUrl="${ldapTestHost}" + p:useStartTLS="true" + p:sslConfig-ref="sslConfig" + p:connectionInitializer-ref="bindConnectionInitializer" + /> + + <bean id="sslConfig" + class="org.ldaptive.ssl.SslConfig" + p:credentialConfig-ref="credentialConfig" + /> + + <bean id="bindConnectionInitializer" + class="org.ldaptive.BindConnectionInitializer" + p:bindDn="${ldapBindDn}" + p:bindCredential="${ldapBindCredential}" + /> + + <bean id="credentialConfig" + class="org.ldaptive.ssl.KeyStoreCredentialConfig" + p:trustStore="classpath:/ldaptive.truststore" + p:trustStoreType="BKS" + p:trustStorePassword="changeit" + /> + +</beans>
diff --git a/integration/src/test/resources/spring-pool-context.xml b/integration/src/test/resources/spring-pool-context.xml new file mode 100644 index 0000000..49bf226 --- /dev/null +++ b/integration/src/test/resources/spring-pool-context.xml
@@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:p="http://www.springframework.org/schema/p" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> + + <bean id="conversionService" + class="org.springframework.context.support.ConversionServiceFactoryBean"> + <property name="converters"> + <set> + <bean class="org.ldaptive.beans.spring.convert.StringToDurationConverter"/> + <bean class="org.ldaptive.beans.spring.convert.DurationToStringConverter"/> + </set> + </property> + </bean> + + <bean id="pool" + class="org.ldaptive.pool.BlockingConnectionPool" + init-method="initialize" + p:blockWaitTime="PT5S" + p:validator-ref="compareValidator"> + <constructor-arg index="0"> + <bean class="org.ldaptive.pool.PoolConfig" + p:minPoolSize="5" + p:maxPoolSize="20" + p:validatePeriodically="true" + p:validatePeriod="PT30S" + /> + </constructor-arg> + <constructor-arg index="1" ref="connectionFactory"/> + </bean> + + <bean id="compareValidator" + class="org.ldaptive.pool.CompareValidator" + /> + + <bean id="connectionFactory" + class="org.ldaptive.DefaultConnectionFactory" + p:connectionConfig-ref="connectionConfig" + /> + + <bean id="connectionConfig" + class="org.ldaptive.ConnectionConfig" + p:ldapUrl="${ldapTestHost}" + p:useStartTLS="true" + p:sslConfig-ref="sslConfig" + p:connectionInitializer-ref="bindConnectionInitializer" + /> + + <bean id="sslConfig" + class="org.ldaptive.ssl.SslConfig" + p:credentialConfig-ref="credentialConfig" + /> + + <bean id="bindConnectionInitializer" + class="org.ldaptive.BindConnectionInitializer" + p:bindDn="${ldapBindDn}" + p:bindCredential="${ldapBindCredential}" + /> + + <bean id="credentialConfig" + class="org.ldaptive.ssl.KeyStoreCredentialConfig" + p:keyStore="classpath:/ldaptive.keystore" + p:keyStoreType="BKS" + p:keyStorePassword="changeit" + p:trustStore="classpath:/ldaptive.truststore" + p:trustStoreType="BKS" + p:trustStorePassword="changeit" + /> + +</beans>
diff --git a/integration/src/test/resources/templates-context.xml b/integration/src/test/resources/templates-context.xml new file mode 100644 index 0000000..1391fc0 --- /dev/null +++ b/integration/src/test/resources/templates-context.xml
@@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ldaptive="http://www.ldaptive.org/schema/spring-ext" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.ldaptive.org/schema/spring-ext http://www.ldaptive.org/schema/spring-ext.xsd"> + + <bean id="conversionService" + class="org.springframework.context.support.ConversionServiceFactoryBean"> + <property name="converters"> + <set> + <bean class="org.ldaptive.beans.spring.convert.StringToDurationConverter"/> + <bean class="org.ldaptive.beans.spring.convert.DurationToStringConverter"/> + </set> + </property> + </bean> + + <ldaptive:aggregate-pooled-search-executor baseDn="${ldapBaseDn}" binaryAttributes="jpegPhoto" /> + + <ldaptive:pooled-connection-factory + ldapUrl="${ldapTestHost}" + useStartTLS="false" + bindDn="${ldapBindDn}" + bindCredential="${ldapBindCredential}" + blockWaitTime="PT5S" + minPoolSize="3" + maxPoolSize="10" + validatePeriodically="true" /> + + <bean id="oneTermSearch" class="org.ldaptive.templates.SearchTemplates"> + <constructor-arg> + <list> + <value>(|(givenName={term1})(sn={term1}))</value> + <value>(|(givenName={term1}*)(sn={term1}*))</value> + <value>(|(givenName=*{term1}*)(sn=*{term1}*))</value> + <value>(mail={term1})</value> + <value>(mail={term1}*)</value> + <value>(mail=*{term1}*)</value> + </list> + </constructor-arg> + </bean> + + <bean id="twoTermSearch" class="org.ldaptive.templates.SearchTemplates"> + <constructor-arg> + <list> + <value>(&(givenName={term1})(sn={term2}))</value> + <value>(cn={term1} {term2})</value> + <value>(&(givenName={term1}*)(sn={term2}*))</value> + <value>(cn={term1}* {term2}*)</value> + <value>(&(givenName=*{term1}*)(sn=*{term2}*))</value> + <value>(cn=*{term1}* *{term2}*)</value> + <value>(&(givenName={initial1}*)(sn={term2}))</value> + <value>(sn={term2})</value> + </list> + </constructor-arg> + </bean> + + <bean id="threeTermSearch" class="org.ldaptive.templates.SearchTemplates"> + <constructor-arg> + <list> + <value>(|(&(givenName={term1})(sn={term3}))(&(givenName={term2})(sn={term3})))</value> + <value>(|(cn={term1} {term2} {term3})(cn={term2} {term1} {term3}))</value> + <value>(|(&(givenName={term1}*)(sn={term3}*))(&(givenName={term2}*)(sn={term3}*)))</value> + <value>(|(cn={term1}* {term2}* {term3}*)(cn={term2}* {term1}* {term3}*))</value> + <value>(|(&(givenName=*{term1}*)(sn=*{term3}*))(&(givenName=*{term2}*)(sn=*{term3}*)))</value> + <value>(|(cn=*{term1}* *{term2}* *{term3}*)(cn=*{term2}* *{term1}* *{term3}*))</value> + <value>(|(&(givenName={term1})(sn={term3}))(&(givenName={term2})(sn={term3})))</value> + <value>(|(&p(givenName={initial1}*)(sn={term3}))(&(givenName={initial2}*)(sn={term3})))</value> + <value>(sn={term3})</value> + </list> + </constructor-arg> + </bean> + +</beans>
diff --git a/integration/src/test/resources/web.xml b/integration/src/test/resources/web.xml new file mode 100644 index 0000000..cb09bb5 --- /dev/null +++ b/integration/src/test/resources/web.xml
@@ -0,0 +1,219 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE web-app + PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" + "http://java.sun.com/dtd/web-app_2_3.dtd"> + +<web-app> + <servlet> + <servlet-name>LdifSearch</servlet-name> + <servlet-class>org.ldaptive.servlets.SearchServlet</servlet-class> + <init-param> + <param-name>searchExecutorClass</param-name> + <param-value>org.ldaptive.servlets.LdifServletSearchExecutor</param-value> + </init-param> + <init-param> + <param-name>ldapUrl</param-name> + <param-value>${ldapTestHost}</param-value> + </init-param> + <init-param> + <param-name>baseDn</param-name> + <param-value>${ldapBaseDn}</param-value> + </init-param> + <init-param> + <param-name>bindDn</param-name> + <param-value>${ldapBindDn}</param-value> + </init-param> + <init-param> + <param-name>bindCredential</param-name> + <param-value>${ldapBindCredential}</param-value> + </init-param> + <init-param> + <param-name>binaryAttributes</param-name> + <param-value>jpegPhoto</param-value> + </init-param> + <init-param> + <param-name>poolType</param-name> + <param-value>BLOCKING</param-value> + </init-param> + <init-param> + <param-name>blockWaitTime</param-name> + <param-value>PT5S</param-value> + </init-param> + </servlet> + <servlet> + <servlet-name>DsmlSearch</servlet-name> + <servlet-class>org.ldaptive.servlets.SearchServlet</servlet-class> + <init-param> + <param-name>ldapUrl</param-name> + <param-value>${ldapTestHost}</param-value> + </init-param> + <init-param> + <param-name>baseDn</param-name> + <param-value>${ldapBaseDn}</param-value> + </init-param> + <init-param> + <param-name>bindDn</param-name> + <param-value>${ldapBindDn}</param-value> + </init-param> + <init-param> + <param-name>bindCredential</param-name> + <param-value>${ldapBindCredential}</param-value> + </init-param> + <init-param> + <param-name>binaryAttributes</param-name> + <param-value>jpegPhoto</param-value> + </init-param> + <init-param> + <param-name>poolType</param-name> + <param-value>SOFTLIMIT</param-value> + </init-param> + </servlet> + <servlet> + <servlet-name>JsonSearch</servlet-name> + <servlet-class>org.ldaptive.servlets.SearchServlet</servlet-class> + <init-param> + <param-name>searchExecutorClass</param-name> + <param-value>org.ldaptive.servlets.JsonServletSearchExecutor</param-value> + </init-param> + <init-param> + <param-name>ldapUrl</param-name> + <param-value>${ldapTestHost}</param-value> + </init-param> + <init-param> + <param-name>baseDn</param-name> + <param-value>${ldapBaseDn}</param-value> + </init-param> + <init-param> + <param-name>bindDn</param-name> + <param-value>${ldapBindDn}</param-value> + </init-param> + <init-param> + <param-name>bindCredential</param-name> + <param-value>${ldapBindCredential}</param-value> + </init-param> + <init-param> + <param-name>binaryAttributes</param-name> + <param-value>jpegPhoto</param-value> + </init-param> + <init-param> + <param-name>poolType</param-name> + <param-value>SOFTLIMIT</param-value> + </init-param> + </servlet> + <servlet> + <servlet-name>AttributeSearch</servlet-name> + <servlet-class>org.ldaptive.servlets.SearchServlet</servlet-class> + <init-param> + <param-name>searchExecutorClass</param-name> + <param-value>org.ldaptive.servlets.AttributeValueServletSearchExecutor</param-value> + </init-param> + <init-param> + <param-name>ldapUrl</param-name> + <param-value>${ldapTestHost}</param-value> + </init-param> + <init-param> + <param-name>baseDn</param-name> + <param-value>${ldapBaseDn}</param-value> + </init-param> + <init-param> + <param-name>bindDn</param-name> + <param-value>${ldapBindDn}</param-value> + </init-param> + <init-param> + <param-name>bindCredential</param-name> + <param-value>${ldapBindCredential}</param-value> + </init-param> + <init-param> + <param-name>binaryAttributes</param-name> + <param-value>jpegPhoto</param-value> + </init-param> + <init-param> + <param-name>poolType</param-name> + <param-value>BLOCKING</param-value> + </init-param> + </servlet> + <servlet> + <servlet-name>TemplatesLdifSearch</servlet-name> + <servlet-class>org.ldaptive.servlets.SearchServlet</servlet-class> + <init-param> + <param-name>searchExecutorClass</param-name> + <param-value>org.ldaptive.servlets.LdifServletSearchTemplatesExecutor</param-value> + </init-param> + <init-param> + <param-name>springContextPath</param-name> + <param-value>/templates-context.xml</param-value> + </init-param> + </servlet> + <servlet> + <servlet-name>TemplatesDsmlSearch</servlet-name> + <servlet-class>org.ldaptive.servlets.SearchServlet</servlet-class> + <init-param> + <param-name>searchExecutorClass</param-name> + <param-value>org.ldaptive.servlets.Dsmlv1ServletSearchTemplatesExecutor</param-value> + </init-param> + <init-param> + <param-name>springContextPath</param-name> + <param-value>/templates-context.xml</param-value> + </init-param> + </servlet> + <servlet> + <servlet-name>TemplatesJsonSearch</servlet-name> + <servlet-class>org.ldaptive.servlets.SearchServlet</servlet-class> + <init-param> + <param-name>searchExecutorClass</param-name> + <param-value>org.ldaptive.servlets.JsonServletSearchTemplatesExecutor</param-value> + </init-param> + <init-param> + <param-name>springContextPath</param-name> + <param-value>/templates-context.xml</param-value> + </init-param> + </servlet> + <servlet> + <servlet-name>TemplatesLdifIgnoreSearch</servlet-name> + <servlet-class>org.ldaptive.servlets.SearchServlet</servlet-class> + <init-param> + <param-name>searchExecutorClass</param-name> + <param-value>org.ldaptive.servlets.LdifServletSearchTemplatesExecutor</param-value> + </init-param> + <init-param> + <param-name>springContextPath</param-name> + <param-value>/templates-context.xml</param-value> + </init-param> + <init-param> + <param-name>ignorePattern</param-name> + <param-value>^\w{1,2}$</param-value> + </init-param> + </servlet> + <servlet-mapping> + <servlet-name>LdifSearch</servlet-name> + <url-pattern>/LdifSearch</url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name>DsmlSearch</servlet-name> + <url-pattern>/DsmlSearch</url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name>JsonSearch</servlet-name> + <url-pattern>/JsonSearch</url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name>AttributeSearch</servlet-name> + <url-pattern>/AttributeSearch</url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name>TemplatesLdifSearch</servlet-name> + <url-pattern>/TemplatesLdifSearch</url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name>TemplatesDsmlSearch</servlet-name> + <url-pattern>/TemplatesDsmlSearch</url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name>TemplatesJsonSearch</servlet-name> + <url-pattern>/TemplatesJsonSearch</url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name>TemplatesLdifIgnoreSearch</servlet-name> + <url-pattern>/TemplatesLdifIgnoreSearch</url-pattern> + </servlet-mapping> +</web-app>
diff --git a/integration/src/test/testng/testng.xml b/integration/src/test/testng/testng.xml new file mode 100644 index 0000000..2f7c68f --- /dev/null +++ b/integration/src/test/testng/testng.xml
@@ -0,0 +1,523 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > + +<suite name="ldaptive" verbose="1" parallel="tests" thread-count="1"> + + <parameter name="ldapTestsIgnoreLock" value="${ldapTestsIgnoreLock}"/> + <parameter name="ldapTestHost" value="${ldapTestHost}"/> + <parameter name="ldapSslTestHost" value="${ldapSslTestHost}"/> + <parameter name="ldapBaseDn" value="${ldapBaseDn}"/> + <parameter name="ldapBindDn" value="${ldapBindDn}"/> + <parameter name="ldapBindCredential" value="${ldapBindCredential}"/> + + <!-- ldap test parameters --> + <parameter name="createEntry2" + value="/org/ldaptive/createLdapEntry-2.ldif"/> + <parameter name="createEntry3" + value="/org/ldaptive/createLdapEntry-3.ldif"/> + <parameter name="createEntry4" + value="/org/ldaptive/createLdapEntry-4.ldif"/> + <parameter name="createEntry5" + value="/org/ldaptive/createLdapEntry-5.ldif"/> + <parameter name="createEntry6" + value="/org/ldaptive/createLdapEntry-6.ldif"/> + <parameter name="createEntry7" + value="/org/ldaptive/createLdapEntry-7.ldif"/> + <parameter name="createEntry8" + value="/org/ldaptive/createLdapEntry-8.ldif"/> + <parameter name="createEntry9" + value="/org/ldaptive/createLdapEntry-9.ldif"/> + <parameter name="createEntry10" + value="/org/ldaptive/createLdapEntry-10.ldif"/> + <parameter name="createEntry11" + value="/org/ldaptive/createLdapEntry-11.ldif"/> + <parameter name="createEntry12" + value="/org/ldaptive/createLdapEntry-12.ldif"/> + <parameter name="createEntry13" + value="/org/ldaptive/createLdapEntry-13.ldif"/> + <parameter name="createEntry14" + value="/org/ldaptive/createLdapEntry-14.ldif"/> + <parameter name="createEntry15" + value="/org/ldaptive/createLdapEntry-15.ldif"/> + <parameter name="createEntry16" + value="/org/ldaptive/createLdapEntry-16.ldif"/> + <parameter name="createEntry17" + value="/org/ldaptive/createLdapEntry-17.ldif"/> + <parameter name="createEntry18" + value="/org/ldaptive/createLdapEntry-18.ldif"/> + <parameter name="createEntry19" + value="/org/ldaptive/createLdapEntry-19.ldif"/> + <parameter name="createEntry20" + value="/org/ldaptive/createLdapEntry-20.ldif"/> + <parameter name="createEntry21" + value="/org/ldaptive/createLdapEntry-21.ldif"/> + <parameter name="createEntry22" + value="/org/ldaptive/createLdapEntry-22.ldif"/> + <parameter name="createEntry23" + value="/org/ldaptive/createLdapEntry-23.ldif"/> + <parameter name="createEntry25" + value="/org/ldaptive/createLdapEntry-25.ldif"/> + <parameter name="createEntry26" + value="/org/ldaptive/createLdapEntry-26.ldif"/> + <parameter name="createEntry27" + value="/org/ldaptive/createLdapEntry-27.ldif"/> + <parameter name="createEntry28" + value="/org/ldaptive/createLdapEntry-28.ldif"/> + <parameter name="createEntry29" + value="/org/ldaptive/createLdapEntry-29.ldif"/> + <parameter name="createEntry30" + value="/org/ldaptive/createLdapEntry-30.ldif"/> + <parameter name="createEntry31" + value="/org/ldaptive/createLdapEntry-31.ldif"/> + <parameter name="createEntry32" + value="/org/ldaptive/createLdapEntry-32.ldif"/> + + <parameter name="createGroup2" + value="/org/ldaptive/createGroupEntry-2.ldif"/> + <parameter name="createGroup3" + value="/org/ldaptive/createGroupEntry-3.ldif"/> + <parameter name="createGroup4" + value="/org/ldaptive/createGroupEntry-4.ldif"/> + <parameter name="createGroup5" + value="/org/ldaptive/createGroupEntry-5.ldif"/> + <parameter name="createGroup6" + value="/org/ldaptive/createGroupEntry-6.ldif"/> + <parameter name="createGroup7" + value="/org/ldaptive/createGroupEntry-7.ldif"/> + <parameter name="createGroup8" + value="/org/ldaptive/createGroupEntry-8.ldif"/> + <parameter name="createGroup9" + value="/org/ldaptive/createGroupEntry-9.ldif"/> + + <parameter name="createSpecialCharsEntry" + value="/org/ldaptive/specialChars.ldif"/> + <parameter name="createSpecialCharsEntry2" + value="/org/ldaptive/specialChars-2.ldif"/> + <parameter name="createSpecialCharsEntry3" + value="/org/ldaptive/specialChars-3.ldif"/> + + <parameter name="multipleLdifResultsIn" + value="/org/ldaptive/multipleEntriesIn.ldif"/> + <parameter name="multipleLdifResultsOut" + value="/org/ldaptive/multipleEntriesOut.ldif"/> + <parameter name="ldifEntry" + value="/org/ldaptive/dfisher.ldif"/> + <parameter name="ldifSortedEntry" + value="/org/ldaptive/dfisher.sorted.ldif"/> + + <parameter name="dsmlv1Entry" + value="/org/ldaptive/dfisher.dsmlv1"/> + <parameter name="dsmlv1SortedEntry" + value="/org/ldaptive/dfisher.sorted.dsmlv1"/> + <parameter name="dsmlv2Entry" + value="/org/ldaptive/dfisher.dsmlv2"/> + <parameter name="dsmlv2SortedEntry" + value="/org/ldaptive/dfisher.sorted.dsmlv2"/> + + <parameter name="searchResults2" + value="/org/ldaptive/searchResults-2.ldif"/> + <parameter name="searchResults3" + value="/org/ldaptive/searchResults-3.ldif"/> + <parameter name="searchResults4" + value="/org/ldaptive/searchResults-4.ldif"/> + <parameter name="searchResults5" + value="/org/ldaptive/searchResults-5.ldif"/> + <parameter name="searchResults6" + value="/org/ldaptive/searchResults-6.ldif"/> + <parameter name="searchResults7" + value="/org/ldaptive/searchResults-7.ldif"/> + <parameter name="searchResults8" + value="/org/ldaptive/searchResults-8.ldif"/> + <parameter name="searchResults9" + value="/org/ldaptive/searchResults-9.ldif"/> + <parameter name="searchResults10" + value="/org/ldaptive/searchResults-10.ldif"/> + <parameter name="searchResults11" + value="/org/ldaptive/searchResults-11.ldif"/> + <parameter name="searchResults12" + value="/org/ldaptive/searchResults-12.ldif"/> + <parameter name="searchResults13" + value="/org/ldaptive/searchResults-13.ldif"/> + <parameter name="searchResults14" + value="/org/ldaptive/searchResults-14.ldif"/> + <parameter name="searchResults15" + value="/org/ldaptive/searchResults-15.ldif"/> + + <parameter name="searchDn" value="${ldapBaseDn}"/> + <parameter name="searchFilter" value="(uid={0})"/> + <parameter name="searchFilterParameters" value="2"/> + <parameter name="searchReturnAttrs" value="departmentNumber|givenName|sn"/> + <parameter name="searchResults" + value="/org/ldaptive/searchResults-2.ldif"/> + + <parameter name="recursiveSearchDn" value="${ldapBaseDn}"/> + <parameter name="recursiveSearchFilter" value="(uugid={0})"/> + <parameter name="recursiveSearchFilterParameters" value="group2"/> + <parameter name="recursiveSearchReturnAttrs" value="cn|contactPerson|creationDate|member|objectClass|uid|uugid"/> + <parameter name="recursiveHandlerResults" + value="/org/ldaptive/recursiveHandlerResults.ldif"/> + + <parameter name="recursiveSearch2Dn" value="${ldapBaseDn}"/> + <parameter name="recursiveSearch2Filter" value="(|(uugid=group1)(uugid=group2)(uugid=group3)(uugid=group4)(uugid=group5))"/> + <parameter name="recursiveSearch2ReturnAttrs" value="member"/> + <parameter name="recursiveHandlerResults2" + value="/org/ldaptive/recursiveHandlerResults-2.ldif"/> + + <parameter name="mergeSearchDn" value="${ldapBaseDn}"/> + <parameter name="mergeSearchFilter" value="(|(uugid=group3)(uugid=group4)(uugid=group5))"/> + <parameter name="mergeSearchReturnAttrs" value="cn|contactPerson|creationDate|member|objectClass|uid|uugid"/> + <parameter name="mergeSearchResults" + value="/org/ldaptive/mergeResults.ldif"/> + + <parameter name="mergeDuplicateSearchDn" value="${ldapBaseDn}"/> + <parameter name="mergeDuplicateSearchFilter" value="(|(uugid=group3)(uugid=group4)(uugid=group5))"/> + <parameter name="mergeDuplicateReturnAttrs" value="cn|contactPerson|creationDate|member|objectClass|uid|uugid"/> + <parameter name="mergeDuplicateSearchResults" + value="/org/ldaptive/mergeDuplicateResults.ldif"/> + + <parameter name="mergeAttributeSearchDn" value="${ldapBaseDn}"/> + <parameter name="mergeAttributeSearchFilter" value="(uid=2)"/> + <parameter name="mergeAttributeReturnAttrs" value="cn|departmentNumber|displayName|givenName|sn|uid"/> + <parameter name="mergeAttributeSearchResults" + value="/org/ldaptive/mergeAttributeResults.ldif"/> + + <parameter name="binarySearchDn" value="${ldapBaseDn}"/> + <parameter name="binarySearchFilter" value="(uid=2)"/> + <parameter name="binarySearchReturnAttr" value="jpegPhoto"/> + <parameter name="binarySearchResult" + value="/9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k="/> + + <parameter name="rangeSearchDn" value="${ldapBaseDn}"/> + <parameter name="rangeSearchFilter" value="(uugid=group550000)"/> + <parameter name="rangeSearchReturnAttrs" value="cn|member|uid|uugid"/> + <parameter name="rangeHandlerResults" + value="/org/ldaptive/rangeHandlerResults.ldif"/> + + <parameter name="miscADControlsHost" value="${ldapTestHost}"/> + <parameter name="miscADControlsDn" value="${ldapBaseDn}"/> + <parameter name="miscADControlsFilter" value="(CN=Test Admin)"/> + + <parameter name="statsSearchDn" value="${ldapBaseDn}"/> + <parameter name="statsSearchFilter" value="(uid=2)"/> + + <parameter name="specialCharSearchDn" value="${ldapBaseDn}"/> + <parameter name="specialCharSearchFilter" value="(&(uid=17893)(sn={0}))"/> + <parameter name="specialCharSearchFilterParameters" value="(Us\er)*"/> + <parameter name="specialCharBinarySearchFilter" value="(&(uid=17893)(givenName={0}))"/> + <parameter name="specialCharBinarySearchFilterParameters" value="VGVzdA=="/> + <parameter name="specialCharReturnAttrs" value="cn|givenName|sn|uid"/> + <parameter name="specialCharSearchResults" + value="/org/ldaptive/specialCharsResults.ldif"/> + + <parameter name="rewriteSearchDn" value="dc=blah"/> + <parameter name="rewriteSearchFilter" value="(uid=17893)"/> + <parameter name="rewriteSearchResults" + value="/org/ldaptive/specialChars.ldif"/> + + <parameter name="searchExceededDn" value="${ldapBaseDn}"/> + <parameter name="searchExceededFilter" value="(|(uugid=group2)(uugid=group3)(uugid=group4))"/> + <parameter name="searchExceededResultsSize" value="3"/> + + <parameter name="searchReferralDn" value="${ldapBaseDn}"/> + <parameter name="searchReferralFilter" value="(objectClass=*)"/> + + <parameter name="searchReferenceDn" value="${ldapBaseDn}"/> + <parameter name="searchReferenceFilter" value="(objectClass=*)"/> + + <parameter name="searchActiveDirectoryDn" value="${ldapBaseDn}"/> + <parameter name="searchActiveDirectoryFilter" value="(objectClass=*)"/> + + <parameter name="searchRetryDn" value="ou=dne,${ldapBaseDn}"/> + <parameter name="searchRetryResultCode" value="NO_SUCH_OBJECT"/> + + <parameter name="getAttributesDn" value="cn=John Adams,${ldapBaseDn}"/> + <parameter name="getAttributesReturnAttrs" value="departmentNumber|givenName|sn"/> + <parameter name="getAttributesResults" + value="departmentNumber=0822|givenName=John|sn=Adams"/> + + <parameter name="getAttributesBase64Dn" value="cn=John Adams,${ldapBaseDn}"/> + <parameter name="getAttributesBase64ReturnAttrs" value="sn|jpegPhoto"/> + <parameter name="getAttributesBase64Results" + value="sn=Adams|jpegPhoto=/9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k="/> + + <parameter name="pagedSearchDn" value="${ldapBaseDn}"/> + <parameter name="pagedSearchFilter" value="(|(uugid=group2)(uugid=group3)(uugid=group4)(uugid=group5))"/> + <parameter name="pagedSearchReturnAttrs" value="cn|contactPerson|creationDate|objectClass|member|uid|uugid"/> + <parameter name="pagedSearchResults" value="/org/ldaptive/pagedResults.ldif"/> + + <parameter name="virtualListViewSearchDn" value="${ldapBaseDn}"/> + <parameter name="virtualListViewSearchFilter" value="(|(uugid=group2)(uugid=group3)(uugid=group4)(uugid=group5))"/> + <parameter name="virtualListViewSearchReturnAttrs" value="cn|contactPerson|creationDate|objectClass|member|uid|uugid"/> + <parameter name="virtualListViewSearchResults" value="/org/ldaptive/virtualListViewResults.ldif"/> + + <parameter name="sortSearchDn" value="${ldapBaseDn}"/> + <parameter name="sortSearchFilter" value="(|(uugid=group2)(uugid=group3)(uugid=group4)(uugid=group5))"/> + + <parameter name="proxyAuthzFrom" value="${ldapBindDn}"/> + <parameter name="proxyAuthzTo" value="CN=John Adams,${ldapBaseDn}"/> + <parameter name="proxyAuthzSearchDn" value="${ldapBaseDn}"/> + <parameter name="proxyAuthzSearchFilter" value="(CN=John Adams)"/> + + <parameter name="searchAsyncDn" value="${ldapBaseDn}"/> + <parameter name="searchAsyncFilter" value="(uid=17)"/> + <parameter name="searchAsyncReturnAttrs" value="departmentNumber|givenName|sn"/> + <parameter name="searchAsyncResults" value="/org/ldaptive/searchResults-17.ldif"/> + + <parameter name="syncReplSearchDn" value="cn=Ulysses Grant,${ldapBaseDn}"/> + <parameter name="syncReplSearchReturnAttrs" value="cn|employeeType|mail|objectClass|sn|uid"/> + <parameter name="syncReplSearchResults" value="/org/ldaptive/syncReplResults.ldif"/> + + <parameter name="persistentSearchDn" value="cn=Herbert Hoover,${ldapBaseDn}"/> + <parameter name="persistentSearchReturnAttrs" value="cn|mail|objectClass|sn|uid"/> + <parameter name="persistentSearchResults" value="/org/ldaptive/persistentSearchResults.ldif"/> + + <parameter name="vlvSearchDn" value="${ldapBaseDn}"/> + <parameter name="vlvSearchFilter" value="(|(uid=19)(uid=20)(uid=21))"/> + + <parameter name="prSearchDn" value="${ldapBaseDn}"/> + <parameter name="prSearchFilter" value="(|(uid=22)(uid=23)(uid=25))"/> + + <parameter name="dsSearchDn" value="${ldapBaseDn}"/> + <parameter name="dsSearchFilter" value="(|(uid=27)(uid=28)(uid=29))"/> + + <parameter name="getSchemaDn" value="${ldapBaseDn}"/> + <parameter name="getSchemaResults" + value="/org/ldaptive/getSchemaResults.ldif"/> + + <parameter name="ncSearchDn" value="${ldapBindDn}"/> + + <parameter name="bindDn" value="cn=Franklin Roosevelt,${ldapBaseDn}"/> + <parameter name="bindPasswd" value="password32"/> + + <parameter name="compareDn" value="cn=Thomas Jefferson,${ldapBaseDn}"/> + <parameter name="compareAttrName" value="departmentNumber"/> + <parameter name="compareAttrValue" value="0823"/> + + <parameter name="compareReferralDn" value="${ldapBaseDn}"/> + <parameter name="compareReferralAttrName" value="objectClass"/> + <parameter name="compareReferralAttrValue" value="organizationalUnit"/> + + <parameter name="addAttributeDn" value="cn=James Madison,${ldapBaseDn}"/> + <parameter name="addAttributeAttribute" + value="title=Test User"/> + + <parameter name="addAttributesDn" value="cn=James Madison,${ldapBaseDn}"/> + <parameter name="addAttributesAttributes" + value="telephoneNumber=15408675309|homePhone=15555555555"/> + + <parameter name="replaceAttributeDn" value="cn=James Madison,${ldapBaseDn}"/> + <parameter name="replaceAttributeAttribute" + value="title=Best Test User"/> + + <parameter name="replaceAttributesDn" value="cn=James Madison,${ldapBaseDn}"/> + <parameter name="replaceAttributesAttributes" + value="telephoneNumber=12223334444|homePhone=155566677777"/> + + <parameter name="removeAttributeDn" value="cn=James Madison,${ldapBaseDn}"/> + <parameter name="removeAttributeAttribute" + value="title=Best Test User"/> + + <parameter name="removeAttributesDn" value="cn=James Madison,${ldapBaseDn}"/> + <parameter name="removeAttributesAttributes" + value="telephoneNumber=12223334444|homePhone=155566677777"/> + + <parameter name="modifyOldDn" value="cn=James Monroe,${ldapBaseDn}"/> + <parameter name="modifyNewDn" value="cn=James Spence Monroe,${ldapBaseDn}"/> + + <parameter name="digestMd5SearchDn" value="${ldapBaseDn}"/> + <parameter name="digestMd5SearchFilter" value="(uid={0})"/> + <parameter name="digestMd5SearchFilterParameters" value="2"/> + <parameter name="digestMd5SearchReturnAttrs" value="departmentNumber|givenName|sn"/> + <parameter name="digestMd5SearchResults" + value="/org/ldaptive/searchResults-2.ldif"/> + + <parameter name="cramMd5SearchDn" value="${ldapBaseDn}"/> + <parameter name="cramMd5SearchFilter" value="(uid={0})"/> + <parameter name="cramMd5SearchFilterParameters" value="test3"/> + <parameter name="cramMd5SearchReturnAttrs" value="cn|sn|uid"/> + <parameter name="cramMd5SearchResults" + value="/org/ldaptive/test3.ldif"/> + + <parameter name="saslExternalSearchDn" value="${ldapBaseDn}"/> + <parameter name="saslExternalSearchFilter" value="(uid={0})"/> + <parameter name="saslExternalSearchFilterParameters" value="2"/> + <parameter name="saslExternalSearchReturnAttrs" value="departmentNumber|givenName|sn"/> + <parameter name="saslExternalSearchResults" + value="/org/ldaptive/searchResults-2.ldif"/> + + <parameter name="krb5Realm" value="VT.EDU"/> + <parameter name="krb5Kdc" value="${ldapTestHost}"/> + <parameter name="gssApiSearchDn" value="${ldapBaseDn}"/> + <parameter name="gssApiSearchFilter" value="(uid={0})"/> + <parameter name="gssApiSearchFilterParameters" value="2"/> + <parameter name="gssApiSearchReturnAttrs" value="departmentNumber|givenName|sn"/> + <parameter name="gssApiSearchResults" + value="/org/ldaptive/searchResults-2.ldif"/> + + <parameter name="loadPropertiesUrl" value="${ldapTestHost}"/> + <parameter name="loadPropertiesBaseDn" value="${ldapBaseDn}"/> + + <parameter name="getDnCn" value="John Quincy Adams"/> + <parameter name="getDnUser" value="jqadams@ldaptive.org"/> + <parameter name="getDnDuplicateFilter" value="(cn=*)"/> + + <parameter name="authenticateDn" value="cn=John Quincy Adams,${ldapBaseDn}"/> + <parameter name="authenticateDnCredential" value="password6"/> + <parameter name="authenticateDnFilter" value="(departmentNumber={0})"/> + <parameter name="authenticateDnFilterParameters" value="0826"/> + <parameter name="authenticateDnReturnAttrs" value="departmentNumber|givenName|sn"/> + <parameter name="authenticateDnResults" + value="/org/ldaptive/searchResults-6.ldif"/> + + <parameter name="authenticateUser" value="jqadams@ldaptive.org"/> + <parameter name="authenticateCredential" value="password6"/> + <parameter name="authenticateFilter" value="(departmentNumber=0826)"/> + <parameter name="authenticateReturnAttrs" value="departmentNumber|givenName|sn"/> + <parameter name="authenticateResults" + value="/org/ldaptive/searchResults-6.ldif"/> + + <parameter name="authenticateSpecialCharsUser2" value="17894"/> + <parameter name="authenticateSpecialCharsCredential2" value="password17894"/> + <parameter name="authenticateSpecialCharsUser3" value="17895"/> + <parameter name="authenticateSpecialCharsCredential3" value="password17895"/> + + <parameter name="digestMd5User" value="test3@vt.edu"/> + <parameter name="digestMd5Credential" value="password"/> + + <parameter name="cramMd5User" value="test3"/> + <parameter name="cramMd5Credential" value="password"/> + + <parameter name="passwordModifyDn" value="cn=Abraham Lincoln,${ldapBaseDn}"/> + <parameter name="passwordModifyOldPass" value="password16"/> + <parameter name="passwordModifyNewPass" value="emancipator"/> + + <parameter name="cancelDn" value="${ldapBaseDn}"/> + + <parameter name="toSearchResultsDn" value="${ldapBaseDn}"/> + <parameter name="toSearchResultsFilter" value="(uid=7)"/> + <parameter name="toSearchResultsAttrs" value="departmentNumber|givenName|sn"/> + <parameter name="toSearchResultsResults" + value="/org/ldaptive/searchResults-7.ldif"/> + + <parameter name="cliAddArgs" + value="-ldapUrl|${ldapTestHost}|-bindDn|${ldapBindDn}|-bindCredential|${ldapBindCredential}|-file|target/test-classes/org/ldaptive/createLdapEntry-8.ldif"/> + <parameter name="cliSearchArgs" + value="-ldapUrl|${ldapTestHost}|-baseDn|${ldapBaseDn}|-bindDn|${ldapBindDn}|-bindCredential|${ldapBindCredential}|-searchFilter|(mail=mvburen@ldaptive.org)|-returnAttributes|departmentNumber,givenName,jpegPhoto,sn|-binaryAttributes|jpegPhoto"/> + <parameter name="cliSearchResults" + value="/org/ldaptive/searchResults-8.ldif"/> + <parameter name="cliCompareArgs" + value="-ldapUrl|${ldapTestHost}|-bindDn|${ldapBindDn}|-bindCredential|${ldapBindCredential}|-dn|cn=Martin Van Buren,${ldapBaseDn}|-attribute|sn:buren"/> + <parameter name="cliDeleteArgs" + value="-ldapUrl|${ldapTestHost}|-bindDn|${ldapBindDn}|-bindCredential|${ldapBindCredential}|-dn|cn=Martin Van Buren,${ldapBaseDn}"/> + + <parameter name="cliAuthTLSArgs" + value="-ldapUrl|${ldapTestHost}|-baseDn|${ldapBaseDn}|-useStartTLS|true|-bindDn|${ldapBindDn}|-bindCredential|${ldapBindCredential}|-userFilter|(mail={user})|-user|whharrison@ldaptive.org|-credential|password9|-returnAttributes|departmentNumber,givenName,sn"/> + <parameter name="cliAuthSSLArgs" + value="-ldapUrl|${ldapSslTestHost}|-baseDn|${ldapBaseDn}|-useSSL|true|-bindDn|${ldapBindDn}|-bindCredential|${ldapBindCredential}|-userFilter|(mail={user})|-user|whharrison@ldaptive.org|-credential|password9|-returnAttributes|departmentNumber,givenName,sn"/> + <parameter name="cliAuthResults" + value="/org/ldaptive/searchResults-9.ldif"/> + + <parameter name="jaasDn" value="cn=John Tyler,${ldapBaseDn}"/> + <parameter name="jaasUser" value="jtyler@ldaptive.org"/> + <parameter name="jaasUserRole" value="0830"/> + <parameter name="jaasUserRoleDefault" value="0830|test-role1|test-role2"/> + <parameter name="jaasRole" value="John Tyler|John|Tyler"/> + <parameter name="jaasRoleCombined" value="0830|John Tyler|John|Tyler"/> + <parameter name="jaasRoleCombinedRecursive" value="0830|group6|group7|group8|group9"/> + <parameter name="jaasCredential" value="password10"/> + + <parameter name="webXml" value="target/test-classes/web.xml"/> + + <parameter name="ldifSearchServletQuery" value="(mail=jkpolk@ldaptive.org)"/> + <parameter name="ldifSearchServletAttrs" value="departmentNumber|givenName|sn|jpegPhoto"/> + <parameter name="ldifSearchServletLdif" value="/org/ldaptive/searchResults-11.ldif"/> + + <parameter name="dsmlSearchServletQuery" value="(uid=11)"/> + <parameter name="dsmlSearchServletAttrs" value="departmentNumber|givenName|sn|jpegPhoto"/> + <parameter name="dsmlSearchServletLdif" value="/org/ldaptive/searchResults-11.ldif"/> + + <parameter name="jsonSearchServletQuery" value="(uid=11)"/> + <parameter name="jsonSearchServletAttrs" value="departmentNumber|givenName|sn|jpegPhoto"/> + <parameter name="jsonSearchServletLdif" value="/org/ldaptive/searchResults-11.ldif"/> + + <parameter name="attributeServletQuery" value="(&(givenName=zachary)(sn=taylor))"/> + <parameter name="attributeServletAttr" value="jpegPhoto"/> + <parameter name="attributeServletValue" value="/9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCAANABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAiEAEAAgIABQUAAAAAAAAAAAABAAMCEQQSMUFxISIjMnP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A71fHZZW+ge48MWqvG0bLMRcnZvsdpnGH0R0ryvhlAAAdCBPRTXkZ7wHWaEI/D9LP0yhA/9k="/> + + <parameter name="ldifTemplateSearchQuery" value="jkpolk"/> + <parameter name="ldifTemplateSearchAttrs" value="departmentNumber|givenName|sn|jpegPhoto"/> + <parameter name="ldifTemplateSearchLdif" value="/org/ldaptive/searchResults-11.ldif"/> + + <parameter name="dsmlTemplateSearchQuery" value="james polk"/> + <parameter name="dsmlTemplateSearchAttrs" value="departmentNumber|givenName|sn|jpegPhoto"/> + <parameter name="dsmlTemplateSearchLdif" value="/org/ldaptive/searchResults-11.ldif"/> + + <parameter name="jsonTemplateSearchQuery" value="polk"/> + <parameter name="jsonTemplateSearchAttrs" value="departmentNumber|givenName|sn|jpegPhoto"/> + <parameter name="jsonTemplateSearchLdif" value="/org/ldaptive/searchResults-11.ldif"/> + + <parameter name="dsmlSearchDn" value="${ldapBaseDn}"/> + <parameter name="dsmlSearchFilter" value="(uid=13)"/> + + <parameter name="ldifSearchDn" value="${ldapBaseDn}"/> + <parameter name="ldifSearchFilter" value="(uid=14)"/> + + <parameter name="sleepTime" value="15000"/> + + <listeners> + <listener class-name="org.ldaptive.SkipTestInvokedMethodListener" /> + </listeners> + + <test name="tests"> + <groups> + <define name="core"> + <include name="bean" /> + <include name="bind" /> + <include name="props" /> + <include name="search" /> + <include name="search-with-retry" /> + <include name="compare" /> + <include name="modify" /> + <include name="modifyDn" /> + <include name="merge" /> + <include name="extended" /> + <include name="async" /> + <include name="control-util" /> + <include name="spring" /> + <include name="auth" /> + <include name="jaas" /> + <include name="servlet" /> + <include name="dsml" /> + <include name="ldif" /> + <include name="ssl" /> + <include name="cli" /> + <include name="templates" /> + <include name="beans-generate" /> + <include name="beans-mapper" /> + <include name="beans-manager" /> + <include name="beans-spring" /> + <include name="conn" /> + </define> + <define name="core-sysprops"> + <include name="ssl-hostname" /> + <include name="authcli" /> + </define> + <define name="load"> + <include name="authload" /> + </define> + <define name="pool"> + <include name="validator" /> + <include name="softlimitpool" /> + <include name="blockingpool" /> + <include name="blockingtimeoutpool" /> + <include name="connstrategypool" /> + </define> + <run> + <include name="${ldapTestGroup}"/> + </run> + </groups> + <packages> + <package name="org.ldaptive.*" /> + </packages> + </test> +</suite>
diff --git a/jldap-provider/pom.xml b/jldap-provider/pom.xml new file mode 100644 index 0000000..825ce3a --- /dev/null +++ b/jldap-provider/pom.xml
@@ -0,0 +1,27 @@ +<?xml version='1.0' encoding='UTF-8'?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>ldaptive-jldap</artifactId> + <packaging>jar</packaging> + <name>LDAPTIVE JLDAP PROVIDER</name> + <description>Ldaptive jldap provider</description> + <parent> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-parent</artifactId> + <version>1.2.3</version> + </parent> + + <dependencies> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive</artifactId> + </dependency> + <dependency> + <groupId>com.novell.ldap</groupId> + <artifactId>jldap</artifactId> + </dependency> + </dependencies> + +</project>
diff --git a/jldap-provider/src/main/java/org/ldaptive/provider/jldap/AbstractJLdapConnectionFactory.java b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/AbstractJLdapConnectionFactory.java new file mode 100644 index 0000000..6847dad --- /dev/null +++ b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/AbstractJLdapConnectionFactory.java
@@ -0,0 +1,125 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jldap; + +import java.time.Duration; +import com.novell.ldap.LDAPConnection; +import com.novell.ldap.LDAPConstraints; +import com.novell.ldap.LDAPException; +import org.ldaptive.ConnectionStrategy; +import org.ldaptive.LdapException; +import org.ldaptive.LdapURL; +import org.ldaptive.provider.AbstractProviderConnectionFactory; +import org.ldaptive.provider.ConnectionException; + +/** + * Base class for JLDAP connection factory implementations. + * + * @param <T> type of jldap connection + * + * @author Middleware Services + */ +public abstract class AbstractJLdapConnectionFactory<T extends JLdapConnection> + extends AbstractProviderConnectionFactory<JLdapProviderConfig> +{ + + /** JLdap connection constraints. */ + private final LDAPConstraints ldapConstraints; + + /** Amount of time in milliseconds that operations will wait. */ + private final Duration socketTimeOut; + + + /** + * Creates a new abstract jldap connection factory. + * + * @param url of the ldap to connect to + * @param strategy connection strategy + * @param config provider configuration + * @param constraints connection constraints + * @param timeOut time in milliseconds that operations will wait + */ + public AbstractJLdapConnectionFactory( + final String url, + final ConnectionStrategy strategy, + final JLdapProviderConfig config, + final LDAPConstraints constraints, + final Duration timeOut) + { + super(url, strategy, config); + ldapConstraints = constraints; + socketTimeOut = timeOut; + } + + + @Override + protected T createInternal(final String url) + throws LdapException + { + final LdapURL ldapUrl = new LdapURL(url); + LDAPConnection conn = null; + T jldapConn = null; + boolean closeConn = false; + try { + conn = createLDAPConnection(); + if (ldapConstraints != null) { + conn.setConstraints(ldapConstraints); + } + if (socketTimeOut != null) { + conn.setSocketTimeOut((int) socketTimeOut.toMillis()); + } + conn.connect(ldapUrl.getLastEntry().getHostnameWithPort(), LDAPConnection.DEFAULT_PORT); + initializeConnection(conn); + jldapConn = createJLdapConnection(conn, getProviderConfig()); + } catch (LDAPException e) { + closeConn = true; + throw new ConnectionException(e); + } catch (RuntimeException e) { + closeConn = true; + throw e; + } finally { + if (closeConn) { + try { + if (conn != null) { + conn.disconnect(); + } + } catch (LDAPException e) { + logger.debug("Problem tearing down connection", e); + } + } + } + return jldapConn; + } + + + /** + * Creates an ldap connection for use with this connection factory. + * + * @return ldap connection + * + * @throws LDAPException if an error occurs creating the connection + */ + protected abstract LDAPConnection createLDAPConnection() + throws LDAPException; + + + /** + * Initialize the supplied connection after a connection has been established. + * + * @param conn to initialize + * + * @throws LDAPException if an error occurs initializing the connection + */ + protected void initializeConnection(final LDAPConnection conn) + throws LDAPException {} + + + /** + * Creates a jldap connection of the appropriate type for this connection factory. + * + * @param conn to create jldap connection with + * @param config provider configuration + * + * @return jldap connection + */ + protected abstract T createJLdapConnection(final LDAPConnection conn, final JLdapProviderConfig config); +}
diff --git a/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapConnection.java b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapConnection.java new file mode 100644 index 0000000..dce5953 --- /dev/null +++ b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapConnection.java
@@ -0,0 +1,1145 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jldap; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import com.novell.ldap.LDAPConnection; +import com.novell.ldap.LDAPConstraints; +import com.novell.ldap.LDAPControl; +import com.novell.ldap.LDAPEntry; +import com.novell.ldap.LDAPException; +import com.novell.ldap.LDAPExtendedOperation; +import com.novell.ldap.LDAPExtendedResponse; +import com.novell.ldap.LDAPIntermediateResponse; +import com.novell.ldap.LDAPMessage; +import com.novell.ldap.LDAPMessageQueue; +import com.novell.ldap.LDAPResponse; +import com.novell.ldap.LDAPResponseQueue; +import com.novell.ldap.LDAPSearchConstraints; +import com.novell.ldap.LDAPSearchQueue; +import com.novell.ldap.LDAPSearchResult; +import com.novell.ldap.LDAPSearchResultReference; +import com.novell.ldap.LDAPUnsolicitedNotificationListener; +import com.novell.security.sasl.RealmCallback; +import com.novell.security.sasl.RealmChoiceCallback; +import org.ldaptive.AddRequest; +import org.ldaptive.BindRequest; +import org.ldaptive.CompareRequest; +import org.ldaptive.DeleteRequest; +import org.ldaptive.DerefAliases; +import org.ldaptive.LdapException; +import org.ldaptive.ModifyDnRequest; +import org.ldaptive.ModifyRequest; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchReference; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchScope; +import org.ldaptive.async.AsyncRequest; +import org.ldaptive.control.RequestControl; +import org.ldaptive.control.ResponseControl; +import org.ldaptive.extended.ExtendedRequest; +import org.ldaptive.extended.ExtendedResponse; +import org.ldaptive.extended.ExtendedResponseFactory; +import org.ldaptive.extended.UnsolicitedNotificationListener; +import org.ldaptive.intermediate.IntermediateResponseFactory; +import org.ldaptive.provider.ProviderConnection; +import org.ldaptive.provider.ProviderUtils; +import org.ldaptive.provider.SearchItem; +import org.ldaptive.provider.SearchIterator; +import org.ldaptive.provider.SearchListener; +import org.ldaptive.sasl.SaslConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * JLDAP provider implementation of ldap operations. + * + * @author Middleware Services + */ +public class JLdapConnection implements ProviderConnection +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Ldap connection. */ + private LDAPConnection connection; + + /** Provider configuration. */ + private final JLdapProviderConfig config; + + /** Receives unsolicited notifications. */ + private final AggregateUnsolicitedNotificationListener notificationListener = + new AggregateUnsolicitedNotificationListener(); + + + /** + * Creates a new jldap connection. + * + * @param conn ldap connection + * @param pc provider configuration + */ + public JLdapConnection(final LDAPConnection conn, final JLdapProviderConfig pc) + { + connection = conn; + config = pc; + connection.addUnsolicitedNotificationListener(notificationListener); + } + + + /** + * Returns the underlying ldap connection. + * + * @return ldap connection + */ + public LDAPConnection getLDAPConnection() + { + return connection; + } + + + @Override + public void close(final RequestControl[] controls) + throws LdapException + { + try { + if (connection != null) { + connection.disconnect(getLDAPConstraints(controls)); + } + } catch (LDAPException e) { + throw new LdapException(e, ResultCode.valueOf(e.getResultCode())); + } finally { + connection = null; + } + } + + + @Override + public Response<Void> bind(final BindRequest request) + throws LdapException + { + Response<Void> response; + if (request.getSaslConfig() != null) { + response = saslBind(request); + } else if (request.getDn() == null && request.getCredential() == null) { + response = anonymousBind(request); + } else { + response = simpleBind(request); + } + return response; + } + + + /** + * Performs an anonymous bind. + * + * @param request to bind with + * + * @return bind response + * + * @throws LdapException if an error occurs + */ + protected Response<Void> anonymousBind(final BindRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final LDAPResponseQueue queue = connection.bind( + LDAPConnection.LDAP_V3, + null, + null, + null, + getLDAPConstraints(request)); + final LDAPResponse lr = (LDAPResponse) queue.getResponse(); + response = createResponse(request, null, lr); + } catch (LDAPException e) { + processLDAPException(e); + } + return response; + } + + + /** + * Performs a simple bind. + * + * @param request to bind with + * + * @return bind response + * + * @throws LdapException if an error occurs + */ + protected Response<Void> simpleBind(final BindRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final LDAPResponseQueue queue = connection.bind( + LDAPConnection.LDAP_V3, + request.getDn(), + request.getCredential().getBytes(), + null, + getLDAPConstraints(request)); + final LDAPResponse lr = (LDAPResponse) queue.getResponse(); + response = createResponse(request, null, lr); + } catch (LDAPException e) { + processLDAPException(e); + } + return response; + } + + + /** + * Performs a sasl bind. + * + * @param request to bind with + * + * @return bind response + * + * @throws LdapException if an error occurs + */ + protected Response<Void> saslBind(final BindRequest request) + throws LdapException + { + try { + final SaslConfig sc = request.getSaslConfig(); + switch (sc.getMechanism()) { + + case EXTERNAL: + throw new UnsupportedOperationException("SASL External not supported"); + /* current implementation appears to be broken + * see http://tinyurl.com/7ojdzlz + * connection.bind( + * (String) null, + * sc.getAuthorizationId(), + * new String[] {"EXTERNAL"}, + * null, + * (Object) null); + * break; + */ + + case DIGEST_MD5: + connection.bind( + null, + request.getDn(), + new String[] {"DIGEST-MD5"}, + null, + new SaslCallbackHandler(null, request.getCredential() != null ? request.getCredential().getString() : null)); + break; + + case CRAM_MD5: + throw new UnsupportedOperationException("CRAM-MD5 not supported"); + + case GSSAPI: + throw new UnsupportedOperationException("GSSAPI not supported"); + + default: + throw new IllegalArgumentException("Unknown SASL authentication mechanism: " + sc.getMechanism()); + } + } catch (LDAPException e) { + processLDAPException(e); + } + return new Response<>(null, ResultCode.SUCCESS); + } + + + @Override + public Response<Void> add(final AddRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final JLdapUtils bu = new JLdapUtils(); + final LDAPResponseQueue queue = connection.add( + new LDAPEntry(request.getDn(), bu.fromLdapAttributes(request.getLdapAttributes())), + null, + getLDAPConstraints(request)); + final LDAPResponse lr = (LDAPResponse) queue.getResponse(); + response = createResponse(request, null, lr); + } catch (LDAPException e) { + processLDAPException(e); + } + return response; + } + + + @Override + public Response<Boolean> compare(final CompareRequest request) + throws LdapException + { + Response<Boolean> response = null; + try { + final JLdapUtils bu = new JLdapUtils(); + final LDAPResponseQueue queue = connection.compare( + request.getDn(), + bu.fromLdapAttribute(request.getAttribute()), + null, + getLDAPConstraints(request)); + final LDAPResponse lr = (LDAPResponse) queue.getResponse(); + response = createResponse(request, lr.getResultCode() == ResultCode.COMPARE_TRUE.value(), lr); + } catch (LDAPException e) { + processLDAPException(e); + } + return response; + } + + + @Override + public Response<Void> delete(final DeleteRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final LDAPResponseQueue queue = connection.delete(request.getDn(), null, getLDAPConstraints(request)); + final LDAPResponse lr = (LDAPResponse) queue.getResponse(); + response = createResponse(request, null, lr); + } catch (LDAPException e) { + processLDAPException(e); + } + return response; + } + + + @Override + public Response<Void> modify(final ModifyRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final JLdapUtils bu = new JLdapUtils(); + final LDAPResponseQueue queue = connection.modify( + request.getDn(), + bu.fromAttributeModification(request.getAttributeModifications()), + null, + getLDAPConstraints(request)); + final LDAPResponse lr = (LDAPResponse) queue.getResponse(); + response = createResponse(request, null, lr); + } catch (LDAPException e) { + processLDAPException(e); + } + return response; + } + + + @Override + public Response<Void> modifyDn(final ModifyDnRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final String[] dn = request.getNewDn().split(",", 2); + final LDAPResponseQueue queue = connection.rename( + request.getDn(), + dn[0], + dn[1], + request.getDeleteOldRDn(), + null, + getLDAPConstraints(request)); + final LDAPResponse lr = (LDAPResponse) queue.getResponse(); + response = createResponse(request, null, lr); + } catch (LDAPException e) { + processLDAPException(e); + } + return response; + } + + + @Override + public SearchIterator search(final SearchRequest request) + throws LdapException + { + final JLdapSearchIterator i = new JLdapSearchIterator(request); + i.initialize(); + return i; + } + + + @Override + public void searchAsync(final SearchRequest request, final SearchListener listener) + throws LdapException + { + final JLdapAsyncSearchListener l = new JLdapAsyncSearchListener(request, listener); + l.initialize(); + } + + + @Override + public void abandon(final int messageId, final RequestControl[] controls) + throws LdapException + { + try { + connection.abandon(messageId, getLDAPConstraints(controls)); + } catch (LDAPException e) { + processLDAPException(e); + } + } + + + @Override + public Response<?> extendedOperation(final ExtendedRequest request) + throws LdapException + { + Response<?> response = null; + try { + final LDAPExtendedResponse ldapExtRes = connection.extendedOperation( + new LDAPExtendedOperation(request.getOID(), request.encode()), + getLDAPConstraints(request)); + final ExtendedResponse<?> extRes = ExtendedResponseFactory.createExtendedResponse( + request.getOID(), + ldapExtRes.getID(), + ldapExtRes.getValue()); + response = createResponse(request, extRes.getValue(), ldapExtRes); + } catch (LDAPException e) { + processLDAPException(e); + } + return response; + } + + + @Override + public void addUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + notificationListener.addUnsolicitedNotificationListener(listener); + } + + + @Override + public void removeUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + notificationListener.removeUnsolicitedNotificationListener(listener); + } + + + /** + * Returns an ldap constraints object configured with the supplied request. + * + * @param request request containing configuration to create constraints + * + * @return ldap constraints + */ + protected LDAPConstraints getLDAPConstraints(final Request request) + { + LDAPConstraints constraints = connection.getConstraints(); + if (constraints == null) { + constraints = new LDAPConstraints(); + } + if (request.getControls() != null) { + constraints.setControls(config.getControlProcessor().processRequestControls(request.getControls())); + } + return constraints; + } + + + /** + * Returns an ldap constraints object configured with the supplied controls. + * + * @param controls to sets in the constraints + * + * @return ldap constraints + */ + protected LDAPConstraints getLDAPConstraints(final RequestControl[] controls) + { + LDAPConstraints constraints = connection.getConstraints(); + if (constraints == null) { + constraints = new LDAPConstraints(); + } + if (controls != null) { + constraints.setControls(config.getControlProcessor().processRequestControls(controls)); + } + return constraints; + } + + + /** + * Determines if the supplied response should result in an operation retry. + * + * @param request that produced the exception + * @param ldapResponse provider response + * + * @throws LdapException wrapping the ldap exception + */ + protected void throwOperationException(final Request request, final LDAPResponse ldapResponse) + throws LdapException + { + ProviderUtils.throwOperationException( + config.getOperationExceptionResultCodes(), + String.format("Ldap returned result code: %s", ldapResponse.getResultCode()), + ldapResponse.getResultCode(), + ldapResponse.getMatchedDN(), + config.getControlProcessor().processResponseControls(ldapResponse.getControls()), + ldapResponse.getReferrals(), + false); + } + + + /** + * Creates an operation response with the supplied response data. + * + * @param <T> type of response + * @param request containing controls + * @param result of the operation + * @param ldapResponse provider response + * + * @return operation response + */ + protected <T> Response<T> createResponse(final Request request, final T result, final LDAPResponse ldapResponse) + { + return + new Response<>( + result, + ResultCode.valueOf(ldapResponse.getResultCode()), + ldapResponse.getErrorMessage(), + ldapResponse.getMatchedDN(), + config.getControlProcessor().processResponseControls(ldapResponse.getControls()), + ldapResponse.getReferrals(), + ldapResponse.getMessageID()); + } + + + /** + * Determines if the supplied ldap exception should result in an operation retry. + * + * @param e that was produced + * + * @throws LdapException wrapping the ldap exception + */ + protected void processLDAPException(final LDAPException e) + throws LdapException + { + ProviderUtils.throwOperationException( + config.getOperationExceptionResultCodes(), + e, + e.getResultCode(), + e.getMatchedDN(), + null, + null, + true); + } + + + /** Callback handler used by SASL mechanisms. */ + private static class SaslCallbackHandler implements CallbackHandler + { + + /** user name. */ + private final String user; + + /** password. */ + private final char[] pass; + + + /** + * Creates a new bind callback handler. + * + * @param u username to bind with + * @param p password to bind with + */ + SaslCallbackHandler(final String u, final String p) + { + user = u; + if (p != null) { + pass = p.toCharArray(); + } else { + pass = null; + } + } + + + @Override + public void handle(final Callback[] callbacks) + throws IOException, UnsupportedCallbackException + { + for (Callback cb : callbacks) { + if (cb instanceof NameCallback) { + // if user is null, the authzId will be used as it's the default name + ((NameCallback) cb).setName(user != null ? user : ((NameCallback) cb).getDefaultName()); + } else if (cb instanceof PasswordCallback) { + ((PasswordCallback) cb).setPassword(pass); + } else if (cb instanceof RealmCallback) { + ((RealmCallback) cb).setText(((RealmCallback) cb).getDefaultText()); + } else if (cb instanceof RealmChoiceCallback) { + ((RealmChoiceCallback) cb).setSelectedIndex(0); + } + } + } + } + + + /** Search iterator for JLdap search results. */ + protected class JLdapSearchIterator extends AbstractJLdapSearch implements SearchIterator + { + + /** Response data. */ + private Response<Void> response; + + /** Ldap search result iterator. */ + private SearchResultIterator resultIterator; + + + /** + * Creates a new jldap search iterator. + * + * @param sr search request + */ + public JLdapSearchIterator(final SearchRequest sr) + { + super(sr); + } + + + /** + * Initializes this jldap search iterator. + * + * @throws LdapException if an error occurs + */ + public void initialize() + throws LdapException + { + try { + resultIterator = new SearchResultIterator(search(connection, request)); + } catch (LDAPException e) { + processLDAPException(e); + } + } + + + @Override + public boolean hasNext() + throws LdapException + { + if (resultIterator == null || response != null) { + return false; + } + + boolean more = false; + try { + more = resultIterator.hasNext(); + if (!more) { + final LDAPResponse res = resultIterator.getResponse(); + logger.trace("reading search response: {}", res); + throwOperationException(request, res); + response = createResponse(request, null, res); + } + } catch (LDAPException e) { + final ResultCode rc = ignoreSearchException(config.getSearchIgnoreResultCodes(), e); + if (rc == null) { + processLDAPException(e); + } + response = new Response<>(null, rc, e.getLDAPErrorMessage(), null, null, null, -1); + } + return more; + } + + + @Override + public SearchItem next() + throws LdapException + { + SearchItem si; + final LDAPMessage message = resultIterator.next(); + if (message instanceof LDAPSearchResult) { + si = processLDAPSearchResult((LDAPSearchResult) message); + } else if (message instanceof LDAPSearchResultReference) { + si = processLDAPSearchResultReference((LDAPSearchResultReference) message); + } else if (message instanceof LDAPIntermediateResponse) { + si = processLDAPIntermediateResponse((LDAPIntermediateResponse) message); + } else { + throw new IllegalStateException("Unknown message: " + message); + } + return si; + } + + + @Override + public Response<Void> getResponse() + { + return response; + } + + + @Override + public void close() + throws LdapException {} + } + + + /** Async search listener for JLdap search results. */ + protected class JLdapAsyncSearchListener extends AbstractJLdapSearch + { + + /** Search result listener. */ + private final SearchListener listener; + + + /** + * Creates a new jldap async search listener. + * + * @param sr search request + * @param sl search listener + */ + public JLdapAsyncSearchListener(final SearchRequest sr, final SearchListener sl) + { + super(sr); + listener = sl; + } + + + /** + * Initializes this jldap search listener. + * + * @throws LdapException if an error occurs + */ + public void initialize() + throws LdapException + { + try { + search(connection, request); + } catch (LDAPException e) { + processLDAPException(e); + } + } + + + /** + * Executes an ldap search. + * + * @param conn to search with + * @param sr to read properties from + * + * @return ldap search queue + * + * @throws LDAPException if an error occurs + */ + protected LDAPSearchQueue search(final LDAPConnection conn, final SearchRequest sr) + throws LDAPException + { + final SearchResultIterator i = new SearchResultIterator(super.search(conn, sr)); + listener.asyncRequestReceived(new JLdapAsyncRequest(i.getLDAPSearchQueue())); + while (i.hasNext()) { + final LDAPMessage message = i.next(); + if (message instanceof LDAPSearchResult) { + listener.searchItemReceived(processLDAPSearchResult((LDAPSearchResult) message)); + } else if (message instanceof LDAPSearchResultReference) { + listener.searchItemReceived(processLDAPSearchResultReference((LDAPSearchResultReference) message)); + } else if (message instanceof LDAPIntermediateResponse) { + listener.searchItemReceived(processLDAPIntermediateResponse((LDAPIntermediateResponse) message)); + } else { + throw new IllegalStateException("Unknown message: " + message); + } + } + + final Response<Void> response = createResponse(request, null, i.getResponse()); + listener.responseReceived(response); + return null; + } + } + + + /** Common search functionality for jldap iterators and listeners. */ + protected abstract class AbstractJLdapSearch + { + + /** Search request. */ + protected final SearchRequest request; + + /** Utility class. */ + protected final JLdapUtils util; + + + /** + * Creates a new abstract jldap search. + * + * @param sr search request + */ + public AbstractJLdapSearch(final SearchRequest sr) + { + request = sr; + util = new JLdapUtils(request.getSortBehavior()); + util.setBinaryAttributes(request.getBinaryAttributes()); + } + + + /** + * Executes an ldap search. + * + * @param conn to search with + * @param sr to read properties from + * + * @return ldap search queue + * + * @throws LDAPException if an error occurs + */ + protected LDAPSearchQueue search(final LDAPConnection conn, final SearchRequest sr) + throws LDAPException + { + final LDAPSearchConstraints constraints = getLDAPSearchConstraints(sr); + final LDAPControl[] lc = config.getControlProcessor().processRequestControls(sr.getControls()); + if (lc != null) { + constraints.setControls(lc); + } + return + conn.search( + sr.getBaseDn(), + getSearchScope(sr.getSearchScope()), + sr.getSearchFilter() != null ? sr.getSearchFilter().format() : null, + sr.getReturnAttributes(), + sr.getTypesOnly(), + null, + constraints); + } + + + /** + * Returns the jldap integer constant for the supplied search scope. + * + * @param ss search scope + * + * @return integer constant + */ + protected int getSearchScope(final SearchScope ss) + { + int scope = -1; + if (ss == SearchScope.OBJECT) { + scope = LDAPConnection.SCOPE_BASE; + } else if (ss == SearchScope.ONELEVEL) { + scope = LDAPConnection.SCOPE_ONE; + } else if (ss == SearchScope.SUBTREE) { + scope = LDAPConnection.SCOPE_SUB; + } + return scope; + } + + + /** + * Returns an ldap search constraints object configured with the supplied search request. + * + * @param sr search request containing configuration to create search constraints + * + * @return ldap search constraints + */ + protected LDAPSearchConstraints getLDAPSearchConstraints(final SearchRequest sr) + { + LDAPSearchConstraints constraints = connection.getSearchConstraints(); + if (constraints == null) { + constraints = new LDAPSearchConstraints(); + } + constraints.setServerTimeLimit((int) sr.getTimeLimit().getSeconds()); + constraints.setMaxResults(Long.valueOf(sr.getSizeLimit()).intValue()); + if (sr.getDerefAliases() != null) { + if (sr.getDerefAliases() == DerefAliases.ALWAYS) { + constraints.setDereference(LDAPSearchConstraints.DEREF_ALWAYS); + } else if (sr.getDerefAliases() == DerefAliases.FINDING) { + constraints.setDereference(LDAPSearchConstraints.DEREF_FINDING); + } else if (sr.getDerefAliases() == DerefAliases.NEVER) { + constraints.setDereference(LDAPSearchConstraints.DEREF_NEVER); + } else if (sr.getDerefAliases() == DerefAliases.SEARCHING) { + constraints.setDereference(LDAPSearchConstraints.DEREF_SEARCHING); + } + } + return constraints; + } + + + /** + * Determines whether the supplied ldap exception should be ignored. + * + * @param ignoreResultCodes to match against the exception + * @param e ldap exception to match + * + * @return result code that should be ignored or null + */ + protected ResultCode ignoreSearchException(final ResultCode[] ignoreResultCodes, final LDAPException e) + { + ResultCode ignore = null; + if (ignoreResultCodes != null && ignoreResultCodes.length > 0) { + for (ResultCode rc : ignoreResultCodes) { + if (e.getResultCode() == rc.value()) { + logger.debug("Ignoring ldap exception", e); + ignore = rc; + break; + } + } + } + return ignore; + } + + + /** + * Processes the response controls on the supplied result and returns a corresponding search item. + * + * @param res to process + * + * @return search item + */ + protected SearchItem processLDAPSearchResult(final LDAPSearchResult res) + { + logger.trace("reading search result: {}", res); + + ResponseControl[] respControls = null; + if (res.getControls() != null && res.getControls().length > 0) { + respControls = config.getControlProcessor().processResponseControls(res.getControls()); + } + + final SearchEntry se = util.toSearchEntry(res.getEntry(), respControls, res.getMessageID()); + return new SearchItem(se); + } + + + /** + * Processes the response controls on the supplied reference and returns a corresponding search item. + * + * @param ref to process + * + * @return search item + */ + protected SearchItem processLDAPSearchResultReference(final LDAPSearchResultReference ref) + { + logger.trace("reading search reference: {}", ref); + + ResponseControl[] respControls = null; + if (ref.getControls() != null && ref.getControls().length > 0) { + respControls = config.getControlProcessor().processResponseControls(ref.getControls()); + } + + final SearchReference sr = new SearchReference(ref.getMessageID(), respControls, ref.getReferrals()); + return new SearchItem(sr); + } + + + /** + * Processes the response controls on the supplied response and returns a corresponding search item. + * + * @param res to process + * + * @return search item + */ + protected SearchItem processLDAPIntermediateResponse(final LDAPIntermediateResponse res) + { + logger.trace("reading intermediate response: {}", res); + + ResponseControl[] respControls = null; + if (res.getControls() != null && res.getControls().length > 0) { + respControls = config.getControlProcessor().processResponseControls(res.getControls()); + } + + final org.ldaptive.intermediate.IntermediateResponse ir = IntermediateResponseFactory.createIntermediateResponse( + res.getID(), + res.getValue(), + respControls, + res.getMessageID()); + return new SearchItem(ir); + } + } + + + /** Iterates over an ldap search queue. */ + protected static class SearchResultIterator + { + + /** Queue to iterate over. */ + private final LDAPSearchQueue queue; + + /** Last response message received from the queue. */ + private LDAPMessage message; + + /** Response available after all messages have been received. */ + private LDAPResponse response; + + + /** + * Create a new ldap result iterator. + * + * @param q ldap search queue + */ + public SearchResultIterator(final LDAPSearchQueue q) + { + queue = q; + } + + + /** + * Returns the search queue used by this iterator. + * + * @return ldap search queue + */ + public LDAPSearchQueue getLDAPSearchQueue() + { + return queue; + } + + + /** + * Returns whether the queue has another message to read. + * + * @return whether the queue has another message to read + * + * @throws LDAPException if an error occurs reading the response + */ + public boolean hasNext() + throws LDAPException + { + if (response != null) { + return false; + } + + boolean more = false; + message = queue.getResponse(); + if (message != null) { + if (message instanceof LDAPSearchResult) { + more = true; + } else if (message instanceof LDAPSearchResultReference) { + more = true; + } else if (message instanceof LDAPIntermediateResponse) { + more = true; + } else { + response = (LDAPResponse) message; + } + } + return more; + } + + + /** + * Returns the next message in the queue. + * + * @return ldap message + */ + public LDAPMessage next() + { + return message; + } + + + /** + * Returns the search response. Available after all messages have been read from the queue. + * + * @return ldap search response + */ + public LDAPResponse getResponse() + { + return response; + } + } + + + /** Async request to invoke abandons. */ + protected class JLdapAsyncRequest implements AsyncRequest + { + + /** Message queue. */ + private final LDAPMessageQueue messageQueue; + + + /** + * Creates a new JLDAP async request. + * + * @param queue from an async operation + */ + public JLdapAsyncRequest(final LDAPMessageQueue queue) + { + messageQueue = queue; + } + + + @Override + public int getMessageId() + { + final int[] ids = messageQueue.getMessageIDs(); + if (ids == null || ids.length == 0) { + return -1; + } + return ids[ids.length - 1]; + } + + + @Override + public void abandon() + throws LdapException + { + try { + LDAPConstraints constraints = connection.getConstraints(); + if (constraints == null) { + constraints = new LDAPConstraints(); + } + connection.abandon(messageQueue, constraints); + } catch (LDAPException e) { + processLDAPException(e); + } + } + + + @Override + public void abandon(final RequestControl[] controls) + throws LdapException + { + try { + LDAPConstraints constraints = connection.getConstraints(); + if (constraints == null) { + constraints = new LDAPConstraints(); + } + if (controls != null) { + constraints.setControls(config.getControlProcessor().processRequestControls(controls)); + } + connection.abandon(messageQueue, constraints); + } catch (LDAPException e) { + processLDAPException(e); + } + } + } + + + /** Allows the use of multiple unsolicited notification handlers per connection. */ + protected class AggregateUnsolicitedNotificationListener implements LDAPUnsolicitedNotificationListener + { + + /** Listeners to receive unsolicited notifications. */ + private final List<UnsolicitedNotificationListener> listeners = new ArrayList<>(); + + + /** + * Adds an unsolicited notification listener to this handler. + * + * @param listener to receive unsolicited notifications + */ + public void addUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + synchronized (listeners) { + listeners.add(listener); + } + } + + + /** + * Removes an unsolicited notification listener from this handler. + * + * @param listener to stop receiving unsolicited notifications + */ + public void removeUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + synchronized (listeners) { + listeners.remove(listener); + } + } + + + @Override + public void messageReceived(final LDAPExtendedResponse extendedResponse) + { + logger.debug("Unsolicited notification received: {}", extendedResponse); + synchronized (listeners) { + final Response<Void> response = createResponse(null, null, extendedResponse); + for (UnsolicitedNotificationListener listener : listeners) { + listener.notificationReceived(extendedResponse.getID(), response); + } + } + } + } +}
diff --git a/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapConnectionFactory.java b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapConnectionFactory.java new file mode 100644 index 0000000..e9dcd0e --- /dev/null +++ b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapConnectionFactory.java
@@ -0,0 +1,52 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jldap; + +import java.time.Duration; +import com.novell.ldap.LDAPConnection; +import com.novell.ldap.LDAPConstraints; +import com.novell.ldap.LDAPException; +import org.ldaptive.ConnectionStrategy; + +/** + * Creates ldap connections using the JLDAP LDAPConnection class. + * + * @author Middleware Services + */ +public class JLdapConnectionFactory extends AbstractJLdapConnectionFactory<JLdapConnection> +{ + + + /** + * Creates a new jldap connection factory. + * + * @param url of the ldap to connect to + * @param strategy connection strategy + * @param config provider configuration + * @param constraints connection constraints + * @param timeOut time in milliseconds that operations will wait + */ + public JLdapConnectionFactory( + final String url, + final ConnectionStrategy strategy, + final JLdapProviderConfig config, + final LDAPConstraints constraints, + final Duration timeOut) + { + super(url, strategy, config, constraints, timeOut); + } + + + @Override + protected LDAPConnection createLDAPConnection() + throws LDAPException + { + return new LDAPConnection(); + } + + + @Override + protected JLdapConnection createJLdapConnection(final LDAPConnection conn, final JLdapProviderConfig config) + { + return new JLdapConnection(conn, config); + } +}
diff --git a/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapControlHandler.java b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapControlHandler.java new file mode 100644 index 0000000..54cd6ca --- /dev/null +++ b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapControlHandler.java
@@ -0,0 +1,52 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jldap; + +import org.ldaptive.control.ControlFactory; +import org.ldaptive.control.RequestControl; +import org.ldaptive.control.ResponseControl; +import org.ldaptive.provider.ControlHandler; + +/** + * JLdap control handler. + * + * @author Middleware Services + */ +public class JLdapControlHandler implements ControlHandler<com.novell.ldap.LDAPControl> +{ + + + @Override + public Class<com.novell.ldap.LDAPControl> getControlType() + { + return com.novell.ldap.LDAPControl.class; + } + + + @Override + public String getOID(final com.novell.ldap.LDAPControl control) + { + return control.getID(); + } + + + @Override + public com.novell.ldap.LDAPControl handleRequest(final RequestControl requestControl) + { + return + new com.novell.ldap.LDAPControl( + requestControl.getOID(), + requestControl.getCriticality(), + requestControl.encode()); + } + + + @Override + public ResponseControl handleResponse(final com.novell.ldap.LDAPControl responseControl) + { + return + ControlFactory.createResponseControl( + responseControl.getID(), + responseControl.isCritical(), + responseControl.getValue()); + } +}
diff --git a/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapProvider.java b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapProvider.java new file mode 100644 index 0000000..70e0416 --- /dev/null +++ b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapProvider.java
@@ -0,0 +1,168 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jldap; + +import java.security.Security; +import javax.net.ssl.SSLSocketFactory; +import com.novell.ldap.LDAPConstraints; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.LdapURL; +import org.ldaptive.provider.Provider; +import org.ldaptive.provider.ProviderConnectionFactory; +import org.ldaptive.ssl.TLSSocketFactory; + +/** + * JLdap provider implementation. Provides connection factories for clear, SSL, and TLS connections. + * + * @author Middleware Services + */ +public class JLdapProvider implements Provider<JLdapProviderConfig> +{ + + /** + * Add novell sasl provider. + */ + static { + Security.addProvider(new com.novell.sasl.client.SaslProvider()); + } + + /** Provider configuration. */ + private JLdapProviderConfig config = new JLdapProviderConfig(); + + + @Override + public ProviderConnectionFactory<JLdapProviderConfig> getConnectionFactory(final ConnectionConfig cc) + { + ProviderConnectionFactory<JLdapProviderConfig> cf; + if (cc.getUseStartTLS()) { + cf = getJLdapStartTLSConnectionFactory(cc, config.getLDAPConstraints()); + } else if (cc.getUseSSL() || cc.getLdapUrl().toLowerCase().contains("ldaps://")) { + cf = getJLdapSSLConnectionFactory(cc, config.getLDAPConstraints()); + } else { + cf = getJLdapConnectionFactory(cc, config.getLDAPConstraints()); + } + return cf; + } + + + /** + * Returns a jldap startTLS connection factory using the properties found in the supplied connection config. If the + * supplied constraints is null, the environment is retrieved from {@link + * #getDefaultLDAPConstraints(ConnectionConfig)}. + * + * @param cc connection config + * @param constraints connection constraints or null to use the default + * + * @return jndi startTLS connection factory + */ + protected JLdapStartTLSConnectionFactory getJLdapStartTLSConnectionFactory( + final ConnectionConfig cc, + final LDAPConstraints constraints) + { + return + new JLdapStartTLSConnectionFactory( + cc.getLdapUrl(), + cc.getConnectionStrategy(), + config, + constraints != null ? constraints : getDefaultLDAPConstraints(cc), + cc.getResponseTimeout(), + config.getSslSocketFactory() != null ? config.getSslSocketFactory() : getHostnameVerifierSocketFactory(cc)); + } + + + /** + * Returns a jldap SSL connection factory using the properties found in the supplied connection config. If the + * supplied constraints is null, the environment is retrieved from {@link + * #getDefaultLDAPConstraints(ConnectionConfig)}. + * + * @param cc connection config + * @param constraints connection constraints or null to use the default + * + * @return jndi SSL connection factory + */ + protected JLdapSSLConnectionFactory getJLdapSSLConnectionFactory( + final ConnectionConfig cc, + final LDAPConstraints constraints) + { + return + new JLdapSSLConnectionFactory( + cc.getLdapUrl(), + cc.getConnectionStrategy(), + config, + constraints != null ? constraints : getDefaultLDAPConstraints(cc), + cc.getResponseTimeout(), + config.getSslSocketFactory() != null ? config.getSslSocketFactory() : getHostnameVerifierSocketFactory(cc)); + } + + + /** + * Returns a jldap connection factory using the properties found in the supplied connection config. If the supplied + * constraints is null, the environment is retrieved from {@link #getDefaultLDAPConstraints(ConnectionConfig)}. + * + * @param cc connection config + * @param constraints connection constraints or null to use the default + * + * @return jndi connection factory + */ + protected JLdapConnectionFactory getJLdapConnectionFactory( + final ConnectionConfig cc, + final LDAPConstraints constraints) + { + return + new JLdapConnectionFactory( + cc.getLdapUrl(), + cc.getConnectionStrategy(), + config, + constraints != null ? constraints : getDefaultLDAPConstraints(cc), + cc.getResponseTimeout()); + } + + + /** + * Returns an SSL socket factory configured with a default hostname verifier. + * + * @param cc connection configuration + * + * @return SSL socket factory + */ + protected SSLSocketFactory getHostnameVerifierSocketFactory(final ConnectionConfig cc) + { + // JLdap does not do hostname verification by default + // set a default hostname verifier + final LdapURL ldapUrl = new LdapURL(cc.getLdapUrl()); + return TLSSocketFactory.getHostnameVerifierFactory(cc.getSslConfig(), ldapUrl.getHostnames()); + } + + + /** + * Returns the default connection constraints for this provider. + * + * @param cc to configure options with + * + * @return ldap connection constraints + */ + protected LDAPConstraints getDefaultLDAPConstraints(final ConnectionConfig cc) + { + return new LDAPConstraints(); + } + + + @Override + public JLdapProviderConfig getProviderConfig() + { + return config; + } + + + @Override + public void setProviderConfig(final JLdapProviderConfig pc) + { + config = pc; + } + + + @Override + public JLdapProvider newInstance() + { + return new JLdapProvider(); + } +}
diff --git a/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapProviderConfig.java b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapProviderConfig.java new file mode 100644 index 0000000..d9ac6ab --- /dev/null +++ b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapProviderConfig.java
@@ -0,0 +1,130 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jldap; + +import java.util.Arrays; +import javax.net.ssl.SSLSocketFactory; +import com.novell.ldap.LDAPConstraints; +import com.novell.ldap.LDAPControl; +import org.ldaptive.ResultCode; +import org.ldaptive.provider.ControlProcessor; +import org.ldaptive.provider.ProviderConfig; + +/** + * Contains configuration data for the JLdap provider. + * + * @author Middleware Services + */ +public class JLdapProviderConfig extends ProviderConfig<LDAPControl> +{ + + /** Connection constraints. */ + private LDAPConstraints ldapConstraints; + + /** Search result codes to ignore. */ + private ResultCode[] searchIgnoreResultCodes; + + /** ldap socket factory used for SSL and TLS. */ + private SSLSocketFactory sslSocketFactory; + + + /** Default constructor. */ + public JLdapProviderConfig() + { + setOperationExceptionResultCodes(ResultCode.CONNECT_ERROR); + setControlProcessor(new ControlProcessor<>(new JLdapControlHandler())); + searchIgnoreResultCodes = new ResultCode[] { + ResultCode.TIME_LIMIT_EXCEEDED, + ResultCode.SIZE_LIMIT_EXCEEDED, + }; + } + + + /** + * Returns the connection constraints. + * + * @return ldap connection constraints + */ + public LDAPConstraints getLDAPConstraints() + { + return ldapConstraints; + } + + + /** + * Sets the connection constraints. + * + * @param constraints ldap connection constraints + */ + public void setLDAPConstraints(final LDAPConstraints constraints) + { + checkImmutable(); + logger.trace("setting ldapConstraints: {}", constraints); + ldapConstraints = constraints; + } + + + /** + * Returns the search ignore result codes. + * + * @return result codes to ignore + */ + public ResultCode[] getSearchIgnoreResultCodes() + { + return searchIgnoreResultCodes; + } + + + /** + * Sets the search ignore result codes. + * + * @param codes to ignore + */ + public void setSearchIgnoreResultCodes(final ResultCode[] codes) + { + checkImmutable(); + logger.trace("setting searchIgnoreResultCodes: {}", Arrays.toString(codes)); + searchIgnoreResultCodes = codes; + } + + + /** + * Returns the SSL socket factory to use for TLS/SSL connections. + * + * @return SSL socket factory + */ + public SSLSocketFactory getSslSocketFactory() + { + return sslSocketFactory; + } + + + /** + * Sets the SSL socket factory to use for TLS/SSL connections. + * + * @param sf SSL socket factory + */ + public void setSslSocketFactory(final SSLSocketFactory sf) + { + checkImmutable(); + logger.trace("setting sslSocketFactory: {}", sf); + sslSocketFactory = sf; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::operationExceptionResultCodes=%s, properties=%s, controlProcessor=%s, ldapConstraints=%s, " + + "searchIgnoreResultCodes=%s, sslSocketFactory=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(getOperationExceptionResultCodes()), + getProperties(), + getControlProcessor(), + ldapConstraints, + Arrays.toString(searchIgnoreResultCodes), + sslSocketFactory); + } +}
diff --git a/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapSSLConnection.java b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapSSLConnection.java new file mode 100644 index 0000000..658589e --- /dev/null +++ b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapSSLConnection.java
@@ -0,0 +1,25 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jldap; + +import com.novell.ldap.LDAPConnection; + +/** + * JLDAP provider implementation of ldap operations over SSL. + * + * @author Middleware Services + */ +public class JLdapSSLConnection extends JLdapConnection +{ + + + /** + * Creates a new jldap ssl connection. + * + * @param conn ldap connection + * @param pc provider configuration + */ + public JLdapSSLConnection(final LDAPConnection conn, final JLdapProviderConfig pc) + { + super(conn, pc); + } +}
diff --git a/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapSSLConnectionFactory.java b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapSSLConnectionFactory.java new file mode 100644 index 0000000..1971282 --- /dev/null +++ b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapSSLConnectionFactory.java
@@ -0,0 +1,66 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jldap; + +import java.time.Duration; +import javax.net.ssl.SSLSocketFactory; +import com.novell.ldap.LDAPConnection; +import com.novell.ldap.LDAPConstraints; +import com.novell.ldap.LDAPException; +import com.novell.ldap.LDAPJSSESecureSocketFactory; +import org.ldaptive.ConnectionStrategy; + +/** + * Creates LDAPS connections using the JLDAP LDAPConnection class. + * + * @author Middleware Services + */ +public class JLdapSSLConnectionFactory extends AbstractJLdapConnectionFactory<JLdapSSLConnection> +{ + + /** SSL socket factory to use for SSL. */ + private final SSLSocketFactory sslSocketFactory; + + + /** + * Creates a new jldap ssl connection factory. + * + * @param url of the ldap to connect to + * @param strategy connection strategy + * @param config provider configuration + * @param constraints connection constraints + * @param timeOut time in milliseconds that operations will wait + * @param factory SSL socket factory + */ + public JLdapSSLConnectionFactory( + final String url, + final ConnectionStrategy strategy, + final JLdapProviderConfig config, + final LDAPConstraints constraints, + final Duration timeOut, + final SSLSocketFactory factory) + { + super(url, strategy, config, constraints, timeOut); + sslSocketFactory = factory; + } + + + @Override + protected LDAPConnection createLDAPConnection() + throws LDAPException + { + LDAPConnection conn; + if (sslSocketFactory != null) { + conn = new LDAPConnection(new LDAPJSSESecureSocketFactory(sslSocketFactory)); + } else { + conn = new LDAPConnection(new LDAPJSSESecureSocketFactory()); + } + return conn; + } + + + @Override + protected JLdapSSLConnection createJLdapConnection(final LDAPConnection conn, final JLdapProviderConfig config) + { + return new JLdapSSLConnection(conn, config); + } +}
diff --git a/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapStartTLSConnection.java b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapStartTLSConnection.java new file mode 100644 index 0000000..6d3ecb0 --- /dev/null +++ b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapStartTLSConnection.java
@@ -0,0 +1,70 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jldap; + +import com.novell.ldap.LDAPConnection; +import com.novell.ldap.LDAPException; +import org.ldaptive.LdapException; +import org.ldaptive.control.RequestControl; + +/** + * JLDAP provider implementation of ldap operations over TLS. + * + * @author Middleware Services + */ +public class JLdapStartTLSConnection extends JLdapConnection +{ + + /** Whether to call {@link LDAPConnection#stopTLS()} when {@link #close(RequestControl[])} is called. */ + private boolean stopTlsOnClose; + + + /** + * Creates a new jldap tls connection. + * + * @param conn ldap connection + * @param pc provider configuration + */ + public JLdapStartTLSConnection(final LDAPConnection conn, final JLdapProviderConfig pc) + { + super(conn, pc); + } + + + /** + * Returns whether to call {@link LDAPConnection#stopTLS()} when {@link #close(RequestControl[])} is called. + * + * @return stop TLS on close + */ + public boolean getStopTlsOnClose() + { + return stopTlsOnClose; + } + + + /** + * Sets whether to call {@link LDAPConnection#stopTLS()} when {@link #close(RequestControl[])} is called. + * + * @param b stop TLS on close + */ + public void setStopTlsOnClose(final boolean b) + { + logger.trace("setting stopTlsOnClose: " + b); + stopTlsOnClose = b; + } + + + @Override + public void close(final RequestControl[] controls) + throws LdapException + { + try { + if (stopTlsOnClose) { + getLDAPConnection().stopTLS(); + } + } catch (LDAPException e) { + logger.error("Error stopping TLS", e); + } finally { + super.close(controls); + } + } +}
diff --git a/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapStartTLSConnectionFactory.java b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapStartTLSConnectionFactory.java new file mode 100644 index 0000000..6c4a0ea --- /dev/null +++ b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapStartTLSConnectionFactory.java
@@ -0,0 +1,74 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jldap; + +import java.time.Duration; +import javax.net.ssl.SSLSocketFactory; +import com.novell.ldap.LDAPConnection; +import com.novell.ldap.LDAPConstraints; +import com.novell.ldap.LDAPException; +import com.novell.ldap.LDAPJSSEStartTLSFactory; +import org.ldaptive.ConnectionStrategy; + +/** + * Creates ldap connections using the JLDAP LDAPConnection class with the startTLS extended operation. + * + * @author Middleware Services + */ +public class JLdapStartTLSConnectionFactory extends AbstractJLdapConnectionFactory<JLdapStartTLSConnection> +{ + + /** SSL socket factory to use for startTLS. */ + private final SSLSocketFactory sslSocketFactory; + + + /** + * Creates a new jldap tls connection factory. + * + * @param url of the ldap to connect to + * @param strategy connection strategy + * @param config provider configuration + * @param constraints connection constraints + * @param timeOut time in milliseconds that operations will wait + * @param factory SSL socket factory + */ + public JLdapStartTLSConnectionFactory( + final String url, + final ConnectionStrategy strategy, + final JLdapProviderConfig config, + final LDAPConstraints constraints, + final Duration timeOut, + final SSLSocketFactory factory) + { + super(url, strategy, config, constraints, timeOut); + sslSocketFactory = factory; + } + + + @Override + protected LDAPConnection createLDAPConnection() + throws LDAPException + { + LDAPConnection conn; + if (sslSocketFactory != null) { + conn = new LDAPConnection(new LDAPJSSEStartTLSFactory(sslSocketFactory)); + } else { + conn = new LDAPConnection(new LDAPJSSEStartTLSFactory()); + } + return conn; + } + + + @Override + protected void initializeConnection(final LDAPConnection conn) + throws LDAPException + { + conn.startTLS(); + } + + + @Override + protected JLdapStartTLSConnection createJLdapConnection(final LDAPConnection conn, final JLdapProviderConfig config) + { + return new JLdapStartTLSConnection(conn, config); + } +}
diff --git a/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapUtils.java b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapUtils.java new file mode 100644 index 0000000..ebb50f8 --- /dev/null +++ b/jldap-provider/src/main/java/org/ldaptive/provider/jldap/JLdapUtils.java
@@ -0,0 +1,236 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.jldap; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import com.novell.ldap.LDAPAttribute; +import com.novell.ldap.LDAPAttributeSet; +import com.novell.ldap.LDAPEntry; +import com.novell.ldap.LDAPModification; +import com.novell.ldap.controls.LDAPSortKey; +import org.ldaptive.AttributeModification; +import org.ldaptive.AttributeModificationType; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.SearchEntry; +import org.ldaptive.SortBehavior; +import org.ldaptive.control.ResponseControl; +import org.ldaptive.control.SortKey; + +/** + * Provides methods for converting between JLDAP specific objects and ldaptive specific objects. + * + * @author Middleware Services + */ +public class JLdapUtils +{ + + /** Ldap result sort behavior. */ + private final SortBehavior sortBehavior; + + /** Attributes that should be treated as binary. */ + private List<String> binaryAttrs; + + + /** Default constructor. */ + public JLdapUtils() + { + sortBehavior = SortBehavior.getDefaultSortBehavior(); + } + + + /** + * Creates a new jldap util. + * + * @param sb sort behavior + */ + public JLdapUtils(final SortBehavior sb) + { + sortBehavior = sb; + } + + + /** + * Returns the list of binary attributes. + * + * @return list of binary attributes + */ + public List<String> getBinaryAttributes() + { + return binaryAttrs; + } + + + /** + * Sets the list of binary attributes. + * + * @param s binary attributes + */ + public void setBinaryAttributes(final String[] s) + { + if (s != null) { + binaryAttrs = Arrays.asList(s); + } + } + + + /** + * Returns a jldap attribute that represents the values in the supplied ldap attribute. + * + * @param la ldap attribute + * + * @return jldap attribute + */ + public LDAPAttribute fromLdapAttribute(final LdapAttribute la) + { + final LDAPAttribute attr = new LDAPAttribute(la.getName()); + if (la.isBinary()) { + la.getBinaryValues().forEach(attr::addValue); + } else { + la.getStringValues().forEach(attr::addValue); + } + return attr; + } + + + /** + * Returns an ldap attribute using the supplied jldap attribute. + * + * @param a jldap attribute + * + * @return ldap attribute + */ + public LdapAttribute toLdapAttribute(final LDAPAttribute a) + { + boolean isBinary = false; + if (a.getName().contains(";binary")) { + isBinary = true; + } else if (binaryAttrs != null && binaryAttrs.contains(a.getName())) { + isBinary = true; + } + + final LdapAttribute la = new LdapAttribute(sortBehavior, isBinary); + la.setName(a.getName()); + if (isBinary) { + for (byte[] b : a.getByteValueArray()) { + la.addBinaryValue(b); + } + } else { + for (String s : a.getStringValueArray()) { + la.addStringValue(s); + } + } + return la; + } + + + /** + * Returns a jldap attribute set that represents the values in the supplied ldap attributes. + * + * @param c ldap attributes + * + * @return jldap attributes + */ + @SuppressWarnings("unchecked") + public LDAPAttributeSet fromLdapAttributes(final Collection<LdapAttribute> c) + { + return c.stream().map(this::fromLdapAttribute).collect(Collectors.toCollection(LDAPAttributeSet::new)); + } + + + /** + * Returns a jldap ldap entry that represents the supplied ldap entry. + * + * @param le ldap entry + * + * @return jldap ldap entry + */ + public LDAPEntry fromLdapEntry(final LdapEntry le) + { + return new LDAPEntry(le.getDn(), fromLdapAttributes(le.getAttributes())); + } + + + /** + * Returns a search entry using the supplied jldap ldap entry. + * + * @param entry jldap ldap entry + * @param c response controls + * @param id message id + * + * @return search entry + */ + @SuppressWarnings("unchecked") + public SearchEntry toSearchEntry(final LDAPEntry entry, final ResponseControl[] c, final int id) + { + final SearchEntry se = new SearchEntry(id, c, sortBehavior); + se.setDn(entry.getDN()); + + for (Object o : entry.getAttributeSet()) { + se.addAttribute(toLdapAttribute((LDAPAttribute) o)); + } + return se; + } + + + /** + * Returns jldap ldap modifications using the supplied attribute modifications. + * + * @param am attribute modifications + * + * @return jldap ldap modifications + */ + public LDAPModification[] fromAttributeModification(final AttributeModification[] am) + { + final LDAPModification[] mods = new LDAPModification[am.length]; + for (int i = 0; i < am.length; i++) { + mods[i] = new LDAPModification( + getAttributeModification(am[i].getAttributeModificationType()), + fromLdapAttribute(am[i].getAttribute())); + } + return mods; + } + + + /** + * Returns jldap sort keys using the supplied sort keys. + * + * @param sk sort keys + * + * @return jldap sort keys + */ + public static LDAPSortKey[] fromSortKey(final SortKey[] sk) + { + LDAPSortKey[] keys = null; + if (sk != null) { + keys = new LDAPSortKey[sk.length]; + for (int i = 0; i < sk.length; i++) { + keys[i] = new LDAPSortKey(sk[i].getAttributeDescription(), sk[i].getReverseOrder(), sk[i].getMatchingRuleId()); + } + } + return keys; + } + + + /** + * Returns the jldap modification integer constant for the supplied attribute modification type. + * + * @param am attribute modification type + * + * @return integer constant + */ + protected static int getAttributeModification(final AttributeModificationType am) + { + int op = -1; + if (am == AttributeModificationType.ADD) { + op = LDAPModification.ADD; + } else if (am == AttributeModificationType.REMOVE) { + op = LDAPModification.DELETE; + } else if (am == AttributeModificationType.REPLACE) { + op = LDAPModification.REPLACE; + } + return op; + } +}
diff --git a/json/pom.xml b/json/pom.xml new file mode 100644 index 0000000..888e98f --- /dev/null +++ b/json/pom.xml
@@ -0,0 +1,35 @@ +<?xml version='1.0' encoding='UTF-8'?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>ldaptive-json</artifactId> + <packaging>jar</packaging> + <name>LDAPTIVE JSON</name> + <description>Provides JSON reader and writer</description> + <parent> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-parent</artifactId> + <version>1.2.3</version> + </parent> + + <dependencies> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive</artifactId> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + </dependency> + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + </dependency> + </dependencies> + +</project>
diff --git a/json/src/main/java/org/ldaptive/io/JsonReader.java b/json/src/main/java/org/ldaptive/io/JsonReader.java new file mode 100644 index 0000000..06f439d --- /dev/null +++ b/json/src/main/java/org/ldaptive/io/JsonReader.java
@@ -0,0 +1,127 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.io.IOException; +import java.io.Reader; +import java.lang.reflect.Type; +import java.util.Map; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.SearchResult; +import org.ldaptive.SortBehavior; + +/** + * Reads JSON from a {@link Reader} and returns a {@link SearchResult}. + * + * @author Middleware Services + */ +public class JsonReader implements SearchResultReader +{ + + /** Reader to read from. */ + private final Reader jsonReader; + + /** To convert JSON to a search result. */ + private final Gson gson; + + + /** + * Creates a new json reader. + * + * @param reader to read JSON from + */ + public JsonReader(final Reader reader) + { + this(reader, SortBehavior.getDefaultSortBehavior()); + } + + + /** + * Creates a new json reader. + * + * @param reader to read JSON from + * @param sb sort behavior of the search result + */ + public JsonReader(final Reader reader, final SortBehavior sb) + { + jsonReader = reader; + if (sb == null) { + throw new IllegalArgumentException("Sort behavior cannot be null"); + } + final GsonBuilder builder = new GsonBuilder(); + builder.registerTypeAdapter(SearchResult.class, new SearchResultDeserializer(sb)); + gson = builder.disableHtmlEscaping().create(); + } + + + /** + * Reads JSON data from the reader and returns a search result. + * + * @return search result derived from the JSON + * + * @throws IOException if an error occurs using the reader + */ + @Override + public SearchResult read() + throws IOException + { + try { + return gson.fromJson(jsonReader, SearchResult.class); + } catch (JsonParseException e) { + throw new IOException(e); + } + } + + + /** + * Deserializes a {@link SearchResult} by iterating over the json elements. + */ + private static class SearchResultDeserializer implements JsonDeserializer<SearchResult> + { + + /** Sort behavior. */ + private final SortBehavior sortBehavior; + + + /** + * Creates a new search result deserializer. + * + * @param sb sort behavior of the search result + */ + SearchResultDeserializer(final SortBehavior sb) + { + sortBehavior = sb; + } + + + @Override + public SearchResult deserialize(final JsonElement json, final Type type, final JsonDeserializationContext context) + throws JsonParseException + { + final SearchResult result = new SearchResult(sortBehavior); + final JsonArray jsonResult = json.getAsJsonArray(); + for (JsonElement jsonEntry : jsonResult) { + final LdapEntry entry = new LdapEntry(sortBehavior); + for (Map.Entry<String, JsonElement> jsonAttr : jsonEntry.getAsJsonObject().entrySet()) { + if ("dn".equals(jsonAttr.getKey())) { + entry.setDn(jsonAttr.getValue().getAsString()); + } else { + final LdapAttribute attr = new LdapAttribute(sortBehavior); + attr.setName(jsonAttr.getKey()); + jsonAttr.getValue().getAsJsonArray().forEach(i -> attr.addStringValue(i.getAsString())); + entry.addAttribute(attr); + } + } + result.addEntry(entry); + } + return result; + } + } +}
diff --git a/json/src/main/java/org/ldaptive/io/JsonWriter.java b/json/src/main/java/org/ldaptive/io/JsonWriter.java new file mode 100644 index 0000000..4538821 --- /dev/null +++ b/json/src/main/java/org/ldaptive/io/JsonWriter.java
@@ -0,0 +1,89 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.io.IOException; +import java.io.Writer; +import java.lang.reflect.Type; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.SearchResult; + +/** + * Writes a {@link SearchResult} as JSON to a {@link Writer}. + * + * @author Middleware Services + */ +public class JsonWriter implements SearchResultWriter +{ + + /** Writer to write to. */ + private final Writer jsonWriter; + + /** To convert a search result to JSON. */ + private final Gson gson; + + + /** + * Creates a new json writer. + * + * @param writer to write JSON to + */ + public JsonWriter(final Writer writer) + { + jsonWriter = writer; + final GsonBuilder builder = new GsonBuilder(); + builder.registerTypeAdapter(SearchResult.class, new SearchResultSerializer()); + gson = builder.disableHtmlEscaping().create(); + } + + + /** + * Writes the supplied search result to the writer. + * + * @param result search result to write + * + * @throws IOException if an error occurs using the writer + */ + @Override + public void write(final SearchResult result) + throws IOException + { + gson.toJson(result, jsonWriter); + jsonWriter.flush(); + } + + + /** + * Serializes a {@link SearchResult} by creating a json array to contain the entries. Each entry is a json object with + * the DN represented as a json primitive. Each attribute contains a json array of values. + */ + private static class SearchResultSerializer implements JsonSerializer<SearchResult> + { + + + @Override + public JsonElement serialize(final SearchResult result, final Type type, final JsonSerializationContext context) + { + final JsonArray json = new JsonArray(); + for (LdapEntry entry : result.getEntries()) { + final JsonObject jsonEntry = new JsonObject(); + jsonEntry.add("dn", entry.getDn() != null ? new JsonPrimitive(entry.getDn()) : null); + for (LdapAttribute attr : entry.getAttributes()) { + final JsonArray jsonAttrValues = new JsonArray(); + attr.getStringValues().forEach(jsonAttrValues::add); + jsonEntry.add(attr.getName(), jsonAttrValues); + } + json.add(jsonEntry); + } + return json; + } + } +}
diff --git a/json/src/main/java/org/ldaptive/servlets/JsonServletSearchExecutor.java b/json/src/main/java/org/ldaptive/servlets/JsonServletSearchExecutor.java new file mode 100644 index 0000000..cf503e6 --- /dev/null +++ b/json/src/main/java/org/ldaptive/servlets/JsonServletSearchExecutor.java
@@ -0,0 +1,29 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.servlets; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; +import javax.servlet.http.HttpServletResponse; +import org.ldaptive.SearchResult; +import org.ldaptive.io.JsonWriter; + +/** + * Writes search results as JSON. See {@link AbstractServletSearchExecutor}. + * + * @author Middleware Services + */ +public class JsonServletSearchExecutor extends AbstractServletSearchExecutor +{ + + + @Override + protected void writeResponse(final SearchResult result, final HttpServletResponse response) + throws IOException + { + response.setContentType("application/json"); + + final JsonWriter writer = new JsonWriter(new BufferedWriter(new OutputStreamWriter(response.getOutputStream()))); + writer.write(result); + } +}
diff --git a/json/src/test/java/org/ldaptive/io/JsonTest.java b/json/src/test/java/org/ldaptive/io/JsonTest.java new file mode 100644 index 0000000..98dd998 --- /dev/null +++ b/json/src/test/java/org/ldaptive/io/JsonTest.java
@@ -0,0 +1,163 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.io; + +import java.io.StringReader; +import java.io.StringWriter; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.SearchResult; +import org.ldaptive.SortBehavior; +import org.testng.AssertJUnit; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link JsonWriter} and {@link JsonReader}. + * + * @author Middleware Services + */ +public class JsonTest +{ + + + /** + * Sample ldap data. + * + * @return executor data + */ + @DataProvider(name = "search-data") + public Object[][] createTestData() + { + final SearchResult result1 = new SearchResult(SortBehavior.ORDERED); + final LdapEntry entry11 = new LdapEntry(SortBehavior.ORDERED); + entry11.setDn("uid=818037,ou=people,dc=ldaptive,dc=org"); + final LdapAttribute attr12 = new LdapAttribute(SortBehavior.ORDERED); + attr12.setName("givenName"); + attr12.addStringValue("Daniel", "Dan"); + entry11.addAttribute( + new LdapAttribute("departmentNumber", "066103"), + attr12, + new LdapAttribute("sn", "Fisher")); + result1.addEntry(entry11); + + final SearchResult result2 = new SearchResult(SortBehavior.ORDERED); + final LdapEntry entry21 = new LdapEntry(SortBehavior.ORDERED); + entry21.setDn("uid=1095747,ou=people,dc=ldaptive,dc=org"); + final LdapAttribute attr212 = new LdapAttribute(SortBehavior.ORDERED); + attr212.setName("givenName"); + attr212.addStringValue("Robert", "Bob"); + entry21.addAttribute( + new LdapAttribute("uid", "1095747"), + attr212, + new LdapAttribute("sn", "Jones")); + final LdapEntry entry22 = new LdapEntry(SortBehavior.ORDERED); + entry22.setDn("uid=1141837,ou=people,dc=ldaptive,dc=org"); + final LdapAttribute attr222 = new LdapAttribute(SortBehavior.ORDERED); + attr222.setName("givenName"); + attr222.addStringValue("William", "Bill"); + entry22.addAttribute( + new LdapAttribute("uid", "1141837"), + attr222, + new LdapAttribute("sn", "Smith")); + final LdapEntry entry23 = new LdapEntry(SortBehavior.ORDERED); + entry23.setDn("uid=1145718,ou=people,dc=ldaptive,dc=org"); + final LdapAttribute attr232 = new LdapAttribute(SortBehavior.ORDERED); + attr232.setName("givenName"); + attr232.addStringValue("Thomas", "Tom"); + entry23.addAttribute( + new LdapAttribute("uid", "1145718"), + attr232, + new LdapAttribute("sn", "Johnson")); + final LdapEntry entry24 = new LdapEntry(SortBehavior.ORDERED); + entry24.setDn("uid=1152120,ou=people,dc=ldaptive,dc=org"); + final LdapAttribute attr242 = new LdapAttribute(SortBehavior.ORDERED); + attr242.setName("givenName"); + attr242.addStringValue("David", "Dave"); + entry24.addAttribute( + new LdapAttribute("uid", "1152120"), + attr242, + new LdapAttribute("sn", "Brown")); + final LdapEntry entry25 = new LdapEntry(SortBehavior.ORDERED); + entry25.setDn("uid=818037,ou=people,dc=ldaptive,dc=org"); + final LdapAttribute attr252 = new LdapAttribute(SortBehavior.ORDERED); + attr252.setName("givenName"); + attr252.addStringValue("Joseph", "Joe"); + entry25.addAttribute( + new LdapAttribute("uid", "818037"), + attr252, + new LdapAttribute("sn", "Anderson")); + result2.addEntry(entry21); + result2.addEntry(entry22); + result2.addEntry(entry23); + result2.addEntry(entry24); + result2.addEntry(entry25); + + return + new Object[][] { + // note that search result isn't ordered, so the json isn't either + { + result1, + "[{\"dn\":\"uid=818037,ou=people,dc=ldaptive,dc=org\"," + + "\"departmentNumber\":[\"066103\"]," + + "\"givenName\":[\"Daniel\",\"Dan\"]," + + "\"sn\":[\"Fisher\"]}]", + }, + { + result2, + // CheckStyle:Indentation OFF + "[{\"dn\":\"uid=1095747,ou=people,dc=ldaptive,dc=org\"," + + "\"uid\":[\"1095747\"]," + + "\"givenName\":[\"Robert\",\"Bob\"]," + + "\"sn\":[\"Jones\"]}," + + "{\"dn\":\"uid=1141837,ou=people,dc=ldaptive,dc=org\"," + + "\"uid\":[\"1141837\"]," + + "\"givenName\":[\"William\",\"Bill\"]," + + "\"sn\":[\"Smith\"]}," + + "{\"dn\":\"uid=1145718,ou=people,dc=ldaptive,dc=org\"," + + "\"uid\":[\"1145718\"]," + + "\"givenName\":[\"Thomas\",\"Tom\"]," + + "\"sn\":[\"Johnson\"]}," + + "{\"dn\":\"uid=1152120,ou=people,dc=ldaptive,dc=org\"," + + "\"uid\":[\"1152120\"]," + + "\"givenName\":[\"David\",\"Dave\"]," + + "\"sn\":[\"Brown\"]}," + + "{\"dn\":\"uid=818037,ou=people,dc=ldaptive,dc=org\"," + + "\"uid\":[\"818037\"]," + + "\"givenName\":[\"Joseph\",\"Joe\"]," + + "\"sn\":[\"Anderson\"]}]", + // CheckStyle:Indentation ON + }, + }; + } + + + /** + * @param result to convert to json. + * @param json to expect from the writer. + * + * @throws Exception On test failure. + */ + @Test(groups = {"jsontest"}, dataProvider = "search-data") + public void writer(final SearchResult result, final String json) + throws Exception + { + final StringWriter writer = new StringWriter(); + (new JsonWriter(writer)).write(result); + AssertJUnit.assertEquals(json, writer.toString()); + } + + + /** + * @param result to convert to json. + * @param json to expect from the writer. + * + * @throws Exception On test failure. + */ + @Test(groups = {"jsontest"}, dataProvider = "search-data") + public void reader(final SearchResult result, final String json) + throws Exception + { + final StringReader reader = new StringReader(json); + AssertJUnit.assertEquals(result, (new JsonReader(reader)).read()); + } +}
diff --git a/ldapi/pom.xml b/ldapi/pom.xml new file mode 100644 index 0000000..626503d --- /dev/null +++ b/ldapi/pom.xml
@@ -0,0 +1,57 @@ +<?xml version='1.0' encoding='UTF-8'?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>ldaptive-ldapi</artifactId> + <packaging>jar</packaging> + <name>LDAPTIVE LDAPI</name> + <description>ldapi support</description> + <parent> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-parent</artifactId> + <version>1.2.3</version> + </parent> + + <properties> + <testng.dir>${basedir}/src/test/testng</testng.dir> + <ldapi.skipTests>true</ldapi.skipTests> + </properties> + + <dependencies> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive</artifactId> + </dependency> + <dependency> + <groupId>com.kohlschutter.junixsocket</groupId> + <artifactId>junixsocket-native-common</artifactId> + <exclusions> + <exclusion> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <!-- tests require local ldap instance --> + <skip>${ldapi.skipTests}</skip> + <suiteXmlFiles> + <suiteXmlFile>${testng.dir}/testng.xml</suiteXmlFile> + </suiteXmlFiles> + </configuration> + </plugin> + </plugins> + </build> +</project>
diff --git a/ldapi/src/main/java/org/ldaptive/ldapi/AFUnixSocketFactory.java b/ldapi/src/main/java/org/ldaptive/ldapi/AFUnixSocketFactory.java new file mode 100644 index 0000000..e859387 --- /dev/null +++ b/ldapi/src/main/java/org/ldaptive/ldapi/AFUnixSocketFactory.java
@@ -0,0 +1,148 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ldapi; + +import java.io.File; +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.URLDecoder; +import javax.net.SocketFactory; +import org.newsclub.net.unix.AFUNIXSocket; +import org.newsclub.net.unix.AFUNIXSocketAddress; + +/** + * AFUnixSocketFactory is an extension of SocketFactory which utilizes {@link AFUNIXSocket} to connect to a host, it is + * intended for local file-based unix native socket connections only. + * + * @author Middleware Services + */ +public class AFUnixSocketFactory extends SocketFactory +{ + + /** System parameter name specifying location of the socket file. */ + public static final String SOCKET_FILE_PROPERTY = "org.ldaptive.ldapi.socketFile"; + + /** File system location of the domain socket. Supplied either via constructor, or {@link #SOCKET_FILE_PROPERTY} */ + private final String socketFile; + + + /** Creates a new AFUnixSocketFactory configured with the system property {@link #SOCKET_FILE_PROPERTY}. */ + public AFUnixSocketFactory() + { + this(System.getProperty(SOCKET_FILE_PROPERTY)); + } + + + /** + * Creates a new AFUnixSocketFactory with a given file path. + * + * @param socket file system location of the domain socket + */ + public AFUnixSocketFactory(final String socket) + { + socketFile = socket; + } + + + /** + * This returns a new instance of AFUnixSocketFactory. See {@link #AFUnixSocketFactory()}. + * + * @return socket factory + */ + public static SocketFactory getDefault() + { + return new AFUnixSocketFactory(); + } + + + /** + * Uses the {@link #socketFile} property as the path to initiate a file socket ignoring all parameters of this + * method. + * + * @param host Unsupported, will be ignored + * @param port Unsupported, will be ignored + * + * @return unix socket + * + * @throws IOException if the file system location cannot be URL decoded + */ + @Override + public Socket createSocket(final String host, final int port) + throws IOException + { + final File file; + if (socketFile == null) { + throw new IOException("socketFile (specified in org.ldaptive.ldapi.socketFile" + + " or passed through factory constructor) MUST be specified to call this method."); + } + file = new File(URLDecoder.decode(socketFile, "UTF-8")); + final AFUNIXSocketAddress localAddress = new AFUNIXSocketAddress(file); + final AFUNIXSocket sock = AFUNIXSocket.newInstance(); + sock.connect(localAddress); + return sock; + } + + + /** + * Uses the {@link #socketFile} property as the path to initiate a file socket ignoring all parameters of this + * method. + * + * @param host Unsupported, will be ignored + * @param port Unsupported, will be ignored + * @param localHost Unsupported, will be ignored + * @param localPort Unsupported, will be ignored + * + * @return unix socket + * + * @throws IOException If socketFile is not specified or an underlying error occurs. + */ + @Override + public Socket createSocket(final String host, final int port, final InetAddress localHost, final int localPort) + throws IOException + { + return createSocket(socketFile, -1); + } + + + /** + * Uses the {@link #socketFile} property as the path to initiate a file socket ignoring all parameters of this + * method. + * + * @param host Unsupported, will be ignored + * @param port Unsupported, will be ignored + * + * @return unix socket + * + * @throws IOException If socketFile is not specified or an underlying error occurs. + */ + @Override + public Socket createSocket(final InetAddress host, final int port) + throws IOException + { + return createSocket(socketFile, -1); + } + + + /** + * Uses the {@link #socketFile} property as the path to initiate a file socket ignoring all parameters of this + * method. + * @param address Unsupported, will be ignored + * @param port Unsupported, will be ignored + * @param localAddress Unsupported, will be ignored + * @param localPort Unsupported, will be ignored + * + * @return unix socket + * + * @throws IOException If socketFile is not specified or an underlying error occurs. + */ + @Override + public Socket createSocket( + final InetAddress address, + final int port, + final InetAddress localAddress, + final int localPort) + throws IOException + { + return createSocket(socketFile, -1); + } +}
diff --git a/ldapi/src/test/java/org/ldaptive/ldapi/PerformanceTest.java b/ldapi/src/test/java/org/ldaptive/ldapi/PerformanceTest.java new file mode 100644 index 0000000..76aa0d9 --- /dev/null +++ b/ldapi/src/test/java/org/ldaptive/ldapi/PerformanceTest.java
@@ -0,0 +1,122 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.ldapi; + +import java.util.HashMap; +import java.util.Map; +import org.ldaptive.Connection; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.ConnectionFactory; +import org.ldaptive.DefaultConnectionFactory; +import org.ldaptive.SearchOperation; +import org.ldaptive.SearchRequest; +import org.ldaptive.SearchResult; +import org.ldaptive.provider.jndi.JndiProvider; +import org.newsclub.net.unix.AFUNIXSocket; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +/** + * Performance test for an ldap search operation over native sockets. + * + * @author Middleware Services + */ +public class PerformanceTest +{ + + /** LDAP host. */ + private String ldapHost; + + /** LDAP base dn. */ + private String ldapBaseDn; + + /** LDAP search filter. */ + private String ldapSearchFilter; + + + /** + * Initialize this test. + * + * @param socketFile file system location of the unix domain socket + * @param host for comparison + * @param baseDn to search on + * @param searchFilter to execute + */ + @BeforeClass(groups = {"ldapi"}) + @Parameters( + { + "ldapSocketFile", + "ldapTestHost", + "ldapBaseDn", + "ldapSearchFilter" + } + ) + public void initialize(final String socketFile, final String host, final String baseDn, final String searchFilter) + { + System.setProperty(AFUnixSocketFactory.SOCKET_FILE_PROPERTY, socketFile); + ldapHost = host; + ldapBaseDn = baseDn; + ldapSearchFilter = searchFilter; + } + + + /** + * Test connection factories. + * + * @return test data + * + * @throws Exception on test failure + */ + @DataProvider(name = "factories") + @SuppressWarnings("unchecked") + public Object[][] connectionFactories() + throws Exception + { + //Make sure native libraries are loaded and supported for the current unix based operating system. + AssertJUnit.assertTrue(AFUNIXSocket.isSupported()); + + final Map<String, Object> props = new HashMap<>(); + props.put(JndiProvider.SOCKET_FACTORY, "org.ldaptive.ldapi.AFUnixSocketFactory"); + + final DefaultConnectionFactory nativeFactory = new DefaultConnectionFactory( + new ConnectionConfig("ldap://domainsocket")); + nativeFactory.getProvider().getProviderConfig().setProperties(props); + + final DefaultConnectionFactory localFactory = new DefaultConnectionFactory(new ConnectionConfig(ldapHost)); + + final SearchRequest request = new SearchRequest(ldapBaseDn, ldapSearchFilter); + return new Object[][] { + new Object[] {nativeFactory, request, }, + new Object[] {localFactory, request, }, + }; + } + + + /** + * Searches with the supplied connection factory. + * + * @param connFactory to get connections from + * @param request to execute + * + * @throws Exception On test errors. + */ + @Test(groups = {"ldapi"}, dataProvider = "factories") + public void search(final ConnectionFactory connFactory, final SearchRequest request) + throws Exception + { + final long beforeTS = System.currentTimeMillis(); + try (Connection conn = connFactory.getConnection()) { + conn.open(); + for (int i = 0; i < 10000; i++) { + final SearchOperation search = new SearchOperation(conn); + final SearchResult result = search.execute(request).getResult(); + result.getEntries().forEach(org.ldaptive.LdapEntry::toString); + } + } + + final long afterTS = System.currentTimeMillis(); + System.out.println(String.format("Total Execution Time %s ms for %s", afterTS - beforeTS, connFactory)); + } +}
diff --git a/ldapi/src/test/testng/testng.xml b/ldapi/src/test/testng/testng.xml new file mode 100644 index 0000000..3e87d92 --- /dev/null +++ b/ldapi/src/test/testng/testng.xml
@@ -0,0 +1,21 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > + +<suite name="ldaptive-ldapi" verbose="1" parallel="tests" thread-count="1"> + + <parameter name="ldapSocketFile" value="${ldapSocketFile}"/> + <parameter name="ldapTestHost" value="${ldapTestHost}"/> + <parameter name="ldapBaseDn" value="${ldapBaseDn}"/> + <parameter name="ldapSearchFilter" value="${ldapSearchFilter}"/> + + <test name="tests" parallel="methods" thread-count="2"> + <groups> + <run> + <include name="ldapi" /> + </run> + </groups> + <packages> + <package name="org.ldaptive.ldapi.*" /> + </packages> + </test> +</suite>
diff --git a/mvn_cmd b/mvn_cmd new file mode 100755 index 0000000..20896e4 --- /dev/null +++ b/mvn_cmd
@@ -0,0 +1,49 @@ +#!/bin/sh + +MVN=mvn + +function run_mvn() { + PROFILES=$1 + PHASES=$2 + SWITCH=$3 + if [ -z "${SWITCH}" ]; then + ${MVN} -U -P${PROFILES} ${PHASES} + else + ${MVN} -U -P${PROFILES} ${PHASES} -D${SWITCH} + fi +} + +case "$1" in + clean) + run_mvn integration,distribution,apache,jldap,opendj,unboundid clean + ;; + javadoc) + run_mvn apache,jldap,opendj,unboundid javadoc:javadoc + ;; + package) + run_mvn distribution,apache,jldap,opendj,unboundid package + ;; + verify) + run_mvn distribution,apache,jldap,opendj,unboundid verify + ;; + install) + run_mvn distribution,apache,jldap,opendj,unboundid install + ;; + deploy) + LOCAL_REPO=${2} + if [ -z "${LOCAL_REPO}" ]; then + echo "USAGE: `basename $0` deploy <repo-directory>" + exit 1 + fi + run_mvn apache,jldap,opendj,unboundid clean + run_mvn apache,jldap,opendj,unboundid deploy "altDeploymentRepository=snapshot::default::file://${LOCAL_REPO}" + ;; + bundle-create) + run_mvn distribution,apache,jldap,opendj,unboundid repository:bundle-create sign=true + ;; + *) + if [ -n "$1" ]; then + echo "Invalid command" + fi + echo "USAGE: `basename $0` clean|javadoc|package|verify|install|deploy|bundle-create" +esac
diff --git a/opendj-provider/pom.xml b/opendj-provider/pom.xml new file mode 100644 index 0000000..26cbe0d --- /dev/null +++ b/opendj-provider/pom.xml
@@ -0,0 +1,27 @@ +<?xml version='1.0' encoding='UTF-8'?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>ldaptive-opendj</artifactId> + <packaging>jar</packaging> + <name>LDAPTIVE OPENDJ PROVIDER</name> + <description>Ldaptive opendj provider</description> + <parent> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-parent</artifactId> + <version>1.2.3</version> + </parent> + + <dependencies> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive</artifactId> + </dependency> + <dependency> + <groupId>org.forgerock.opendj</groupId> + <artifactId>opendj-ldap-sdk</artifactId> + </dependency> + </dependencies> + +</project>
diff --git a/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJConnection.java b/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJConnection.java new file mode 100644 index 0000000..f797db9 --- /dev/null +++ b/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJConnection.java
@@ -0,0 +1,1188 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.opendj; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; +import org.forgerock.opendj.ldap.ByteString; +import org.forgerock.opendj.ldap.Connection; +import org.forgerock.opendj.ldap.ConnectionEventListener; +import org.forgerock.opendj.ldap.DereferenceAliasesPolicy; +import org.forgerock.opendj.ldap.ErrorResultException; +import org.forgerock.opendj.ldap.FutureResult; +import org.forgerock.opendj.ldap.IntermediateResponseHandler; +import org.forgerock.opendj.ldap.Modification; +import org.forgerock.opendj.ldap.ReferralException; +import org.forgerock.opendj.ldap.SearchResultHandler; +import org.forgerock.opendj.ldap.SearchScope; +import org.forgerock.opendj.ldap.controls.Control; +import org.forgerock.opendj.ldap.requests.DigestMD5SASLBindRequest; +import org.forgerock.opendj.ldap.requests.ExternalSASLBindRequest; +import org.forgerock.opendj.ldap.requests.GSSAPISASLBindRequest; +import org.forgerock.opendj.ldap.requests.GenericExtendedRequest; +import org.forgerock.opendj.ldap.requests.Requests; +import org.forgerock.opendj.ldap.requests.SASLBindRequest; +import org.forgerock.opendj.ldap.requests.SearchRequest; +import org.forgerock.opendj.ldap.requests.SimpleBindRequest; +import org.forgerock.opendj.ldap.responses.BindResult; +import org.forgerock.opendj.ldap.responses.CompareResult; +import org.forgerock.opendj.ldap.responses.ExtendedResult; +import org.forgerock.opendj.ldap.responses.GenericExtendedResult; +import org.forgerock.opendj.ldap.responses.IntermediateResponse; +import org.forgerock.opendj.ldap.responses.Result; +import org.forgerock.opendj.ldap.responses.SearchResultEntry; +import org.forgerock.opendj.ldap.responses.SearchResultReference; +import org.ldaptive.AddRequest; +import org.ldaptive.BindRequest; +import org.ldaptive.CompareRequest; +import org.ldaptive.DeleteRequest; +import org.ldaptive.DerefAliases; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.ModifyDnRequest; +import org.ldaptive.ModifyRequest; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchReference; +import org.ldaptive.async.AsyncRequest; +import org.ldaptive.control.RequestControl; +import org.ldaptive.control.ResponseControl; +import org.ldaptive.extended.ExtendedRequest; +import org.ldaptive.extended.ExtendedResponse; +import org.ldaptive.extended.ExtendedResponseFactory; +import org.ldaptive.extended.UnsolicitedNotificationListener; +import org.ldaptive.intermediate.IntermediateResponseFactory; +import org.ldaptive.provider.ProviderUtils; +import org.ldaptive.provider.SearchItem; +import org.ldaptive.provider.SearchIterator; +import org.ldaptive.provider.SearchListener; +import org.ldaptive.sasl.DigestMd5Config; +import org.ldaptive.sasl.QualityOfProtection; +import org.ldaptive.sasl.SaslConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * OpenDJ provider implementation of ldap operations. + * + * @author Middleware Services + */ +public class OpenDJConnection implements org.ldaptive.provider.ProviderConnection +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Ldap connection. */ + private Connection connection; + + /** Provider configuration. */ + private final OpenDJProviderConfig config; + + /** Connection event listener for unsolicited notifications. */ + private final AggregateUnsolicitedNotificationListener notificationListener = + new AggregateUnsolicitedNotificationListener(); + + + /** + * Creates a new opendj ldap connection. + * + * @param c ldap connection + * @param pc provider configuration + */ + public OpenDJConnection(final Connection c, final OpenDJProviderConfig pc) + { + connection = c; + config = pc; + connection.addConnectionEventListener(notificationListener); + } + + + /** + * Returns the underlying ldap connection. + * + * @return ldap connection + */ + public Connection getLdapConnection() + { + return connection; + } + + + @Override + public void close(final RequestControl[] controls) + throws LdapException + { + if (connection != null) { + final org.forgerock.opendj.ldap.requests.UnbindRequest ur = Requests.newUnbindRequest(); + if (controls != null) { + for (Control c : config.getControlProcessor().processRequestControls(controls)) { + ur.addControl(c); + } + } + + try { + connection.close(ur, "Close requested by client"); + } finally { + connection = null; + } + } + } + + + @Override + public Response<Void> bind(final BindRequest request) + throws LdapException + { + Response<Void> response; + if (request.getSaslConfig() != null) { + response = saslBind(request); + } else if (request.getDn() == null && request.getCredential() == null) { + response = anonymousBind(request); + } else { + response = simpleBind(request); + } + return response; + } + + + /** + * Performs an anonymous bind. + * + * @param request to bind with + * + * @return bind response + * + * @throws LdapException if an error occurs + */ + protected Response<Void> anonymousBind(final BindRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final SimpleBindRequest sbr = Requests.newSimpleBindRequest(); + if (request.getControls() != null) { + for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) { + sbr.addControl(c); + } + } + + final BindResult result = connection.bind(sbr); + response = createResponse(request, null, result); + } catch (ReferralException e) { + response = createResponse(request, null, e.getResult()); + } catch (ErrorResultException e) { + processErrorResultException(request, e); + } + return response; + } + + + /** + * Performs a simple bind. + * + * @param request to bind with + * + * @return bind response + * + * @throws LdapException if an error occurs + */ + protected Response<Void> simpleBind(final BindRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final SimpleBindRequest sbr = Requests.newSimpleBindRequest(request.getDn(), request.getCredential().getChars()); + if (request.getControls() != null) { + for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) { + sbr.addControl(c); + } + } + + final BindResult result = connection.bind(sbr); + response = createResponse(request, null, result); + } catch (ReferralException e) { + response = createResponse(request, null, e.getResult()); + } catch (ErrorResultException e) { + processErrorResultException(request, e); + } + return response; + } + + + /** + * Performs a sasl bind. + * + * @param request to bind with + * + * @return bind response + * + * @throws LdapException if an error occurs + */ + protected Response<Void> saslBind(final BindRequest request) + throws LdapException + { + Response<Void> response = null; + SASLBindRequest sbr; + final SaslConfig sc = request.getSaslConfig(); + switch (sc.getMechanism()) { + + case EXTERNAL: + sbr = Requests.newExternalSASLBindRequest(); + ((ExternalSASLBindRequest) sbr).setAuthorizationID(sc.getAuthorizationId()); + break; + + case DIGEST_MD5: + sbr = Requests.newDigestMD5SASLBindRequest( + request.getDn() != null ? + request.getDn() : "", request.getCredential() != null ? request.getCredential().getBytes() : null); + String digestMd5Realm = sc instanceof DigestMd5Config ? ((DigestMd5Config) sc).getRealm() : null; + if (digestMd5Realm == null && request.getDn().contains("@")) { + digestMd5Realm = request.getDn().substring(request.getDn().indexOf("@") + 1); + } + if (digestMd5Realm != null) { + ((DigestMD5SASLBindRequest) sbr).setRealm(digestMd5Realm); + } + break; + + case CRAM_MD5: + throw new UnsupportedOperationException("CRAM-MD5 not supported"); + // LDAP reports: error: SASL bind in progress (tag=99) + /* + * sbr = Requests.newCRAMMD5SASLBindRequest( + * request.getDn() != null ? request.getDn() : "", + * request.getCredential() != null ? + * request.getCredential().getBytes() : null); + * break; + */ + + case GSSAPI: + throw new UnsupportedOperationException("GSSAPI not supported"); + /* + * sbr = Requests.newGSSAPISASLBindRequest( + * request.getDn() != null ? request.getDn() : "", + * request.getCredential() != null ? + * request.getCredential().getBytes() : new byte[0]); + * ((GSSAPISASLBindRequest) sbr).setAuthorizationID( + * sc.getAuthorizationId()); + * final String gssApiRealm = sc instanceof GssApiConfig + * ? ((GssApiConfig) sc).getRealm() : null; + * if (gssApiRealm != null) { + * ((GSSAPISASLBindRequest) sbr).setRealm(gssApiRealm); + * } + * if (sc.getQualityOfProtection() != null) { + * ((GSSAPISASLBindRequest) sbr).addQOP( + * getQualityOfProtection(sc.getQualityOfProtection())); + * } + * break; + */ + + default: + throw new IllegalArgumentException("Unknown SASL authentication mechanism: " + sc.getMechanism()); + } + + if (request.getControls() != null) { + for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) { + sbr.addControl(c); + } + } + + try { + final BindResult result = connection.bind(sbr); + response = createResponse(request, null, result); + } catch (ReferralException e) { + response = createResponse(request, null, e.getResult()); + } catch (ErrorResultException e) { + processErrorResultException(request, e); + } + return response; + } + + + /** + * Returns the SASL quality of protection string for the supplied enum. + * + * @param qop quality of protection enum + * + * @return SASL quality of protection string + */ + protected static String getQualityOfProtection(final QualityOfProtection qop) + { + String name; + switch (qop) { + + case AUTH: + name = GSSAPISASLBindRequest.QOP_AUTH; + break; + + case AUTH_INT: + name = GSSAPISASLBindRequest.QOP_AUTH_INT; + break; + + case AUTH_CONF: + name = GSSAPISASLBindRequest.QOP_AUTH_CONF; + break; + + default: + throw new IllegalArgumentException("Unknown SASL quality of protection: " + qop); + } + return name; + } + + + @Override + public Response<Void> add(final AddRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final OpenDJUtils util = new OpenDJUtils(); + final org.forgerock.opendj.ldap.requests.AddRequest ar = Requests.newAddRequest( + util.fromLdapEntry(new LdapEntry(request.getDn(), request.getLdapAttributes()))); + if (request.getControls() != null) { + for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) { + ar.addControl(c); + } + } + + final Result result = connection.add(ar); + response = createResponse(request, null, result); + } catch (ReferralException e) { + response = createResponse(request, null, e.getResult()); + } catch (ErrorResultException e) { + processErrorResultException(request, e); + } + return response; + } + + + @Override + public Response<Boolean> compare(final CompareRequest request) + throws LdapException + { + Response<Boolean> response = null; + try { + final OpenDJUtils util = new OpenDJUtils(); + org.forgerock.opendj.ldap.requests.CompareRequest cr; + if (request.getAttribute().isBinary()) { + cr = Requests.newCompareRequest( + request.getDn(), + request.getAttribute().getName(), + util.fromBinaryValues(request.getAttribute().getBinaryValues())[0]); + } else { + cr = Requests.newCompareRequest( + request.getDn(), + request.getAttribute().getName(), + util.fromStringValues(request.getAttribute().getStringValues())[0]); + } + if (request.getControls() != null) { + for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) { + cr.addControl(c); + } + } + + final CompareResult result = connection.compare(cr); + response = createResponse(request, result.matched(), result); + } catch (ReferralException e) { + response = createResponse(request, null, e.getResult()); + } catch (ErrorResultException e) { + processErrorResultException(request, e); + } + return response; + } + + + @Override + public Response<Void> delete(final DeleteRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final org.forgerock.opendj.ldap.requests.DeleteRequest dr = Requests.newDeleteRequest(request.getDn()); + if (request.getControls() != null) { + for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) { + dr.addControl(c); + } + } + + final Result result = connection.delete(dr); + response = createResponse(request, null, result); + } catch (ReferralException e) { + response = createResponse(request, null, e.getResult()); + } catch (ErrorResultException e) { + processErrorResultException(request, e); + } + return response; + } + + + @Override + public Response<Void> modify(final ModifyRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final OpenDJUtils util = new OpenDJUtils(); + final org.forgerock.opendj.ldap.requests.ModifyRequest mr = Requests.newModifyRequest(request.getDn()); + for (Modification m : util.fromAttributeModification(request.getAttributeModifications())) { + mr.addModification(m); + } + if (request.getControls() != null) { + for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) { + mr.addControl(c); + } + } + + final Result result = connection.modify(mr); + response = createResponse(request, null, result); + } catch (ReferralException e) { + response = createResponse(request, null, e.getResult()); + } catch (ErrorResultException e) { + processErrorResultException(request, e); + } + return response; + } + + + @Override + public Response<Void> modifyDn(final ModifyDnRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final org.forgerock.opendj.ldap.requests.ModifyDNRequest mdr = Requests.newModifyDNRequest( + request.getDn(), + request.getNewDn()); + mdr.setDeleteOldRDN(request.getDeleteOldRDn()); + if (request.getControls() != null) { + for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) { + mdr.addControl(c); + } + } + + final Result result = connection.modifyDN(mdr); + response = createResponse(request, null, result); + } catch (ReferralException e) { + response = createResponse(request, null, e.getResult()); + } catch (ErrorResultException e) { + processErrorResultException(request, e); + } + return response; + } + + + @Override + public SearchIterator search(final org.ldaptive.SearchRequest request) + throws LdapException + { + final OpenDJSearchIterator i = new OpenDJSearchIterator(request); + i.initialize(); + return i; + } + + + @Override + public void searchAsync(final org.ldaptive.SearchRequest request, final SearchListener listener) + throws LdapException + { + final OpenDJAsyncSearchListener l = new OpenDJAsyncSearchListener(request, listener); + l.initialize(); + } + + + @Override + public void abandon(final int messageId, final RequestControl[] controls) + throws LdapException + { + final org.forgerock.opendj.ldap.requests.AbandonRequest ar = Requests.newAbandonRequest(messageId); + if (controls != null) { + for (Control c : config.getControlProcessor().processRequestControls(controls)) { + ar.addControl(c); + } + } + + connection.abandonAsync(ar); + } + + + @Override + public Response<?> extendedOperation(final ExtendedRequest request) + throws LdapException + { + Response<?> response = null; + try { + GenericExtendedRequest er; + final byte[] requestBerValue = request.encode(); + if (requestBerValue == null) { + er = Requests.newGenericExtendedRequest(request.getOID()); + } else { + er = Requests.newGenericExtendedRequest(request.getOID(), ByteString.wrap(requestBerValue)); + } + if (request.getControls() != null) { + for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) { + er.addControl(c); + } + } + + final GenericExtendedResult result = connection.extendedRequest(er); + final byte[] responseBerValue = result.getValue() != null ? result.getValue().toByteArray() : null; + final ExtendedResponse<?> extRes = ExtendedResponseFactory.createExtendedResponse( + request.getOID(), + result.getOID(), + responseBerValue); + response = createResponse(request, extRes.getValue(), result); + } catch (ErrorResultException e) { + processErrorResultException(request, e); + } + return response; + } + + + @Override + public void addUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + notificationListener.addUnsolicitedNotificationListener(listener); + } + + + @Override + public void removeUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + notificationListener.removeUnsolicitedNotificationListener(listener); + } + + + /** + * Creates an operation response with the supplied response data. + * + * @param <T> type of response + * @param request containing controls + * @param result of the operation + * @param ldapResult provider result + * + * @return operation response + */ + protected <T> Response<T> createResponse(final Request request, final T result, final Result ldapResult) + { + final List<Control> ctls = ldapResult.getControls(); + final List<String> urls = ldapResult.getReferralURIs(); + return + new Response<>( + result, + ResultCode.valueOf(ldapResult.getResultCode().intValue()), + ldapResult.getDiagnosticMessage(), + ldapResult.getMatchedDN(), + config.getControlProcessor().processResponseControls(ctls.toArray(new Control[ctls.size()])), + urls.toArray(new String[urls.size()]), + -1); + } + + + /** + * Determines if the supplied error result exception should result in an operation retry. + * + * @param request that produced the exception + * @param e that was produced + * + * @throws LdapException wrapping the error result exception + */ + protected void processErrorResultException(final Request request, final ErrorResultException e) + throws LdapException + { + final List<Control> ctls = e.getResult().getControls(); + final List<String> urls = e.getResult().getReferralURIs(); + ProviderUtils.throwOperationException( + config.getOperationExceptionResultCodes(), + e, + e.getResult().getResultCode().intValue(), + e.getResult().getMatchedDN(), + config.getControlProcessor().processResponseControls(ctls.toArray(new Control[ctls.size()])), + urls.toArray(new String[urls.size()]), + true); + } + + + /** Search iterator for opendj search results. */ + protected class OpenDJSearchIterator extends AbstractOpenDJSearch implements SearchIterator + { + + /** Response data. */ + private org.ldaptive.Response<Void> response; + + /** Search result iterator. */ + private SearchResultIterator resultIterator; + + + /** + * Creates a new opendj search iterator. + * + * @param sr search request + */ + public OpenDJSearchIterator(final org.ldaptive.SearchRequest sr) + { + super(sr); + } + + + /** + * Initializes this opendj search iterator. + * + * @throws LdapException if an error occurs + */ + public void initialize() + throws LdapException + { + resultIterator = search(connection, request); + } + + + /** + * Executes an ldap search. + * + * @param conn to search with + * @param sr to read properties from + * + * @return ldap search results + * + * @throws LdapException if an error occurs + */ + protected SearchResultIterator search(final Connection conn, final org.ldaptive.SearchRequest sr) + throws LdapException + { + final SearchRequest opendjSr = getSearchRequest(sr); + if (sr.getControls() != null) { + for (Control c : config.getControlProcessor().processRequestControls(sr.getControls())) { + opendjSr.addControl(c); + } + } + + final SearchResultIterator i = new SearchResultIterator(); + try { + conn.search(opendjSr, i); + } catch (ErrorResultException e) { + final ResultCode rc = ignoreSearchException(config.getSearchIgnoreResultCodes(), e); + if (rc == null) { + processErrorResultException(request, e); + } + } + return i; + } + + + @Override + public boolean hasNext() + throws LdapException + { + if (resultIterator == null || response != null) { + return false; + } + + final boolean more = resultIterator.hasNext(); + if (!more) { + final Result result = resultIterator.getResult(); + logger.trace("reading search result: {}", result); + response = createResponse(request, null, result); + } + return more; + } + + + @Override + public SearchItem next() + throws LdapException + { + return resultIterator.next(); + } + + + @Override + public org.ldaptive.Response<Void> getResponse() + { + return response; + } + + + @Override + public void close() + throws LdapException {} + + + /** Search results handler for storing entries returned by a search operation. */ + protected class SearchResultIterator implements SearchResultHandler + { + + /** Search items. */ + protected final Queue<SearchItem> queue = new ArrayDeque<>(); + + /** Search result. */ + private Result result; + + + /** + * Returns the next search item from the queue. + * + * @return search item + */ + public SearchItem next() + { + return queue.poll(); + } + + + /** + * Returns the result of the search. + * + * @return search result + */ + public Result getResult() + { + return result; + } + + + /** + * Whether the queue is empty. + * + * @return whether the queue is empty + */ + public boolean hasNext() + { + return !queue.isEmpty(); + } + + + @Override + public void handleErrorResult(final ErrorResultException e) + { + logger.trace("reading error result: {}", e); + result = e.getResult(); + } + + + @Override + public void handleResult(final Result r) + { + logger.trace("reading result: {}", r); + result = r; + } + + + @Override + public boolean handleEntry(final SearchResultEntry entry) + { + return queue.add(processSearchResultEntry(entry)); + } + + + @Override + public boolean handleReference(final SearchResultReference ref) + { + return queue.add(processSearchResultReference(ref)); + } + } + } + + + /** Search listener for opendj id async search results. */ + protected class OpenDJAsyncSearchListener extends AbstractOpenDJSearch + implements SearchResultHandler, IntermediateResponseHandler + { + + /** Search result listener. */ + private final SearchListener listener; + + + /** + * Creates a new opendj async search listener. + * + * @param sr search request + * @param sl search listener + */ + public OpenDJAsyncSearchListener(final org.ldaptive.SearchRequest sr, final SearchListener sl) + { + super(sr); + listener = sl; + } + + + /** + * Initializes this opendj async search listener. + * + * @throws LdapException if an error occurs + */ + public void initialize() + throws LdapException + { + search(connection, request); + } + + + /** + * Executes an asynchronous ldap search. + * + * @param conn to search with + * @param sr to read properties from + * + * @throws LdapException if an error occurs + */ + protected void search(final Connection conn, final org.ldaptive.SearchRequest sr) + throws LdapException + { + final SearchRequest opendjSr = getSearchRequest(sr); + if (sr.getControls() != null) { + for (Control c : config.getControlProcessor().processRequestControls(sr.getControls())) { + opendjSr.addControl(c); + } + } + + final FutureResult<Result> result = conn.searchAsync(opendjSr, this, this); + listener.asyncRequestReceived(new OpenDJAsyncRequest(result)); + } + + + @Override + public void handleErrorResult(final ErrorResultException e) + { + logger.trace("reading error result: {}", e); + + final List<Control> ctls = e.getResult().getControls(); + final List<String> urls = e.getResult().getReferralURIs(); + listener.exceptionReceived( + new LdapException( + e.getMessage(), + new Exception(e.getCause()), + ResultCode.valueOf(e.getResult().getResultCode().intValue()), + e.getResult().getMatchedDN(), + config.getControlProcessor().processResponseControls(ctls.toArray(new Control[ctls.size()])), + urls.toArray(new String[urls.size()]))); + } + + + @Override + public void handleResult(final Result r) + { + logger.trace("reading result: {}", r); + + final org.ldaptive.Response<Void> response = createResponse(request, null, r); + listener.responseReceived(response); + } + + + @Override + public boolean handleEntry(final SearchResultEntry entry) + { + listener.searchItemReceived(processSearchResultEntry(entry)); + return true; + } + + + @Override + public boolean handleReference(final SearchResultReference ref) + { + listener.searchItemReceived(processSearchResultReference(ref)); + return true; + } + + + @Override + public boolean handleIntermediateResponse(final IntermediateResponse res) + { + listener.searchItemReceived(processIntermediateResponse(res)); + return true; + } + } + + + /** Common search functionality for opendj iterators and listeners. */ + protected abstract class AbstractOpenDJSearch + { + + /** Search request. */ + protected final org.ldaptive.SearchRequest request; + + /** Utility class. */ + protected final OpenDJUtils util; + + + /** + * Creates a new abstract opendj search. + * + * @param sr search request + */ + public AbstractOpenDJSearch(final org.ldaptive.SearchRequest sr) + { + request = sr; + util = new OpenDJUtils(request.getSortBehavior()); + util.setBinaryAttributes(request.getBinaryAttributes()); + } + + + /** + * Returns an opendj search request object configured with the supplied search request. + * + * @param sr search request containing configuration to create opendj search request + * + * @return search request + */ + protected SearchRequest getSearchRequest(final org.ldaptive.SearchRequest sr) + { + final SearchRequest opendjSr = Requests.newSearchRequest( + sr.getBaseDn(), + getSearchScope(sr.getSearchScope()), + sr.getSearchFilter() != null ? sr.getSearchFilter().format() : null, + sr.getReturnAttributes()); + opendjSr.setDereferenceAliasesPolicy(getDereferencePolicy(sr.getDerefAliases())); + opendjSr.setSizeLimit((int) sr.getSizeLimit()); + opendjSr.setTimeLimit((int) sr.getTimeLimit().getSeconds()); + opendjSr.setTypesOnly(sr.getTypesOnly()); + return opendjSr; + } + + + /** + * Returns the opendj search scope for the supplied search scope. + * + * @param ss search scope + * + * @return opendj search scope + */ + protected SearchScope getSearchScope(final org.ldaptive.SearchScope ss) + { + SearchScope scope = null; + if (ss == org.ldaptive.SearchScope.OBJECT) { + scope = SearchScope.BASE_OBJECT; + } else if (ss == org.ldaptive.SearchScope.ONELEVEL) { + scope = SearchScope.SINGLE_LEVEL; + } else if (ss == org.ldaptive.SearchScope.SUBTREE) { + scope = SearchScope.WHOLE_SUBTREE; + } + return scope; + } + + + /** + * Returns the opendj deference policy for the supplied deref aliases. + * + * @param deref deref aliases + * + * @return dereference policy + */ + protected DereferenceAliasesPolicy getDereferencePolicy(final DerefAliases deref) + { + DereferenceAliasesPolicy policy = DereferenceAliasesPolicy.NEVER; + if (deref == DerefAliases.ALWAYS) { + policy = DereferenceAliasesPolicy.ALWAYS; + } else if (deref == DerefAliases.FINDING) { + policy = DereferenceAliasesPolicy.FINDING_BASE; + } else if (deref == DerefAliases.NEVER) { + policy = DereferenceAliasesPolicy.NEVER; + } else if (deref == DerefAliases.SEARCHING) { + policy = DereferenceAliasesPolicy.IN_SEARCHING; + } + return policy; + } + + + /** + * Determines whether the supplied ldap exception should be ignored. + * + * @param ignoreResultCodes to match against the exception + * @param e ldap exception to match + * + * @return result code that should be ignored or null + */ + protected ResultCode ignoreSearchException(final ResultCode[] ignoreResultCodes, final ErrorResultException e) + { + ResultCode ignore = null; + if (ignoreResultCodes != null && ignoreResultCodes.length > 0) { + for (ResultCode rc : ignoreResultCodes) { + if (e.getResult().getResultCode().intValue() == rc.value()) { + logger.debug("Ignoring ldap exception", e); + ignore = rc; + break; + } + } + } + return ignore; + } + + + /** + * Processes the response controls on the supplied entry and returns a corresponding search item. + * + * @param entry to process + * + * @return search item + */ + protected SearchItem processSearchResultEntry(final SearchResultEntry entry) + { + logger.trace("reading search entry: {}", entry); + + ResponseControl[] respControls = null; + if (entry.getControls() != null && entry.getControls().size() > 0) { + final List<Control> ctls = entry.getControls(); + respControls = config.getControlProcessor().processResponseControls(ctls.toArray(new Control[ctls.size()])); + } + + final SearchEntry se = util.toSearchEntry(entry, respControls, -1); + return new SearchItem(se); + } + + + /** + * Processes the response controls on the supplied reference and returns a corresponding search item. + * + * @param ref to process + * + * @return search item + */ + protected SearchItem processSearchResultReference(final SearchResultReference ref) + { + logger.trace("reading search reference: {}", ref); + + ResponseControl[] respControls = null; + if (ref.getControls() != null && ref.getControls().size() > 0) { + final List<Control> ctls = ref.getControls(); + respControls = config.getControlProcessor().processResponseControls(ctls.toArray(new Control[ctls.size()])); + } + + final SearchReference sr = new SearchReference(-1, respControls, ref.getURIs()); + return new SearchItem(sr); + } + + + /** + * Processes the response controls on the supplied response and returns a corresponding search item. + * + * @param res to process + * + * @return search item + */ + protected SearchItem processIntermediateResponse(final IntermediateResponse res) + { + logger.trace("reading intermediate response: {}", res); + + ResponseControl[] respControls = null; + if (res.getControls() != null && res.getControls().size() > 0) { + final List<Control> ctls = res.getControls(); + respControls = config.getControlProcessor().processResponseControls(ctls.toArray(new Control[ctls.size()])); + } + + final org.ldaptive.intermediate.IntermediateResponse ir = IntermediateResponseFactory.createIntermediateResponse( + res.getOID(), + res.getValue().toByteArray(), + respControls, + -1); + return new SearchItem(ir); + } + } + + + /** Async request to invoke abandons. */ + protected class OpenDJAsyncRequest implements AsyncRequest + { + + /** Future result. */ + private final FutureResult<Result> result; + + + /** + * Creates a new OpenDJ async request. + * + * @param r future result from an async operation + */ + public OpenDJAsyncRequest(final FutureResult<Result> r) + { + result = r; + } + + + @Override + public int getMessageId() + { + return result.getRequestID(); + } + + + @Override + public void abandon() + throws LdapException + { + final org.forgerock.opendj.ldap.requests.AbandonRequest ar = Requests.newAbandonRequest(result.getRequestID()); + connection.abandonAsync(ar); + } + + + @Override + public void abandon(final RequestControl[] controls) + throws LdapException + { + final org.forgerock.opendj.ldap.requests.AbandonRequest ar = Requests.newAbandonRequest(result.getRequestID()); + if (controls != null) { + for (Control c : config.getControlProcessor().processRequestControls(controls)) { + ar.addControl(c); + } + } + connection.abandonAsync(ar); + } + } + + + /** Allows the use of multiple unsolicited notification listeners per connection. */ + protected class AggregateUnsolicitedNotificationListener implements ConnectionEventListener + { + + /** Listeners to receive unsolicited notifications. */ + private final List<UnsolicitedNotificationListener> listeners = new ArrayList<>(); + + + /** + * Adds an unsolicited notification listener to this listener. + * + * @param listener to receive unsolicited notifications + */ + public void addUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + synchronized (listeners) { + listeners.add(listener); + } + } + + + /** + * Removes an unsolicited notification listener from this listener. + * + * @param listener to stop receiving unsolicited notifications + */ + public void removeUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + synchronized (listeners) { + listeners.remove(listener); + } + } + + + @Override + public void handleConnectionClosed() {} + + + @Override + public void handleConnectionError(final boolean b, final ErrorResultException e) {} + + + @Override + public void handleUnsolicitedNotification(final ExtendedResult extendedResult) + { + logger.debug("Unsolicited notification received: {}", extendedResult); + synchronized (listeners) { + final Response<Void> response = createResponse(null, null, extendedResult); + for (UnsolicitedNotificationListener listener : listeners) { + listener.notificationReceived(extendedResult.getOID(), response); + } + } + } + } +}
diff --git a/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJConnectionFactory.java b/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJConnectionFactory.java new file mode 100644 index 0000000..a85943b --- /dev/null +++ b/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJConnectionFactory.java
@@ -0,0 +1,75 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.opendj; + +import org.forgerock.opendj.ldap.Connection; +import org.forgerock.opendj.ldap.ErrorResultException; +import org.forgerock.opendj.ldap.LDAPConnectionFactory; +import org.forgerock.opendj.ldap.LDAPOptions; +import org.ldaptive.ConnectionStrategy; +import org.ldaptive.LdapException; +import org.ldaptive.LdapURL; +import org.ldaptive.provider.AbstractProviderConnectionFactory; +import org.ldaptive.provider.ConnectionException; + +/** + * Creates ldap connections using the OpenDJ LDAPConnectionFactory class. + * + * @author Middleware Services + */ +public class OpenDJConnectionFactory extends AbstractProviderConnectionFactory<OpenDJProviderConfig> +{ + + /** Ldap connection options. */ + private final LDAPOptions ldapOptions; + + + /** + * Creates a new OpenDJ connection factory. + * + * @param url of the ldap to connect to + * @param strategy connection strategy + * @param config provider configuration + * @param options connection options + */ + public OpenDJConnectionFactory( + final String url, + final ConnectionStrategy strategy, + final OpenDJProviderConfig config, + final LDAPOptions options) + { + super(url, strategy, config); + ldapOptions = options; + } + + + @Override + protected OpenDJConnection createInternal(final String url) + throws LdapException + { + final LdapURL ldapUrl = new LdapURL(url); + OpenDJConnection conn = null; + boolean closeConn = false; + try { + final LDAPConnectionFactory cf = new LDAPConnectionFactory( + ldapUrl.getLastEntry().getHostname(), + ldapUrl.getLastEntry().getPort(), + ldapOptions); + final Connection c = cf.getConnection(); + conn = new OpenDJConnection(c, getProviderConfig()); + } catch (ErrorResultException e) { + closeConn = true; + throw new ConnectionException(e, org.ldaptive.ResultCode.valueOf(e.getResult().getResultCode().intValue())); + } finally { + if (closeConn) { + try { + if (conn != null) { + conn.close(null); + } + } catch (LdapException e) { + logger.debug("Problem tearing down connection", e); + } + } + } + return conn; + } +}
diff --git a/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJControlHandler.java b/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJControlHandler.java new file mode 100644 index 0000000..ffc2adf --- /dev/null +++ b/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJControlHandler.java
@@ -0,0 +1,58 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.opendj; + +import org.forgerock.opendj.ldap.ByteStringBuilder; +import org.forgerock.opendj.ldap.controls.GenericControl; +import org.ldaptive.control.ControlFactory; +import org.ldaptive.control.RequestControl; +import org.ldaptive.control.ResponseControl; +import org.ldaptive.provider.ControlHandler; + +/** + * OpenDJ control handler. + * + * @author Middleware Services + */ +public class OpenDJControlHandler implements ControlHandler<org.forgerock.opendj.ldap.controls.Control> +{ + + + @Override + public Class<org.forgerock.opendj.ldap.controls.Control> getControlType() + { + return org.forgerock.opendj.ldap.controls.Control.class; + } + + + @Override + public String getOID(final org.forgerock.opendj.ldap.controls.Control control) + { + return control.getOID(); + } + + + @Override + public org.forgerock.opendj.ldap.controls.Control handleRequest(final RequestControl requestControl) + { + final byte[] value = requestControl.encode(); + if (value == null) { + return GenericControl.newControl(requestControl.getOID(), requestControl.getCriticality()); + } else { + final ByteStringBuilder builder = new ByteStringBuilder(value.length); + builder.append(value); + return + GenericControl.newControl(requestControl.getOID(), requestControl.getCriticality(), builder.toByteString()); + } + } + + + @Override + public ResponseControl handleResponse(final org.forgerock.opendj.ldap.controls.Control responseControl) + { + return + ControlFactory.createResponseControl( + responseControl.getOID(), + responseControl.isCritical(), + responseControl.getValue().toByteArray()); + } +}
diff --git a/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJProvider.java b/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJProvider.java new file mode 100644 index 0000000..5becd6e --- /dev/null +++ b/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJProvider.java
@@ -0,0 +1,149 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.opendj; + +import java.security.GeneralSecurityException; +import java.util.concurrent.TimeUnit; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import org.forgerock.opendj.ldap.LDAPOptions; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.LdapURL; +import org.ldaptive.provider.Provider; +import org.ldaptive.provider.ProviderConnectionFactory; +import org.ldaptive.ssl.CertificateHostnameVerifier; +import org.ldaptive.ssl.CredentialConfig; +import org.ldaptive.ssl.DefaultHostnameVerifier; +import org.ldaptive.ssl.DefaultSSLContextInitializer; +import org.ldaptive.ssl.HostnameVerifierConfig; +import org.ldaptive.ssl.HostnameVerifyingTrustManager; +import org.ldaptive.ssl.SSLContextInitializer; + +/** + * OpenDJ provider implementation. Provides connection factories for clear, SSL, and TLS connections. + * + * @author Middleware Services + */ +public class OpenDJProvider implements Provider<OpenDJProviderConfig> +{ + + /** Provider configuration. */ + private OpenDJProviderConfig config = new OpenDJProviderConfig(); + + + @Override + public ProviderConnectionFactory<OpenDJProviderConfig> getConnectionFactory(final ConnectionConfig cc) + { + LDAPOptions options = config.getOptions(); + if (options == null) { + options = getDefaultLDAPOptions(cc); + } + return new OpenDJConnectionFactory(cc.getLdapUrl(), cc.getConnectionStrategy(), config, options); + } + + + /** + * Returns an SSLContext configured with a default hostname verifier. Uses a {@link DefaultHostnameVerifier} if no + * trust managers have been configured. + * + * @param cc connection configuration + * + * @return SSL Context + */ + protected SSLContext getHostnameVerifierSSLContext(final ConnectionConfig cc) + { + final LdapURL ldapUrl = new LdapURL(cc.getLdapUrl()); + SSLContextInitializer contextInit; + if (cc.getSslConfig() != null && !cc.getSslConfig().isEmpty()) { + final CredentialConfig credConfig = cc.getSslConfig().getCredentialConfig(); + final TrustManager[] managers = cc.getSslConfig().getTrustManagers(); + final CertificateHostnameVerifier verifier = cc.getSslConfig().getHostnameVerifier(); + if (credConfig != null) { + try { + contextInit = credConfig.createSSLContextInitializer(); + } catch (GeneralSecurityException e) { + throw new IllegalArgumentException(e); + } + } else { + if (managers != null) { + contextInit = new DefaultSSLContextInitializer(false); + } else { + contextInit = new DefaultSSLContextInitializer(true); + } + } + + if (managers != null) { + contextInit.setTrustManagers(managers); + } + if (verifier != null) { + contextInit.setHostnameVerifierConfig(new HostnameVerifierConfig(verifier, ldapUrl.getHostnames())); + } else { + contextInit.setHostnameVerifierConfig( + new HostnameVerifierConfig(new DefaultHostnameVerifier(), ldapUrl.getHostnames())); + } + } else { + contextInit = new DefaultSSLContextInitializer(true); + contextInit.setTrustManagers( + new HostnameVerifyingTrustManager(new DefaultHostnameVerifier(), ldapUrl.getHostnames())); + } + + try { + return contextInit.initSSLContext("TLS"); + } catch (GeneralSecurityException e) { + throw new IllegalArgumentException(e); + } + } + + + /** + * Returns the default connection options for this provider. + * + * @param cc to configure options with + * + * @return ldap connection options + */ + protected LDAPOptions getDefaultLDAPOptions(final ConnectionConfig cc) + { + final LDAPOptions options = new LDAPOptions(); + SSLContext sslContext; + if (cc.getUseStartTLS() || cc.getUseSSL() || cc.getLdapUrl().toLowerCase().contains("ldaps://")) { + sslContext = getHostnameVerifierSSLContext(cc); + options.setSSLContext(sslContext); + } + if (cc.getUseStartTLS()) { + options.setUseStartTLS(true); + } else if (cc.getUseSSL() || cc.getLdapUrl().toLowerCase().contains("ldaps://")) { + options.setUseStartTLS(false); + } + if (cc.getSslConfig() != null && cc.getSslConfig().getEnabledCipherSuites() != null) { + options.addEnabledCipherSuite(cc.getSslConfig().getEnabledCipherSuites()); + } + if (cc.getSslConfig() != null && cc.getSslConfig().getEnabledProtocols() != null) { + options.addEnabledProtocol(cc.getSslConfig().getEnabledProtocols()); + } + if (cc.getResponseTimeout() != null) { + options.setTimeout(cc.getResponseTimeout().toMillis(), TimeUnit.MILLISECONDS); + } + return options; + } + + + @Override + public OpenDJProviderConfig getProviderConfig() + { + return config; + } + + + @Override + public void setProviderConfig(final OpenDJProviderConfig pc) + { + config = pc; + } + + + @Override + public OpenDJProvider newInstance() + { + return new OpenDJProvider(); + } +}
diff --git a/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJProviderConfig.java b/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJProviderConfig.java new file mode 100644 index 0000000..cf44ff0 --- /dev/null +++ b/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJProviderConfig.java
@@ -0,0 +1,100 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.opendj; + +import java.util.Arrays; +import org.forgerock.opendj.ldap.LDAPOptions; +import org.forgerock.opendj.ldap.controls.Control; +import org.ldaptive.ResultCode; +import org.ldaptive.provider.ControlProcessor; +import org.ldaptive.provider.ProviderConfig; + +/** + * Contains configuration data for the OpenDJ provider. + * + * @author Middleware Services + */ +public class OpenDJProviderConfig extends ProviderConfig<Control> +{ + + /** Connection options. */ + private LDAPOptions options; + + /** Search result codes to ignore. */ + private ResultCode[] searchIgnoreResultCodes; + + + /** Default constructor. */ + public OpenDJProviderConfig() + { + setOperationExceptionResultCodes(ResultCode.SERVER_DOWN); + setControlProcessor(new ControlProcessor<>(new OpenDJControlHandler())); + searchIgnoreResultCodes = new ResultCode[] { + ResultCode.TIME_LIMIT_EXCEEDED, + ResultCode.SIZE_LIMIT_EXCEEDED, + ResultCode.REFERRAL, + }; + } + + + /** + * Returns the connection options. + * + * @return ldap options + */ + public LDAPOptions getOptions() + { + return options; + } + + + /** + * Sets the connection options. + * + * @param o ldap options + */ + public void setOptions(final LDAPOptions o) + { + options = o; + } + + + /** + * Returns the search ignore result codes. + * + * @return result codes to ignore + */ + public ResultCode[] getSearchIgnoreResultCodes() + { + return searchIgnoreResultCodes; + } + + + /** + * Sets the search ignore result codes. + * + * @param codes to ignore + */ + public void setSearchIgnoreResultCodes(final ResultCode[] codes) + { + checkImmutable(); + logger.trace("setting searchIgnoreResultCodes: {}", Arrays.toString(codes)); + searchIgnoreResultCodes = codes; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::operationExceptionResultCodes=%s, properties=%s, controlProcessor=%s, options=%s, " + + "searchIgnoreResultCodes=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(getOperationExceptionResultCodes()), + getProperties(), + getControlProcessor(), + options, + Arrays.toString(searchIgnoreResultCodes)); + } +}
diff --git a/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJUtils.java b/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJUtils.java new file mode 100644 index 0000000..1d2927f --- /dev/null +++ b/opendj-provider/src/main/java/org/ldaptive/provider/opendj/OpenDJUtils.java
@@ -0,0 +1,314 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.opendj; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import org.forgerock.opendj.ldap.Attribute; +import org.forgerock.opendj.ldap.ByteString; +import org.forgerock.opendj.ldap.ByteStringBuilder; +import org.forgerock.opendj.ldap.DN; +import org.forgerock.opendj.ldap.Entry; +import org.forgerock.opendj.ldap.LinkedAttribute; +import org.forgerock.opendj.ldap.LinkedHashMapEntry; +import org.forgerock.opendj.ldap.Modification; +import org.forgerock.opendj.ldap.ModificationType; +import org.forgerock.opendj.ldap.SortKey; +import org.ldaptive.AttributeModification; +import org.ldaptive.AttributeModificationType; +import org.ldaptive.LdapAttribute; +import org.ldaptive.LdapEntry; +import org.ldaptive.SearchEntry; +import org.ldaptive.SortBehavior; +import org.ldaptive.control.ResponseControl; + +/** + * Provides methods for converting between OpenDJ specific objects and ldaptive specific objects. + * + * @author Middleware Services + */ +public class OpenDJUtils +{ + + /** Ldap result sort behavior. */ + private final SortBehavior sortBehavior; + + /** Attributes that should be treated as binary. */ + private List<String> binaryAttrs; + + + /** Default constructor. */ + public OpenDJUtils() + { + sortBehavior = SortBehavior.getDefaultSortBehavior(); + } + + + /** + * Creates a new opendj util. + * + * @param sb sort behavior + */ + public OpenDJUtils(final SortBehavior sb) + { + sortBehavior = sb; + } + + + /** + * Returns the list of binary attributes. + * + * @return list of binary attributes + */ + public List<String> getBinaryAttributes() + { + return binaryAttrs; + } + + + /** + * Sets the list of binary attributes. + * + * @param s binary attributes + */ + public void setBinaryAttributes(final String[] s) + { + if (s != null) { + binaryAttrs = Arrays.asList(s); + } + } + + + /** + * Returns an opendj byte string that represents the values in the supplied collection. + * + * @param values to convert to byte strings + * + * @return byte strings + */ + public ByteString[] fromStringValues(final Collection<String> values) + { + final ByteString[] bstrings = new ByteString[values.size()]; + int i = 0; + for (String s : values) { + final ByteStringBuilder builder = new ByteStringBuilder(s.length()); + builder.append(s); + bstrings[i++] = builder.toByteString(); + } + return bstrings; + } + + + /** + * Returns an opendj byte string that represents the values in the supplied collection. + * + * @param values to convert to byte strings + * + * @return byte strings + */ + public ByteString[] fromBinaryValues(final Collection<byte[]> values) + { + final ByteString[] bstrings = new ByteString[values.size()]; + int i = 0; + for (byte[] b : values) { + final ByteStringBuilder builder = new ByteStringBuilder(b.length); + builder.append(b); + bstrings[i++] = builder.toByteString(); + } + return bstrings; + } + + + /** + * Returns string values for the supplied byte strings. + * + * @param values to convert to strings + * + * @return string values + */ + public String[] toStringValues(final ByteString[] values) + { + final String[] strings = new String[values.length]; + for (int i = 0; i < values.length; i++) { + strings[i] = values[i].toString(); + } + return strings; + } + + + /** + * Returns byte array values for the supplied byte strings. + * + * @param values to convert to byte arrays + * + * @return byte array values + */ + public byte[][] toBinaryValues(final ByteString[] values) + { + final byte[][] bytes = new byte[values.length][]; + for (int i = 0; i < values.length; i++) { + bytes[i] = values[i].toByteArray(); + } + return bytes; + } + + + /** + * Returns an opendj attribute that represents the values in the supplied ldap attribute. + * + * @param la ldap attribute + * + * @return opendj attribute + */ + public Attribute fromLdapAttribute(final LdapAttribute la) + { + Attribute attribute; + if (la.isBinary()) { + attribute = new LinkedAttribute(la.getName(), (Object[]) fromBinaryValues(la.getBinaryValues())); + } else { + attribute = new LinkedAttribute(la.getName(), (Object[]) fromStringValues(la.getStringValues())); + } + return attribute; + } + + + /** + * Returns an ldap attribute using the supplied opendj attribute. + * + * @param a opendj attribute + * + * @return ldap attribute + */ + public LdapAttribute toLdapAttribute(final Attribute a) + { + boolean isBinary = false; + if (a.getAttributeDescriptionAsString().contains(";binary")) { + isBinary = true; + } else if (binaryAttrs != null && binaryAttrs.contains(a.getAttributeDescriptionAsString())) { + isBinary = true; + } + + final LdapAttribute la = new LdapAttribute(sortBehavior, isBinary); + la.setName(a.getAttributeDescriptionAsString()); + if (isBinary) { + la.addBinaryValue(toBinaryValues(a.toArray())); + } else { + la.addStringValue(toStringValues(a.toArray())); + } + return la; + } + + + /** + * Returns a list of opendj attribute that represents the values in the supplied ldap attributes. + * + * @param c ldap attributes + * + * @return opendj attributes + */ + public Attribute[] fromLdapAttributes(final Collection<LdapAttribute> c) + { + return c.stream().map(this::fromLdapAttribute).toArray(Attribute[]::new); + } + + + /** + * Returns an opendj entry that represents the values in the supplied entry. + * + * @param le ldap entry + * + * @return opendj entry + */ + public Entry fromLdapEntry(final LdapEntry le) + { + final Entry entry = new LinkedHashMapEntry(); + entry.setName(DN.valueOf(le.getDn())); + for (LdapAttribute la : le.getAttributes()) { + entry.addAttribute(fromLdapAttribute(la), null); + } + return entry; + } + + + /** + * Returns a search entry using the supplied opendj entry. + * + * @param e opendj entry + * @param c response controls + * @param id message id + * + * @return search entry + */ + public SearchEntry toSearchEntry(final Entry e, final ResponseControl[] c, final int id) + { + final SearchEntry se = new SearchEntry(id, c, sortBehavior); + se.setDn(e.getName().toString()); + for (Attribute a : e.getAllAttributes()) { + se.addAttribute(toLdapAttribute(a)); + } + return se; + } + + + /** + * Returns opendj modifications using the supplied attribute modifications. + * + * @param am attribute modifications + * + * @return opendj modifications + */ + public Modification[] fromAttributeModification(final AttributeModification[] am) + { + final Modification[] mods = new Modification[am.length]; + for (int i = 0; i < am.length; i++) { + final Attribute a = fromLdapAttribute(am[i].getAttribute()); + if (am[i].getAttribute().isBinary()) { + mods[i] = new Modification(getModificationType(am[i].getAttributeModificationType()), a); + } else { + mods[i] = new Modification(getModificationType(am[i].getAttributeModificationType()), a); + } + } + return mods; + } + + + /** + * Returns opendj sort keys using the supplied sort keys. + * + * @param sk sort keys + * + * @return opendj sort keys + */ + public static SortKey[] fromSortKey(final org.ldaptive.control.SortKey[] sk) + { + SortKey[] keys = null; + if (sk != null) { + keys = new SortKey[sk.length]; + for (int i = 0; i < sk.length; i++) { + keys[i] = new SortKey(sk[i].getAttributeDescription(), sk[i].getReverseOrder(), sk[i].getMatchingRuleId()); + } + } + return keys; + } + + + /** + * Returns the opendj modification type for the supplied attribute modification type. + * + * @param am attribute modification type + * + * @return modification type + */ + protected static ModificationType getModificationType(final AttributeModificationType am) + { + ModificationType type = null; + if (am == AttributeModificationType.ADD) { + type = ModificationType.ADD; + } else if (am == AttributeModificationType.REMOVE) { + type = ModificationType.DELETE; + } else if (am == AttributeModificationType.REPLACE) { + type = ModificationType.REPLACE; + } + return type; + } +}
diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..f4f00af --- /dev/null +++ b/pom.xml
@@ -0,0 +1,602 @@ +<?xml version='1.0' encoding='UTF-8'?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-parent</artifactId> + <packaging>pom</packaging> + <version>1.2.3</version> + <name>LDAPTIVE PARENT</name> + <description>Java LDAP API</description> + <url>http://www.ldaptive.org</url> + <issueManagement> + <system>GitHub</system> + <url>https://github.com/vt-middleware/ldaptive/issues</url> + </issueManagement> + <mailingLists> + <mailingList> + <name>ldaptive</name> + <subscribe>ldaptive+subscribe@googlegroups.com</subscribe> + <unsubscribe>ldaptive+unsubscribe@googlegroups.com</unsubscribe> + <post>ldaptive@googlegroups.com</post> + <archive>http://groups.google.com/group/ldaptive</archive> + </mailingList> + </mailingLists> + <licenses> + <license> + <name>Apache 2</name> + <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url> + </license> + <license> + <name>GNU Lesser General Public License</name> + <url>http://www.gnu.org/licenses/lgpl-3.0.txt</url> + </license> + </licenses> + <scm> + <connection>scm:git:git@github.com:vt-middleware/ldaptive.git</connection> + <url>scm:git:git@github.com:vt-middleware/ldaptive.git</url> + </scm> + <developers> + <developer> + <id>dfisher</id> + <name>Daniel Fisher</name> + <email>dfisher@vt.edu</email> + <organization>Virginia Tech</organization> + <organizationUrl>http://www.vt.edu</organizationUrl> + <roles> + <role>developer</role> + </roles> + </developer> + <developer> + <id>marvin.addison</id> + <name>Marvin Addison</name> + <email>serac@vt.edu</email> + <organization>Virginia Tech</organization> + <organizationUrl>http://www.vt.edu</organizationUrl> + <roles> + <role>developer</role> + </roles> + </developer> + <developer> + <id>ememisya</id> + <name>Erdem Memisyazici</name> + <email>ememisya@vt.edu</email> + <organization>Virginia Tech</organization> + <organizationUrl>http://www.vt.edu</organizationUrl> + <roles> + <role>developer</role> + </roles> + </developer> + </developers> + + <prerequisites> + <maven>3.0.5</maven> + </prerequisites> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> + <checkstyle.dir>src/main/checkstyle</checkstyle.dir> + <org.slf4j.version>1.7.25</org.slf4j.version> + <org.springframework.version>4.3.11.RELEASE</org.springframework.version> + <commons-cli.version>1.4</commons-cli.version> + <japicmp.enabled>true</japicmp.enabled> + <japicmp.oldVersion>1.2.0</japicmp.oldVersion> + </properties> + + <modules> + <module>core</module> + <module>beans</module> + <module>json</module> + <module>templates</module> + <module>webapp</module> + <module>ldapi</module> + </modules> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${org.slf4j.version}</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + <version>${org.slf4j.version}</version> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <version>1.2.17</version> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-beans</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-json</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-templates</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-webapp</artifactId> + <version>${project.version}</version> + <type>war</type> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-apache</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-jldap</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-opendj</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-unboundid</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-ldapi</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <version>${commons-cli.version}</version> + <optional>true</optional> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <version>3.1.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + <version>6.11</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.bouncycastle</groupId> + <artifactId>bcprov-jdk15on</artifactId> + <version>1.58</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>httpunit</groupId> + <artifactId>httpunit</artifactId> + <version>1.6.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.velocity</groupId> + <artifactId>velocity</artifactId> + <version>1.7</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.directory.api</groupId> + <artifactId>api-all</artifactId> + <version>1.0.0</version> + </dependency> + <dependency> + <groupId>com.novell.ldap</groupId> + <artifactId>jldap</artifactId> + <version>2009-10-07</version> + </dependency> + <dependency> + <groupId>org.forgerock.opendj</groupId> + <artifactId>opendj-ldap-sdk</artifactId> + <version>2.6.11</version> + </dependency> + <dependency> + <groupId>com.unboundid</groupId> + <artifactId>unboundid-ldapsdk</artifactId> + <version>4.0.1</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-beans</artifactId> + <version>${org.springframework.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + <version>${org.springframework.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-core</artifactId> + <version>${org.springframework.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-expression</artifactId> + <version>${org.springframework.version}</version> + </dependency> + <dependency> + <groupId>com.sun.codemodel</groupId> + <artifactId>codemodel</artifactId> + <version>2.6</version> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>2.8.1</version> + </dependency> + <dependency> + <groupId>com.kohlschutter.junixsocket</groupId> + <artifactId>junixsocket-native-common</artifactId> + <version>2.0.4</version> + </dependency> + </dependencies> + </dependencyManagement> + + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-clean-plugin</artifactId> + <version>3.0.0</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-deploy-plugin</artifactId> + <version>2.8.2</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>2.5.2</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-site-plugin</artifactId> + <version>3.6</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-war-plugin</artifactId> + <version>3.1.0</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-enforcer-plugin</artifactId> + <version>1.4.1</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <version>3.0.2</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <version>3.0.2</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.7.0</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + <version>2.17</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.20.1</version> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <version>3.0.0</version> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <version>1.6.0</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>2.10.4</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <version>3.0.1</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <version>3.0.2</version> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <version>3.3.0</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <version>3.1.0</version> + </plugin> + <plugin> + <groupId>com.github.siom79.japicmp</groupId> + <artifactId>japicmp-maven-plugin</artifactId> + <version>0.10.0</version> + </plugin> + </plugins> + </pluginManagement> + + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <fork>true</fork> + <debug>true</debug> + <showDeprecation>true</showDeprecation> + <showWarnings>true</showWarnings> + <compilerArgument>-Xlint:unchecked</compilerArgument> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + <configuration> + <configLocation>${checkstyle.dir}/checks.xml</configLocation> + <headerLocation>${checkstyle.dir}/header.txt</headerLocation> + <suppressionsLocation>${checkstyle.dir}/suppressions.xml</suppressionsLocation> + <includeTestSourceDirectory>true</includeTestSourceDirectory> + <failsOnError>true</failsOnError> + <outputFileFormat>plain</outputFileFormat> + <outputFile>${project.build.directory}/checkstyle-result.txt</outputFile> + </configuration> + <executions> + <execution> + <id>checkstyle</id> + <phase>compile</phase> + <goals> + <goal>checkstyle</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <links> + <link>http://download.oracle.com/javase/8/docs/api</link> + <link>http://www.slf4j.org/apidocs/</link> + </links> + <quiet>true</quiet> + <author>false</author> + <show>private</show> + <version>true</version> + <doctitle>Ldaptive ${project.version} API</doctitle> + <windowtitle>Ldaptive ${project.version} API</windowtitle> + <bottom><![CDATA[<i>Copyright © 2003-2017 Virginia Tech. All Rights Reserved.</i>]]></bottom> + <additionalDependencies> + <additionalDependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <version>${commons-cli.version}</version> + </additionalDependency> + </additionalDependencies> + </configuration> + <executions> + <execution> + <id>javadoc</id> + <phase>package</phase> + <goals> + <goal>jar</goal> + </goals> + <configuration> + <sourcepath>${project.build.sourceDirectory}:${project.build.directory}/sources</sourcepath> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <executions> + <execution> + <id>source</id> + <phase>package</phase> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile> + </archive> + <skipIfEmpty>true</skipIfEmpty> + </configuration> + <executions> + <execution> + <id>jar</id> + <phase>package</phase> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <executions> + <execution> + <id>bundle-manifest</id> + <phase>process-classes</phase> + <goals> + <goal>manifest</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>com.github.siom79.japicmp</groupId> + <artifactId>japicmp-maven-plugin</artifactId> + <configuration> + <oldVersion> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>${project.artifactId}</artifactId> + <version>${japicmp.oldVersion}</version> + <type>jar</type> + </dependency> + </oldVersion> + <newVersion> + <file> + <path>${project.build.directory}/${project.artifactId}-${project.version}.${project.packaging}</path> + </file> + </newVersion> + <parameter> + <ignoreNonResolvableArtifacts>true</ignoreNonResolvableArtifacts> + <onlyBinaryIncompatible>true</onlyBinaryIncompatible> + <breakBuildOnBinaryIncompatibleModifications>${japicmp.enabled}</breakBuildOnBinaryIncompatibleModifications> + <packagingSupporteds> + <packagingSupported>jar</packagingSupported> + </packagingSupporteds> + </parameter> + <dependencies> + <!-- include optional dependencies --> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-beans</artifactId> + <version>${org.springframework.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-expression</artifactId> + <version>${org.springframework.version}</version> + </dependency> + </dependencies> + </configuration> + <executions> + <execution> + <phase>verify</phase> + <goals> + <goal>cmp</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + <profiles> + <profile> + <id>apache</id> + <modules> + <module>apache-provider</module> + </modules> + </profile> + <profile> + <id>jldap</id> + <modules> + <module>jldap-provider</module> + </modules> + </profile> + <profile> + <id>opendj</id> + <modules> + <module>opendj-provider</module> + </modules> + <repositories> + <repository> + <id>vt-middleware</id> + <name>VT Middleware GitHub Repository</name> + <url>https://raw.github.com/vt-middleware/maven-repo/master</url> + <snapshots> + <enabled>false</enabled> + </snapshots> + </repository> + </repositories> + </profile> + <profile> + <id>unboundid</id> + <modules> + <module>unboundid-provider</module> + </modules> + </profile> + <profile> + <id>integration</id> + <modules> + <module>integration</module> + </modules> + </profile> + <profile> + <id>distribution</id> + <modules> + <module>distribution</module> + </modules> + </profile> + <profile> + <id>sign-artifacts</id> + <activation> + <property> + <name>sign</name> + <value>true</value> + </property> + </activation> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-gpg-plugin</artifactId> + <version>1.6</version> + <executions> + <execution> + <id>sign-artifacts</id> + <phase>package</phase> + <goals> + <goal>sign</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> +</project>
diff --git a/src/main/checkstyle/checks.xml b/src/main/checkstyle/checks.xml new file mode 100644 index 0000000..92d78bd --- /dev/null +++ b/src/main/checkstyle/checks.xml
@@ -0,0 +1,224 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module PUBLIC + "-//Puppy Crawl//DTD Check Configuration 1.2//EN" + "http://www.puppycrawl.com/dtds/configuration_1_2.dtd"> + +<module name="Checker"> + + <!-- limit source file size --> + <module name="FileLength"> + <property name="max" value="2000"/> + </module> + + <!-- require a header --> + <module name="RegexpHeader"> + <property name="headerFile" value="${checkstyle.header.file}"/> + <property name="fileExtensions" value="java"/> + </module> + + <!-- forbid tab characters in source files --> + <module name="FileTabCharacter"/> + + <module name="SuppressionCommentFilter"> + <property name="offCommentFormat" value="CheckStyle\:([\w\|]+) OFF"/> + <property name="onCommentFormat" value="CheckStyle\:([\w\|]+) ON"/> + <property name="checkFormat" value="$1"/> + </module> + <module name="NewlineAtEndOfFile"> + <property name="fileExtensions" value="java"/> + </module> + <module name="TreeWalker"> + <property name="tabWidth" value="2"/> + + <module name="FileContentsHolder"/> + + <!-- annotations --> + <module name="AnnotationUseStyle"/> + <module name="MissingDeprecated"/> + <module name="MissingOverride"/> + <module name="SuppressWarnings"/> + + <!-- javadocs --> + <module name="JavadocType"> + <property name="authorFormat" value="\S+"/> + </module> + <module name="JavadocMethod"> + <property name="allowThrowsTagsForSubclasses" value="true"/> + <property name="allowUndeclaredRTE" value="true"/> + </module> + <module name="JavadocVariable"/> + <module name="JavadocStyle"> + <property name="checkFirstSentence" value="false"/> + </module> + + <!-- naming --> + <module name="AbstractClassName"> + <property name="format" value="^Abstract.*$"/> + </module> + <module name="ClassTypeParameterName"/> + <module name="ConstantName"/> + <module name="LocalFinalVariableName"/> + <module name="LocalVariableName"/> + <module name="MemberName"/> + <module name="MethodName"/> + <module name="MethodTypeParameterName"/> + <module name="PackageName"/> + <module name="ParameterName"/> + <module name="StaticVariableName"/> + <module name="TypeName"/> + + <!-- imports --> + <module name="AvoidStarImport"/> + <module name="AvoidStaticImport"/> + <module name="IllegalImport"/> + <module name="RedundantImport"/> + <module name="UnusedImports"/> + <module name="ImportOrder"> + <property name="groups" value="java,javax"/> + <property name="ordered" value="true"/> + <property name="option" value="bottom"/> + </module> + + <!-- sizes --> + <module name="LineLength"> + <property name="ignorePattern" value="(^.*\$.*\$.*$)|(^import .*)"/> + <property name="max" value="120"/> + </module> + <module name="MethodLength"> + <property name="max" value="300"/> + </module> + <module name="AnonInnerLength"> + <property name="max" value="30"/> + </module> + <module name="ParameterNumber"/> + <module name="OuterTypeNumber"/> + + <!-- whitespace --> + <module name="GenericWhitespace"/> + <module name="EmptyForInitializerPad"/> + <module name="EmptyForIteratorPad"/> + <module name="MethodParamPad"/> + <module name="NoWhitespaceAfter"/> + <module name="NoWhitespaceBefore"> + <property name="allowLineBreaks" value="true"/> + <property name="tokens" + value="SEMI,DOT,POST_DEC,POST_INC"/> + </module> + <module name="OperatorWrap"> + <property name="option" value="eol"/> + <property name="tokens" + value="BAND,BOR,BSR,BXOR,DIV,EQUAL,GE,GT,LAND,LE, + LITERAL_INSTANCEOF,LOR,LT,MINUS,MOD,NOT_EQUAL,PLUS, + SL,SR,STAR"/> + </module> + <module name="ParenPad"/> + <module name="TypecastParenPad"/> + <module name="WhitespaceAfter"/> + <module name="WhitespaceAround"> + <property name="tokens" + value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN, + BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,EQUAL,GE,GT,LAND, + LE,LITERAL_ASSERT,LITERAL_CATCH,LITERAL_DO, + LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF, + LITERAL_RETURN,LITERAL_SYNCHRONIZED,LITERAL_TRY, + LITERAL_WHILE,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN, + NOT_EQUAL,PLUS_ASSIGN,QUESTION,SL, + SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN"/> + </module> + + <!-- modifiers --> + <module name="ModifierOrder"/> + <module name="RedundantModifier"/> + + <!-- blocks --> + <module name="EmptyBlock"/> + <module name="LeftCurly"> + <property name="option" value="nl"/> + <property name="tokens" + value="CLASS_DEF,CTOR_DEF,INTERFACE_DEF,METHOD_DEF"/> + </module> + <module name="NeedBraces"/> + <module name="RightCurly"/> + <module name="AvoidNestedBlocks"/> + + <!-- coding --> + <module name="ArrayTrailingComma"/> + <module name="CovariantEquals"/> + <module name="EmptyStatement"/> + <module name="EqualsAvoidNull"/> + <module name="EqualsHashCode"/> + <module name="FinalLocalVariable"/> + <module name="HiddenField"/> + <module name="IllegalInstantiation"> + <property name="classes" value="java.lang.Boolean"/> + </module> + <module name="InnerAssignment"/> + <module name="MagicNumber"/> + <module name="MissingSwitchDefault"/> + <module name="SimplifyBooleanExpression"/> + <module name="SimplifyBooleanReturn"/> + <module name="StringLiteralEquality"/> + <module name="NestedIfDepth"> + <property name="max" value="5"/> + </module> + <module name="NestedTryDepth"> + <property name="max" value="5"/> + </module> + <module name="SuperClone"/> + <module name="SuperFinalize"/> + <module name="PackageDeclaration"/> + <module name="ReturnCount"/> + <module name="IllegalType"> + <property name="illegalClassNames" + value="java.util.GregorianCalendar, java.util.Hashtable, + java.util.HashSet, java.util.HashMap, + java.util.ArrayList, java.util.LinkedList, + java.util.LinkedHashMap, java.util.LinkedHashSet, + java.util.TreeSet, java.util.TreeMap, java.util.Vector"/> + </module> + <module name="DeclarationOrder"/> + <module name="ParameterAssignment"/> + <module name="ExplicitInitialization"/> + <module name="DefaultComesLast"/> + <module name="FallThrough"/> + <module name="MultipleVariableDeclarations"/> + <module name="RequireThis"> + <property name="checkFields" value="false"/> + <property name="checkMethods" value="false"/> + </module> + <module name="UnnecessaryParentheses"/> + + <!-- design --> + <module name="VisibilityModifier"> + <property name="protectedAllowed" value="true"/> + </module> + <module name="FinalClass"/> + <module name="InterfaceIsType"/> + <module name="HideUtilityClassConstructor"/> + <module name="MutableException"/> + <module name="ThrowsCount"> + <property name="max" value="2"/> + </module> + + <!-- prevent trailing whitespace --> + <module name="Regexp"> + <property name="format" value="[ \t]+$"/> + <property name="illegalPattern" value="true"/> + <property name="message" value="Trailing whitespace"/> + </module> + + <!-- misc --> + <module name="UpperEll"/> + <module name="ArrayTypeStyle"/> + <module name="FinalParameters"/> + <module name="Indentation"> + <property name="basicOffset" value="2"/> + <property name="caseIndent" value="0"/> + <property name="throwsIndent" value="2"/> + <property name="arrayInitIndent" value="2"/> + <property name="lineWrappingIndentation" value="2"/> + </module> + <module name="TrailingComment"/> + + </module> +</module>
diff --git a/src/main/checkstyle/header.txt b/src/main/checkstyle/header.txt new file mode 100644 index 0000000..0ce0ff7 --- /dev/null +++ b/src/main/checkstyle/header.txt
@@ -0,0 +1 @@ +/\* See LICENSE for licensing and NOTICE for copyright. \*/
diff --git a/src/main/checkstyle/suppressions.xml b/src/main/checkstyle/suppressions.xml new file mode 100644 index 0000000..42dc962 --- /dev/null +++ b/src/main/checkstyle/suppressions.xml
@@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE suppressions PUBLIC + "-//Puppy Crawl//DTD Suppressions 1.1//EN" + "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd"> + +<suppressions> + <!-- nothing magic about test data --> + <suppress checks="MagicNumber" files=".*Test\.java" /> + <suppress checks="FileLength" files=".*Test\.java" /> + <suppress checks="MagicNumber" files="ClassGenerator\.java" /> + <suppress checks="Header" files="Base64\.java" /> + <suppress checks=".*" files="InetOrgPerson\.java" /> + <suppress checks=".*" files="OrganizationalPerson\.java" /> + <suppress checks=".*" files="MyObject\.java" /> +</suppressions>
diff --git a/templates/pom.xml b/templates/pom.xml new file mode 100644 index 0000000..8c2f37a --- /dev/null +++ b/templates/pom.xml
@@ -0,0 +1,51 @@ +<?xml version='1.0' encoding='UTF-8'?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>ldaptive-templates</artifactId> + <packaging>jar</packaging> + <name>LDAPTIVE TEMPLATES</name> + <description>Templating functionality for aggregating LDAP searches</description> + <parent> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-parent</artifactId> + <version>1.2.3</version> + </parent> + + <dependencies> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive</artifactId> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-json</artifactId> + </dependency> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-beans</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-beans</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-core</artifactId> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + </dependency> + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + </dependency> + </dependencies> + +</project>
diff --git a/templates/src/main/java/org/ldaptive/servlets/AbstractServletSearchTemplatesExecutor.java b/templates/src/main/java/org/ldaptive/servlets/AbstractServletSearchTemplatesExecutor.java new file mode 100644 index 0000000..9cd2b08 --- /dev/null +++ b/templates/src/main/java/org/ldaptive/servlets/AbstractServletSearchTemplatesExecutor.java
@@ -0,0 +1,154 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.servlets; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.servlet.ServletConfig; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.ldaptive.LdapException; +import org.ldaptive.SearchResult; +import org.ldaptive.concurrent.AggregatePooledSearchExecutor; +import org.ldaptive.pool.PooledConnectionFactory; +import org.ldaptive.templates.Query; +import org.ldaptive.templates.SearchTemplates; +import org.ldaptive.templates.SearchTemplatesExecutor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * Searches an LDAP using a defined set of search templates. For each term count some number of templates are defined + * and used for searching. + * + * @author Middleware Services + */ +public abstract class AbstractServletSearchTemplatesExecutor extends SearchTemplatesExecutor + implements ServletSearchExecutor +{ + + /** Spring context path. */ + private static final String SPRING_CONTEXT_PATH = "springContextPath"; + + /** Default spring context path. */ + private static final String DEFAULT_SPRING_CONTEXT_PATH = "/templates-context.xml"; + + /** Ignore pattern. */ + private static final String IGNORE_PATTERN = "ignorePattern"; + + /** Minimum query term length. */ + private static final String MINIMUM_QUERY_TERM_LENGTH = "minimumQueryTermLength"; + + /** Regex pattern to ignore a query. */ + private Pattern ignorePattern; + + /** Minimum length for at least one query term. */ + private int minimumQueryTermLength; + + + @Override + public void initialize(final ServletConfig config) + { + final String springContextPath = config.getInitParameter(SPRING_CONTEXT_PATH) != null + ? config.getInitParameter(SPRING_CONTEXT_PATH) : DEFAULT_SPRING_CONTEXT_PATH; + logger.debug("{} = {}", SPRING_CONTEXT_PATH, springContextPath); + + final ApplicationContext context = new ClassPathXmlApplicationContext(springContextPath); + setSearchExecutor(context.getBean(AggregatePooledSearchExecutor.class)); + logger.debug("searchExecutor = {}", getSearchExecutor()); + + final Map<String, PooledConnectionFactory> factories = context.getBeansOfType(PooledConnectionFactory.class); + setConnectionFactories(factories.values().toArray(new PooledConnectionFactory[factories.size()])); + logger.debug("connectionFactories = {}", Arrays.toString(getConnectionFactories())); + + final Map<String, SearchTemplates> templates = context.getBeansOfType(SearchTemplates.class); + setSearchTemplates(templates.values().toArray(new SearchTemplates[templates.size()])); + logger.debug("searchTemplates = {}", Arrays.toString(getSearchTemplates())); + + ignorePattern = config.getInitParameter(IGNORE_PATTERN) != null + ? Pattern.compile(config.getInitParameter(IGNORE_PATTERN)) : null; + logger.debug("{} = {}", IGNORE_PATTERN, ignorePattern); + + minimumQueryTermLength = config.getInitParameter(MINIMUM_QUERY_TERM_LENGTH) != null + ? Integer.parseInt(config.getInitParameter(MINIMUM_QUERY_TERM_LENGTH)) : 0; + logger.debug("{} = {}", MINIMUM_QUERY_TERM_LENGTH, minimumQueryTermLength); + } + + + @Override + public void search(final HttpServletRequest request, final HttpServletResponse response) + throws LdapException, IOException + { + Integer fromResult = null; + if (request.getParameter("from-result") != null) { + try { + fromResult = Integer.valueOf(request.getParameter("from-result")); + } catch (NumberFormatException e) { + logger.warn("Received invalid fromResult parameter: {}", request.getParameter("from-result")); + } + } + + Integer toResult = null; + if (request.getParameter("to-result") != null) { + try { + toResult = Integer.valueOf(request.getParameter("to-result")); + } catch (NumberFormatException e) { + logger.warn("Received invalid toResult parameter: {}", request.getParameter("to-result")); + } + } + + boolean doSearch = true; + final String queryString = request.getParameter("query"); + if (queryString == null || queryString.length() == 0) { + logger.info("Ignoring empty query"); + doSearch = false; + } + if (doSearch && ignorePattern != null) { + final Matcher matcher = ignorePattern.matcher(queryString); + if (matcher.matches()) { + logger.info("Ignoring query {}", queryString); + doSearch = false; + } + } + if (doSearch) { + final Query query = new Query(queryString); + if (minimumQueryTermLength > 0) { + boolean hasMinimumLengthQueryTerm = false; + for (String term : query.getTerms()) { + if (term.length() >= minimumQueryTermLength) { + hasMinimumLengthQueryTerm = true; + break; + } + } + if (!hasMinimumLengthQueryTerm) { + logger.info("Does not meet minimum query term length {}", queryString); + doSearch = false; + } + } + if (doSearch) { + query.setReturnAttributes(request.getParameterValues("attrs")); + query.setSearchRestrictions(request.getParameter("search-restrictions")); + query.setFromResult(fromResult); + query.setToResult(toResult); + logger.info("Performing query {}", query); + + final SearchResult result = search(query); + writeResponse(result, response); + } + } + } + + + /** + * Writes the supplied search result to the servlet response output stream. + * + * @param result search result to write + * @param response to write to + * + * @throws IOException if an error occurs writing to the response + */ + protected abstract void writeResponse(final SearchResult result, final HttpServletResponse response) + throws IOException; +}
diff --git a/templates/src/main/java/org/ldaptive/servlets/Dsmlv1ServletSearchTemplatesExecutor.java b/templates/src/main/java/org/ldaptive/servlets/Dsmlv1ServletSearchTemplatesExecutor.java new file mode 100644 index 0000000..909a0e7 --- /dev/null +++ b/templates/src/main/java/org/ldaptive/servlets/Dsmlv1ServletSearchTemplatesExecutor.java
@@ -0,0 +1,30 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.servlets; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; +import javax.servlet.http.HttpServletResponse; +import org.ldaptive.SearchResult; +import org.ldaptive.io.Dsmlv1Writer; + +/** + * Writes search results as DSML version 1. See {@link AbstractServletSearchTemplatesExecutor}. + * + * @author Middleware Services + */ +public class Dsmlv1ServletSearchTemplatesExecutor extends AbstractServletSearchTemplatesExecutor +{ + + + @Override + protected void writeResponse(final SearchResult result, final HttpServletResponse response) + throws IOException + { + response.setContentType("text/xml"); + + final Dsmlv1Writer writer = new Dsmlv1Writer( + new BufferedWriter(new OutputStreamWriter(response.getOutputStream()))); + writer.write(result); + } +}
diff --git a/templates/src/main/java/org/ldaptive/servlets/JsonServletSearchTemplatesExecutor.java b/templates/src/main/java/org/ldaptive/servlets/JsonServletSearchTemplatesExecutor.java new file mode 100644 index 0000000..d368eb3 --- /dev/null +++ b/templates/src/main/java/org/ldaptive/servlets/JsonServletSearchTemplatesExecutor.java
@@ -0,0 +1,29 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.servlets; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; +import javax.servlet.http.HttpServletResponse; +import org.ldaptive.SearchResult; +import org.ldaptive.io.JsonWriter; + +/** + * Writes search results as JSON. See {@link AbstractServletSearchTemplatesExecutor}. + * + * @author Middleware Services + */ +public class JsonServletSearchTemplatesExecutor extends AbstractServletSearchTemplatesExecutor +{ + + + @Override + protected void writeResponse(final SearchResult result, final HttpServletResponse response) + throws IOException + { + response.setContentType("application/json"); + + final JsonWriter writer = new JsonWriter(new BufferedWriter(new OutputStreamWriter(response.getOutputStream()))); + writer.write(result); + } +}
diff --git a/templates/src/main/java/org/ldaptive/servlets/LdifServletSearchTemplatesExecutor.java b/templates/src/main/java/org/ldaptive/servlets/LdifServletSearchTemplatesExecutor.java new file mode 100644 index 0000000..4903abd --- /dev/null +++ b/templates/src/main/java/org/ldaptive/servlets/LdifServletSearchTemplatesExecutor.java
@@ -0,0 +1,29 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.servlets; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; +import javax.servlet.http.HttpServletResponse; +import org.ldaptive.SearchResult; +import org.ldaptive.io.LdifWriter; + +/** + * Writes search results in LDIF format. See {@link AbstractServletSearchTemplatesExecutor}. + * + * @author Middleware Services + */ +public class LdifServletSearchTemplatesExecutor extends AbstractServletSearchTemplatesExecutor +{ + + + @Override + protected void writeResponse(final SearchResult result, final HttpServletResponse response) + throws IOException + { + response.setContentType("text/plain"); + + final LdifWriter writer = new LdifWriter(new BufferedWriter(new OutputStreamWriter(response.getOutputStream()))); + writer.write(result); + } +}
diff --git a/templates/src/main/java/org/ldaptive/templates/Query.java b/templates/src/main/java/org/ldaptive/templates/Query.java new file mode 100644 index 0000000..0d5acc4 --- /dev/null +++ b/templates/src/main/java/org/ldaptive/templates/Query.java
@@ -0,0 +1,170 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.templates; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.StringTokenizer; + +/** + * Contains data associated with a query request. + * + * @author Middleware Services + */ +public class Query +{ + + /** Used for setting empty terms. */ + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + + /** Query separated into terms. */ + private final String[] terms; + + /** Attributes to return with the ldap query. */ + private String[] returnAttributes; + + /** Additional restrictions to place on every query. */ + private String searchRestrictions; + + /** Start index of search results to return. */ + private Integer fromResult; + + /** End index of search results to return. */ + private Integer toResult; + + + /** + * Parses the query from a string into query terms. + * + * @param query to parse + */ + public Query(final String query) + { + if (query != null) { + final List<String> l = new ArrayList<>(); + final StringTokenizer queryTokens = new StringTokenizer(query.toLowerCase().trim()); + while (queryTokens.hasMoreTokens()) { + l.add(queryTokens.nextToken()); + } + terms = l.toArray(new String[l.size()]); + } else { + terms = EMPTY_STRING_ARRAY; + } + } + + + /** + * Returns the terms. + * + * @return query terms + */ + public String[] getTerms() + { + return terms; + } + + + /** + * Sets the return attributes. + * + * @param attrs return attributes + */ + public void setReturnAttributes(final String[] attrs) + { + returnAttributes = attrs; + } + + + /** + * Returns the return attributes. + * + * @return return attributes + */ + public String[] getReturnAttributes() + { + return returnAttributes; + } + + + /** + * Sets the search restrictions. + * + * @param restrictions search restrictions + */ + public void setSearchRestrictions(final String restrictions) + { + searchRestrictions = restrictions; + } + + + /** + * Returns the search restrictions. + * + * @return search restrictions + */ + public String getSearchRestrictions() + { + return searchRestrictions; + } + + + /** + * Sets the index of the result to begin searching. + * + * @param i from index + */ + public void setFromResult(final Integer i) + { + fromResult = i; + } + + + /** + * Returns the from result. + * + * @return from result + */ + public Integer getFromResult() + { + return fromResult; + } + + + /** + * Sets the index of the result to stop searching. + * + * @param i to result + */ + public void setToResult(final Integer i) + { + toResult = i; + } + + + /** + * Returns the to result. + * + * @return to result + */ + public Integer getToResult() + { + return toResult; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::terms=%s, returnAttributes=%s, searchRestrictions=%s, " + + "fromResult=%d, toResult=%d]", + getClass().getName(), + hashCode(), + Arrays.toString(terms), + Arrays.toString(returnAttributes), + searchRestrictions, + fromResult, + toResult); + } +}
diff --git a/templates/src/main/java/org/ldaptive/templates/SearchTemplates.java b/templates/src/main/java/org/ldaptive/templates/SearchTemplates.java new file mode 100644 index 0000000..dda9c44 --- /dev/null +++ b/templates/src/main/java/org/ldaptive/templates/SearchTemplates.java
@@ -0,0 +1,242 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.templates; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.ldaptive.SearchFilter; + +/** + * Contains a list of common search filter templates that can be formatted for any given query. + * + * @author Middleware Services + */ +public class SearchTemplates +{ + + /** Search filter templates. */ + private final String[] filterTemplates; + + /** Appended to every search filter to restrict results. */ + private String searchRestrictions; + + /** Term parsers for creating filter parameters. */ + private TermParser[] termParsers = new TermParser[] { + new DefaultTermParser(), + new InitialTermParser(), + }; + + + /** + * Creates a new search templates. + * + * @param templates list of search filters + */ + public SearchTemplates(final String... templates) + { + filterTemplates = templates; + } + + + /** + * Returns the filter to use for search restrictions. + * + * @return search restrictions + */ + public String getSearchRestrictions() + { + return searchRestrictions; + } + + + /** + * Sets the filter to use for search restrictions. + * + * @param restrictions search restrictions + */ + public void setSearchRestrictions(final String restrictions) + { + searchRestrictions = restrictions; + } + + + /** + * Returns the term parsers used for creating filter parameters. + * + * @return term parsers + */ + public TermParser[] getTermParsers() + { + return termParsers; + } + + + /** + * Sets the term parsers used for creating filter parameters. + * + * @param parsers term parsers + */ + public void setTermParsers(final TermParser... parsers) + { + termParsers = parsers; + } + + + /** + * Creates the search filters using configured templates and the supplied query. + * + * @param query to create search filter with + * + * @return search filters + */ + public SearchFilter[] format(final Query query) + { + final List<SearchFilter> filters = new ArrayList<>(filterTemplates.length); + for (String template : filterTemplates) { + final SearchFilter filter = new SearchFilter( + concatFilters(template, query.getSearchRestrictions(), searchRestrictions)); + for (TermParser parser : termParsers) { + for (Map.Entry<String, String> e : parser.parse(query.getTerms()).entrySet()) { + filter.setParameter(e.getKey(), e.getValue()); + } + } + filters.add(filter); + } + return filters.toArray(new SearchFilter[filters.size()]); + } + + + /** + * Concatenates the supplied filters into a single filter will all arguments ANDED together. Null array values are + * ignored. + * + * @param filters to concatenate + * + * @return search filter + */ + private String concatFilters(final String... filters) + { + final List<String> nonNullFilters = new ArrayList<>(filters.length); + for (String s : filters) { + if (s != null) { + nonNullFilters.add(s); + } + } + if (nonNullFilters.size() > 1) { + final StringBuilder sb = new StringBuilder("(&"); + nonNullFilters.forEach(sb::append); + sb.append(")"); + return sb.toString(); + } else { + return nonNullFilters.get(0); + } + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::filterTemplates=%s, searchRestrictions=%s, termParsers=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(filterTemplates), + searchRestrictions, + Arrays.toString(termParsers)); + } + + + /** Converts query terms into search filter parameters. */ + public interface TermParser + { + + + /** + * Returns search filter parameters for the supplied query terms. + * + * @param terms to parse + * + * @return search filter parameters + */ + Map<String, String> parse(final String[] terms); + } + + + /** + * Adds each term as a filter parameter using the name 'termX' where X is the index of the term. For the argument: + * {'fname', 'lname' }, produces: + * + * <pre> + { + 'term1' => 'fname', + 'term2' => 'lname', + } + * </pre> + */ + public class DefaultTermParser implements TermParser + { + + + @Override + public Map<String, String> parse(final String[] terms) + { + final Map<String, String> filterParams = new HashMap<>(terms.length); + for (int i = 1; i <= terms.length; i++) { + filterParams.put("term" + i, terms[i - 1]); + } + return filterParams; + } + } + + + /** + * Adds the first letter of each term as a filter parameter using the name 'initialX' where X is the index of the + * term. For the argument: {'fname', 'lname' }, produces: + * + * <pre> + { + 'initial1' => 'f', + 'initial2' => 'l', + } + * </pre> + */ + public class InitialTermParser implements TermParser + { + + + @Override + public Map<String, String> parse(final String[] terms) + { + final Map<String, String> filterParams = new HashMap<>(terms.length); + final String[] initialParams = getInitials(terms); + for (int i = 1; i <= initialParams.length; i++) { + filterParams.put("initial" + i, initialParams[i - 1]); + } + return filterParams; + } + + + /** + * This converts an array of names into an array of initials. + * + * @param names to convert to initials + * + * @return initials + */ + private String[] getInitials(final String[] names) + { + final String[] initials = new String[names.length]; + for (int i = 0; i < initials.length; i++) { + if (names[i] != null && names[i].length() > 0) { + initials[i] = names[i].substring(0, 1); + } else { + initials[i] = null; + } + } + return initials; + } + } +}
diff --git a/templates/src/main/java/org/ldaptive/templates/SearchTemplatesExecutor.java b/templates/src/main/java/org/ldaptive/templates/SearchTemplatesExecutor.java new file mode 100644 index 0000000..653034d --- /dev/null +++ b/templates/src/main/java/org/ldaptive/templates/SearchTemplatesExecutor.java
@@ -0,0 +1,249 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.templates; + +import java.util.Arrays; +import java.util.Collection; +import org.ldaptive.LdapEntry; +import org.ldaptive.LdapException; +import org.ldaptive.Response; +import org.ldaptive.SearchFilter; +import org.ldaptive.SearchResult; +import org.ldaptive.SortBehavior; +import org.ldaptive.concurrent.AggregatePooledSearchExecutor; +import org.ldaptive.pool.PooledConnectionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Searches an LDAP using a defined set of search templates. For each term count some number of templates are defined + * and used for searching. + * + * @author Middleware Services + */ +public class SearchTemplatesExecutor +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Search executor. */ + private AggregatePooledSearchExecutor searchExecutor; + + /** Connection factory. */ + private PooledConnectionFactory[] connectionFactories; + + /** Search templates. */ + private SearchTemplates[] searchTemplates; + + + /** Default constructor. */ + public SearchTemplatesExecutor() {} + + + /** + * Creates a new templates search executor. + * + * @param executor aggregate pooled search executor + * @param factories pooled connection factories + * @param templates search templates + */ + public SearchTemplatesExecutor( + final AggregatePooledSearchExecutor executor, + final PooledConnectionFactory[] factories, + final SearchTemplates... templates) + { + searchExecutor = executor; + connectionFactories = factories; + searchTemplates = templates; + } + + + /** + * Returns the search executor. + * + * @return aggregate pooled search executor + */ + public AggregatePooledSearchExecutor getSearchExecutor() + { + return searchExecutor; + } + + + /** + * Sets the search executor. + * + * @param executor aggregate pooled search executor + */ + public void setSearchExecutor(final AggregatePooledSearchExecutor executor) + { + searchExecutor = executor; + } + + + /** + * Returns the connection factories. + * + * @return pooled connection factories + */ + public PooledConnectionFactory[] getConnectionFactories() + { + return connectionFactories; + } + + + /** + * Sets the connection factories. + * + * @param factories pooled connection factory + */ + public void setConnectionFactories(final PooledConnectionFactory[] factories) + { + connectionFactories = factories; + } + + + /** + * Returns the search templates. + * + * @return search templates + */ + public SearchTemplates[] getSearchTemplates() + { + return searchTemplates; + } + + + /** + * Sets the search templates. + * + * @param templates search templates + */ + public void setSearchTemplates(final SearchTemplates[] templates) + { + searchTemplates = templates; + } + + + /** + * Applies the supplied query to a search templates and aggregates all results into a single search result. + * + * @param query to execute + * + * @return ldap result + * + * @throws LdapException if the search fails + */ + public SearchResult search(final Query query) + throws LdapException + { + logger.debug("Query: {}", query); + + // get a search object + SearchTemplates templates = null; + if (query.getTerms().length > 0) { + + logger.debug("Processing query: {}", Arrays.toString(query.getTerms())); + + int termCount = query.getTerms().length; + // if term count exceeds the highest defined templates + // use the highest set of templates available + if (termCount > searchTemplates.length) { + termCount = searchTemplates.length; + } + if (termCount > 0) { + templates = searchTemplates[termCount - 1]; + if (templates != null) { + logger.debug("Found search templates {} for term count of {}", templates, termCount); + } else { + logger.debug("No search module found for term count of {}", termCount); + } + } else { + logger.debug("No terms found in query {}", query); + } + } + + if (templates != null) { + return search(templates.format(query), query.getReturnAttributes(), query.getFromResult(), query.getToResult()); + } else { + return null; + } + } + + + /** + * Performs an LDAP search with the supplied filters and aggregates all the search results together. + * + * @param filters to execute + * @param returnAttrs attributes to return from the search + * @param fromResult index to return results from + * @param toResult index to return results to + * + * @return ldap result containing all results + * + * @throws LdapException if the search fails + */ + protected SearchResult search( + final SearchFilter[] filters, + final String[] returnAttrs, + final Integer fromResult, + final Integer toResult) + throws LdapException + { + logger.debug("Performing search with {} filters", Arrays.toString(filters)); + + // perform parallel searches + final Collection<Response<SearchResult>> responses = searchExecutor.search( + connectionFactories, + filters, + returnAttrs); + + // iterate over all results and store each entry + final SearchResult result = new SearchResult(SortBehavior.ORDERED); + for (Response<SearchResult> r : responses) { + for (LdapEntry le : r.getResult().getEntries()) { + result.addEntry(le); + logger.debug("Search found: {}", le.getDn()); + } + } + + SearchResult subResult; + if (fromResult != null) { + if (toResult != null) { + subResult = result.subResult(fromResult, toResult); + } else { + subResult = result.subResult(fromResult, result.size()); + } + } else if (toResult != null) { + subResult = result.subResult(0, toResult); + } else { + subResult = result; + } + return subResult; + } + + + /** Closes any resources associated with this object. */ + public void close() + { + if (connectionFactories != null) { + for (PooledConnectionFactory factory : connectionFactories) { + factory.getConnectionPool().close(); + } + } + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::searchExecutor=%s, connectionFactories=%s, " + + "searchTemplates=%s]", + getClass().getName(), + hashCode(), + searchExecutor, + Arrays.toString(connectionFactories), + Arrays.toString(searchTemplates)); + } +}
diff --git a/templates/src/test/java/org/ldaptive/templates/QueryTest.java b/templates/src/test/java/org/ldaptive/templates/QueryTest.java new file mode 100644 index 0000000..79653f1 --- /dev/null +++ b/templates/src/test/java/org/ldaptive/templates/QueryTest.java
@@ -0,0 +1,64 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.templates; + +import org.testng.AssertJUnit; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link Query}. + * + * @author Middleware Services + */ +public class QueryTest +{ + + + /** + * Sample query data. + * + * @return query data + */ + @DataProvider(name = "query-data") + public Object[][] createTestData() + { + return + new Object[][] { + { + new Query(null), + new String[] {}, + }, + { + new Query(""), + new String[] {}, + }, + { + new Query(" dfisher "), + new String[] {"dfisher"}, + }, + { + new Query("d fisher"), + new String[] {"d", "fisher", }, + }, + { + new Query("daniel fisher"), + new String[] {"daniel", "fisher", }, + }, + { + new Query("daniel w fisher"), + new String[] {"daniel", "w", "fisher", }, + }, + }; + } + + + /** + * @param query to get terms from + * @param terms to compare + */ + @Test(groups = {"querytest"}, dataProvider = "query-data") + public void format(final Query query, final String[] terms) + { + AssertJUnit.assertArrayEquals(terms, query.getTerms()); + } +}
diff --git a/templates/src/test/java/org/ldaptive/templates/SearchTemplatesTest.java b/templates/src/test/java/org/ldaptive/templates/SearchTemplatesTest.java new file mode 100644 index 0000000..3300e24 --- /dev/null +++ b/templates/src/test/java/org/ldaptive/templates/SearchTemplatesTest.java
@@ -0,0 +1,237 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.templates; + +import org.ldaptive.SearchFilter; +import org.testng.AssertJUnit; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link SearchTemplates}. + * + * @author Middleware Services + */ +public class SearchTemplatesTest +{ + + + /** + * Sample template data. + * + * @return template data + */ + @DataProvider(name = "template-data") + public Object[][] createTestData() + { + // test data for one term query + final SearchFilter sf11 = new SearchFilter("(|(telephoneNumber={term1})(localPhone={term1}))"); + sf11.setParameter("term1", "fisher"); + sf11.setParameter("initial1", "f"); + + final SearchFilter sf12 = new SearchFilter("(|(telephoneNumber=*{term1})(localPhone=*{term1}))"); + sf12.setParameter("term1", "fisher"); + sf12.setParameter("initial1", "f"); + + final SearchFilter sf13 = new SearchFilter("(|(givenName={term1})(sn={term1}))"); + sf13.setParameter("term1", "fisher"); + sf13.setParameter("initial1", "f"); + + final SearchFilter sf14 = new SearchFilter("(|(givenName={term1}*)(sn={term1}*))"); + sf14.setParameter("term1", "fisher"); + sf14.setParameter("initial1", "f"); + + final SearchFilter sf15 = new SearchFilter("(|(givenName=*{term1}*)(sn=*{term1}*))"); + sf15.setParameter("term1", "fisher"); + sf15.setParameter("initial1", "f"); + + // test data for two term query + final SearchFilter sf21 = new SearchFilter("(&(givenName={term1})(sn={term2}))"); + sf21.setParameter("term1", "daniel"); + sf21.setParameter("term2", "fisher"); + sf21.setParameter("initial1", "d"); + sf21.setParameter("initial2", "f"); + + final SearchFilter sf22 = new SearchFilter("(cn={term1} {term2})"); + sf22.setParameter("term1", "daniel"); + sf22.setParameter("term2", "fisher"); + sf22.setParameter("initial1", "d"); + sf22.setParameter("initial2", "f"); + + final SearchFilter sf23 = new SearchFilter("(&(givenName={term1}*)(sn={term2}*))"); + sf23.setParameter("term1", "daniel"); + sf23.setParameter("term2", "fisher"); + sf23.setParameter("initial1", "d"); + sf23.setParameter("initial2", "f"); + + final SearchFilter sf24 = new SearchFilter("(cn={term1}* {term2}*)"); + sf24.setParameter("term1", "daniel"); + sf24.setParameter("term2", "fisher"); + sf24.setParameter("initial1", "d"); + sf24.setParameter("initial2", "f"); + + final SearchFilter sf25 = new SearchFilter("(&(givenName=*{term1}*)(sn=*{term2}*))"); + sf25.setParameter("term1", "daniel"); + sf25.setParameter("term2", "fisher"); + sf25.setParameter("initial1", "d"); + sf25.setParameter("initial2", "f"); + + final SearchFilter sf26 = new SearchFilter("(cn=*{term1}* *{term2}*)"); + sf26.setParameter("term1", "daniel"); + sf26.setParameter("term2", "fisher"); + sf26.setParameter("initial1", "d"); + sf26.setParameter("initial2", "f"); + + final SearchFilter sf27 = new SearchFilter( + "(|(&(givenName={initial1}*)(sn={term2}))" + + "(&(middleName={initial1}*)(sn={term2})))"); + sf27.setParameter("term1", "daniel"); + sf27.setParameter("term2", "fisher"); + sf27.setParameter("initial1", "d"); + sf27.setParameter("initial2", "f"); + + final SearchFilter sf28 = new SearchFilter("(sn={term2})"); + sf28.setParameter("term1", "daniel"); + sf28.setParameter("term2", "fisher"); + sf28.setParameter("initial1", "d"); + sf28.setParameter("initial2", "f"); + + // test data for three term query + final SearchFilter sf31 = new SearchFilter( + "(|(&(givenName={term1})(sn={term3}))(&(givenName={term2})(sn={term3})))"); + sf31.setParameter("term1", "daniel"); + sf31.setParameter("term2", "wayne"); + sf31.setParameter("term3", "fisher"); + sf31.setParameter("initial1", "d"); + sf31.setParameter("initial2", "w"); + sf31.setParameter("initial3", "f"); + + final SearchFilter sf32 = new SearchFilter("(|(cn={term1} {term2} {term3})(cn={term2} {term1} {term3}))"); + sf32.setParameter("term1", "daniel"); + sf32.setParameter("term2", "wayne"); + sf32.setParameter("term3", "fisher"); + sf32.setParameter("initial1", "d"); + sf32.setParameter("initial2", "w"); + sf32.setParameter("initial3", "f"); + + final SearchFilter sf33 = new SearchFilter( + "(|(&(givenName={term1}*)(sn={term3}*))(&(givenName={term2}*)(sn={term3}*)))"); + sf33.setParameter("term1", "daniel"); + sf33.setParameter("term2", "wayne"); + sf33.setParameter("term3", "fisher"); + sf33.setParameter("initial1", "d"); + sf33.setParameter("initial2", "w"); + sf33.setParameter("initial3", "f"); + + final SearchFilter sf34 = new SearchFilter("(|(cn={term1}* {term2}* {term3}*)(cn={term2}* {term1}* {term3}*))"); + sf34.setParameter("term1", "daniel"); + sf34.setParameter("term2", "wayne"); + sf34.setParameter("term3", "fisher"); + sf34.setParameter("initial1", "d"); + sf34.setParameter("initial2", "w"); + sf34.setParameter("initial3", "f"); + + final SearchFilter sf35 = new SearchFilter( + "(|(&(givenName=*{term1}*)(sn=*{term3}*))(&(givenName=*{term2}*)(sn=*{term3}*)))"); + sf35.setParameter("term1", "daniel"); + sf35.setParameter("term2", "wayne"); + sf35.setParameter("term3", "fisher"); + sf35.setParameter("initial1", "d"); + sf35.setParameter("initial2", "w"); + sf35.setParameter("initial3", "f"); + + final SearchFilter sf36 = new SearchFilter( + "(|(cn=*{term1}* *{term2}* *{term3}*)(cn=*{term2}* *{term1}* *{term3}*))"); + sf36.setParameter("term1", "daniel"); + sf36.setParameter("term2", "wayne"); + sf36.setParameter("term3", "fisher"); + sf36.setParameter("initial1", "d"); + sf36.setParameter("initial2", "w"); + sf36.setParameter("initial3", "f"); + + final SearchFilter sf37 = new SearchFilter( + "(|(&(givenName={term1})(middleName={initial2}*)(sn={term3}))" + + "(&(givenName={term2})(middleName={initial1}*)(sn={term3})))"); + sf37.setParameter("term1", "daniel"); + sf37.setParameter("term2", "wayne"); + sf37.setParameter("term3", "fisher"); + sf37.setParameter("initial1", "d"); + sf37.setParameter("initial2", "w"); + sf37.setParameter("initial3", "f"); + + final SearchFilter sf38 = new SearchFilter( + "(|(&p(givenName={initial1}*)(middlename={initial2}*)(sn={term3}))" + + "(&(givenName={initial2}*)(middleName={initial1}*)(sn={term3})))"); + sf38.setParameter("term1", "daniel"); + sf38.setParameter("term2", "wayne"); + sf38.setParameter("term3", "fisher"); + sf38.setParameter("initial1", "d"); + sf38.setParameter("initial2", "w"); + sf38.setParameter("initial3", "f"); + + final SearchFilter sf39 = new SearchFilter("(sn={term3})"); + sf39.setParameter("term1", "daniel"); + sf39.setParameter("term2", "wayne"); + sf39.setParameter("term3", "fisher"); + sf39.setParameter("initial1", "d"); + sf39.setParameter("initial2", "w"); + sf39.setParameter("initial3", "f"); + + // test data for special characters + final SearchFilter sf41 = new SearchFilter("(cn=*{term1}*)"); + sf41.setParameter("term1", "d\\\\i$h3\\*r"); + sf41.setParameter("initial1", "d"); + + return + new Object[][] { + { + new SearchTemplates(sf11.getFilter(), sf12.getFilter(), sf13.getFilter(), sf14.getFilter(), sf15.getFilter()), + new Query("fisher"), + new SearchFilter[] {sf11, sf12, sf13, sf14, sf15, }, + }, + { + new SearchTemplates( + sf21.getFilter(), + sf22.getFilter(), + sf23.getFilter(), + sf24.getFilter(), + sf25.getFilter(), + sf26.getFilter(), + sf27.getFilter(), + sf28.getFilter()), + new Query("daniel fisher"), + new SearchFilter[] {sf21, sf22, sf23, sf24, sf25, sf26, sf27, sf28, }, + }, + { + new SearchTemplates( + sf31.getFilter(), + sf32.getFilter(), + sf33.getFilter(), + sf34.getFilter(), + sf35.getFilter(), + sf36.getFilter(), + sf37.getFilter(), + sf38.getFilter(), + sf39.getFilter()), + new Query("daniel wayne fisher"), + new SearchFilter[] {sf31, sf32, sf33, sf34, sf35, sf36, sf37, sf38, sf39, }, + }, + { + new SearchTemplates(sf41.getFilter()), + new Query("d\\\\i$h3\\*r"), + new SearchFilter[] {sf41, }, + }, + }; + } + + + /** + * @param templates to format + * @param query to apply to the template + * @param filters to compare + */ + @Test(groups = {"templatestest"}, dataProvider = "template-data") + public void format(final SearchTemplates templates, final Query query, final SearchFilter[] filters) + { + AssertJUnit.assertArrayEquals(filters, templates.format(query)); + } +}
diff --git a/unboundid-provider/pom.xml b/unboundid-provider/pom.xml new file mode 100644 index 0000000..ab20d3e --- /dev/null +++ b/unboundid-provider/pom.xml
@@ -0,0 +1,27 @@ +<?xml version='1.0' encoding='UTF-8'?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>ldaptive-unboundid</artifactId> + <packaging>jar</packaging> + <name>LDAPTIVE UNBOUNDID PROVIDER</name> + <description>Ldaptive unboundid provider</description> + <parent> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-parent</artifactId> + <version>1.2.3</version> + </parent> + + <dependencies> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive</artifactId> + </dependency> + <dependency> + <groupId>com.unboundid</groupId> + <artifactId>unboundid-ldapsdk</artifactId> + </dependency> + </dependencies> + +</project>
diff --git a/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDConnection.java b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDConnection.java new file mode 100644 index 0000000..1023555 --- /dev/null +++ b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDConnection.java
@@ -0,0 +1,1187 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.unboundid; + +import java.util.ArrayDeque; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import com.unboundid.asn1.ASN1OctetString; +import com.unboundid.ldap.sdk.AsyncRequestID; +import com.unboundid.ldap.sdk.AsyncSearchResultListener; +import com.unboundid.ldap.sdk.BindResult; +import com.unboundid.ldap.sdk.CRAMMD5BindRequest; +import com.unboundid.ldap.sdk.CompareResult; +import com.unboundid.ldap.sdk.Control; +import com.unboundid.ldap.sdk.DIGESTMD5BindRequest; +import com.unboundid.ldap.sdk.DIGESTMD5BindRequestProperties; +import com.unboundid.ldap.sdk.DN; +import com.unboundid.ldap.sdk.DereferencePolicy; +import com.unboundid.ldap.sdk.DisconnectHandler; +import com.unboundid.ldap.sdk.DisconnectType; +import com.unboundid.ldap.sdk.EXTERNALBindRequest; +import com.unboundid.ldap.sdk.ExtendedResult; +import com.unboundid.ldap.sdk.GSSAPIBindRequest; +import com.unboundid.ldap.sdk.GSSAPIBindRequestProperties; +import com.unboundid.ldap.sdk.IntermediateResponse; +import com.unboundid.ldap.sdk.IntermediateResponseListener; +import com.unboundid.ldap.sdk.LDAPConnection; +import com.unboundid.ldap.sdk.LDAPConnectionOptions; +import com.unboundid.ldap.sdk.LDAPException; +import com.unboundid.ldap.sdk.LDAPResult; +import com.unboundid.ldap.sdk.LDAPSearchException; +import com.unboundid.ldap.sdk.SASLBindRequest; +import com.unboundid.ldap.sdk.SearchRequest; +import com.unboundid.ldap.sdk.SearchResult; +import com.unboundid.ldap.sdk.SearchResultEntry; +import com.unboundid.ldap.sdk.SearchResultListener; +import com.unboundid.ldap.sdk.SearchResultReference; +import com.unboundid.ldap.sdk.SearchScope; +import com.unboundid.ldap.sdk.SimpleBindRequest; +import com.unboundid.ldap.sdk.UnsolicitedNotificationHandler; +import org.ldaptive.AddRequest; +import org.ldaptive.BindRequest; +import org.ldaptive.CompareRequest; +import org.ldaptive.DeleteRequest; +import org.ldaptive.DerefAliases; +import org.ldaptive.LdapException; +import org.ldaptive.ModifyDnRequest; +import org.ldaptive.ModifyRequest; +import org.ldaptive.Request; +import org.ldaptive.Response; +import org.ldaptive.ResultCode; +import org.ldaptive.SearchEntry; +import org.ldaptive.SearchReference; +import org.ldaptive.async.AsyncRequest; +import org.ldaptive.control.RequestControl; +import org.ldaptive.control.ResponseControl; +import org.ldaptive.extended.ExtendedRequest; +import org.ldaptive.extended.ExtendedResponse; +import org.ldaptive.extended.ExtendedResponseFactory; +import org.ldaptive.extended.UnsolicitedNotificationListener; +import org.ldaptive.intermediate.IntermediateResponseFactory; +import org.ldaptive.provider.ProviderConnection; +import org.ldaptive.provider.ProviderUtils; +import org.ldaptive.provider.SearchItem; +import org.ldaptive.provider.SearchIterator; +import org.ldaptive.provider.SearchListener; +import org.ldaptive.sasl.SaslConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Unbound ID provider implementation of ldap operations. + * + * @author Middleware Services + */ +public class UnboundIDConnection implements ProviderConnection +{ + + /** Logger for this class. */ + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + /** Ldap connection. */ + private LDAPConnection connection; + + /** Provider configuration. */ + private final UnboundIDProviderConfig config; + + /** Receives unsolicited notifications. */ + private final AggregateUnsolicitedNotificationHandler notificationHandler = + new AggregateUnsolicitedNotificationHandler(); + + /** Receives disconnect notifications. */ + private final AggregateDisconnectHandler disconnectHandler = new AggregateDisconnectHandler(); + + + /** + * Creates a new unboundid ldap connection. + * + * @param lc ldap connection + * @param pc provider configuration + */ + public UnboundIDConnection(final LDAPConnection lc, final UnboundIDProviderConfig pc) + { + connection = lc; + config = pc; + + final LDAPConnectionOptions options = connection.getConnectionOptions(); + if (options.getUnsolicitedNotificationHandler() == null) { + options.setUnsolicitedNotificationHandler(notificationHandler); + } + if (options.getDisconnectHandler() == null) { + options.setDisconnectHandler(disconnectHandler); + } + } + + + /** + * Returns the underlying ldap connection. + * + * @return ldap connection + */ + public LDAPConnection getLdapConnection() + { + return connection; + } + + + @Override + public void close(final RequestControl[] controls) + throws LdapException + { + if (connection != null) { + try { + connection.close(config.getControlProcessor().processRequestControls(controls)); + } finally { + connection = null; + } + } + } + + + @Override + public Response<Void> bind(final BindRequest request) + throws LdapException + { + Response<Void> response; + if (request.getSaslConfig() != null) { + response = saslBind(request); + } else if (request.getDn() == null && request.getCredential() == null) { + response = anonymousBind(request); + } else { + response = simpleBind(request); + } + return response; + } + + + /** + * Performs an anonymous bind. + * + * @param request to bind with + * + * @return bind response + * + * @throws LdapException if an error occurs + */ + protected Response<Void> anonymousBind(final BindRequest request) + throws LdapException + { + Response<Void> response = null; + try { + SimpleBindRequest sbr; + if (request.getControls() != null) { + sbr = new SimpleBindRequest( + "", + new byte[0], + config.getControlProcessor().processRequestControls(request.getControls())); + } else { + sbr = new SimpleBindRequest(); + } + + final BindResult result = connection.bind(sbr); + response = createResponse(request, null, result); + } catch (LDAPException e) { + if (com.unboundid.ldap.sdk.ResultCode.REFERRAL == e.getResultCode()) { + response = createResponse(request, null, e.toLDAPResult()); + } else { + processLDAPException(request, e); + } + } + return response; + } + + + /** + * Performs a simple bind. + * + * @param request to bind with + * + * @return bind response + * + * @throws LdapException if an error occurs + */ + protected Response<Void> simpleBind(final BindRequest request) + throws LdapException + { + Response<Void> response = null; + try { + SimpleBindRequest sbr; + if (request.getControls() != null) { + sbr = new SimpleBindRequest( + new DN(request.getDn()), + request.getCredential().getBytes(), + config.getControlProcessor().processRequestControls(request.getControls())); + } else { + sbr = new SimpleBindRequest(request.getDn(), request.getCredential().getBytes()); + } + + final BindResult result = connection.bind(sbr); + response = createResponse(request, null, result); + } catch (LDAPException e) { + if (com.unboundid.ldap.sdk.ResultCode.REFERRAL == e.getResultCode()) { + response = createResponse(request, null, e.toLDAPResult()); + } else { + processLDAPException(request, e); + } + } + return response; + } + + + /** + * Performs a sasl bind. + * + * @param request to bind with + * + * @return bind response + * + * @throws LdapException if an error occurs + */ + protected Response<Void> saslBind(final BindRequest request) + throws LdapException + { + Response<Void> response = null; + try { + SASLBindRequest sbr; + final SaslConfig sc = request.getSaslConfig(); + switch (sc.getMechanism()) { + + case EXTERNAL: + sbr = new EXTERNALBindRequest( + sc.getAuthorizationId(), + config.getControlProcessor().processRequestControls(request.getControls())); + break; + + case DIGEST_MD5: + + final DIGESTMD5BindRequestProperties digestMd5Props = UnboundIDSaslUtils.createDigestMd5Properties( + request.getDn(), + request.getCredential(), + request.getSaslConfig()); + sbr = new DIGESTMD5BindRequest( + digestMd5Props, + config.getControlProcessor().processRequestControls(request.getControls())); + break; + + case CRAM_MD5: + sbr = new CRAMMD5BindRequest( + request.getDn(), + request.getCredential() != null ? request.getCredential().getBytes() : null, + config.getControlProcessor().processRequestControls(request.getControls())); + break; + + case GSSAPI: + + final GSSAPIBindRequestProperties props = UnboundIDSaslUtils.createGssApiProperties( + request.getDn(), + request.getCredential(), + request.getSaslConfig()); + sbr = new GSSAPIBindRequest(props, config.getControlProcessor().processRequestControls(request.getControls())); + break; + + default: + throw new IllegalArgumentException("Unknown SASL authentication mechanism: " + sc.getMechanism()); + } + + final BindResult result = connection.bind(sbr); + response = createResponse(request, null, result); + } catch (LDAPException e) { + if (com.unboundid.ldap.sdk.ResultCode.REFERRAL == e.getResultCode()) { + response = createResponse(request, null, e.toLDAPResult()); + } else { + processLDAPException(request, e); + } + } + return response; + } + + + @Override + public Response<Void> add(final AddRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final UnboundIDUtils util = new UnboundIDUtils(); + final com.unboundid.ldap.sdk.AddRequest ar = new com.unboundid.ldap.sdk.AddRequest( + new DN(request.getDn()), + util.fromLdapAttributes(request.getLdapAttributes()), + config.getControlProcessor().processRequestControls(request.getControls())); + + final LDAPResult result = connection.add(ar); + response = createResponse(request, null, result); + } catch (LDAPException e) { + if (com.unboundid.ldap.sdk.ResultCode.REFERRAL == e.getResultCode()) { + response = createResponse(request, null, e.toLDAPResult()); + } else { + processLDAPException(request, e); + } + } + return response; + } + + + @Override + public Response<Boolean> compare(final CompareRequest request) + throws LdapException + { + Response<Boolean> response = null; + try { + com.unboundid.ldap.sdk.CompareRequest cr; + if (request.getAttribute().isBinary()) { + cr = new com.unboundid.ldap.sdk.CompareRequest( + new DN(request.getDn()), + request.getAttribute().getName(), + request.getAttribute().getBinaryValue(), + config.getControlProcessor().processRequestControls(request.getControls())); + } else { + cr = new com.unboundid.ldap.sdk.CompareRequest( + new DN(request.getDn()), + request.getAttribute().getName(), + request.getAttribute().getStringValue(), + config.getControlProcessor().processRequestControls(request.getControls())); + } + + final CompareResult result = connection.compare(cr); + response = createResponse(request, result.compareMatched(), result); + } catch (LDAPException e) { + if (com.unboundid.ldap.sdk.ResultCode.REFERRAL == e.getResultCode()) { + response = createResponse(request, null, e.toLDAPResult()); + } else { + processLDAPException(request, e); + } + } + return response; + } + + + @Override + public Response<Void> delete(final DeleteRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final com.unboundid.ldap.sdk.DeleteRequest dr = new com.unboundid.ldap.sdk.DeleteRequest( + new DN(request.getDn()), + config.getControlProcessor().processRequestControls(request.getControls())); + + final LDAPResult result = connection.delete(dr); + response = createResponse(request, null, result); + } catch (LDAPException e) { + if (com.unboundid.ldap.sdk.ResultCode.REFERRAL == e.getResultCode()) { + response = createResponse(request, null, e.toLDAPResult()); + } else { + processLDAPException(request, e); + } + } + return response; + } + + + @Override + public Response<Void> modify(final ModifyRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final UnboundIDUtils bu = new UnboundIDUtils(); + final com.unboundid.ldap.sdk.ModifyRequest mr = new com.unboundid.ldap.sdk.ModifyRequest( + new DN(request.getDn()), + bu.fromAttributeModification(request.getAttributeModifications()), + config.getControlProcessor().processRequestControls(request.getControls())); + + final LDAPResult result = connection.modify(mr); + response = createResponse(request, null, result); + } catch (LDAPException e) { + if (com.unboundid.ldap.sdk.ResultCode.REFERRAL == e.getResultCode()) { + response = createResponse(request, null, e.toLDAPResult()); + } else { + processLDAPException(request, e); + } + } + return response; + } + + + @Override + public Response<Void> modifyDn(final ModifyDnRequest request) + throws LdapException + { + Response<Void> response = null; + try { + final DN dn = new DN(request.getDn()); + final DN newDn = new DN(request.getNewDn()); + final com.unboundid.ldap.sdk.ModifyDNRequest mdr = new com.unboundid.ldap.sdk.ModifyDNRequest( + dn, + newDn.getRDN(), + request.getDeleteOldRDn(), + newDn.getParent(), + config.getControlProcessor().processRequestControls(request.getControls())); + + final LDAPResult result = connection.modifyDN(mdr); + response = createResponse(request, null, result); + } catch (LDAPException e) { + if (com.unboundid.ldap.sdk.ResultCode.REFERRAL == e.getResultCode()) { + response = createResponse(request, null, e.toLDAPResult()); + } else { + processLDAPException(request, e); + } + } + return response; + } + + + @Override + public SearchIterator search(final org.ldaptive.SearchRequest request) + throws LdapException + { + final UnboundIDSearchIterator i = new UnboundIDSearchIterator(request); + i.initialize(); + return i; + } + + + @Override + public void searchAsync(final org.ldaptive.SearchRequest request, final SearchListener listener) + throws LdapException + { + final UnboundIDAsyncSearchListener l = new UnboundIDAsyncSearchListener(request, listener); + l.initialize(); + } + + + @Override + public void abandon(final int messageId, final RequestControl[] controls) + throws LdapException + { + throw new UnsupportedOperationException("Abandons via messageId not supported, use AsyncRequest instead"); + } + + + @Override + public Response<?> extendedOperation(final ExtendedRequest request) + throws LdapException + { + Response<?> response = null; + try { + com.unboundid.ldap.sdk.ExtendedRequest er; + final byte[] requestBerValue = request.encode(); + if (requestBerValue == null) { + er = new com.unboundid.ldap.sdk.ExtendedRequest( + request.getOID(), + config.getControlProcessor().processRequestControls(request.getControls())); + } else { + er = new com.unboundid.ldap.sdk.ExtendedRequest( + request.getOID(), + new ASN1OctetString(requestBerValue), + config.getControlProcessor().processRequestControls(request.getControls())); + } + + final ExtendedResult result = connection.processExtendedOperation(er); + final byte[] responseBerValue = result.getValue() != null ? result.getValue().getValue() : null; + final ExtendedResponse<?> extRes = ExtendedResponseFactory.createExtendedResponse( + request.getOID(), + result.getOID(), + responseBerValue); + response = createResponse(request, extRes.getValue(), result); + } catch (LDAPException e) { + processLDAPException(request, e); + } + return response; + } + + + @Override + public void addUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + notificationHandler.addUnsolicitedNotificationListener(listener); + } + + + @Override + public void removeUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + notificationHandler.removeUnsolicitedNotificationListener(listener); + } + + + /** + * Creates an operation response with the supplied response data. + * + * @param <T> type of response + * @param request containing controls + * @param result of the operation + * @param ldapResult provider result + * + * @return operation response + */ + protected <T> Response<T> createResponse(final Request request, final T result, final LDAPResult ldapResult) + { + return + new Response<>( + result, + ResultCode.valueOf(ldapResult.getResultCode().intValue()), + ldapResult.getDiagnosticMessage(), + ldapResult.getMatchedDN(), + config.getControlProcessor().processResponseControls(ldapResult.getResponseControls()), + ldapResult.getReferralURLs(), + ldapResult.getMessageID()); + } + + + /** + * Determines if the supplied ldap exception should result in an operation retry. + * + * @param request that produced the exception + * @param e that was produced + * + * @throws LdapException wrapping the ldap exception + */ + protected void processLDAPException(final Request request, final LDAPException e) + throws LdapException + { + ProviderUtils.throwOperationException( + config.getOperationExceptionResultCodes(), + e, + e.getResultCode().intValue(), + e.getMatchedDN(), + config.getControlProcessor().processResponseControls(e.getResponseControls()), + e.getReferralURLs(), + true); + } + + + /** Search iterator for unbound id search results. */ + protected class UnboundIDSearchIterator extends AbstractUnboundIDSearch implements SearchIterator + { + + /** Response data. */ + private org.ldaptive.Response<Void> response; + + /** Search result iterator. */ + private SearchResultIterator resultIterator; + + + /** + * Creates a new unbound id search iterator. + * + * @param sr search request + */ + public UnboundIDSearchIterator(final org.ldaptive.SearchRequest sr) + { + super(sr); + } + + + /** + * Initializes this unbound id search iterator. + * + * @throws org.ldaptive.LdapException if an error occurs + */ + public void initialize() + throws org.ldaptive.LdapException + { + resultIterator = search(connection, request); + } + + + /** + * Executes an ldap search. + * + * @param conn to search with + * @param sr to read properties from + * + * @return ldap search results + * + * @throws LdapException if an error occurs + */ + protected SearchResultIterator search(final LDAPConnection conn, final org.ldaptive.SearchRequest sr) + throws LdapException + { + final SearchResultIterator i = new SearchResultIterator(); + try { + final SearchRequest unboundIdSr = getSearchRequest(sr, i, i); + final Control[] c = config.getControlProcessor().processRequestControls(sr.getControls()); + unboundIdSr.addControls(c); + logger.debug("performing search: {}", unboundIdSr); + + final SearchResult result = conn.search(unboundIdSr); + response = createResponse(request, null, result); + logger.debug("created response: {}", response); + } catch (LDAPSearchException e) { + final ResultCode rc = ignoreSearchException(config.getSearchIgnoreResultCodes(), e); + if (rc == null) { + processLDAPException(sr, e); + } + response = createResponse( + request, + null, + new SearchResult( + -1, + e.getResultCode(), + e.getDiagnosticMessage(), + e.getMatchedDN(), + e.getReferralURLs(), + e.getEntryCount(), + e.getReferenceCount(), + e.getResponseControls())); + logger.debug("created response from exception: {}", response); + } + return i; + } + + + @Override + public boolean hasNext() + throws org.ldaptive.LdapException + { + return resultIterator != null && resultIterator.hasNext(); + } + + + @Override + public SearchItem next() + throws org.ldaptive.LdapException + { + return resultIterator.next(); + } + + + @Override + public org.ldaptive.Response<Void> getResponse() + { + return response; + } + + + @Override + public void close() + throws LdapException {} + + + /** Search results listener for storing entries returned by the search operation. */ + protected class SearchResultIterator implements SearchResultListener, IntermediateResponseListener + { + + /** Search items. */ + protected final Queue<SearchItem> queue = new ArrayDeque<>(); + + + /** + * Returns the next search item from the queue. + * + * @return search result entry + */ + public SearchItem next() + { + return queue.poll(); + } + + + /** + * Whether the queue is empty. + * + * @return whether the queue is empty + */ + public boolean hasNext() + { + return !queue.isEmpty(); + } + + + @Override + public void searchEntryReturned(final SearchResultEntry entry) + { + queue.add(processSearchResultEntry(entry)); + } + + + @Override + public void searchReferenceReturned(final SearchResultReference ref) + { + queue.add(processSearchResultReference(ref)); + } + + + @Override + public void intermediateResponseReturned(final IntermediateResponse res) + { + queue.add(processIntermediateResponse(res)); + } + } + } + + + /** Search listener for unbound id async search results. */ + protected class UnboundIDAsyncSearchListener extends AbstractUnboundIDSearch + implements AsyncSearchResultListener, IntermediateResponseListener + { + + /** Search result listener. */ + private final SearchListener listener; + + /** Request ID of the search operation. */ + private AsyncRequestID requestID; + + /** Receives disconnect notifications for this async operation. */ + private final DisconnectHandler handler; + + + /** + * Creates a new unbound id search listener. + * + * @param sr search request + * @param sl search listener + */ + public UnboundIDAsyncSearchListener(final org.ldaptive.SearchRequest sr, final SearchListener sl) + { + super(sr); + listener = sl; + handler = new DisconnectHandler() { + @Override + public void handleDisconnect( + final LDAPConnection ldapConnection, + final String host, + final int port, + final DisconnectType disconnectType, + final String message, + final Throwable throwable) + { + listener.exceptionReceived(new Exception(message, throwable)); + disconnectHandler.removeDisconnectHandler(this); + } + }; + } + + + /** + * Returns the request ID. + * + * @return request ID + */ + public AsyncRequestID getRequestID() + { + return requestID; + } + + + /** + * Initializes this unbound id search listener. + * + * @throws LdapException if an error occurs + */ + public void initialize() + throws LdapException + { + search(connection, request); + } + + + /** + * Executes an ldap search. + * + * @param conn to search with + * @param sr to read properties from + * + * @throws LdapException if an error occurs + */ + protected void search(final LDAPConnection conn, final org.ldaptive.SearchRequest sr) + throws LdapException + { + try { + final SearchRequest unboundIdSr = getSearchRequest(sr, this, this); + final Control[] c = config.getControlProcessor().processRequestControls(sr.getControls()); + unboundIdSr.addControls(c); + logger.debug("performing search: {}", unboundIdSr); + requestID = conn.asyncSearch(unboundIdSr); + disconnectHandler.addDisconnectHandler(handler); + listener.asyncRequestReceived(new UnboundIDAsyncRequest(requestID, sr)); + } catch (LDAPSearchException e) { + final ResultCode rc = ignoreSearchException(config.getSearchIgnoreResultCodes(), e); + if (rc == null) { + processLDAPException(sr, e); + } + } catch (LDAPException e) { + processLDAPException(sr, e); + } + } + + + @Override + public void searchEntryReturned(final SearchResultEntry entry) + { + listener.searchItemReceived(processSearchResultEntry(entry)); + } + + + @Override + public void searchReferenceReturned(final SearchResultReference ref) + { + listener.searchItemReceived(processSearchResultReference(ref)); + } + + + @Override + public void intermediateResponseReturned(final IntermediateResponse res) + { + listener.searchItemReceived(processIntermediateResponse(res)); + } + + + @Override + public void searchResultReceived(final AsyncRequestID id, final SearchResult res) + { + logger.trace("reading result: {}", res); + + disconnectHandler.removeDisconnectHandler(handler); + + final org.ldaptive.Response<Void> response = createResponse(request, null, res); + listener.responseReceived(response); + } + } + + + /** Common search functionality for unbound id iterators and listeners. */ + protected abstract class AbstractUnboundIDSearch + { + + /** Search request. */ + protected final org.ldaptive.SearchRequest request; + + /** Utility class. */ + protected final UnboundIDUtils util; + + + /** + * Creates a new abstract unbound id search. + * + * @param sr search request + */ + public AbstractUnboundIDSearch(final org.ldaptive.SearchRequest sr) + { + request = sr; + util = new UnboundIDUtils(request.getSortBehavior()); + util.setBinaryAttributes(request.getBinaryAttributes()); + } + + + /** + * Returns an unbound id search request object configured with the supplied search request. + * + * @param sr search request containing configuration to create unbound id search request + * @param srListener search result listener + * @param irListener intermediate response listener + * + * @return search request + * + * @throws LDAPSearchException if the search request cannot be initialized + */ + protected SearchRequest getSearchRequest( + final org.ldaptive.SearchRequest sr, + final SearchResultListener srListener, + final IntermediateResponseListener irListener) + throws LDAPSearchException + { + try { + final SearchRequest req = new SearchRequest( + srListener, + sr.getBaseDn(), + getSearchScope(sr.getSearchScope()), + getDereferencePolicy(sr.getDerefAliases()), + (int) sr.getSizeLimit(), + (int) sr.getTimeLimit().getSeconds(), + sr.getTypesOnly(), + sr.getSearchFilter() != null ? sr.getSearchFilter().format() : null, + sr.getReturnAttributes()); + if (irListener != null) { + req.setIntermediateResponseListener(irListener); + } + return req; + } catch (LDAPException e) { + // thrown if the filter cannot be parsed + throw new LDAPSearchException(e); + } + } + + + /** + * Returns the unbound id search scope for the supplied search scope. + * + * @param ss search scope + * + * @return unbound id search scope + */ + protected SearchScope getSearchScope(final org.ldaptive.SearchScope ss) + { + SearchScope scope = null; + if (ss == org.ldaptive.SearchScope.OBJECT) { + scope = SearchScope.BASE; + } else if (ss == org.ldaptive.SearchScope.ONELEVEL) { + scope = SearchScope.ONE; + } else if (ss == org.ldaptive.SearchScope.SUBTREE) { + scope = SearchScope.SUB; + } + return scope; + } + + + /** + * Returns the unbound id deference policy for the supplied deref aliases. + * + * @param deref deref aliases + * + * @return dereference policy + */ + protected DereferencePolicy getDereferencePolicy(final DerefAliases deref) + { + DereferencePolicy policy = DereferencePolicy.NEVER; + if (deref == DerefAliases.ALWAYS) { + policy = DereferencePolicy.ALWAYS; + } else if (deref == DerefAliases.FINDING) { + policy = DereferencePolicy.FINDING; + } else if (deref == DerefAliases.NEVER) { + policy = DereferencePolicy.NEVER; + } else if (deref == DerefAliases.SEARCHING) { + policy = DereferencePolicy.SEARCHING; + } + return policy; + } + + + /** + * Determines whether the supplied ldap exception should be ignored. + * + * @param ignoreResultCodes to match against the exception + * @param e ldap exception to match + * + * @return result code that should be ignored or null + */ + protected ResultCode ignoreSearchException(final ResultCode[] ignoreResultCodes, final LDAPException e) + { + ResultCode ignore = null; + if (ignoreResultCodes != null && ignoreResultCodes.length > 0) { + for (ResultCode rc : ignoreResultCodes) { + if (e.getResultCode().intValue() == rc.value()) { + logger.debug("Ignoring ldap exception", e); + ignore = rc; + break; + } + } + } + return ignore; + } + + + /** + * Processes the response controls on the supplied entry and returns a corresponding search item. + * + * @param entry to process + * + * @return search item + */ + protected SearchItem processSearchResultEntry(final SearchResultEntry entry) + { + logger.trace("reading search entry: {}", entry); + + ResponseControl[] respControls = null; + if (entry.getControls() != null && entry.getControls().length > 0) { + respControls = config.getControlProcessor().processResponseControls(entry.getControls()); + } + + final SearchEntry se = util.toSearchEntry(entry, respControls, entry.getMessageID()); + return new SearchItem(se); + } + + + /** + * Processes the response controls on the supplied reference and returns a corresponding search item. + * + * @param ref to process + * + * @return search item + */ + protected SearchItem processSearchResultReference(final SearchResultReference ref) + { + logger.trace("reading search reference: {}", ref); + + ResponseControl[] respControls = null; + if (ref.getControls() != null && ref.getControls().length > 0) { + respControls = config.getControlProcessor().processResponseControls(ref.getControls()); + } + + final SearchReference sr = new SearchReference(ref.getMessageID(), respControls, ref.getReferralURLs()); + return new SearchItem(sr); + } + + + /** + * Processes the response controls on the supplied response and returns a corresponding search item. + * + * @param res to process + * + * @return search item + */ + protected SearchItem processIntermediateResponse(final IntermediateResponse res) + { + logger.trace("reading intermediate response: {}", res); + + ResponseControl[] respControls = null; + if (res.getControls() != null && res.getControls().length > 0) { + respControls = config.getControlProcessor().processResponseControls(res.getControls()); + } + + final org.ldaptive.intermediate.IntermediateResponse ir = IntermediateResponseFactory.createIntermediateResponse( + res.getOID(), + res.getValue().getValue(), + respControls, + res.getMessageID()); + return new SearchItem(ir); + } + } + + + /** Async request to invoke abandons. */ + protected class UnboundIDAsyncRequest implements AsyncRequest + { + + /** Async request id. */ + private final AsyncRequestID requestID; + + /** Request that produced this async request. */ + private final Request request; + + + /** + * Creates a new unboundid async request. + * + * @param id async request id + * @param r request + */ + public UnboundIDAsyncRequest(final AsyncRequestID id, final Request r) + { + requestID = id; + request = r; + } + + + @Override + public int getMessageId() + { + return requestID.getMessageID(); + } + + + @Override + public void abandon() + throws LdapException + { + try { + connection.abandon(requestID); + } catch (LDAPException e) { + processLDAPException(request, e); + } + } + + + @Override + public void abandon(final RequestControl[] controls) + throws LdapException + { + try { + connection.abandon(requestID, config.getControlProcessor().processRequestControls(request.getControls())); + } catch (LDAPException e) { + processLDAPException(request, e); + } + } + } + + + /** Allows the use of multiple unsolicited notification handlers per connection. */ + protected class AggregateUnsolicitedNotificationHandler implements UnsolicitedNotificationHandler + { + + /** Listeners to receive unsolicited notifications. */ + private final Queue<UnsolicitedNotificationListener> listeners = new ConcurrentLinkedQueue<>(); + + + /** + * Adds an unsolicited notification listener to this handler. + * + * @param listener to receive unsolicited notifications + */ + public void addUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + listeners.add(listener); + } + + + /** + * Removes an unsolicited notification listener from this handler. + * + * @param listener to stop receiving unsolicited notifications + */ + public void removeUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener) + { + listeners.remove(listener); + } + + + @Override + public void handleUnsolicitedNotification(final LDAPConnection ldapConnection, final ExtendedResult extendedResult) + { + logger.debug("Unsolicited notification received: {}", extendedResult); + + final Response<Void> response = createResponse(null, null, extendedResult); + for (UnsolicitedNotificationListener listener : listeners) { + listener.notificationReceived(extendedResult.getOID(), response); + } + } + } + + + /** Allows the use of multiple disconnect handlers per connection. */ + protected class AggregateDisconnectHandler implements DisconnectHandler + { + + /** Handlers to receive disconnect notifications. */ + private final Queue<DisconnectHandler> handlers = new ConcurrentLinkedQueue<>(); + + + /** + * Adds an disconnect handler to this handler. + * + * @param handler to receive disconnect notifications + */ + public void addDisconnectHandler(final DisconnectHandler handler) + { + handlers.add(handler); + } + + + /** + * Removes a disconnect handler from this handler. + * + * @param handler to stop receiving disconnect notifications + */ + public void removeDisconnectHandler(final DisconnectHandler handler) + { + handlers.remove(handler); + } + + + @Override + public void handleDisconnect( + final LDAPConnection ldapConnection, + final String host, + final int port, + final DisconnectType disconnectType, + final String message, + final Throwable throwable) + { + logger.debug("Disconnection received: {}", disconnectType); + for (DisconnectHandler handler : handlers) { + handler.handleDisconnect(ldapConnection, host, port, disconnectType, message, throwable); + } + } + } +}
diff --git a/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDConnectionFactory.java b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDConnectionFactory.java new file mode 100644 index 0000000..3798e85 --- /dev/null +++ b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDConnectionFactory.java
@@ -0,0 +1,79 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.unboundid; + +import javax.net.ssl.SSLSocketFactory; +import com.unboundid.ldap.sdk.LDAPConnection; +import com.unboundid.ldap.sdk.LDAPConnectionOptions; +import com.unboundid.ldap.sdk.LDAPException; +import org.ldaptive.ConnectionStrategy; +import org.ldaptive.LdapException; +import org.ldaptive.LdapURL; +import org.ldaptive.provider.AbstractProviderConnectionFactory; +import org.ldaptive.provider.ConnectionException; + +/** + * Creates ldap connections using the UnboundID LDAPConnection class. + * + * @author Middleware Services + */ +public class UnboundIDConnectionFactory extends AbstractProviderConnectionFactory<UnboundIDProviderConfig> +{ + + /** Socket factory to use for LDAPS connections. */ + private final SSLSocketFactory socketFactory; + + /** UnboundID connection options. */ + private final LDAPConnectionOptions ldapOptions; + + + /** + * Creates a new Unbound ID connection factory. + * + * @param url of the ldap to connect to + * @param strategy connection strategy + * @param config provider configuration + * @param factory SSL socket factory to use for LDAP and LDAPS + * @param options connection options + */ + public UnboundIDConnectionFactory( + final String url, + final ConnectionStrategy strategy, + final UnboundIDProviderConfig config, + final SSLSocketFactory factory, + final LDAPConnectionOptions options) + { + super(url, strategy, config); + socketFactory = factory; + ldapOptions = options; + } + + + @Override + protected UnboundIDConnection createInternal(final String url) + throws LdapException + { + final LdapURL ldapUrl = new LdapURL(url); + UnboundIDConnection conn = null; + boolean closeConn = false; + try { + final LDAPConnection lc = new LDAPConnection( + socketFactory != null ? socketFactory : getProviderConfig().getSocketFactory(), ldapOptions); + conn = new UnboundIDConnection(lc, getProviderConfig()); + lc.connect(ldapUrl.getLastEntry().getHostname(), ldapUrl.getLastEntry().getPort()); + } catch (LDAPException e) { + closeConn = true; + throw new ConnectionException(e, org.ldaptive.ResultCode.valueOf(e.getResultCode().intValue())); + } finally { + if (closeConn) { + try { + if (conn != null) { + conn.close(null); + } + } catch (LdapException e) { + logger.debug("Problem tearing down connection", e); + } + } + } + return conn; + } +}
diff --git a/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDControlHandler.java b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDControlHandler.java new file mode 100644 index 0000000..5e1ea92 --- /dev/null +++ b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDControlHandler.java
@@ -0,0 +1,58 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.unboundid; + +import com.unboundid.asn1.ASN1OctetString; +import org.ldaptive.control.ControlFactory; +import org.ldaptive.control.RequestControl; +import org.ldaptive.control.ResponseControl; +import org.ldaptive.provider.ControlHandler; + +/** + * Unbound ID control handler. + * + * @author Middleware Services + */ +public class UnboundIDControlHandler implements ControlHandler<com.unboundid.ldap.sdk.Control> +{ + + + @Override + public Class<com.unboundid.ldap.sdk.Control> getControlType() + { + return com.unboundid.ldap.sdk.Control.class; + } + + + @Override + public String getOID(final com.unboundid.ldap.sdk.Control control) + { + return control.getOID(); + } + + + @Override + public com.unboundid.ldap.sdk.Control handleRequest(final RequestControl requestControl) + { + final byte[] value = requestControl.encode(); + if (value == null) { + return new com.unboundid.ldap.sdk.Control(requestControl.getOID(), requestControl.getCriticality()); + } else { + return + new com.unboundid.ldap.sdk.Control( + requestControl.getOID(), + requestControl.getCriticality(), + new ASN1OctetString(value)); + } + } + + + @Override + public ResponseControl handleResponse(final com.unboundid.ldap.sdk.Control responseControl) + { + return + ControlFactory.createResponseControl( + responseControl.getOID(), + responseControl.isCritical(), + responseControl.getValue().getValue()); + } +}
diff --git a/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDProvider.java b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDProvider.java new file mode 100644 index 0000000..03eb6aa --- /dev/null +++ b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDProvider.java
@@ -0,0 +1,181 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.unboundid; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import com.unboundid.ldap.sdk.LDAPConnectionOptions; +import com.unboundid.ldap.sdk.LDAPException; +import com.unboundid.ldap.sdk.ResultCode; +import com.unboundid.util.ssl.SSLSocketVerifier; +import com.unboundid.util.ssl.SSLUtil; +import org.ldaptive.ConnectionConfig; +import org.ldaptive.LdapURL; +import org.ldaptive.provider.Provider; +import org.ldaptive.provider.ProviderConnectionFactory; +import org.ldaptive.ssl.DefaultHostnameVerifier; +import org.ldaptive.ssl.HostnameVerifierAdapter; +import org.ldaptive.ssl.SslConfig; +import org.ldaptive.ssl.TLSSocketFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * UnboundID provider implementation. Provides connection factories for clear, SSL, and TLS connections. + * + * @author Middleware Services + */ +public class UnboundIDProvider implements Provider<UnboundIDProviderConfig> +{ + + /** Provider configuration. */ + private UnboundIDProviderConfig config = new UnboundIDProviderConfig(); + + + @Override + public ProviderConnectionFactory<UnboundIDProviderConfig> getConnectionFactory(final ConnectionConfig cc) + { + SSLSocketFactory factory = config.getSSLSocketFactory(); + if (factory == null) { + if (cc.getUseStartTLS() || cc.getUseSSL() || cc.getLdapUrl().toLowerCase().contains("ldaps://")) { + if (cc.getSslConfig() != null && !cc.getSslConfig().isEmpty()) { + final TLSSocketFactory sf = new TLSSocketFactory(); + sf.setSslConfig(SslConfig.newSslConfig(cc.getSslConfig())); + try { + sf.initialize(); + } catch (GeneralSecurityException e) { + throw new IllegalArgumentException(e); + } + factory = sf; + } else if (cc.getUseSSL() || cc.getLdapUrl().toLowerCase().contains("ldaps://")) { + final SSLUtil util = new SSLUtil(); + try { + factory = util.createSSLSocketFactory(); + } catch (GeneralSecurityException e) { + throw new IllegalArgumentException(e); + } + } + } + } + + LDAPConnectionOptions options = config.getConnectionOptions(); + if (options == null) { + options = getDefaultLDAPConnectionOptions(cc); + } + + ProviderConnectionFactory<UnboundIDProviderConfig> cf; + if (cc.getUseStartTLS()) { + cf = new UnboundIDStartTLSConnectionFactory( + cc.getLdapUrl(), + cc.getConnectionStrategy(), + config, + factory, + options); + } else { + cf = new UnboundIDConnectionFactory(cc.getLdapUrl(), cc.getConnectionStrategy(), config, factory, options); + } + return cf; + } + + + /** + * Returns an SSL socket factory configured with a default hostname verifier. + * + * @param cc connection configuration + * + * @return SSL socket factory + */ + protected SSLSocketFactory getHostnameVerifierSocketFactory(final ConnectionConfig cc) + { + final LdapURL ldapUrl = new LdapURL(cc.getLdapUrl()); + return TLSSocketFactory.getHostnameVerifierFactory(cc.getSslConfig(), ldapUrl.getHostnames()); + } + + + /** + * Returns the default connection options for this provider. + * + * @param cc to configure options with + * + * @return ldap connection options + */ + protected LDAPConnectionOptions getDefaultLDAPConnectionOptions(final ConnectionConfig cc) + { + final LDAPConnectionOptions options = new LDAPConnectionOptions(); + if (cc.getConnectTimeout() != null) { + options.setConnectTimeoutMillis((int) cc.getConnectTimeout().toMillis()); + } + if (cc.getResponseTimeout() != null) { + options.setResponseTimeoutMillis(cc.getResponseTimeout().toMillis()); + } + // UnboundID does not do hostname verification by default + // set a default hostname verifier if no SSL socket verifier configured + final HostnameVerifier verifier; + if (cc.getSslConfig() != null && !cc.getSslConfig().isEmpty()) { + if (cc.getSslConfig().getHostnameVerifier() != null) { + verifier = new HostnameVerifierAdapter(cc.getSslConfig().getHostnameVerifier()); + } else { + verifier = new DefaultHostnameVerifier(); + } + } else { + verifier = new DefaultHostnameVerifier(); + } + options.setSSLSocketVerifier(new SSLSocketVerifier() + { + /** Logger for this class. */ + private final Logger logger = LoggerFactory.getLogger(getClass()); + + + @Override + public void verifySSLSocket( + final String host, + final int port, + final SSLSocket sslSocket) + throws LDAPException + { + logger.trace("Verifying SSLSocket {} for host {} with verifier {}", sslSocket, host, verifier); + final SSLSession session = sslSocket.getSession(); + try { + // confirm that the trust manager succeeded + session.getPeerCertificates(); + if (!verifier.verify(host, session)) { + try { + sslSocket.close(); + } catch (IOException e) { + logger.debug("Error closing SSL socket", e); + } + throw new LDAPException(ResultCode.CONNECT_ERROR, "Hostname verification failed for " + host); + } + } catch (SSLPeerUnverifiedException e) { + throw new LDAPException(ResultCode.CONNECT_ERROR, "Trust verification failed for " + host, e); + } + } + }); + return options; + } + + + @Override + public UnboundIDProviderConfig getProviderConfig() + { + return config; + } + + + @Override + public void setProviderConfig(final UnboundIDProviderConfig pc) + { + config = pc; + } + + + @Override + public UnboundIDProvider newInstance() + { + return new UnboundIDProvider(); + } +}
diff --git a/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDProviderConfig.java b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDProviderConfig.java new file mode 100644 index 0000000..9cbd3f6 --- /dev/null +++ b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDProviderConfig.java
@@ -0,0 +1,158 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.unboundid; + +import java.util.Arrays; +import javax.net.SocketFactory; +import javax.net.ssl.SSLSocketFactory; +import com.unboundid.ldap.sdk.Control; +import com.unboundid.ldap.sdk.LDAPConnectionOptions; +import org.ldaptive.ResultCode; +import org.ldaptive.provider.ControlProcessor; +import org.ldaptive.provider.ProviderConfig; + +/** + * Contains configuration data for the UnboundID provider. + * + * @author Middleware Services + */ +public class UnboundIDProviderConfig extends ProviderConfig<Control> +{ + + /** Connection options. */ + private LDAPConnectionOptions connectionOptions; + + /** socket factory for ldap connections. */ + private SocketFactory socketFactory; + + /** socket factory for ldaps and startTLS connections. */ + private SSLSocketFactory sslSocketFactory; + + /** Search result codes to ignore. */ + private ResultCode[] searchIgnoreResultCodes; + + + /** Default constructor. */ + public UnboundIDProviderConfig() + { + setOperationExceptionResultCodes(ResultCode.SERVER_DOWN); + setControlProcessor(new ControlProcessor<>(new UnboundIDControlHandler())); + searchIgnoreResultCodes = new ResultCode[] { + ResultCode.TIME_LIMIT_EXCEEDED, + ResultCode.SIZE_LIMIT_EXCEEDED, + ResultCode.REFERRAL, + }; + } + + + /** + * Returns the connection options. + * + * @return ldap connection options + */ + public LDAPConnectionOptions getConnectionOptions() + { + return connectionOptions; + } + + + /** + * Sets the connection options. + * + * @param options ldap connection options + */ + public void setConnectionOptions(final LDAPConnectionOptions options) + { + connectionOptions = options; + } + + + /** + * Returns the socket factory to use for LDAP connections. + * + * @return socket factory + */ + public SocketFactory getSocketFactory() + { + return socketFactory; + } + + + /** + * Sets the socket factory to use for LDAP connections. + * + * @param sf socket factory + */ + public void setSocketFactory(final SocketFactory sf) + { + checkImmutable(); + logger.trace("setting socketFactory: {}", sf); + socketFactory = sf; + } + + + /** + * Returns the SSL socket factory to use for LDAPS and startTLS connections. + * + * @return SSL socket factory + */ + public SSLSocketFactory getSSLSocketFactory() + { + return sslSocketFactory; + } + + + /** + * Sets the SSL socket factory to use for LDAPS and startTLS connections. + * + * @param sf socket factory + */ + public void setSSLSocketFactory(final SSLSocketFactory sf) + { + checkImmutable(); + logger.trace("setting sslSocketFactory: {}", sf); + sslSocketFactory = sf; + } + + + /** + * Returns the search ignore result codes. + * + * @return result codes to ignore + */ + public ResultCode[] getSearchIgnoreResultCodes() + { + return searchIgnoreResultCodes; + } + + + /** + * Sets the search ignore result codes. + * + * @param codes to ignore + */ + public void setSearchIgnoreResultCodes(final ResultCode[] codes) + { + checkImmutable(); + logger.trace("setting searchIgnoreResultCodes: {}", Arrays.toString(codes)); + searchIgnoreResultCodes = codes; + } + + + @Override + public String toString() + { + return + String.format( + "[%s@%d::operationExceptionResultCodes=%s, properties=%s, controlProcessor=%s, connectionOptions=%s, " + + "socketFactory=%s, sslSocketFactory=%s, searchIgnoreResultCodes=%s]", + getClass().getName(), + hashCode(), + Arrays.toString(getOperationExceptionResultCodes()), + getProperties(), + getControlProcessor(), + connectionOptions, + socketFactory, + sslSocketFactory, + Arrays.toString(searchIgnoreResultCodes)); + } +}
diff --git a/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDSaslUtils.java b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDSaslUtils.java new file mode 100644 index 0000000..b57709d --- /dev/null +++ b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDSaslUtils.java
@@ -0,0 +1,121 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.unboundid; + +import com.unboundid.ldap.sdk.DIGESTMD5BindRequestProperties; +import com.unboundid.ldap.sdk.GSSAPIBindRequestProperties; +import com.unboundid.ldap.sdk.SASLQualityOfProtection; +import org.ldaptive.Credential; +import org.ldaptive.sasl.DigestMd5Config; +import org.ldaptive.sasl.GssApiConfig; +import org.ldaptive.sasl.QualityOfProtection; +import org.ldaptive.sasl.SaslConfig; + +/** + * Support for SASL authentication. + * + * @author Middleware Services + */ +public final class UnboundIDSaslUtils +{ + + + /** Default constructor. */ + private UnboundIDSaslUtils() {} + + + /** + * Creates a new digest md5 request properties. + * + * @param username to bind as + * @param credential to bind with + * @param config to set sasl parameters + * + * @return digest md5 request properties + */ + protected static DIGESTMD5BindRequestProperties createDigestMd5Properties( + final String username, + final Credential credential, + final SaslConfig config) + { + final DIGESTMD5BindRequestProperties props = new DIGESTMD5BindRequestProperties( + username, + credential != null ? credential.getBytes() : null); + if (config.getAuthorizationId() != null && !"".equals(config.getAuthorizationId())) { + props.setAuthorizationID(config.getAuthorizationId()); + } + if (config.getQualityOfProtection() != null) { + props.setAllowedQoP(getQualityOfProtection(config.getQualityOfProtection())); + } + if (config instanceof DigestMd5Config) { + final DigestMd5Config c = (DigestMd5Config) config; + if (c.getRealm() != null) { + props.setRealm(c.getRealm()); + } + } + return props; + } + + + /** + * Creates a new gssapi request properties. + * + * @param username to bind as + * @param credential to bind with + * @param config to set sasl parameters + * + * @return gssapi request properties + */ + protected static GSSAPIBindRequestProperties createGssApiProperties( + final String username, + final Credential credential, + final SaslConfig config) + { + final GSSAPIBindRequestProperties props = new GSSAPIBindRequestProperties( + username, + credential != null ? credential.getBytes() : null); + if (config.getAuthorizationId() != null) { + props.setAuthorizationID(config.getAuthorizationId()); + } + if (config.getQualityOfProtection() != null) { + props.setAllowedQoP(getQualityOfProtection(config.getQualityOfProtection())); + } + if (config instanceof GssApiConfig) { + final GssApiConfig c = (GssApiConfig) config; + if (c.getRealm() != null) { + props.setRealm(c.getRealm()); + } + } + return props; + } + + + /** + * Returns the SASL quality of protection string for the supplied enum. + * + * @param qop quality of protection enum + * + * @return SASL quality of protection + */ + protected static SASLQualityOfProtection getQualityOfProtection(final QualityOfProtection qop) + { + SASLQualityOfProtection e; + switch (qop) { + + case AUTH: + e = SASLQualityOfProtection.AUTH; + break; + + case AUTH_INT: + e = SASLQualityOfProtection.AUTH_INT; + break; + + case AUTH_CONF: + e = SASLQualityOfProtection.AUTH_CONF; + break; + + default: + throw new IllegalArgumentException("Unknown SASL quality of protection: " + qop); + } + return e; + } +}
diff --git a/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDStartTLSConnectionFactory.java b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDStartTLSConnectionFactory.java new file mode 100644 index 0000000..04d045c --- /dev/null +++ b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDStartTLSConnectionFactory.java
@@ -0,0 +1,90 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.unboundid; + +import javax.net.ssl.SSLSocketFactory; +import com.unboundid.ldap.sdk.ExtendedResult; +import com.unboundid.ldap.sdk.LDAPConnection; +import com.unboundid.ldap.sdk.LDAPConnectionOptions; +import com.unboundid.ldap.sdk.LDAPException; +import com.unboundid.ldap.sdk.ResultCode; +import com.unboundid.ldap.sdk.extensions.StartTLSExtendedRequest; +import org.ldaptive.ConnectionStrategy; +import org.ldaptive.LdapException; +import org.ldaptive.LdapURL; +import org.ldaptive.provider.AbstractProviderConnectionFactory; +import org.ldaptive.provider.ConnectionException; + +/** + * Creates ldap connections using the UnboundID LDAPConnection class and performs the startTLS extended operation. + * + * @author Middleware Services + */ +public class UnboundIDStartTLSConnectionFactory extends AbstractProviderConnectionFactory<UnboundIDProviderConfig> +{ + + /** Socket factory to use for startTLS. */ + private final SSLSocketFactory socketFactory; + + /** UnboundID connection options. */ + private final LDAPConnectionOptions ldapOptions; + + + /** + * Creates a new Unbound ID connection factory. + * + * @param url of the ldap to connect to + * @param strategy connection strategy + * @param config provider configuration + * @param factory SSL socket factory to use for startTLS + * @param options connection options + */ + public UnboundIDStartTLSConnectionFactory( + final String url, + final ConnectionStrategy strategy, + final UnboundIDProviderConfig config, + final SSLSocketFactory factory, + final LDAPConnectionOptions options) + { + super(url, strategy, config); + socketFactory = factory; + ldapOptions = options; + } + + + @Override + protected UnboundIDConnection createInternal(final String url) + throws LdapException + { + final LdapURL ldapUrl = new LdapURL(url); + UnboundIDConnection conn = null; + boolean closeConn = false; + try { + final LDAPConnection lc = new LDAPConnection(getProviderConfig().getSocketFactory(), ldapOptions); + conn = new UnboundIDConnection(lc, getProviderConfig()); + lc.connect(ldapUrl.getLastEntry().getHostname(), ldapUrl.getLastEntry().getPort()); + + final ExtendedResult result = lc.processExtendedOperation( + new StartTLSExtendedRequest(socketFactory != null ? socketFactory : getProviderConfig().getSSLSocketFactory())); + if (result.getResultCode() != ResultCode.SUCCESS) { + closeConn = true; + throw new ConnectionException( + "StartTLS failed", + org.ldaptive.ResultCode.valueOf(result.getResultCode().intValue())); + } + } catch (LDAPException e) { + closeConn = true; + throw new ConnectionException(e, org.ldaptive.ResultCode.valueOf(e.getResultCode().intValue())); + } finally { + if (closeConn) { + try { + if (conn != null) { + conn.close(null); + } + } catch (LdapException e) { + logger.debug("Problem tearing down connection", e); + } + } + } + return conn; + } +}
diff --git a/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDSyncProvider.java b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDSyncProvider.java new file mode 100644 index 0000000..9b36396 --- /dev/null +++ b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDSyncProvider.java
@@ -0,0 +1,24 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.unboundid; + +import com.unboundid.ldap.sdk.LDAPConnectionOptions; +import org.ldaptive.ConnectionConfig; + +/** + * UnboundID provider implementation that uses synchronous options. Attempting to use connections by this provider in an + * asynchronous manner with throw exceptions. + * + * @author Middleware Services + */ +public class UnboundIDSyncProvider extends UnboundIDProvider +{ + + + @Override + protected LDAPConnectionOptions getDefaultLDAPConnectionOptions(final ConnectionConfig cc) + { + final LDAPConnectionOptions options = super.getDefaultLDAPConnectionOptions(cc); + options.setUseSynchronousMode(true); + return options; + } +}
diff --git a/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDUtils.java b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDUtils.java new file mode 100644 index 0000000..3c28c6e --- /dev/null +++ b/unboundid-provider/src/main/java/org/ldaptive/provider/unboundid/UnboundIDUtils.java
@@ -0,0 +1,222 @@ +/* See LICENSE for licensing and NOTICE for copyright. */ +package org.ldaptive.provider.unboundid; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import com.unboundid.ldap.sdk.Attribute; +import com.unboundid.ldap.sdk.Entry; +import com.unboundid.ldap.sdk.Modification; +import com.unboundid.ldap.sdk.ModificationType; +import com.unboundid.ldap.sdk.controls.SortKey; +import org.ldaptive.AttributeModification; +import org.ldaptive.AttributeModificationType; +import org.ldaptive.LdapAttribute; +import org.ldaptive.SearchEntry; +import org.ldaptive.SortBehavior; +import org.ldaptive.control.ResponseControl; + +/** + * Provides methods for converting between Unbound ID specific objects and ldaptive specific objects. + * + * @author Middleware Services + */ +public class UnboundIDUtils +{ + + /** Ldap result sort behavior. */ + private final SortBehavior sortBehavior; + + /** Attributes that should be treated as binary. */ + private List<String> binaryAttrs; + + + /** Default constructor. */ + public UnboundIDUtils() + { + sortBehavior = SortBehavior.getDefaultSortBehavior(); + } + + + /** + * Creates a new unboundid util. + * + * @param sb sort behavior + */ + public UnboundIDUtils(final SortBehavior sb) + { + sortBehavior = sb; + } + + + /** + * Returns the list of binary attributes. + * + * @return list of binary attributes + */ + public List<String> getBinaryAttributes() + { + return binaryAttrs; + } + + + /** + * Sets the list of binary attributes. + * + * @param s binary attributes + */ + public void setBinaryAttributes(final String[] s) + { + if (s != null) { + binaryAttrs = Arrays.asList(s); + } + } + + + /** + * Returns an unbound id attribute that represents the values in the supplied ldap attribute. + * + * @param la ldap attribute + * + * @return unbound id attribute + */ + public Attribute fromLdapAttribute(final LdapAttribute la) + { + Attribute attribute; + if (la.isBinary()) { + attribute = new Attribute(la.getName(), la.getBinaryValues().toArray(new byte[la.size()][])); + } else { + attribute = new Attribute(la.getName(), la.getStringValues()); + } + return attribute; + } + + + /** + * Returns an ldap attribute using the supplied unbound id attribute. + * + * @param a unbound id attribute + * + * @return ldap attribute + */ + public LdapAttribute toLdapAttribute(final Attribute a) + { + boolean isBinary = false; + if (a.getOptions().contains("binary")) { + isBinary = true; + } else if (binaryAttrs != null && binaryAttrs.contains(a.getName())) { + isBinary = true; + } + + final LdapAttribute la = new LdapAttribute(sortBehavior, isBinary); + la.setName(a.getName()); + if (isBinary) { + la.addBinaryValue(a.getValueByteArrays()); + } else { + la.addStringValue(a.getValues()); + } + return la; + } + + + /** + * Returns a list of unbound id attribute that represents the values in the supplied ldap attributes. + * + * @param c ldap attributes + * + * @return unbound id attributes + */ + public Attribute[] fromLdapAttributes(final Collection<LdapAttribute> c) + { + return c.stream().map(this::fromLdapAttribute).toArray(Attribute[]::new); + } + + + /** + * Returns a search entry using the supplied unbound id entry. + * + * @param e unbound id entry + * @param c response controls + * @param id message id + * + * @return search entry + */ + public SearchEntry toSearchEntry(final Entry e, final ResponseControl[] c, final int id) + { + final SearchEntry se = new SearchEntry(id, c, sortBehavior); + se.setDn(e.getDN()); + for (Attribute a : e.getAttributes()) { + se.addAttribute(toLdapAttribute(a)); + } + return se; + } + + + /** + * Returns unbound id modifications using the supplied attribute modifications. + * + * @param am attribute modifications + * + * @return unbound id modifications + */ + public Modification[] fromAttributeModification(final AttributeModification[] am) + { + final Modification[] mods = new Modification[am.length]; + for (int i = 0; i < am.length; i++) { + final Attribute a = fromLdapAttribute(am[i].getAttribute()); + if (am[i].getAttribute().isBinary()) { + mods[i] = new Modification( + getModificationType(am[i].getAttributeModificationType()), + a.getName(), + a.getValueByteArrays()); + } else { + mods[i] = new Modification( + getModificationType(am[i].getAttributeModificationType()), + a.getName(), + a.getValues()); + } + } + return mods; + } + + + /** + * Returns unbound id sort keys using the supplied sort keys. + * + * @param sk sort keys + * + * @return unbound id sort keys + */ + public static SortKey[] fromSortKey(final org.ldaptive.control.SortKey[] sk) + { + SortKey[] keys = null; + if (sk != null) { + keys = new SortKey[sk.length]; + for (int i = 0; i < sk.length; i++) { + keys[i] = new SortKey(sk[i].getAttributeDescription(), sk[i].getMatchingRuleId(), sk[i].getReverseOrder()); + } + } + return keys; + } + + + /** + * Returns the unbound id modification type for the supplied attribute modification type. + * + * @param am attribute modification type + * + * @return modification type + */ + protected static ModificationType getModificationType(final AttributeModificationType am) + { + ModificationType type = null; + if (am == AttributeModificationType.ADD) { + type = ModificationType.ADD; + } else if (am == AttributeModificationType.REMOVE) { + type = ModificationType.DELETE; + } else if (am == AttributeModificationType.REPLACE) { + type = ModificationType.REPLACE; + } + return type; + } +}
diff --git a/webapp/pom.xml b/webapp/pom.xml new file mode 100644 index 0000000..8130808 --- /dev/null +++ b/webapp/pom.xml
@@ -0,0 +1,42 @@ +<?xml version='1.0' encoding='UTF-8'?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>ldaptive-webapp</artifactId> + <packaging>war</packaging> + <name>LDAPTIVE WEB APPLICATION</name> + <description>Web interface to demonstrate templating functionality</description> + <parent> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-parent</artifactId> + <version>1.2.3</version> + </parent> + + <dependencies> + <dependency> + <groupId>org.ldaptive</groupId> + <artifactId>ldaptive-templates</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + <includes> + <include>**/*.xml</include> + </includes> + </resource> + </resources> + </build> +</project>
diff --git a/webapp/src/main/resources/log4j.xml b/webapp/src/main/resources/log4j.xml new file mode 100644 index 0000000..d9c2abe --- /dev/null +++ b/webapp/src/main/resources/log4j.xml
@@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> + +<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" + debug="false"> + + <appender name="CONSOLE" + class="org.apache.log4j.ConsoleAppender"> + <param name="Target" value="System.out"/> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%X{host} %d %-5p [%c] %m%n"/> + </layout> + </appender> + + <category name="org.ldaptive" + additivity="false"> + <priority value="INFO"/> + <appender-ref ref="CONSOLE"/> + </category> + + <category name="org.springframework" + additivity="false"> + <priority value="ERROR"/> + <appender-ref ref="CONSOLE"/> + </category> + + <root> + <priority value="INFO"/> + <appender-ref ref="CONSOLE"/> + </root> + +</log4j:configuration>
diff --git a/webapp/src/main/resources/templates-context.xml b/webapp/src/main/resources/templates-context.xml new file mode 100644 index 0000000..2cad869 --- /dev/null +++ b/webapp/src/main/resources/templates-context.xml
@@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ldaptive="http://www.ldaptive.org/schema/spring-ext" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.ldaptive.org/schema/spring-ext http://www.ldaptive.org/schema/spring-ext.xsd"> + + <bean id="conversionService" + class="org.springframework.context.support.ConversionServiceFactoryBean"> + <property name="converters"> + <set> + <bean class="org.ldaptive.beans.spring.convert.StringToDurationConverter"/> + <bean class="org.ldaptive.beans.spring.convert.DurationToStringConverter"/> + </set> + </property> + </bean> + + <ldaptive:aggregate-pooled-search-executor baseDn="${baseDn}" /> + + <ldaptive:pooled-connection-factory + ldapUrl="${ldapUrl}" + useStartTLS="false" + blockWaitTime="PT5S" + minPoolSize="5" + maxPoolSize="10" + validatePeriodically="true" + /> + + <!-- SEARCH CONFIG --> + + <!-- searches are defined in the following section + A bean is defined to handle a specific number of query terms. + When a query arrives the searches are executed that match the number of + terms entered. + The following syntax is used to match query terms: + {term1} == the first query term entered + {term2} == the second query term entered, and so forth + {initial1} == the first letter of the first query term entered + in this manner you can construct search filters such as: + (givenName={term1})(middleName={initial2}*)(sn={term3}) --> + + <!-- ONE TERM QUERIES --> + <bean id="oneTermSearch" class="org.ldaptive.templates.SearchTemplates"> + <constructor-arg> + <list> + <!-- phone number search --> + <!-- note that openldap removes dashes and spaces for all phone number queries --> + <value>(telephoneNumber={term1})</value> + <value>(telephoneNumber=*{term1})</value> + + <!-- name search --> + <value>(|(givenName={term1})(sn={term1}))</value> + <value>(|(givenName={term1}*)(sn={term1}*))</value> + <value>(|(givenName=*{term1}*)(sn=*{term1}*))</value> + + <!-- email search --> + <value>(mail={term1})</value> + <value>(mail={term1}*)</value> + <value>(mail=*{term1}*)</value> + </list> + </constructor-arg> + </bean> + + <!-- TWO TERM QUERIES --> + <bean id="twoTermSearch" class="org.ldaptive.templates.SearchTemplates"> + <constructor-arg> + <list> + <!-- name search --> + <value>(&(givenName={term1})(sn={term2}))</value> + <value>(cn={term1} {term2})</value> + <value>(&(givenName={term1}*)(sn={term2}*))</value> + <value>(cn={term1}* {term2}*)</value> + <value>(&(givenName=*{term1}*)(sn=*{term2}*))</value> + <value>(cn=*{term1}* *{term2}*)</value> + + <!-- initial search --> + <value>(|(&(givenName={initial1}*)(sn={term2}))(&(middleName={initial1}*)(sn={term2})))</value> + + <!-- last name search --> + <value>(sn={term2})</value> + </list> + </constructor-arg> + </bean> + + <!-- THREE TERM QUERIES --> + <bean id="threeTermSearch" class="org.ldaptive.templates.SearchTemplates"> + <constructor-arg> + <list> + <!-- name search --> + <value>(|(&(givenName={term1})(sn={term3}))(&(givenName={term2})(sn={term3})))</value> + <value>(|(cn={term1} {term2} {term3})(cn={term2} {term1} {term3}))</value> + <value>(|(&(givenName={term1}*)(sn={term3}*))(&(givenName={term2}*)(sn={term3}*)))</value> + <value>(|(cn={term1}* {term2}* {term3}*)(cn={term2}* {term1}* {term3}*))</value> + <value>(|(&(givenName=*{term1}*)(sn=*{term3}*))(&(givenName=*{term2}*)(sn=*{term3}*)))</value> + <value>(|(cn=*{term1}* *{term2}* *{term3}*)(cn=*{term2}* *{term1}* *{term3}*))</value> + + <!-- initial search --> + <value>(|(&(givenName={term1})(middleName={initial2}*)(sn={term3}))(&(givenName={term2})(middleName={initial1}*)(sn={term3})))</value> + <value>(|(&p(givenName={initial1}*)(middlename={initial2}*)(sn={term3}))(&(givenName={initial2}*)(middleName={initial1}*)(sn={term3})))</value> + + <!-- last name search --> + <value>(sn={term3})</value> + </list> + </constructor-arg> + </bean> + +</beans>
diff --git a/webapp/src/main/webapp/WEB-INF/web.xml b/webapp/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..749a322 --- /dev/null +++ b/webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<web-app id="ldaptive-templates" + version="2.4" + xmlns="http://java.sun.com/xml/ns/j2ee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> + + <display-name>Templates Search</display-name> + <description> + Templates Search is a web application which accepts search queries and returns best fit information from a LDAP. + </description> + + <!-- Search servlet --> + <servlet> + <servlet-name>JsonSearch</servlet-name> + <servlet-class>org.ldaptive.servlets.SearchServlet</servlet-class> + <init-param> + <param-name>searchExecutorClass</param-name> + <param-value>org.ldaptive.servlets.JsonServletSearchTemplatesExecutor</param-value> + </init-param> + <!-- Classpath location of the spring context --> + <init-param> + <param-name>springContextPath</param-name> + <param-value>/templates-context.xml</param-value> + </init-param> + <!-- Ignore pattern --> + <init-param> + <param-name>ignorePattern</param-name> + <param-value>^\w{1,2}$</param-value> + </init-param> + <!-- Minimum query term length --> + <init-param> + <param-name>minimumQueryTermLength</param-name> + <param-value>3</param-value> + </init-param> + <load-on-startup>1</load-on-startup> + </servlet> + + <servlet-mapping> + <servlet-name>JsonSearch</servlet-name> + <url-pattern>/Search</url-pattern> + </servlet-mapping> + +</web-app>
diff --git a/webapp/src/main/webapp/css/templates.css b/webapp/src/main/webapp/css/templates.css new file mode 100644 index 0000000..e83bec3 --- /dev/null +++ b/webapp/src/main/webapp/css/templates.css
@@ -0,0 +1,59 @@ +body { + margin:0 8% 10px 8%; + padding:0; + background-color:#8696cf; + font-family:Helvetica, Arial, Sans-Serif; + font-size:.9em; +} + +tr td { + border-top:1px solid #8696cf; + font-size:0.9em; + padding: 8px; + background-color:#b2d1b0; + line-height: 1.2; +} + +#page-wrapper { + background-color:white; +} + +#page-header { + border-top:6px solid #8696cf; + padding:10px; + margin-bottom:10px; + background-color:white; + background-repeat:repeat-y; + color:white; +} + +#page-footer { + border-top:3px solid #8696cf; + border-bottom:6px solid #8696cf; + margin-top:8%; + background-color:white; + font-size:90%; + padding:10px; +} + +#page-footer p { + margin:0px; + padding:0px; + text-align:center; +} + +h1 { + font-size:1.6em; +} + +h2 { + font-size:1.4; +} + +h3 { + font-size:1.2; +} + +#content { + margin:5px 10px 5px 10px; +}
diff --git a/webapp/src/main/webapp/favicon.ico b/webapp/src/main/webapp/favicon.ico new file mode 100644 index 0000000..a363470 --- /dev/null +++ b/webapp/src/main/webapp/favicon.ico Binary files differ
diff --git a/webapp/src/main/webapp/images/logo.png b/webapp/src/main/webapp/images/logo.png new file mode 100644 index 0000000..1b58800 --- /dev/null +++ b/webapp/src/main/webapp/images/logo.png Binary files differ
diff --git a/webapp/src/main/webapp/index.html b/webapp/src/main/webapp/index.html new file mode 100644 index 0000000..473929a --- /dev/null +++ b/webapp/src/main/webapp/index.html
@@ -0,0 +1,108 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd "> +<html xmlns=" http://www.w3.org/1999/xhtml "> +<head> + <title>Ldaptive</title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <link rel="stylesheet" type="text/css" media="screen" href="css/templates.css" /> + <script src="js/jquery-1.8.2.min.js"></script> + <script type="text/javascript"> + var size = 10; // change this to control page size + var from = null; + var to = null; + var cache = null; + $(document).ready(function(){ + $('#search').keyup(function() { + var val = $(this).val(); + if (val != '') { + $('#query').val(val); + $.getJSON('Search?query='+encodeURIComponent(val), function(data) { + if ($('#query').val() == val) { + cache = data; + from = 1; + to = size; + showResults(from, to); + } + }); + } else { + $('#results').html("<tbody><tr><td>Start typing to search</td></tr></tbody>"); + } + }); + //focus first input form field on page + $("input:visible:enabled:first").focus(); + }); + String.prototype.htmlEscape = function() { + return $('<div/>').text(this.toString()).html(); + }; + function showResults(from, to) { + if (cache != null && cache.length > 0) { + var x = from - 1; + var y = to < cache.length ? to : cache.length; + var html = ""; + $.each(cache, function(index, value) { + if (index >= x && index < y) { + var name = !value.displayName ? "" : value.displayName[0].htmlEscape(); + var title = !value.title ? "" : value.title[0].htmlEscape(); + var address = !value.postalAddress ? "" : value.postalAddress[0].htmlEscape(); + var mail = !value.mail ? "" : value.mail[0].htmlEscape(); + var phone = !value.telephoneNumber ? "" : value.telephoneNumber[0].htmlEscape(); + + html += "<tr>"; + html += "<td>"+name+"<br/><em>"+title+"</em></td>"; + html += "<td>"+address.replace(/\$/g,"<br/>")+"</td>"; + html += "<td><a href=\"mailto:"+mail+"\">"+mail+"</a><br/>"+phone.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3')+"</td>"; + html += "</tr>"; + } + }); + var out = "<tbody><tr>"; + out += "<td>Results "+(x+1)+" - "+y+" of "+cache.length+"</td>"; + out += "<td> </td>"; + out += "<td align=\"right\">"; + if (x - size >= 0) { + out += "<a id=\"prev\" href=\"#\" onClick=\"prev();return false;\">Prev</a> "; + } else { + out += "<a id=\"prev\" href=\"#\" onClick=\"prev();return false;\" style=\"display:none\">Prev</a> "; + } + if (y < cache.length) { + out += "<a id=\"next\" href=\"#\" onClick=\"next();return false;\">Next</a>"; + } else { + out += "<a id=\"next\" href=\"#\" onClick=\"next();return false;\" style=\"display:none\">Next</a>"; + } + out += "</td></tr>"+html+"</tbody>"; + $('#results').html(out); + } else { + $('#results').html("<tbody><tr><td>No results found</td></tr></tbody>"); + } + } + function prev() { + from -= size; + to -= size; + showResults(from, to); + } + function next() { + from += size; + to += size; + showResults(from, to); + } + </script> +</head> +<body> +<div id="page-wrapper"> + <div id="page-header" align="center"> + <a href="http://www.ldaptive.org"><img src="images/logo.png" alt="Ldaptive Logo" border="0"/></a> + </div> + <div id="content" align="center"> + <form onSubmit="return false;"> + <input id="search" type="text"/> + <input id="query" type="hidden"/> + </form> + <br/><br/> + <div> + <table id="results" cellspacing="0" cellpadding="0" border="0" width="100%"><tbody/></table> + </div> + </div> + <div id="page-footer" align="right"> + <p>© 2016 <a href="http://www.vt.edu" target="_blank">Virginia Polytechnic Institute and State University</a></p> + </div> +</div> +</body> +</html>
diff --git a/webapp/src/main/webapp/js/jquery-1.8.2.min.js b/webapp/src/main/webapp/js/jquery-1.8.2.min.js new file mode 100644 index 0000000..f65cf1d --- /dev/null +++ b/webapp/src/main/webapp/js/jquery-1.8.2.min.js
@@ -0,0 +1,2 @@ +/*! jQuery v1.8.2 jquery.com | jquery.org/license */ +(function(a,b){function G(a){var b=F[a]={};return p.each(a.split(s),function(a,c){b[c]=!0}),b}function J(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(I,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:+d+""===d?+d:H.test(d)?p.parseJSON(d):d}catch(f){}p.data(a,c,d)}else d=b}return d}function K(a){var b;for(b in a){if(b==="data"&&p.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function ba(){return!1}function bb(){return!0}function bh(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function bi(a,b){do a=a[b];while(a&&a.nodeType!==1);return a}function bj(a,b,c){b=b||0;if(p.isFunction(b))return p.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return p.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=p.grep(a,function(a){return a.nodeType===1});if(be.test(b))return p.filter(b,d,!c);b=p.filter(b,d)}return p.grep(a,function(a,d){return p.inArray(a,b)>=0===c})}function bk(a){var b=bl.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function bC(a,b){return a.getElementsByTagName(b)[0]||a.appendChild(a.ownerDocument.createElement(b))}function bD(a,b){if(b.nodeType!==1||!p.hasData(a))return;var c,d,e,f=p._data(a),g=p._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;d<e;d++)p.event.add(b,c,h[c][d])}g.data&&(g.data=p.extend({},g.data))}function bE(a,b){var c;if(b.nodeType!==1)return;b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?(b.parentNode&&(b.outerHTML=a.outerHTML),p.support.html5Clone&&a.innerHTML&&!p.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):c==="input"&&bv.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text),b.removeAttribute(p.expando)}function bF(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bG(a){bv.test(a.type)&&(a.defaultChecked=a.checked)}function bY(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=bW.length;while(e--){b=bW[e]+c;if(b in a)return b}return d}function bZ(a,b){return a=b||a,p.css(a,"display")==="none"||!p.contains(a.ownerDocument,a)}function b$(a,b){var c,d,e=[],f=0,g=a.length;for(;f<g;f++){c=a[f];if(!c.style)continue;e[f]=p._data(c,"olddisplay"),b?(!e[f]&&c.style.display==="none"&&(c.style.display=""),c.style.display===""&&bZ(c)&&(e[f]=p._data(c,"olddisplay",cc(c.nodeName)))):(d=bH(c,"display"),!e[f]&&d!=="none"&&p._data(c,"olddisplay",d))}for(f=0;f<g;f++){c=a[f];if(!c.style)continue;if(!b||c.style.display==="none"||c.style.display==="")c.style.display=b?e[f]||"":"none"}return a}function b_(a,b,c){var d=bP.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function ca(a,b,c,d){var e=c===(d?"border":"content")?4:b==="width"?1:0,f=0;for(;e<4;e+=2)c==="margin"&&(f+=p.css(a,c+bV[e],!0)),d?(c==="content"&&(f-=parseFloat(bH(a,"padding"+bV[e]))||0),c!=="margin"&&(f-=parseFloat(bH(a,"border"+bV[e]+"Width"))||0)):(f+=parseFloat(bH(a,"padding"+bV[e]))||0,c!=="padding"&&(f+=parseFloat(bH(a,"border"+bV[e]+"Width"))||0));return f}function cb(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=!0,f=p.support.boxSizing&&p.css(a,"boxSizing")==="border-box";if(d<=0||d==null){d=bH(a,b);if(d<0||d==null)d=a.style[b];if(bQ.test(d))return d;e=f&&(p.support.boxSizingReliable||d===a.style[b]),d=parseFloat(d)||0}return d+ca(a,b,c||(f?"border":"content"),e)+"px"}function cc(a){if(bS[a])return bS[a];var b=p("<"+a+">").appendTo(e.body),c=b.css("display");b.remove();if(c==="none"||c===""){bI=e.body.appendChild(bI||p.extend(e.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!bJ||!bI.createElement)bJ=(bI.contentWindow||bI.contentDocument).document,bJ.write("<!doctype html><html><body>"),bJ.close();b=bJ.body.appendChild(bJ.createElement(a)),c=bH(b,"display"),e.body.removeChild(bI)}return bS[a]=c,c}function ci(a,b,c,d){var e;if(p.isArray(b))p.each(b,function(b,e){c||ce.test(a)?d(a,e):ci(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&p.type(b)==="object")for(e in b)ci(a+"["+e+"]",b[e],c,d);else d(a,b)}function cz(a){return function(b,c){typeof b!="string"&&(c=b,b="*");var d,e,f,g=b.toLowerCase().split(s),h=0,i=g.length;if(p.isFunction(c))for(;h<i;h++)d=g[h],f=/^\+/.test(d),f&&(d=d.substr(1)||"*"),e=a[d]=a[d]||[],e[f?"unshift":"push"](c)}}function cA(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h,i=a[f],j=0,k=i?i.length:0,l=a===cv;for(;j<k&&(l||!h);j++)h=i[j](c,d,e),typeof h=="string"&&(!l||g[h]?h=b:(c.dataTypes.unshift(h),h=cA(a,c,d,e,h,g)));return(l||!h)&&!g["*"]&&(h=cA(a,c,d,e,"*",g)),h}function cB(a,c){var d,e,f=p.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((f[d]?a:e||(e={}))[d]=c[d]);e&&p.extend(!0,a,e)}function cC(a,c,d){var e,f,g,h,i=a.contents,j=a.dataTypes,k=a.responseFields;for(f in k)f in d&&(c[k[f]]=d[f]);while(j[0]==="*")j.shift(),e===b&&(e=a.mimeType||c.getResponseHeader("content-type"));if(e)for(f in i)if(i[f]&&i[f].test(e)){j.unshift(f);break}if(j[0]in d)g=j[0];else{for(f in d){if(!j[0]||a.converters[f+" "+j[0]]){g=f;break}h||(h=f)}g=g||h}if(g)return g!==j[0]&&j.unshift(g),d[g]}function cD(a,b){var c,d,e,f,g=a.dataTypes.slice(),h=g[0],i={},j=0;a.dataFilter&&(b=a.dataFilter(b,a.dataType));if(g[1])for(c in a.converters)i[c.toLowerCase()]=a.converters[c];for(;e=g[++j];)if(e!=="*"){if(h!=="*"&&h!==e){c=i[h+" "+e]||i["* "+e];if(!c)for(d in i){f=d.split(" ");if(f[1]===e){c=i[h+" "+f[0]]||i["* "+f[0]];if(c){c===!0?c=i[d]:i[d]!==!0&&(e=f[0],g.splice(j--,0,e));break}}}if(c!==!0)if(c&&a["throws"])b=c(b);else try{b=c(b)}catch(k){return{state:"parsererror",error:c?k:"No conversion from "+h+" to "+e}}}h=e}return{state:"success",data:b}}function cL(){try{return new a.XMLHttpRequest}catch(b){}}function cM(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function cU(){return setTimeout(function(){cN=b},0),cN=p.now()}function cV(a,b){p.each(b,function(b,c){var d=(cT[b]||[]).concat(cT["*"]),e=0,f=d.length;for(;e<f;e++)if(d[e].call(a,b,c))return})}function cW(a,b,c){var d,e=0,f=0,g=cS.length,h=p.Deferred().always(function(){delete i.elem}),i=function(){var b=cN||cU(),c=Math.max(0,j.startTime+j.duration-b),d=1-(c/j.duration||0),e=0,f=j.tweens.length;for(;e<f;e++)j.tweens[e].run(d);return h.notifyWith(a,[j,d,c]),d<1&&f?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:p.extend({},b),opts:p.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:cN||cU(),duration:c.duration,tweens:[],createTween:function(b,c,d){var e=p.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(e),e},stop:function(b){var c=0,d=b?j.tweens.length:0;for(;c<d;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;cX(k,j.opts.specialEasing);for(;e<g;e++){d=cS[e].call(j,a,k,j.opts);if(d)return d}return cV(j,k),p.isFunction(j.opts.start)&&j.opts.start.call(a,j),p.fx.timer(p.extend(i,{anim:j,queue:j.opts.queue,elem:a})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}function cX(a,b){var c,d,e,f,g;for(c in a){d=p.camelCase(c),e=b[d],f=a[c],p.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=p.cssHooks[d];if(g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}}function cY(a,b,c){var d,e,f,g,h,i,j,k,l=this,m=a.style,n={},o=[],q=a.nodeType&&bZ(a);c.queue||(j=p._queueHooks(a,"fx"),j.unqueued==null&&(j.unqueued=0,k=j.empty.fire,j.empty.fire=function(){j.unqueued||k()}),j.unqueued++,l.always(function(){l.always(function(){j.unqueued--,p.queue(a,"fx").length||j.empty.fire()})})),a.nodeType===1&&("height"in b||"width"in b)&&(c.overflow=[m.overflow,m.overflowX,m.overflowY],p.css(a,"display")==="inline"&&p.css(a,"float")==="none"&&(!p.support.inlineBlockNeedsLayout||cc(a.nodeName)==="inline"?m.display="inline-block":m.zoom=1)),c.overflow&&(m.overflow="hidden",p.support.shrinkWrapBlocks||l.done(function(){m.overflow=c.overflow[0],m.overflowX=c.overflow[1],m.overflowY=c.overflow[2]}));for(d in b){f=b[d];if(cP.exec(f)){delete b[d];if(f===(q?"hide":"show"))continue;o.push(d)}}g=o.length;if(g){h=p._data(a,"fxshow")||p._data(a,"fxshow",{}),q?p(a).show():l.done(function(){p(a).hide()}),l.done(function(){var b;p.removeData(a,"fxshow",!0);for(b in n)p.style(a,b,n[b])});for(d=0;d<g;d++)e=o[d],i=l.createTween(e,q?h[e]:0),n[e]=h[e]||p.style(a,e),e in h||(h[e]=i.start,q&&(i.end=i.start,i.start=e==="width"||e==="height"?1:0))}}function cZ(a,b,c,d,e){return new cZ.prototype.init(a,b,c,d,e)}function c$(a,b){var c,d={height:a},e=0;b=b?1:0;for(;e<4;e+=2-b)c=bV[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function da(a){return p.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}var c,d,e=a.document,f=a.location,g=a.navigator,h=a.jQuery,i=a.$,j=Array.prototype.push,k=Array.prototype.slice,l=Array.prototype.indexOf,m=Object.prototype.toString,n=Object.prototype.hasOwnProperty,o=String.prototype.trim,p=function(a,b){return new p.fn.init(a,b,c)},q=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,r=/\S/,s=/\s+/,t=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,u=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,y=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,z=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,A=/^-ms-/,B=/-([\da-z])/gi,C=function(a,b){return(b+"").toUpperCase()},D=function(){e.addEventListener?(e.removeEventListener("DOMContentLoaded",D,!1),p.ready()):e.readyState==="complete"&&(e.detachEvent("onreadystatechange",D),p.ready())},E={};p.fn=p.prototype={constructor:p,init:function(a,c,d){var f,g,h,i;if(!a)return this;if(a.nodeType)return this.context=this[0]=a,this.length=1,this;if(typeof a=="string"){a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3?f=[null,a,null]:f=u.exec(a);if(f&&(f[1]||!c)){if(f[1])return c=c instanceof p?c[0]:c,i=c&&c.nodeType?c.ownerDocument||c:e,a=p.parseHTML(f[1],i,!0),v.test(f[1])&&p.isPlainObject(c)&&this.attr.call(a,c,!0),p.merge(this,a);g=e.getElementById(f[2]);if(g&&g.parentNode){if(g.id!==f[2])return d.find(a);this.length=1,this[0]=g}return this.context=e,this.selector=a,this}return!c||c.jquery?(c||d).find(a):this.constructor(c).find(a)}return p.isFunction(a)?d.ready(a):(a.selector!==b&&(this.selector=a.selector,this.context=a.context),p.makeArray(a,this))},selector:"",jquery:"1.8.2",length:0,size:function(){return this.length},toArray:function(){return k.call(this)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=p.merge(this.constructor(),a);return d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")"),d},each:function(a,b){return p.each(this,a,b)},ready:function(a){return p.ready.promise().done(a),this},eq:function(a){return a=+a,a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(k.apply(this,arguments),"slice",k.call(arguments).join(","))},map:function(a){return this.pushStack(p.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:j,sort:[].sort,splice:[].splice},p.fn.init.prototype=p.fn,p.extend=p.fn.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;typeof h=="boolean"&&(k=h,h=arguments[1]||{},i=2),typeof h!="object"&&!p.isFunction(h)&&(h={}),j===i&&(h=this,--i);for(;i<j;i++)if((a=arguments[i])!=null)for(c in a){d=h[c],e=a[c];if(h===e)continue;k&&e&&(p.isPlainObject(e)||(f=p.isArray(e)))?(f?(f=!1,g=d&&p.isArray(d)?d:[]):g=d&&p.isPlainObject(d)?d:{},h[c]=p.extend(k,g,e)):e!==b&&(h[c]=e)}return h},p.extend({noConflict:function(b){return a.$===p&&(a.$=i),b&&a.jQuery===p&&(a.jQuery=h),p},isReady:!1,readyWait:1,holdReady:function(a){a?p.readyWait++:p.ready(!0)},ready:function(a){if(a===!0?--p.readyWait:p.isReady)return;if(!e.body)return setTimeout(p.ready,1);p.isReady=!0;if(a!==!0&&--p.readyWait>0)return;d.resolveWith(e,[p]),p.fn.trigger&&p(e).trigger("ready").off("ready")},isFunction:function(a){return p.type(a)==="function"},isArray:Array.isArray||function(a){return p.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):E[m.call(a)]||"object"},isPlainObject:function(a){if(!a||p.type(a)!=="object"||a.nodeType||p.isWindow(a))return!1;try{if(a.constructor&&!n.call(a,"constructor")&&!n.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||n.call(a,d)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},error:function(a){throw new Error(a)},parseHTML:function(a,b,c){var d;return!a||typeof a!="string"?null:(typeof b=="boolean"&&(c=b,b=0),b=b||e,(d=v.exec(a))?[b.createElement(d[1])]:(d=p.buildFragment([a],b,c?null:[]),p.merge([],(d.cacheable?p.clone(d.fragment):d.fragment).childNodes)))},parseJSON:function(b){if(!b||typeof b!="string")return null;b=p.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(w.test(b.replace(y,"@").replace(z,"]").replace(x,"")))return(new Function("return "+b))();p.error("Invalid JSON: "+b)},parseXML:function(c){var d,e;if(!c||typeof c!="string")return null;try{a.DOMParser?(e=new DOMParser,d=e.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(f){d=b}return(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&p.error("Invalid XML: "+c),d},noop:function(){},globalEval:function(b){b&&r.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(A,"ms-").replace(B,C)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,c,d){var e,f=0,g=a.length,h=g===b||p.isFunction(a);if(d){if(h){for(e in a)if(c.apply(a[e],d)===!1)break}else for(;f<g;)if(c.apply(a[f++],d)===!1)break}else if(h){for(e in a)if(c.call(a[e],e,a[e])===!1)break}else for(;f<g;)if(c.call(a[f],f,a[f++])===!1)break;return a},trim:o&&!o.call(" ")?function(a){return a==null?"":o.call(a)}:function(a){return a==null?"":(a+"").replace(t,"")},makeArray:function(a,b){var c,d=b||[];return a!=null&&(c=p.type(a),a.length==null||c==="string"||c==="function"||c==="regexp"||p.isWindow(a)?j.call(d,a):p.merge(d,a)),d},inArray:function(a,b,c){var d;if(b){if(l)return l.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=c.length,e=a.length,f=0;if(typeof d=="number")for(;f<d;f++)a[e++]=c[f];else while(c[f]!==b)a[e++]=c[f++];return a.length=e,a},grep:function(a,b,c){var d,e=[],f=0,g=a.length;c=!!c;for(;f<g;f++)d=!!b(a[f],f),c!==d&&e.push(a[f]);return e},map:function(a,c,d){var e,f,g=[],h=0,i=a.length,j=a instanceof p||i!==b&&typeof i=="number"&&(i>0&&a[0]&&a[i-1]||i===0||p.isArray(a));if(j)for(;h<i;h++)e=c(a[h],h,d),e!=null&&(g[g.length]=e);else for(f in a)e=c(a[f],f,d),e!=null&&(g[g.length]=e);return g.concat.apply([],g)},guid:1,proxy:function(a,c){var d,e,f;return typeof c=="string"&&(d=a[c],c=a,a=d),p.isFunction(a)?(e=k.call(arguments,2),f=function(){return a.apply(c,e.concat(k.call(arguments)))},f.guid=a.guid=a.guid||p.guid++,f):b},access:function(a,c,d,e,f,g,h){var i,j=d==null,k=0,l=a.length;if(d&&typeof d=="object"){for(k in d)p.access(a,c,k,d[k],1,g,e);f=1}else if(e!==b){i=h===b&&p.isFunction(e),j&&(i?(i=c,c=function(a,b,c){return i.call(p(a),c)}):(c.call(a,e),c=null));if(c)for(;k<l;k++)c(a[k],d,i?e.call(a[k],k,c(a[k],d)):e,h);f=1}return f?a:j?c.call(a):l?c(a[0],d):g},now:function(){return(new Date).getTime()}}),p.ready.promise=function(b){if(!d){d=p.Deferred();if(e.readyState==="complete")setTimeout(p.ready,1);else if(e.addEventListener)e.addEventListener("DOMContentLoaded",D,!1),a.addEventListener("load",p.ready,!1);else{e.attachEvent("onreadystatechange",D),a.attachEvent("onload",p.ready);var c=!1;try{c=a.frameElement==null&&e.documentElement}catch(f){}c&&c.doScroll&&function g(){if(!p.isReady){try{c.doScroll("left")}catch(a){return setTimeout(g,50)}p.ready()}}()}}return d.promise(b)},p.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){E["[object "+b+"]"]=b.toLowerCase()}),c=p(e);var F={};p.Callbacks=function(a){a=typeof a=="string"?F[a]||G(a):p.extend({},a);var c,d,e,f,g,h,i=[],j=!a.once&&[],k=function(b){c=a.memory&&b,d=!0,h=f||0,f=0,g=i.length,e=!0;for(;i&&h<g;h++)if(i[h].apply(b[0],b[1])===!1&&a.stopOnFalse){c=!1;break}e=!1,i&&(j?j.length&&k(j.shift()):c?i=[]:l.disable())},l={add:function(){if(i){var b=i.length;(function d(b){p.each(b,function(b,c){var e=p.type(c);e==="function"&&(!a.unique||!l.has(c))?i.push(c):c&&c.length&&e!=="string"&&d(c)})})(arguments),e?g=i.length:c&&(f=b,k(c))}return this},remove:function(){return i&&p.each(arguments,function(a,b){var c;while((c=p.inArray(b,i,c))>-1)i.splice(c,1),e&&(c<=g&&g--,c<=h&&h--)}),this},has:function(a){return p.inArray(a,i)>-1},empty:function(){return i=[],this},disable:function(){return i=j=c=b,this},disabled:function(){return!i},lock:function(){return j=b,c||l.disable(),this},locked:function(){return!j},fireWith:function(a,b){return b=b||[],b=[a,b.slice?b.slice():b],i&&(!d||j)&&(e?j.push(b):k(b)),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!d}};return l},p.extend({Deferred:function(a){var b=[["resolve","done",p.Callbacks("once memory"),"resolved"],["reject","fail",p.Callbacks("once memory"),"rejected"],["notify","progress",p.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return p.Deferred(function(c){p.each(b,function(b,d){var f=d[0],g=a[b];e[d[1]](p.isFunction(g)?function(){var a=g.apply(this,arguments);a&&p.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f+"With"](this===e?c:this,[a])}:c[f])}),a=null}).promise()},promise:function(a){return a!=null?p.extend(a,d):d}},e={};return d.pipe=d.then,p.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[a^1][2].disable,b[2][2].lock),e[f[0]]=g.fire,e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=k.call(arguments),d=c.length,e=d!==1||a&&p.isFunction(a.promise)?d:0,f=e===1?a:p.Deferred(),g=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?k.call(arguments):d,c===h?f.notifyWith(b,c):--e||f.resolveWith(b,c)}},h,i,j;if(d>1){h=new Array(d),i=new Array(d),j=new Array(d);for(;b<d;b++)c[b]&&p.isFunction(c[b].promise)?c[b].promise().done(g(b,j,c)).fail(f.reject).progress(g(b,i,h)):--e}return e||f.resolveWith(j,c),f.promise()}}),p.support=function(){var b,c,d,f,g,h,i,j,k,l,m,n=e.createElement("div");n.setAttribute("className","t"),n.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",c=n.getElementsByTagName("*"),d=n.getElementsByTagName("a")[0],d.style.cssText="top:1px;float:left;opacity:.5";if(!c||!c.length)return{};f=e.createElement("select"),g=f.appendChild(e.createElement("option")),h=n.getElementsByTagName("input")[0],b={leadingWhitespace:n.firstChild.nodeType===3,tbody:!n.getElementsByTagName("tbody").length,htmlSerialize:!!n.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.5/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:n.className!=="t",enctype:!!e.createElement("form").enctype,html5Clone:e.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:e.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},h.checked=!0,b.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,b.optDisabled=!g.disabled;try{delete n.test}catch(o){b.deleteExpando=!1}!n.addEventListener&&n.attachEvent&&n.fireEvent&&(n.attachEvent("onclick",m=function(){b.noCloneEvent=!1}),n.cloneNode(!0).fireEvent("onclick"),n.detachEvent("onclick",m)),h=e.createElement("input"),h.value="t",h.setAttribute("type","radio"),b.radioValue=h.value==="t",h.setAttribute("checked","checked"),h.setAttribute("name","t"),n.appendChild(h),i=e.createDocumentFragment(),i.appendChild(n.lastChild),b.checkClone=i.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=h.checked,i.removeChild(h),i.appendChild(n);if(n.attachEvent)for(k in{submit:!0,change:!0,focusin:!0})j="on"+k,l=j in n,l||(n.setAttribute(j,"return;"),l=typeof n[j]=="function"),b[k+"Bubbles"]=l;return p(function(){var c,d,f,g,h="padding:0;margin:0;border:0;display:block;overflow:hidden;",i=e.getElementsByTagName("body")[0];if(!i)return;c=e.createElement("div"),c.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",i.insertBefore(c,i.firstChild),d=e.createElement("div"),c.appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",f=d.getElementsByTagName("td"),f[0].style.cssText="padding:0;margin:0;border:0;display:none",l=f[0].offsetHeight===0,f[0].style.display="",f[1].style.display="none",b.reliableHiddenOffsets=l&&f[0].offsetHeight===0,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",b.boxSizing=d.offsetWidth===4,b.doesNotIncludeMarginInBodyOffset=i.offsetTop!==1,a.getComputedStyle&&(b.pixelPosition=(a.getComputedStyle(d,null)||{}).top!=="1%",b.boxSizingReliable=(a.getComputedStyle(d,null)||{width:"4px"}).width==="4px",g=e.createElement("div"),g.style.cssText=d.style.cssText=h,g.style.marginRight=g.style.width="0",d.style.width="1px",d.appendChild(g),b.reliableMarginRight=!parseFloat((a.getComputedStyle(g,null)||{}).marginRight)),typeof d.style.zoom!="undefined"&&(d.innerHTML="",d.style.cssText=h+"width:1px;padding:1px;display:inline;zoom:1",b.inlineBlockNeedsLayout=d.offsetWidth===3,d.style.display="block",d.style.overflow="visible",d.innerHTML="<div></div>",d.firstChild.style.width="5px",b.shrinkWrapBlocks=d.offsetWidth!==3,c.style.zoom=1),i.removeChild(c),c=d=f=g=null}),i.removeChild(n),c=d=f=g=h=i=n=null,b}();var H=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,I=/([A-Z])/g;p.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(p.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){return a=a.nodeType?p.cache[a[p.expando]]:a[p.expando],!!a&&!K(a)},data:function(a,c,d,e){if(!p.acceptData(a))return;var f,g,h=p.expando,i=typeof c=="string",j=a.nodeType,k=j?p.cache:a,l=j?a[h]:a[h]&&h;if((!l||!k[l]||!e&&!k[l].data)&&i&&d===b)return;l||(j?a[h]=l=p.deletedIds.pop()||p.guid++:l=h),k[l]||(k[l]={},j||(k[l].toJSON=p.noop));if(typeof c=="object"||typeof c=="function")e?k[l]=p.extend(k[l],c):k[l].data=p.extend(k[l].data,c);return f=k[l],e||(f.data||(f.data={}),f=f.data),d!==b&&(f[p.camelCase(c)]=d),i?(g=f[c],g==null&&(g=f[p.camelCase(c)])):g=f,g},removeData:function(a,b,c){if(!p.acceptData(a))return;var d,e,f,g=a.nodeType,h=g?p.cache:a,i=g?a[p.expando]:p.expando;if(!h[i])return;if(b){d=c?h[i]:h[i].data;if(d){p.isArray(b)||(b in d?b=[b]:(b=p.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,f=b.length;e<f;e++)delete d[b[e]];if(!(c?K:p.isEmptyObject)(d))return}}if(!c){delete h[i].data;if(!K(h[i]))return}g?p.cleanData([a],!0):p.support.deleteExpando||h!=h.window?delete h[i]:h[i]=null},_data:function(a,b,c){return p.data(a,b,c,!0)},acceptData:function(a){var b=a.nodeName&&p.noData[a.nodeName.toLowerCase()];return!b||b!==!0&&a.getAttribute("classid")===b}}),p.fn.extend({data:function(a,c){var d,e,f,g,h,i=this[0],j=0,k=null;if(a===b){if(this.length){k=p.data(i);if(i.nodeType===1&&!p._data(i,"parsedAttrs")){f=i.attributes;for(h=f.length;j<h;j++)g=f[j].name,g.indexOf("data-")||(g=p.camelCase(g.substring(5)),J(i,g,k[g]));p._data(i,"parsedAttrs",!0)}}return k}return typeof a=="object"?this.each(function(){p.data(this,a)}):(d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!",p.access(this,function(c){if(c===b)return k=this.triggerHandler("getData"+e,[d[0]]),k===b&&i&&(k=p.data(i,a),k=J(i,a,k)),k===b&&d[1]?this.data(d[0]):k;d[1]=c,this.each(function(){var b=p(this);b.triggerHandler("setData"+e,d),p.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1))},removeData:function(a){return this.each(function(){p.removeData(this,a)})}}),p.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=p._data(a,b),c&&(!d||p.isArray(c)?d=p._data(a,b,p.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=p.queue(a,b),d=c.length,e=c.shift(),f=p._queueHooks(a,b),g=function(){p.dequeue(a,b)};e==="inprogress"&&(e=c.shift(),d--),e&&(b==="fx"&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return p._data(a,c)||p._data(a,c,{empty:p.Callbacks("once memory").add(function(){p.removeData(a,b+"queue",!0),p.removeData(a,c,!0)})})}}),p.fn.extend({queue:function(a,c){var d=2;return typeof a!="string"&&(c=a,a="fx",d--),arguments.length<d?p.queue(this[0],a):c===b?this:this.each(function(){var b=p.queue(this,a,c);p._queueHooks(this,a),a==="fx"&&b[0]!=="inprogress"&&p.dequeue(this,a)})},dequeue:function(a){return this.each(function(){p.dequeue(this,a)})},delay:function(a,b){return a=p.fx?p.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){var d,e=1,f=p.Deferred(),g=this,h=this.length,i=function(){--e||f.resolveWith(g,[g])};typeof a!="string"&&(c=a,a=b),a=a||"fx";while(h--)d=p._data(g[h],a+"queueHooks"),d&&d.empty&&(e++,d.empty.add(i));return i(),f.promise(c)}});var L,M,N,O=/[\t\r\n]/g,P=/\r/g,Q=/^(?:button|input)$/i,R=/^(?:button|input|object|select|textarea)$/i,S=/^a(?:rea|)$/i,T=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,U=p.support.getSetAttribute;p.fn.extend({attr:function(a,b){return p.access(this,p.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){p.removeAttr(this,a)})},prop:function(a,b){return p.access(this,p.prop,a,b,arguments.length>1)},removeProp:function(a){return a=p.propFix[a]||a,this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,f,g,h;if(p.isFunction(a))return this.each(function(b){p(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(s);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{f=" "+e.className+" ";for(g=0,h=b.length;g<h;g++)f.indexOf(" "+b[g]+" ")<0&&(f+=b[g]+" ");e.className=p.trim(f)}}}return this},removeClass:function(a){var c,d,e,f,g,h,i;if(p.isFunction(a))return this.each(function(b){p(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(s);for(h=0,i=this.length;h<i;h++){e=this[h];if(e.nodeType===1&&e.className){d=(" "+e.className+" ").replace(O," ");for(f=0,g=c.length;f<g;f++)while(d.indexOf(" "+c[f]+" ")>=0)d=d.replace(" "+c[f]+" "," ");e.className=a?p.trim(d):""}}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";return p.isFunction(a)?this.each(function(c){p(this).toggleClass(a.call(this,c,this.className,b),b)}):this.each(function(){if(c==="string"){var e,f=0,g=p(this),h=b,i=a.split(s);while(e=i[f++])h=d?h:!g.hasClass(e),g[h?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&p._data(this,"__className__",this.className),this.className=this.className||a===!1?"":p._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(O," ").indexOf(b)>=0)return!0;return!1},val:function(a){var c,d,e,f=this[0];if(!arguments.length){if(f)return c=p.valHooks[f.type]||p.valHooks[f.nodeName.toLowerCase()],c&&"get"in c&&(d=c.get(f,"value"))!==b?d:(d=f.value,typeof d=="string"?d.replace(P,""):d==null?"":d);return}return e=p.isFunction(a),this.each(function(d){var f,g=p(this);if(this.nodeType!==1)return;e?f=a.call(this,d,g.val()):f=a,f==null?f="":typeof f=="number"?f+="":p.isArray(f)&&(f=p.map(f,function(a){return a==null?"":a+""})),c=p.valHooks[this.type]||p.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,f,"value")===b)this.value=f})}}),p.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,f=a.selectedIndex,g=[],h=a.options,i=a.type==="select-one";if(f<0)return null;c=i?f:0,d=i?f+1:h.length;for(;c<d;c++){e=h[c];if(e.selected&&(p.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!p.nodeName(e.parentNode,"optgroup"))){b=p(e).val();if(i)return b;g.push(b)}}return i&&!g.length&&h.length?p(h[f]).val():g},set:function(a,b){var c=p.makeArray(b);return p(a).find("option").each(function(){this.selected=p.inArray(p(this).val(),c)>=0}),c.length||(a.selectedIndex=-1),c}}},attrFn:{},attr:function(a,c,d,e){var f,g,h,i=a.nodeType;if(!a||i===3||i===8||i===2)return;if(e&&p.isFunction(p.fn[c]))return p(a)[c](d);if(typeof a.getAttribute=="undefined")return p.prop(a,c,d);h=i!==1||!p.isXMLDoc(a),h&&(c=c.toLowerCase(),g=p.attrHooks[c]||(T.test(c)?M:L));if(d!==b){if(d===null){p.removeAttr(a,c);return}return g&&"set"in g&&h&&(f=g.set(a,d,c))!==b?f:(a.setAttribute(c,d+""),d)}return g&&"get"in g&&h&&(f=g.get(a,c))!==null?f:(f=a.getAttribute(c),f===null?b:f)},removeAttr:function(a,b){var c,d,e,f,g=0;if(b&&a.nodeType===1){d=b.split(s);for(;g<d.length;g++)e=d[g],e&&(c=p.propFix[e]||e,f=T.test(e),f||p.attr(a,e,""),a.removeAttribute(U?e:c),f&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(Q.test(a.nodeName)&&a.parentNode)p.error("type property can't be changed");else if(!p.support.radioValue&&b==="radio"&&p.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}},value:{get:function(a,b){return L&&p.nodeName(a,"button")?L.get(a,b):b in a?a.value:null},set:function(a,b,c){if(L&&p.nodeName(a,"button"))return L.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,f,g,h=a.nodeType;if(!a||h===3||h===8||h===2)return;return g=h!==1||!p.isXMLDoc(a),g&&(c=p.propFix[c]||c,f=p.propHooks[c]),d!==b?f&&"set"in f&&(e=f.set(a,d,c))!==b?e:a[c]=d:f&&"get"in f&&(e=f.get(a,c))!==null?e:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):R.test(a.nodeName)||S.test(a.nodeName)&&a.href?0:b}}}}),M={get:function(a,c){var d,e=p.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;return b===!1?p.removeAttr(a,c):(d=p.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase())),c}},U||(N={name:!0,id:!0,coords:!0},L=p.valHooks.button={get:function(a,c){var d;return d=a.getAttributeNode(c),d&&(N[c]?d.value!=="":d.specified)?d.value:b},set:function(a,b,c){var d=a.getAttributeNode(c);return d||(d=e.createAttribute(c),a.setAttributeNode(d)),d.value=b+""}},p.each(["width","height"],function(a,b){p.attrHooks[b]=p.extend(p.attrHooks[b],{set:function(a,c){if(c==="")return a.setAttribute(b,"auto"),c}})}),p.attrHooks.contenteditable={get:L.get,set:function(a,b,c){b===""&&(b="false"),L.set(a,b,c)}}),p.support.hrefNormalized||p.each(["href","src","width","height"],function(a,c){p.attrHooks[c]=p.extend(p.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),p.support.style||(p.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=b+""}}),p.support.optSelected||(p.propHooks.selected=p.extend(p.propHooks.selected,{get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}})),p.support.enctype||(p.propFix.enctype="encoding"),p.support.checkOn||p.each(["radio","checkbox"],function(){p.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),p.each(["radio","checkbox"],function(){p.valHooks[this]=p.extend(p.valHooks[this],{set:function(a,b){if(p.isArray(b))return a.checked=p.inArray(p(a).val(),b)>=0}})});var V=/^(?:textarea|input|select)$/i,W=/^([^\.]*|)(?:\.(.+)|)$/,X=/(?:^|\s)hover(\.\S+|)\b/,Y=/^key/,Z=/^(?:mouse|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=function(a){return p.event.special.hover?a:a.replace(X,"mouseenter$1 mouseleave$1")};p.event={add:function(a,c,d,e,f){var g,h,i,j,k,l,m,n,o,q,r;if(a.nodeType===3||a.nodeType===8||!c||!d||!(g=p._data(a)))return;d.handler&&(o=d,d=o.handler,f=o.selector),d.guid||(d.guid=p.guid++),i=g.events,i||(g.events=i={}),h=g.handle,h||(g.handle=h=function(a){return typeof p!="undefined"&&(!a||p.event.triggered!==a.type)?p.event.dispatch.apply(h.elem,arguments):b},h.elem=a),c=p.trim(_(c)).split(" ");for(j=0;j<c.length;j++){k=W.exec(c[j])||[],l=k[1],m=(k[2]||"").split(".").sort(),r=p.event.special[l]||{},l=(f?r.delegateType:r.bindType)||l,r=p.event.special[l]||{},n=p.extend({type:l,origType:k[1],data:e,handler:d,guid:d.guid,selector:f,needsContext:f&&p.expr.match.needsContext.test(f),namespace:m.join(".")},o),q=i[l];if(!q){q=i[l]=[],q.delegateCount=0;if(!r.setup||r.setup.call(a,e,m,h)===!1)a.addEventListener?a.addEventListener(l,h,!1):a.attachEvent&&a.attachEvent("on"+l,h)}r.add&&(r.add.call(a,n),n.handler.guid||(n.handler.guid=d.guid)),f?q.splice(q.delegateCount++,0,n):q.push(n),p.event.global[l]=!0}a=null},global:{},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,q,r=p.hasData(a)&&p._data(a);if(!r||!(m=r.events))return;b=p.trim(_(b||"")).split(" ");for(f=0;f<b.length;f++){g=W.exec(b[f])||[],h=i=g[1],j=g[2];if(!h){for(h in m)p.event.remove(a,h+b[f],c,d,!0);continue}n=p.event.special[h]||{},h=(d?n.delegateType:n.bindType)||h,o=m[h]||[],k=o.length,j=j?new RegExp("(^|\\.)"+j.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(l=0;l<o.length;l++)q=o[l],(e||i===q.origType)&&(!c||c.guid===q.guid)&&(!j||j.test(q.namespace))&&(!d||d===q.selector||d==="**"&&q.selector)&&(o.splice(l--,1),q.selector&&o.delegateCount--,n.remove&&n.remove.call(a,q));o.length===0&&k!==o.length&&((!n.teardown||n.teardown.call(a,j,r.handle)===!1)&&p.removeEvent(a,h,r.handle),delete m[h])}p.isEmptyObject(m)&&(delete r.handle,p.removeData(a,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,f,g){if(!f||f.nodeType!==3&&f.nodeType!==8){var h,i,j,k,l,m,n,o,q,r,s=c.type||c,t=[];if($.test(s+p.event.triggered))return;s.indexOf("!")>=0&&(s=s.slice(0,-1),i=!0),s.indexOf(".")>=0&&(t=s.split("."),s=t.shift(),t.sort());if((!f||p.event.customEvent[s])&&!p.event.global[s])return;c=typeof c=="object"?c[p.expando]?c:new p.Event(s,c):new p.Event(s),c.type=s,c.isTrigger=!0,c.exclusive=i,c.namespace=t.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,m=s.indexOf(":")<0?"on"+s:"";if(!f){h=p.cache;for(j in h)h[j].events&&h[j].events[s]&&p.event.trigger(c,d,h[j].handle.elem,!0);return}c.result=b,c.target||(c.target=f),d=d!=null?p.makeArray(d):[],d.unshift(c),n=p.event.special[s]||{};if(n.trigger&&n.trigger.apply(f,d)===!1)return;q=[[f,n.bindType||s]];if(!g&&!n.noBubble&&!p.isWindow(f)){r=n.delegateType||s,k=$.test(r+s)?f:f.parentNode;for(l=f;k;k=k.parentNode)q.push([k,r]),l=k;l===(f.ownerDocument||e)&&q.push([l.defaultView||l.parentWindow||a,r])}for(j=0;j<q.length&&!c.isPropagationStopped();j++)k=q[j][0],c.type=q[j][1],o=(p._data(k,"events")||{})[c.type]&&p._data(k,"handle"),o&&o.apply(k,d),o=m&&k[m],o&&p.acceptData(k)&&o.apply&&o.apply(k,d)===!1&&c.preventDefault();return c.type=s,!g&&!c.isDefaultPrevented()&&(!n._default||n._default.apply(f.ownerDocument,d)===!1)&&(s!=="click"||!p.nodeName(f,"a"))&&p.acceptData(f)&&m&&f[s]&&(s!=="focus"&&s!=="blur"||c.target.offsetWidth!==0)&&!p.isWindow(f)&&(l=f[m],l&&(f[m]=null),p.event.triggered=s,f[s](),p.event.triggered=b,l&&(f[m]=l)),c.result}return},dispatch:function(c){c=p.event.fix(c||a.event);var d,e,f,g,h,i,j,l,m,n,o=(p._data(this,"events")||{})[c.type]||[],q=o.delegateCount,r=k.call(arguments),s=!c.exclusive&&!c.namespace,t=p.event.special[c.type]||{},u=[];r[0]=c,c.delegateTarget=this;if(t.preDispatch&&t.preDispatch.call(this,c)===!1)return;if(q&&(!c.button||c.type!=="click"))for(f=c.target;f!=this;f=f.parentNode||this)if(f.disabled!==!0||c.type!=="click"){h={},j=[];for(d=0;d<q;d++)l=o[d],m=l.selector,h[m]===b&&(h[m]=l.needsContext?p(m,this).index(f)>=0:p.find(m,this,null,[f]).length),h[m]&&j.push(l);j.length&&u.push({elem:f,matches:j})}o.length>q&&u.push({elem:this,matches:o.slice(q)});for(d=0;d<u.length&&!c.isPropagationStopped();d++){i=u[d],c.currentTarget=i.elem;for(e=0;e<i.matches.length&&!c.isImmediatePropagationStopped();e++){l=i.matches[e];if(s||!c.namespace&&!l.namespace||c.namespace_re&&c.namespace_re.test(l.namespace))c.data=l.data,c.handleObj=l,g=((p.event.special[l.origType]||{}).handle||l.handler).apply(i.elem,r),g!==b&&(c.result=g,g===!1&&(c.preventDefault(),c.stopPropagation()))}}return t.postDispatch&&t.postDispatch.call(this,c),c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,c){var d,f,g,h=c.button,i=c.fromElement;return a.pageX==null&&c.clientX!=null&&(d=a.target.ownerDocument||e,f=d.documentElement,g=d.body,a.pageX=c.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=c.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?c.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0),a}},fix:function(a){if(a[p.expando])return a;var b,c,d=a,f=p.event.fixHooks[a.type]||{},g=f.props?this.props.concat(f.props):this.props;a=p.Event(d);for(b=g.length;b;)c=g[--b],a[c]=d[c];return a.target||(a.target=d.srcElement||e),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,f.filter?f.filter(a,d):a},special:{load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){p.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=p.extend(new p.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?p.event.trigger(e,null,b):p.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},p.event.handle=p.event.dispatch,p.removeEvent=e.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]=="undefined"&&(a[d]=null),a.detachEvent(d,c))},p.Event=function(a,b){if(this instanceof p.Event)a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?bb:ba):this.type=a,b&&p.extend(this,b),this.timeStamp=a&&a.timeStamp||p.now(),this[p.expando]=!0;else return new p.Event(a,b)},p.Event.prototype={preventDefault:function(){this.isDefaultPrevented=bb;var a=this.originalEvent;if(!a)return;a.preventDefault?a.preventDefault():a.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=bb;var a=this.originalEvent;if(!a)return;a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()},isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationStopped:ba},p.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){p.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj,g=f.selector;if(!e||e!==d&&!p.contains(d,e))a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b;return c}}}),p.support.submitBubbles||(p.event.special.submit={setup:function(){if(p.nodeName(this,"form"))return!1;p.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=p.nodeName(c,"input")||p.nodeName(c,"button")?c.form:b;d&&!p._data(d,"_submit_attached")&&(p.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),p._data(d,"_submit_attached",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&p.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(p.nodeName(this,"form"))return!1;p.event.remove(this,"._submit")}}),p.support.changeBubbles||(p.event.special.change={setup:function(){if(V.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")p.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),p.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),p.event.simulate("change",this,a,!0)});return!1}p.event.add(this,"beforeactivate._change",function(a){var b=a.target;V.test(b.nodeName)&&!p._data(b,"_change_attached")&&(p.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&p.event.simulate("change",this.parentNode,a,!0)}),p._data(b,"_change_attached",!0))})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){return p.event.remove(this,"._change"),!V.test(this.nodeName)}}),p.support.focusinBubbles||p.each({focus:"focusin",blur:"focusout"},function(a,b){var c=0,d=function(a){p.event.simulate(b,a.target,p.event.fix(a),!0)};p.event.special[b]={setup:function(){c++===0&&e.addEventListener(a,d,!0)},teardown:function(){--c===0&&e.removeEventListener(a,d,!0)}}}),p.fn.extend({on:function(a,c,d,e,f){var g,h;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(h in a)this.on(h,c,d,a[h],f);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=ba;else if(!e)return this;return f===1&&(g=e,e=function(a){return p().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=p.guid++)),this.each(function(){p.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){var e,f;if(a&&a.preventDefault&&a.handleObj)return e=a.handleObj,p(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler),this;if(typeof a=="object"){for(f in a)this.off(f,c,a[f]);return this}if(c===!1||typeof c=="function")d=c,c=b;return d===!1&&(d=ba),this.each(function(){p.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){return p(this.context).on(a,this.selector,b,c),this},die:function(a,b){return p(this.context).off(a,this.selector||"**",b),this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length===1?this.off(a,"**"):this.off(b,a||"**",c)},trigger:function(a,b){return this.each(function(){p.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return p.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||p.guid++,d=0,e=function(c){var e=(p._data(this,"lastToggle"+a.guid)||0)%d;return p._data(this,"lastToggle"+a.guid,e+1),c.preventDefault(),b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),p.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){p.fn[b]=function(a,c){return c==null&&(c=a,a=null),arguments.length>0?this.on(b,null,a,c):this.trigger(b)},Y.test(b)&&(p.event.fixHooks[b]=p.event.keyHooks),Z.test(b)&&(p.event.fixHooks[b]=p.event.mouseHooks)}),function(a,b){function bc(a,b,c,d){c=c||[],b=b||r;var e,f,i,j,k=b.nodeType;if(!a||typeof a!="string")return c;if(k!==1&&k!==9)return[];i=g(b);if(!i&&!d)if(e=P.exec(a))if(j=e[1]){if(k===9){f=b.getElementById(j);if(!f||!f.parentNode)return c;if(f.id===j)return c.push(f),c}else if(b.ownerDocument&&(f=b.ownerDocument.getElementById(j))&&h(b,f)&&f.id===j)return c.push(f),c}else{if(e[2])return w.apply(c,x.call(b.getElementsByTagName(a),0)),c;if((j=e[3])&&_&&b.getElementsByClassName)return w.apply(c,x.call(b.getElementsByClassName(j),0)),c}return bp(a.replace(L,"$1"),b,c,d,i)}function bd(a){return function(b){var c=b.nodeName.toLowerCase();return c==="input"&&b.type===a}}function be(a){return function(b){var c=b.nodeName.toLowerCase();return(c==="input"||c==="button")&&b.type===a}}function bf(a){return z(function(b){return b=+b,z(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function bg(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}function bh(a,b){var c,d,f,g,h,i,j,k=C[o][a];if(k)return b?0:k.slice(0);h=a,i=[],j=e.preFilter;while(h){if(!c||(d=M.exec(h)))d&&(h=h.slice(d[0].length)),i.push(f=[]);c=!1;if(d=N.exec(h))f.push(c=new q(d.shift())),h=h.slice(c.length),c.type=d[0].replace(L," ");for(g in e.filter)(d=W[g].exec(h))&&(!j[g]||(d=j[g](d,r,!0)))&&(f.push(c=new q(d.shift())),h=h.slice(c.length),c.type=g,c.matches=d);if(!c)break}return b?h.length:h?bc.error(a):C(a,i).slice(0)}function bi(a,b,d){var e=b.dir,f=d&&b.dir==="parentNode",g=u++;return b.first?function(b,c,d){while(b=b[e])if(f||b.nodeType===1)return a(b,c,d)}:function(b,d,h){if(!h){var i,j=t+" "+g+" ",k=j+c;while(b=b[e])if(f||b.nodeType===1){if((i=b[o])===k)return b.sizset;if(typeof i=="string"&&i.indexOf(j)===0){if(b.sizset)return b}else{b[o]=k;if(a(b,d,h))return b.sizset=!0,b;b.sizset=!1}}}else while(b=b[e])if(f||b.nodeType===1)if(a(b,d,h))return b}}function bj(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function bk(a,b,c,d,e){var f,g=[],h=0,i=a.length,j=b!=null;for(;h<i;h++)if(f=a[h])if(!c||c(f,d,e))g.push(f),j&&b.push(h);return g}function bl(a,b,c,d,e,f){return d&&!d[o]&&(d=bl(d)),e&&!e[o]&&(e=bl(e,f)),z(function(f,g,h,i){if(f&&e)return;var j,k,l,m=[],n=[],o=g.length,p=f||bo(b||"*",h.nodeType?[h]:h,[],f),q=a&&(f||!b)?bk(p,m,a,h,i):p,r=c?e||(f?a:o||d)?[]:g:q;c&&c(q,r,h,i);if(d){l=bk(r,n),d(l,[],h,i),j=l.length;while(j--)if(k=l[j])r[n[j]]=!(q[n[j]]=k)}if(f){j=a&&r.length;while(j--)if(k=r[j])f[m[j]]=!(g[m[j]]=k)}else r=bk(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):w.apply(g,r)})}function bm(a){var b,c,d,f=a.length,g=e.relative[a[0].type],h=g||e.relative[" "],i=g?1:0,j=bi(function(a){return a===b},h,!0),k=bi(function(a){return y.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==l)||((b=c).nodeType?j(a,c,d):k(a,c,d))}];for(;i<f;i++)if(c=e.relative[a[i].type])m=[bi(bj(m),c)];else{c=e.filter[a[i].type].apply(null,a[i].matches);if(c[o]){d=++i;for(;d<f;d++)if(e.relative[a[d].type])break;return bl(i>1&&bj(m),i>1&&a.slice(0,i-1).join("").replace(L,"$1"),c,i<d&&bm(a.slice(i,d)),d<f&&bm(a=a.slice(d)),d<f&&a.join(""))}m.push(c)}return bj(m)}function bn(a,b){var d=b.length>0,f=a.length>0,g=function(h,i,j,k,m){var n,o,p,q=[],s=0,u="0",x=h&&[],y=m!=null,z=l,A=h||f&&e.find.TAG("*",m&&i.parentNode||i),B=t+=z==null?1:Math.E;y&&(l=i!==r&&i,c=g.el);for(;(n=A[u])!=null;u++){if(f&&n){for(o=0;p=a[o];o++)if(p(n,i,j)){k.push(n);break}y&&(t=B,c=++g.el)}d&&((n=!p&&n)&&s--,h&&x.push(n))}s+=u;if(d&&u!==s){for(o=0;p=b[o];o++)p(x,q,i,j);if(h){if(s>0)while(u--)!x[u]&&!q[u]&&(q[u]=v.call(k));q=bk(q)}w.apply(k,q),y&&!h&&q.length>0&&s+b.length>1&&bc.uniqueSort(k)}return y&&(t=B,l=z),x};return g.el=0,d?z(g):g}function bo(a,b,c,d){var e=0,f=b.length;for(;e<f;e++)bc(a,b[e],c,d);return c}function bp(a,b,c,d,f){var g,h,j,k,l,m=bh(a),n=m.length;if(!d&&m.length===1){h=m[0]=m[0].slice(0);if(h.length>2&&(j=h[0]).type==="ID"&&b.nodeType===9&&!f&&e.relative[h[1].type]){b=e.find.ID(j.matches[0].replace(V,""),b,f)[0];if(!b)return c;a=a.slice(h.shift().length)}for(g=W.POS.test(a)?-1:h.length-1;g>=0;g--){j=h[g];if(e.relative[k=j.type])break;if(l=e.find[k])if(d=l(j.matches[0].replace(V,""),R.test(h[0].type)&&b.parentNode||b,f)){h.splice(g,1),a=d.length&&h.join("");if(!a)return w.apply(c,x.call(d,0)),c;break}}}return i(a,m)(d,b,f,c,R.test(a)),c}function bq(){}var c,d,e,f,g,h,i,j,k,l,m=!0,n="undefined",o=("sizcache"+Math.random()).replace(".",""),q=String,r=a.document,s=r.documentElement,t=0,u=0,v=[].pop,w=[].push,x=[].slice,y=[].indexOf||function(a){var b=0,c=this.length;for(;b<c;b++)if(this[b]===a)return b;return-1},z=function(a,b){return a[o]=b==null||b,a},A=function(){var a={},b=[];return z(function(c,d){return b.push(c)>e.cacheLength&&delete a[b.shift()],a[c]=d},a)},B=A(),C=A(),D=A(),E="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",G=F.replace("w","w#"),H="([*^$|!~]?=)",I="\\["+E+"*("+F+")"+E+"*(?:"+H+E+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+G+")|)|)"+E+"*\\]",J=":("+F+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+I+")|[^:]|\\\\.)*|.*))\\)|)",K=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+E+"*((?:-\\d)?\\d*)"+E+"*\\)|)(?=[^-]|$)",L=new RegExp("^"+E+"+|((?:^|[^\\\\])(?:\\\\.)*)"+E+"+$","g"),M=new RegExp("^"+E+"*,"+E+"*"),N=new RegExp("^"+E+"*([\\x20\\t\\r\\n\\f>+~])"+E+"*"),O=new RegExp(J),P=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,Q=/^:not/,R=/[\x20\t\r\n\f]*[+~]/,S=/:not\($/,T=/h\d/i,U=/input|select|textarea|button/i,V=/\\(?!\\)/g,W={ID:new RegExp("^#("+F+")"),CLASS:new RegExp("^\\.("+F+")"),NAME:new RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:new RegExp("^("+F.replace("w","w*")+")"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+J),POS:new RegExp(K,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+E+"*(even|odd|(([+-]|)(\\d*)n|)"+E+"*(?:([+-]|)"+E+"*(\\d+)|))"+E+"*\\)|)","i"),needsContext:new RegExp("^"+E+"*[>+~]|"+K,"i")},X=function(a){var b=r.createElement("div");try{return a(b)}catch(c){return!1}finally{b=null}},Y=X(function(a){return a.appendChild(r.createComment("")),!a.getElementsByTagName("*").length}),Z=X(function(a){return a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!==n&&a.firstChild.getAttribute("href")==="#"}),$=X(function(a){a.innerHTML="<select></select>";var b=typeof a.lastChild.getAttribute("multiple");return b!=="boolean"&&b!=="string"}),_=X(function(a){return a.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!a.getElementsByClassName||!a.getElementsByClassName("e").length?!1:(a.lastChild.className="e",a.getElementsByClassName("e").length===2)}),ba=X(function(a){a.id=o+0,a.innerHTML="<a name='"+o+"'></a><div name='"+o+"'></div>",s.insertBefore(a,s.firstChild);var b=r.getElementsByName&&r.getElementsByName(o).length===2+r.getElementsByName(o+0).length;return d=!r.getElementById(o),s.removeChild(a),b});try{x.call(s.childNodes,0)[0].nodeType}catch(bb){x=function(a){var b,c=[];for(;b=this[a];a++)c.push(b);return c}}bc.matches=function(a,b){return bc(a,null,null,b)},bc.matchesSelector=function(a,b){return bc(b,null,null,[a]).length>0},f=bc.getText=function(a){var b,c="",d=0,e=a.nodeType;if(e){if(e===1||e===9||e===11){if(typeof a.textContent=="string")return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=f(a)}else if(e===3||e===4)return a.nodeValue}else for(;b=a[d];d++)c+=f(b);return c},g=bc.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?b.nodeName!=="HTML":!1},h=bc.contains=s.contains?function(a,b){var c=a.nodeType===9?a.documentElement:a,d=b&&b.parentNode;return a===d||!!(d&&d.nodeType===1&&c.contains&&c.contains(d))}:s.compareDocumentPosition?function(a,b){return b&&!!(a.compareDocumentPosition(b)&16)}:function(a,b){while(b=b.parentNode)if(b===a)return!0;return!1},bc.attr=function(a,b){var c,d=g(a);return d||(b=b.toLowerCase()),(c=e.attrHandle[b])?c(a):d||$?a.getAttribute(b):(c=a.getAttributeNode(b),c?typeof a[b]=="boolean"?a[b]?b:null:c.specified?c.value:null:null)},e=bc.selectors={cacheLength:50,createPseudo:z,match:W,attrHandle:Z?{}:{href:function(a){return a.getAttribute("href",2)},type:function(a){return a.getAttribute("type")}},find:{ID:d?function(a,b,c){if(typeof b.getElementById!==n&&!c){var d=b.getElementById(a);return d&&d.parentNode?[d]:[]}}:function(a,c,d){if(typeof c.getElementById!==n&&!d){var e=c.getElementById(a);return e?e.id===a||typeof e.getAttributeNode!==n&&e.getAttributeNode("id").value===a?[e]:b:[]}},TAG:Y?function(a,b){if(typeof b.getElementsByTagName!==n)return b.getElementsByTagName(a)}:function(a,b){var c=b.getElementsByTagName(a);if(a==="*"){var d,e=[],f=0;for(;d=c[f];f++)d.nodeType===1&&e.push(d);return e}return c},NAME:ba&&function(a,b){if(typeof b.getElementsByName!==n)return b.getElementsByName(name)},CLASS:_&&function(a,b,c){if(typeof b.getElementsByClassName!==n&&!c)return b.getElementsByClassName(a)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(V,""),a[3]=(a[4]||a[5]||"").replace(V,""),a[2]==="~="&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),a[1]==="nth"?(a[2]||bc.error(a[0]),a[3]=+(a[3]?a[4]+(a[5]||1):2*(a[2]==="even"||a[2]==="odd")),a[4]=+(a[6]+a[7]||a[2]==="odd")):a[2]&&bc.error(a[0]),a},PSEUDO:function(a){var b,c;if(W.CHILD.test(a[0]))return null;if(a[3])a[2]=a[3];else if(b=a[4])O.test(b)&&(c=bh(b,!0))&&(c=b.indexOf(")",b.length-c)-b.length)&&(b=b.slice(0,c),a[0]=a[0].slice(0,c)),a[2]=b;return a.slice(0,3)}},filter:{ID:d?function(a){return a=a.replace(V,""),function(b){return b.getAttribute("id")===a}}:function(a){return a=a.replace(V,""),function(b){var c=typeof b.getAttributeNode!==n&&b.getAttributeNode("id");return c&&c.value===a}},TAG:function(a){return a==="*"?function(){return!0}:(a=a.replace(V,"").toLowerCase(),function(b){return b.nodeName&&b.nodeName.toLowerCase()===a})},CLASS:function(a){var b=B[o][a];return b||(b=B(a,new RegExp("(^|"+E+")"+a+"("+E+"|$)"))),function(a){return b.test(a.className||typeof a.getAttribute!==n&&a.getAttribute("class")||"")}},ATTR:function(a,b,c){return function(d,e){var f=bc.attr(d,a);return f==null?b==="!=":b?(f+="",b==="="?f===c:b==="!="?f!==c:b==="^="?c&&f.indexOf(c)===0:b==="*="?c&&f.indexOf(c)>-1:b==="$="?c&&f.substr(f.length-c.length)===c:b==="~="?(" "+f+" ").indexOf(c)>-1:b==="|="?f===c||f.substr(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d){return a==="nth"?function(a){var b,e,f=a.parentNode;if(c===1&&d===0)return!0;if(f){e=0;for(b=f.firstChild;b;b=b.nextSibling)if(b.nodeType===1){e++;if(a===b)break}}return e-=d,e===c||e%c===0&&e/c>=0}:function(b){var c=b;switch(a){case"only":case"first":while(c=c.previousSibling)if(c.nodeType===1)return!1;if(a==="first")return!0;c=b;case"last":while(c=c.nextSibling)if(c.nodeType===1)return!1;return!0}}},PSEUDO:function(a,b){var c,d=e.pseudos[a]||e.setFilters[a.toLowerCase()]||bc.error("unsupported pseudo: "+a);return d[o]?d(b):d.length>1?(c=[a,a,"",b],e.setFilters.hasOwnProperty(a.toLowerCase())?z(function(a,c){var e,f=d(a,b),g=f.length;while(g--)e=y.call(a,f[g]),a[e]=!(c[e]=f[g])}):function(a){return d(a,0,c)}):d}},pseudos:{not:z(function(a){var b=[],c=[],d=i(a.replace(L,"$1"));return d[o]?z(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)if(f=g[h])a[h]=!(b[h]=f)}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:z(function(a){return function(b){return bc(a,b).length>0}}),contains:z(function(a){return function(b){return(b.textContent||b.innerText||f(b)).indexOf(a)>-1}}),enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&!!a.checked||b==="option"&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},parent:function(a){return!e.pseudos.empty(a)},empty:function(a){var b;a=a.firstChild;while(a){if(a.nodeName>"@"||(b=a.nodeType)===3||b===4)return!1;a=a.nextSibling}return!0},header:function(a){return T.test(a.nodeName)},text:function(a){var b,c;return a.nodeName.toLowerCase()==="input"&&(b=a.type)==="text"&&((c=a.getAttribute("type"))==null||c.toLowerCase()===b)},radio:bd("radio"),checkbox:bd("checkbox"),file:bd("file"),password:bd("password"),image:bd("image"),submit:be("submit"),reset:be("reset"),button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&a.type==="button"||b==="button"},input:function(a){return U.test(a.nodeName)},focus:function(a){var b=a.ownerDocument;return a===b.activeElement&&(!b.hasFocus||b.hasFocus())&&(!!a.type||!!a.href)},active:function(a){return a===a.ownerDocument.activeElement},first:bf(function(a,b,c){return[0]}),last:bf(function(a,b,c){return[b-1]}),eq:bf(function(a,b,c){return[c<0?c+b:c]}),even:bf(function(a,b,c){for(var d=0;d<b;d+=2)a.push(d);return a}),odd:bf(function(a,b,c){for(var d=1;d<b;d+=2)a.push(d);return a}),lt:bf(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:bf(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},j=s.compareDocumentPosition?function(a,b){return a===b?(k=!0,0):(!a.compareDocumentPosition||!b.compareDocumentPosition?a.compareDocumentPosition:a.compareDocumentPosition(b)&4)?-1:1}:function(a,b){if(a===b)return k=!0,0;if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,h=b.parentNode,i=g;if(g===h)return bg(a,b);if(!g)return-1;if(!h)return 1;while(i)e.unshift(i),i=i.parentNode;i=h;while(i)f.unshift(i),i=i.parentNode;c=e.length,d=f.length;for(var j=0;j<c&&j<d;j++)if(e[j]!==f[j])return bg(e[j],f[j]);return j===c?bg(a,f[j],-1):bg(e[j],b,1)},[0,0].sort(j),m=!k,bc.uniqueSort=function(a){var b,c=1;k=m,a.sort(j);if(k)for(;b=a[c];c++)b===a[c-1]&&a.splice(c--,1);return a},bc.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},i=bc.compile=function(a,b){var c,d=[],e=[],f=D[o][a];if(!f){b||(b=bh(a)),c=b.length;while(c--)f=bm(b[c]),f[o]?d.push(f):e.push(f);f=D(a,bn(e,d))}return f},r.querySelectorAll&&function(){var a,b=bp,c=/'|\\/g,d=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,e=[":focus"],f=[":active",":focus"],h=s.matchesSelector||s.mozMatchesSelector||s.webkitMatchesSelector||s.oMatchesSelector||s.msMatchesSelector;X(function(a){a.innerHTML="<select><option selected=''></option></select>",a.querySelectorAll("[selected]").length||e.push("\\["+E+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),a.querySelectorAll(":checked").length||e.push(":checked")}),X(function(a){a.innerHTML="<p test=''></p>",a.querySelectorAll("[test^='']").length&&e.push("[*^$]="+E+"*(?:\"\"|'')"),a.innerHTML="<input type='hidden'/>",a.querySelectorAll(":enabled").length||e.push(":enabled",":disabled")}),e=new RegExp(e.join("|")),bp=function(a,d,f,g,h){if(!g&&!h&&(!e||!e.test(a))){var i,j,k=!0,l=o,m=d,n=d.nodeType===9&&a;if(d.nodeType===1&&d.nodeName.toLowerCase()!=="object"){i=bh(a),(k=d.getAttribute("id"))?l=k.replace(c,"\\$&"):d.setAttribute("id",l),l="[id='"+l+"'] ",j=i.length;while(j--)i[j]=l+i[j].join("");m=R.test(a)&&d.parentNode||d,n=i.join(",")}if(n)try{return w.apply(f,x.call(m.querySelectorAll(n),0)),f}catch(p){}finally{k||d.removeAttribute("id")}}return b(a,d,f,g,h)},h&&(X(function(b){a=h.call(b,"div");try{h.call(b,"[test!='']:sizzle"),f.push("!=",J)}catch(c){}}),f=new RegExp(f.join("|")),bc.matchesSelector=function(b,c){c=c.replace(d,"='$1']");if(!g(b)&&!f.test(c)&&(!e||!e.test(c)))try{var i=h.call(b,c);if(i||a||b.document&&b.document.nodeType!==11)return i}catch(j){}return bc(c,null,null,[b]).length>0})}(),e.pseudos.nth=e.pseudos.eq,e.filters=bq.prototype=e.pseudos,e.setFilters=new bq,bc.attr=p.attr,p.find=bc,p.expr=bc.selectors,p.expr[":"]=p.expr.pseudos,p.unique=bc.uniqueSort,p.text=bc.getText,p.isXMLDoc=bc.isXML,p.contains=bc.contains}(a);var bc=/Until$/,bd=/^(?:parents|prev(?:Until|All))/,be=/^.[^:#\[\.,]*$/,bf=p.expr.match.needsContext,bg={children:!0,contents:!0,next:!0,prev:!0};p.fn.extend({find:function(a){var b,c,d,e,f,g,h=this;if(typeof a!="string")return p(a).filter(function(){for(b=0,c=h.length;b<c;b++)if(p.contains(h[b],this))return!0});g=this.pushStack("","find",a);for(b=0,c=this.length;b<c;b++){d=g.length,p.find(a,this[b],g);if(b>0)for(e=d;e<g.length;e++)for(f=0;f<d;f++)if(g[f]===g[e]){g.splice(e--,1);break}}return g},has:function(a){var b,c=p(a,this),d=c.length;return this.filter(function(){for(b=0;b<d;b++)if(p.contains(this,c[b]))return!0})},not:function(a){return this.pushStack(bj(this,a,!1),"not",a)},filter:function(a){return this.pushStack(bj(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?bf.test(a)?p(a,this.context).index(this[0])>=0:p.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c,d=0,e=this.length,f=[],g=bf.test(a)||typeof a!="string"?p(a,b||this.context):0;for(;d<e;d++){c=this[d];while(c&&c.ownerDocument&&c!==b&&c.nodeType!==11){if(g?g.index(c)>-1:p.find.matchesSelector(c,a)){f.push(c);break}c=c.parentNode}}return f=f.length>1?p.unique(f):f,this.pushStack(f,"closest",a)},index:function(a){return a?typeof a=="string"?p.inArray(this[0],p(a)):p.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(a,b){var c=typeof a=="string"?p(a,b):p.makeArray(a&&a.nodeType?[a]:a),d=p.merge(this.get(),c);return this.pushStack(bh(c[0])||bh(d[0])?d:p.unique(d))},addBack:function(a){return this.add(a==null?this.prevObject:this.prevObject.filter(a))}}),p.fn.andSelf=p.fn.addBack,p.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return p.dir(a,"parentNode")},parentsUntil:function(a,b,c){return p.dir(a,"parentNode",c)},next:function(a){return bi(a,"nextSibling")},prev:function(a){return bi(a,"previousSibling")},nextAll:function(a){return p.dir(a,"nextSibling")},prevAll:function(a){return p.dir(a,"previousSibling")},nextUntil:function(a,b,c){return p.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return p.dir(a,"previousSibling",c)},siblings:function(a){return p.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return p.sibling(a.firstChild)},contents:function(a){return p.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:p.merge([],a.childNodes)}},function(a,b){p.fn[a]=function(c,d){var e=p.map(this,b,c);return bc.test(a)||(d=c),d&&typeof d=="string"&&(e=p.filter(d,e)),e=this.length>1&&!bg[a]?p.unique(e):e,this.length>1&&bd.test(a)&&(e=e.reverse()),this.pushStack(e,a,k.call(arguments).join(","))}}),p.extend({filter:function(a,b,c){return c&&(a=":not("+a+")"),b.length===1?p.find.matchesSelector(b[0],a)?[b[0]]:[]:p.find.matches(a,b)},dir:function(a,c,d){var e=[],f=a[c];while(f&&f.nodeType!==9&&(d===b||f.nodeType!==1||!p(f).is(d)))f.nodeType===1&&e.push(f),f=f[c];return e},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var bl="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",bm=/ jQuery\d+="(?:null|\d+)"/g,bn=/^\s+/,bo=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bp=/<([\w:]+)/,bq=/<tbody/i,br=/<|&#?\w+;/,bs=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,bu=new RegExp("<(?:"+bl+")[\\s/>]","i"),bv=/^(?:checkbox|radio)$/,bw=/checked\s*(?:[^=]|=\s*.checked.)/i,bx=/\/(java|ecma)script/i,by=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,bz={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bA=bk(e),bB=bA.appendChild(e.createElement("div"));bz.optgroup=bz.option,bz.tbody=bz.tfoot=bz.colgroup=bz.caption=bz.thead,bz.th=bz.td,p.support.htmlSerialize||(bz._default=[1,"X<div>","</div>"]),p.fn.extend({text:function(a){return p.access(this,function(a){return a===b?p.text(this):this.empty().append((this[0]&&this[0].ownerDocument||e).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(p.isFunction(a))return this.each(function(b){p(this).wrapAll(a.call(this,b))});if(this[0]){var b=p(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return p.isFunction(a)?this.each(function(b){p(this).wrapInner(a.call(this,b))}):this.each(function(){var b=p(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=p.isFunction(a);return this.each(function(c){p(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){p.nodeName(this,"body")||p(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(a,this.firstChild)})},before:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(a,this),"before",this.selector)}},after:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(this,a),"after",this.selector)}},remove:function(a,b){var c,d=0;for(;(c=this[d])!=null;d++)if(!a||p.filter(a,[c]).length)!b&&c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),p.cleanData([c])),c.parentNode&&c.parentNode.removeChild(c);return this},empty:function(){var a,b=0;for(;(a=this[b])!=null;b++){a.nodeType===1&&p.cleanData(a.getElementsByTagName("*"));while(a.firstChild)a.removeChild(a.firstChild)}return this},clone:function(a,b){return a=a==null?!1:a,b=b==null?a:b,this.map(function(){return p.clone(this,a,b)})},html:function(a){return p.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(bm,""):b;if(typeof a=="string"&&!bs.test(a)&&(p.support.htmlSerialize||!bu.test(a))&&(p.support.leadingWhitespace||!bn.test(a))&&!bz[(bp.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(bo,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(f){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){return bh(this[0])?this.length?this.pushStack(p(p.isFunction(a)?a():a),"replaceWith",a):this:p.isFunction(a)?this.each(function(b){var c=p(this),d=c.html();c.replaceWith(a.call(this,b,d))}):(typeof a!="string"&&(a=p(a).detach()),this.each(function(){var b=this.nextSibling,c=this.parentNode;p(this).remove(),b?p(b).before(a):p(c).append(a)}))},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){a=[].concat.apply([],a);var e,f,g,h,i=0,j=a[0],k=[],l=this.length;if(!p.support.checkClone&&l>1&&typeof j=="string"&&bw.test(j))return this.each(function(){p(this).domManip(a,c,d)});if(p.isFunction(j))return this.each(function(e){var f=p(this);a[0]=j.call(this,e,c?f.html():b),f.domManip(a,c,d)});if(this[0]){e=p.buildFragment(a,this,k),g=e.fragment,f=g.firstChild,g.childNodes.length===1&&(g=f);if(f){c=c&&p.nodeName(f,"tr");for(h=e.cacheable||l-1;i<l;i++)d.call(c&&p.nodeName(this[i],"table")?bC(this[i],"tbody"):this[i],i===h?g:p.clone(g,!0,!0))}g=f=null,k.length&&p.each(k,function(a,b){b.src?p.ajax?p.ajax({url:b.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):p.error("no ajax"):p.globalEval((b.text||b.textContent||b.innerHTML||"").replace(by,"")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),p.buildFragment=function(a,c,d){var f,g,h,i=a[0];return c=c||e,c=!c.nodeType&&c[0]||c,c=c.ownerDocument||c,a.length===1&&typeof i=="string"&&i.length<512&&c===e&&i.charAt(0)==="<"&&!bt.test(i)&&(p.support.checkClone||!bw.test(i))&&(p.support.html5Clone||!bu.test(i))&&(g=!0,f=p.fragments[i],h=f!==b),f||(f=c.createDocumentFragment(),p.clean(a,c,f,d),g&&(p.fragments[i]=h&&f)),{fragment:f,cacheable:g}},p.fragments={},p.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){p.fn[a]=function(c){var d,e=0,f=[],g=p(c),h=g.length,i=this.length===1&&this[0].parentNode;if((i==null||i&&i.nodeType===11&&i.childNodes.length===1)&&h===1)return g[b](this[0]),this;for(;e<h;e++)d=(e>0?this.clone(!0):this).get(),p(g[e])[b](d),f=f.concat(d);return this.pushStack(f,a,g.selector)}}),p.extend({clone:function(a,b,c){var d,e,f,g;p.support.html5Clone||p.isXMLDoc(a)||!bu.test("<"+a.nodeName+">")?g=a.cloneNode(!0):(bB.innerHTML=a.outerHTML,bB.removeChild(g=bB.firstChild));if((!p.support.noCloneEvent||!p.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!p.isXMLDoc(a)){bE(a,g),d=bF(a),e=bF(g);for(f=0;d[f];++f)e[f]&&bE(d[f],e[f])}if(b){bD(a,g);if(c){d=bF(a),e=bF(g);for(f=0;d[f];++f)bD(d[f],e[f])}}return d=e=null,g},clean:function(a,b,c,d){var f,g,h,i,j,k,l,m,n,o,q,r,s=b===e&&bA,t=[];if(!b||typeof b.createDocumentFragment=="undefined")b=e;for(f=0;(h=a[f])!=null;f++){typeof h=="number"&&(h+="");if(!h)continue;if(typeof h=="string")if(!br.test(h))h=b.createTextNode(h);else{s=s||bk(b),l=b.createElement("div"),s.appendChild(l),h=h.replace(bo,"<$1></$2>"),i=(bp.exec(h)||["",""])[1].toLowerCase(),j=bz[i]||bz._default,k=j[0],l.innerHTML=j[1]+h+j[2];while(k--)l=l.lastChild;if(!p.support.tbody){m=bq.test(h),n=i==="table"&&!m?l.firstChild&&l.firstChild.childNodes:j[1]==="<table>"&&!m?l.childNodes:[];for(g=n.length-1;g>=0;--g)p.nodeName(n[g],"tbody")&&!n[g].childNodes.length&&n[g].parentNode.removeChild(n[g])}!p.support.leadingWhitespace&&bn.test(h)&&l.insertBefore(b.createTextNode(bn.exec(h)[0]),l.firstChild),h=l.childNodes,l.parentNode.removeChild(l)}h.nodeType?t.push(h):p.merge(t,h)}l&&(h=l=s=null);if(!p.support.appendChecked)for(f=0;(h=t[f])!=null;f++)p.nodeName(h,"input")?bG(h):typeof h.getElementsByTagName!="undefined"&&p.grep(h.getElementsByTagName("input"),bG);if(c){q=function(a){if(!a.type||bx.test(a.type))return d?d.push(a.parentNode?a.parentNode.removeChild(a):a):c.appendChild(a)};for(f=0;(h=t[f])!=null;f++)if(!p.nodeName(h,"script")||!q(h))c.appendChild(h),typeof h.getElementsByTagName!="undefined"&&(r=p.grep(p.merge([],h.getElementsByTagName("script")),q),t.splice.apply(t,[f+1,0].concat(r)),f+=r.length)}return t},cleanData:function(a,b){var c,d,e,f,g=0,h=p.expando,i=p.cache,j=p.support.deleteExpando,k=p.event.special;for(;(e=a[g])!=null;g++)if(b||p.acceptData(e)){d=e[h],c=d&&i[d];if(c){if(c.events)for(f in c.events)k[f]?p.event.remove(e,f):p.removeEvent(e,f,c.handle);i[d]&&(delete i[d],j?delete e[h]:e.removeAttribute?e.removeAttribute(h):e[h]=null,p.deletedIds.push(d))}}}}),function(){var a,b;p.uaMatch=function(a){a=a.toLowerCase();var b=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||a.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},a=p.uaMatch(g.userAgent),b={},a.browser&&(b[a.browser]=!0,b.version=a.version),b.chrome?b.webkit=!0:b.webkit&&(b.safari=!0),p.browser=b,p.sub=function(){function a(b,c){return new a.fn.init(b,c)}p.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function c(c,d){return d&&d instanceof p&&!(d instanceof a)&&(d=a(d)),p.fn.init.call(this,c,d,b)},a.fn.init.prototype=a.fn;var b=a(e);return a}}();var bH,bI,bJ,bK=/alpha\([^)]*\)/i,bL=/opacity=([^)]*)/,bM=/^(top|right|bottom|left)$/,bN=/^(none|table(?!-c[ea]).+)/,bO=/^margin/,bP=new RegExp("^("+q+")(.*)$","i"),bQ=new RegExp("^("+q+")(?!px)[a-z%]+$","i"),bR=new RegExp("^([-+])=("+q+")","i"),bS={},bT={position:"absolute",visibility:"hidden",display:"block"},bU={letterSpacing:0,fontWeight:400},bV=["Top","Right","Bottom","Left"],bW=["Webkit","O","Moz","ms"],bX=p.fn.toggle;p.fn.extend({css:function(a,c){return p.access(this,function(a,c,d){return d!==b?p.style(a,c,d):p.css(a,c)},a,c,arguments.length>1)},show:function(){return b$(this,!0)},hide:function(){return b$(this)},toggle:function(a,b){var c=typeof a=="boolean";return p.isFunction(a)&&p.isFunction(b)?bX.apply(this,arguments):this.each(function(){(c?a:bZ(this))?p(this).show():p(this).hide()})}}),p.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bH(a,"opacity");return c===""?"1":c}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":p.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!a||a.nodeType===3||a.nodeType===8||!a.style)return;var f,g,h,i=p.camelCase(c),j=a.style;c=p.cssProps[i]||(p.cssProps[i]=bY(j,i)),h=p.cssHooks[c]||p.cssHooks[i];if(d===b)return h&&"get"in h&&(f=h.get(a,!1,e))!==b?f:j[c];g=typeof d,g==="string"&&(f=bR.exec(d))&&(d=(f[1]+1)*f[2]+parseFloat(p.css(a,c)),g="number");if(d==null||g==="number"&&isNaN(d))return;g==="number"&&!p.cssNumber[i]&&(d+="px");if(!h||!("set"in h)||(d=h.set(a,d,e))!==b)try{j[c]=d}catch(k){}},css:function(a,c,d,e){var f,g,h,i=p.camelCase(c);return c=p.cssProps[i]||(p.cssProps[i]=bY(a.style,i)),h=p.cssHooks[c]||p.cssHooks[i],h&&"get"in h&&(f=h.get(a,!0,e)),f===b&&(f=bH(a,c)),f==="normal"&&c in bU&&(f=bU[c]),d||e!==b?(g=parseFloat(f),d||p.isNumeric(g)?g||0:f):f},swap:function(a,b,c){var d,e,f={};for(e in b)f[e]=a.style[e],a.style[e]=b[e];d=c.call(a);for(e in b)a.style[e]=f[e];return d}}),a.getComputedStyle?bH=function(b,c){var d,e,f,g,h=a.getComputedStyle(b,null),i=b.style;return h&&(d=h[c],d===""&&!p.contains(b.ownerDocument,b)&&(d=p.style(b,c)),bQ.test(d)&&bO.test(c)&&(e=i.width,f=i.minWidth,g=i.maxWidth,i.minWidth=i.maxWidth=i.width=d,d=h.width,i.width=e,i.minWidth=f,i.maxWidth=g)),d}:e.documentElement.currentStyle&&(bH=function(a,b){var c,d,e=a.currentStyle&&a.currentStyle[b],f=a.style;return e==null&&f&&f[b]&&(e=f[b]),bQ.test(e)&&!bM.test(b)&&(c=f.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":e,e=f.pixelLeft+"px",f.left=c,d&&(a.runtimeStyle.left=d)),e===""?"auto":e}),p.each(["height","width"],function(a,b){p.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth===0&&bN.test(bH(a,"display"))?p.swap(a,bT,function(){return cb(a,b,d)}):cb(a,b,d)},set:function(a,c,d){return b_(a,c,d?ca(a,b,d,p.support.boxSizing&&p.css(a,"boxSizing")==="border-box"):0)}}}),p.support.opacity||(p.cssHooks.opacity={get:function(a,b){return bL.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=p.isNumeric(b)?"alpha(opacity="+b*100+")":"",f=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&p.trim(f.replace(bK,""))===""&&c.removeAttribute){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bK.test(f)?f.replace(bK,e):f+" "+e}}),p(function(){p.support.reliableMarginRight||(p.cssHooks.marginRight={get:function(a,b){return p.swap(a,{display:"inline-block"},function(){if(b)return bH(a,"marginRight")})}}),!p.support.pixelPosition&&p.fn.position&&p.each(["top","left"],function(a,b){p.cssHooks[b]={get:function(a,c){if(c){var d=bH(a,b);return bQ.test(d)?p(a).position()[b]+"px":d}}}})}),p.expr&&p.expr.filters&&(p.expr.filters.hidden=function(a){return a.offsetWidth===0&&a.offsetHeight===0||!p.support.reliableHiddenOffsets&&(a.style&&a.style.display||bH(a,"display"))==="none"},p.expr.filters.visible=function(a){return!p.expr.filters.hidden(a)}),p.each({margin:"",padding:"",border:"Width"},function(a,b){p.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bV[d]+b]=e[d]||e[d-2]||e[0];return f}},bO.test(a)||(p.cssHooks[a+b].set=b_)});var cd=/%20/g,ce=/\[\]$/,cf=/\r?\n/g,cg=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,ch=/^(?:select|textarea)/i;p.fn.extend({serialize:function(){return p.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?p.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ch.test(this.nodeName)||cg.test(this.type))}).map(function(a,b){var c=p(this).val();return c==null?null:p.isArray(c)?p.map(c,function(a,c){return{name:b.name,value:a.replace(cf,"\r\n")}}):{name:b.name,value:c.replace(cf,"\r\n")}}).get()}}),p.param=function(a,c){var d,e=[],f=function(a,b){b=p.isFunction(b)?b():b==null?"":b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=p.ajaxSettings&&p.ajaxSettings.traditional);if(p.isArray(a)||a.jquery&&!p.isPlainObject(a))p.each(a,function(){f(this.name,this.value)});else for(d in a)ci(d,a[d],c,f);return e.join("&").replace(cd,"+")};var cj,ck,cl=/#.*$/,cm=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,cn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,co=/^(?:GET|HEAD)$/,cp=/^\/\//,cq=/\?/,cr=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,cs=/([?&])_=[^&]*/,ct=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,cu=p.fn.load,cv={},cw={},cx=["*/"]+["*"];try{ck=f.href}catch(cy){ck=e.createElement("a"),ck.href="",ck=ck.href}cj=ct.exec(ck.toLowerCase())||[],p.fn.load=function(a,c,d){if(typeof a!="string"&&cu)return cu.apply(this,arguments);if(!this.length)return this;var e,f,g,h=this,i=a.indexOf(" ");return i>=0&&(e=a.slice(i,a.length),a=a.slice(0,i)),p.isFunction(c)?(d=c,c=b):c&&typeof c=="object"&&(f="POST"),p.ajax({url:a,type:f,dataType:"html",data:c,complete:function(a,b){d&&h.each(d,g||[a.responseText,b,a])}}).done(function(a){g=arguments,h.html(e?p("<div>").append(a.replace(cr,"")).find(e):a)}),this},p.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){p.fn[b]=function(a){return this.on(b,a)}}),p.each(["get","post"],function(a,c){p[c]=function(a,d,e,f){return p.isFunction(d)&&(f=f||e,e=d,d=b),p.ajax({type:c,url:a,data:d,success:e,dataType:f})}}),p.extend({getScript:function(a,c){return p.get(a,b,c,"script")},getJSON:function(a,b,c){return p.get(a,b,c,"json")},ajaxSetup:function(a,b){return b?cB(a,p.ajaxSettings):(b=a,a=p.ajaxSettings),cB(a,b),a},ajaxSettings:{url:ck,isLocal:cn.test(cj[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":cx},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":p.parseJSON,"text xml":p.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:cz(cv),ajaxTransport:cz(cw),ajax:function(a,c){function y(a,c,f,i){var k,s,t,u,w,y=c;if(v===2)return;v=2,h&&clearTimeout(h),g=b,e=i||"",x.readyState=a>0?4:0,f&&(u=cC(l,x,f));if(a>=200&&a<300||a===304)l.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(p.lastModified[d]=w),w=x.getResponseHeader("Etag"),w&&(p.etag[d]=w)),a===304?(y="notmodified",k=!0):(k=cD(l,u),y=k.state,s=k.data,t=k.error,k=!t);else{t=y;if(!y||a)y="error",a<0&&(a=0)}x.status=a,x.statusText=(c||y)+"",k?o.resolveWith(m,[s,y,x]):o.rejectWith(m,[x,y,t]),x.statusCode(r),r=b,j&&n.trigger("ajax"+(k?"Success":"Error"),[x,l,k?s:t]),q.fireWith(m,[x,y]),j&&(n.trigger("ajaxComplete",[x,l]),--p.active||p.event.trigger("ajaxStop"))}typeof a=="object"&&(c=a,a=b),c=c||{};var d,e,f,g,h,i,j,k,l=p.ajaxSetup({},c),m=l.context||l,n=m!==l&&(m.nodeType||m instanceof p)?p(m):p.event,o=p.Deferred(),q=p.Callbacks("once memory"),r=l.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,setRequestHeader:function(a,b){if(!v){var c=a.toLowerCase();a=u[c]=u[c]||a,t[a]=b}return this},getAllResponseHeaders:function(){return v===2?e:null},getResponseHeader:function(a){var c;if(v===2){if(!f){f={};while(c=cm.exec(e))f[c[1].toLowerCase()]=c[2]}c=f[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){return v||(l.mimeType=a),this},abort:function(a){return a=a||w,g&&g.abort(a),y(0,a),this}};o.promise(x),x.success=x.done,x.error=x.fail,x.complete=q.add,x.statusCode=function(a){if(a){var b;if(v<2)for(b in a)r[b]=[r[b],a[b]];else b=a[x.status],x.always(b)}return this},l.url=((a||l.url)+"").replace(cl,"").replace(cp,cj[1]+"//"),l.dataTypes=p.trim(l.dataType||"*").toLowerCase().split(s),l.crossDomain==null&&(i=ct.exec(l.url.toLowerCase())||!1,l.crossDomain=i&&i.join(":")+(i[3]?"":i[1]==="http:"?80:443)!==cj.join(":")+(cj[3]?"":cj[1]==="http:"?80:443)),l.data&&l.processData&&typeof l.data!="string"&&(l.data=p.param(l.data,l.traditional)),cA(cv,l,c,x);if(v===2)return x;j=l.global,l.type=l.type.toUpperCase(),l.hasContent=!co.test(l.type),j&&p.active++===0&&p.event.trigger("ajaxStart");if(!l.hasContent){l.data&&(l.url+=(cq.test(l.url)?"&":"?")+l.data,delete l.data),d=l.url;if(l.cache===!1){var z=p.now(),A=l.url.replace(cs,"$1_="+z);l.url=A+(A===l.url?(cq.test(l.url)?"&":"?")+"_="+z:"")}}(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",l.contentType),l.ifModified&&(d=d||l.url,p.lastModified[d]&&x.setRequestHeader("If-Modified-Since",p.lastModified[d]),p.etag[d]&&x.setRequestHeader("If-None-Match",p.etag[d])),x.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(l.dataTypes[0]!=="*"?", "+cx+"; q=0.01":""):l.accepts["*"]);for(k in l.headers)x.setRequestHeader(k,l.headers[k]);if(!l.beforeSend||l.beforeSend.call(m,x,l)!==!1&&v!==2){w="abort";for(k in{success:1,error:1,complete:1})x[k](l[k]);g=cA(cw,l,c,x);if(!g)y(-1,"No Transport");else{x.readyState=1,j&&n.trigger("ajaxSend",[x,l]),l.async&&l.timeout>0&&(h=setTimeout(function(){x.abort("timeout")},l.timeout));try{v=1,g.send(t,y)}catch(B){if(v<2)y(-1,B);else throw B}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var cE=[],cF=/\?/,cG=/(=)\?(?=&|$)|\?\?/,cH=p.now();p.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=cE.pop()||p.expando+"_"+cH++;return this[a]=!0,a}}),p.ajaxPrefilter("json jsonp",function(c,d,e){var f,g,h,i=c.data,j=c.url,k=c.jsonp!==!1,l=k&&cG.test(j),m=k&&!l&&typeof i=="string"&&!(c.contentType||"").indexOf("application/x-www-form-urlencoded")&&cG.test(i);if(c.dataTypes[0]==="jsonp"||l||m)return f=c.jsonpCallback=p.isFunction(c.jsonpCallback)?c.jsonpCallback():c.jsonpCallback,g=a[f],l?c.url=j.replace(cG,"$1"+f):m?c.data=i.replace(cG,"$1"+f):k&&(c.url+=(cF.test(j)?"&":"?")+c.jsonp+"="+f),c.converters["script json"]=function(){return h||p.error(f+" was not called"),h[0]},c.dataTypes[0]="json",a[f]=function(){h=arguments},e.always(function(){a[f]=g,c[f]&&(c.jsonpCallback=d.jsonpCallback,cE.push(f)),h&&p.isFunction(g)&&g(h[0]),h=g=b}),"script"}),p.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){return p.globalEval(a),a}}}),p.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),p.ajaxTransport("script",function(a){if(a.crossDomain){var c,d=e.head||e.getElementsByTagName("head")[0]||e.documentElement;return{send:function(f,g){c=e.createElement("script"),c.async="async",a.scriptCharset&&(c.charset=a.scriptCharset),c.src=a.url,c.onload=c.onreadystatechange=function(a,e){if(e||!c.readyState||/loaded|complete/.test(c.readyState))c.onload=c.onreadystatechange=null,d&&c.parentNode&&d.removeChild(c),c=b,e||g(200,"success")},d.insertBefore(c,d.firstChild)},abort:function(){c&&c.onload(0,1)}}}});var cI,cJ=a.ActiveXObject?function(){for(var a in cI)cI[a](0,1)}:!1,cK=0;p.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&cL()||cM()}:cL,function(a){p.extend(p.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(p.ajaxSettings.xhr()),p.support.ajax&&p.ajaxTransport(function(c){if(!c.crossDomain||p.support.cors){var d;return{send:function(e,f){var g,h,i=c.xhr();c.username?i.open(c.type,c.url,c.async,c.username,c.password):i.open(c.type,c.url,c.async);if(c.xhrFields)for(h in c.xhrFields)i[h]=c.xhrFields[h];c.mimeType&&i.overrideMimeType&&i.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(h in e)i.setRequestHeader(h,e[h])}catch(j){}i.send(c.hasContent&&c.data||null),d=function(a,e){var h,j,k,l,m;try{if(d&&(e||i.readyState===4)){d=b,g&&(i.onreadystatechange=p.noop,cJ&&delete cI[g]);if(e)i.readyState!==4&&i.abort();else{h=i.status,k=i.getAllResponseHeaders(),l={},m=i.responseXML,m&&m.documentElement&&(l.xml=m);try{l.text=i.responseText}catch(a){}try{j=i.statusText}catch(n){j=""}!h&&c.isLocal&&!c.crossDomain?h=l.text?200:404:h===1223&&(h=204)}}}catch(o){e||f(-1,o)}l&&f(h,j,l,k)},c.async?i.readyState===4?setTimeout(d,0):(g=++cK,cJ&&(cI||(cI={},p(a).unload(cJ)),cI[g]=d),i.onreadystatechange=d):d()},abort:function(){d&&d(0,1)}}}});var cN,cO,cP=/^(?:toggle|show|hide)$/,cQ=new RegExp("^(?:([-+])=|)("+q+")([a-z%]*)$","i"),cR=/queueHooks$/,cS=[cY],cT={"*":[function(a,b){var c,d,e=this.createTween(a,b),f=cQ.exec(b),g=e.cur(),h=+g||0,i=1,j=20;if(f){c=+f[2],d=f[3]||(p.cssNumber[a]?"":"px");if(d!=="px"&&h){h=p.css(e.elem,a,!0)||c||1;do i=i||".5",h=h/i,p.style(e.elem,a,h+d);while(i!==(i=e.cur()/g)&&i!==1&&--j)}e.unit=d,e.start=h,e.end=f[1]?h+(f[1]+1)*c:c}return e}]};p.Animation=p.extend(cW,{tweener:function(a,b){p.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");var c,d=0,e=a.length;for(;d<e;d++)c=a[d],cT[c]=cT[c]||[],cT[c].unshift(b)},prefilter:function(a,b){b?cS.unshift(a):cS.push(a)}}),p.Tween=cZ,cZ.prototype={constructor:cZ,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(p.cssNumber[c]?"":"px")},cur:function(){var a=cZ.propHooks[this.prop];return a&&a.get?a.get(this):cZ.propHooks._default.get(this)},run:function(a){var b,c=cZ.propHooks[this.prop];return this.options.duration?this.pos=b=p.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):cZ.propHooks._default.set(this),this}},cZ.prototype.init.prototype=cZ.prototype,cZ.propHooks={_default:{get:function(a){var b;return a.elem[a.prop]==null||!!a.elem.style&&a.elem.style[a.prop]!=null?(b=p.css(a.elem,a.prop,!1,""),!b||b==="auto"?0:b):a.elem[a.prop]},set:function(a){p.fx.step[a.prop]?p.fx.step[a.prop](a):a.elem.style&&(a.elem.style[p.cssProps[a.prop]]!=null||p.cssHooks[a.prop])?p.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},cZ.propHooks.scrollTop=cZ.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},p.each(["toggle","show","hide"],function(a,b){var c=p.fn[b];p.fn[b]=function(d,e,f){return d==null||typeof d=="boolean"||!a&&p.isFunction(d)&&p.isFunction(e)?c.apply(this,arguments):this.animate(c$(b,!0),d,e,f)}}),p.fn.extend({fadeTo:function(a,b,c,d){return this.filter(bZ).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=p.isEmptyObject(a),f=p.speed(b,c,d),g=function(){var b=cW(this,p.extend({},a),f);e&&b.stop(!0)};return e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,c,d){var e=function(a){var b=a.stop;delete a.stop,b(d)};return typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,c=a!=null&&a+"queueHooks",f=p.timers,g=p._data(this);if(c)g[c]&&g[c].stop&&e(g[c]);else for(c in g)g[c]&&g[c].stop&&cR.test(c)&&e(g[c]);for(c=f.length;c--;)f[c].elem===this&&(a==null||f[c].queue===a)&&(f[c].anim.stop(d),b=!1,f.splice(c,1));(b||!d)&&p.dequeue(this,a)})}}),p.each({slideDown:c$("show"),slideUp:c$("hide"),slideToggle:c$("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){p.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),p.speed=function(a,b,c){var d=a&&typeof a=="object"?p.extend({},a):{complete:c||!c&&b||p.isFunction(a)&&a,duration:a,easing:c&&b||b&&!p.isFunction(b)&&b};d.duration=p.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in p.fx.speeds?p.fx.speeds[d.duration]:p.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";return d.old=d.complete,d.complete=function(){p.isFunction(d.old)&&d.old.call(this),d.queue&&p.dequeue(this,d.queue)},d},p.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},p.timers=[],p.fx=cZ.prototype.init,p.fx.tick=function(){var a,b=p.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||p.fx.stop()},p.fx.timer=function(a){a()&&p.timers.push(a)&&!cO&&(cO=setInterval(p.fx.tick,p.fx.interval))},p.fx.interval=13,p.fx.stop=function(){clearInterval(cO),cO=null},p.fx.speeds={slow:600,fast:200,_default:400},p.fx.step={},p.expr&&p.expr.filters&&(p.expr.filters.animated=function(a){return p.grep(p.timers,function(b){return a===b.elem}).length});var c_=/^(?:body|html)$/i;p.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){p.offset.setOffset(this,a,b)});var c,d,e,f,g,h,i,j={top:0,left:0},k=this[0],l=k&&k.ownerDocument;if(!l)return;return(d=l.body)===k?p.offset.bodyOffset(k):(c=l.documentElement,p.contains(c,k)?(typeof k.getBoundingClientRect!="undefined"&&(j=k.getBoundingClientRect()),e=da(l),f=c.clientTop||d.clientTop||0,g=c.clientLeft||d.clientLeft||0,h=e.pageYOffset||c.scrollTop,i=e.pageXOffset||c.scrollLeft,{top:j.top+h-f,left:j.left+i-g}):j)},p.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;return p.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(p.css(a,"marginTop"))||0,c+=parseFloat(p.css(a,"marginLeft"))||0),{top:b,left:c}},setOffset:function(a,b,c){var d=p.css(a,"position");d==="static"&&(a.style.position="relative");var e=p(a),f=e.offset(),g=p.css(a,"top"),h=p.css(a,"left"),i=(d==="absolute"||d==="fixed")&&p.inArray("auto",[g,h])>-1,j={},k={},l,m;i?(k=e.position(),l=k.top,m=k.left):(l=parseFloat(g)||0,m=parseFloat(h)||0),p.isFunction(b)&&(b=b.call(a,c,f)),b.top!=null&&(j.top=b.top-f.top+l),b.left!=null&&(j.left=b.left-f.left+m),"using"in b?b.using.call(a,j):e.css(j)}},p.fn.extend({position:function(){if(!this[0])return;var a=this[0],b=this.offsetParent(),c=this.offset(),d=c_.test(b[0].nodeName)?{top:0,left:0}:b.offset();return c.top-=parseFloat(p.css(a,"marginTop"))||0,c.left-=parseFloat(p.css(a,"marginLeft"))||0,d.top+=parseFloat(p.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(p.css(b[0],"borderLeftWidth"))||0,{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||e.body;while(a&&!c_.test(a.nodeName)&&p.css(a,"position")==="static")a=a.offsetParent;return a||e.body})}}),p.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);p.fn[a]=function(e){return p.access(this,function(a,e,f){var g=da(a);if(f===b)return g?c in g?g[c]:g.document.documentElement[e]:a[e];g?g.scrollTo(d?p(g).scrollLeft():f,d?f:p(g).scrollTop()):a[e]=f},a,e,arguments.length,null)}}),p.each({Height:"height",Width:"width"},function(a,c){p.each({padding:"inner"+a,content:c,"":"outer"+a},function(d,e){p.fn[e]=function(e,f){var g=arguments.length&&(d||typeof e!="boolean"),h=d||(e===!0||f===!0?"margin":"border");return p.access(this,function(c,d,e){var f;return p.isWindow(c)?c.document.documentElement["client"+a]:c.nodeType===9?(f=c.documentElement,Math.max(c.body["scroll"+a],f["scroll"+a],c.body["offset"+a],f["offset"+a],f["client"+a])):e===b?p.css(c,d,e,h):p.style(c,d,e,h)},c,g?e:b,g,null)}})}),a.jQuery=a.$=p,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return p})})(window); \ No newline at end of file